SUMO - Simulation of Urban MObility
ROEdge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
20 // A basic edge for routing applications
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28 
30 #include <utils/common/ToString.h>
31 #include <algorithm>
32 #include <cassert>
33 #include <iostream>
37 #include "ROLane.h"
38 #include "RONet.h"
39 #include "ROVehicle.h"
40 #include "ROEdge.h"
41 
42 
43 // ===========================================================================
44 // static member definitions
45 // ===========================================================================
46 bool ROEdge::myInterpolate = false;
47 bool ROEdge::myHaveTTWarned = false;
48 bool ROEdge::myHaveEWarned = false;
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
55 ROEdge::ROEdge(const std::string& id, RONode* from, RONode* to, int index, const int priority) :
56  Named(id),
57  myFromJunction(from),
58  myToJunction(to),
59  myIndex(index),
60  myPriority(priority),
61  mySpeed(-1),
62  myLength(0),
63  myAmSink(false),
64  myAmSource(false),
65  myUsingTTTimeLine(false),
66  myUsingETimeLine(false),
67  myCombinedPermissions(0) {
68  while ((int)myEdges.size() <= index) {
69  myEdges.push_back(0);
70  }
71  myEdges[index] = this;
72  if (from == 0 && to == 0) {
73  // TAZ edge, no lanes
75  }
76 }
77 
78 
80  for (std::vector<ROLane*>::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
81  delete(*i);
82  }
83 }
84 
85 
86 void
88  assert(myLanes.empty() || lane->getLength() == myLength);
89  myLength = lane->getLength();
90  const double speed = lane->getSpeed();
91  mySpeed = speed > mySpeed ? speed : mySpeed;
92  myLanes.push_back(lane);
93 
94  // integrate new allowed classes
96 }
97 
98 
99 void
100 ROEdge::addSuccessor(ROEdge* s, ROEdge* via, std::string) {
101  if (find(myFollowingEdges.begin(), myFollowingEdges.end(), s) == myFollowingEdges.end()) {
102  myFollowingEdges.push_back(s);
103  myFollowingViaEdges.push_back(std::make_pair(s, via));
104  if (isTazConnector()) {
106  }
107  if (!isInternal()) {
108  s->myApproachingEdges.push_back(this);
109  if (s->isTazConnector()) {
110  s->myTazBoundary.add(getToJunction()->getPosition());
111  }
112  if (via != nullptr) {
113  if (via->myApproachingEdges.size() == 0) {
114  via->myApproachingEdges.push_back(this);
115  }
116  }
117  }
118  }
119 }
120 
121 
122 void
123 ROEdge::addEffort(double value, double timeBegin, double timeEnd) {
124  myEfforts.add(timeBegin, timeEnd, value);
125  myUsingETimeLine = true;
126 }
127 
128 
129 void
130 ROEdge::addTravelTime(double value, double timeBegin, double timeEnd) {
131  myTravelTimes.add(timeBegin, timeEnd, value);
132  myUsingTTTimeLine = true;
133 }
134 
135 
136 double
137 ROEdge::getEffort(const ROVehicle* const veh, double time) const {
138  double ret = 0;
139  if (!getStoredEffort(time, ret)) {
140  return myLength / MIN2(veh->getType()->maxSpeed, mySpeed);
141  }
142  return ret;
143 }
144 
145 
146 double
147 ROEdge::getDistanceTo(const ROEdge* other) const {
148  if (isTazConnector()) {
149  if (other->isTazConnector()) {
151  }
153  }
154  if (other->isTazConnector()) {
155  return other->myTazBoundary.distanceTo2D(getToJunction()->getPosition());
156  }
158 }
159 
160 
161 bool
162 ROEdge::hasLoadedTravelTime(double time) const {
164 }
165 
166 
167 double
168 ROEdge::getTravelTime(const ROVehicle* const veh, double time) const {
169  if (myUsingTTTimeLine) {
170  if (myTravelTimes.describesTime(time)) {
171  double lineTT = myTravelTimes.getValue(time);
172  if (myInterpolate) {
173  const double inTT = lineTT;
174  const double split = (double)(myTravelTimes.getSplitTime(time, time + inTT) - time);
175  if (split >= 0) {
176  lineTT = myTravelTimes.getValue(time + inTT) * ((double)1. - split / inTT) + split;
177  }
178  }
179  return MAX2(getMinimumTravelTime(veh), lineTT);
180  } else {
181  if (!myHaveTTWarned) {
182  WRITE_WARNING("No interval matches passed time " + toString(time) + " in edge '" + myID + "'.\n Using edge's length / max speed.");
183  myHaveTTWarned = true;
184  }
185  }
186  }
187  const double speed = veh != nullptr ? MIN2(veh->getType()->maxSpeed, veh->getType()->speedFactor.getParameter()[0] * mySpeed) : mySpeed;
188  return myLength / speed;
189 }
190 
191 
192 double
193 ROEdge::getNoiseEffort(const ROEdge* const edge, const ROVehicle* const veh, double time) {
194  double ret = 0;
195  if (!edge->getStoredEffort(time, ret)) {
196  const double v = MIN2(veh->getType()->maxSpeed, edge->mySpeed);
198  }
199  return ret;
200 }
201 
202 
203 bool
204 ROEdge::getStoredEffort(double time, double& ret) const {
205  if (myUsingETimeLine) {
206  if (!myEfforts.describesTime(time)) {
207  if (!myHaveEWarned) {
208  WRITE_WARNING("No interval matches passed time " + toString(time) + " in edge '" + myID + "'.\n Using edge's length / edge's speed.");
209  myHaveEWarned = true;
210  }
211  return false;
212  }
213  if (myInterpolate) {
214  const double inTT = myTravelTimes.getValue(time);
215  const double ratio = (myEfforts.getSplitTime(time, time + inTT) - time) / inTT;
216  if (ratio >= 0.) {
217  ret = ratio * myEfforts.getValue(time) + (1. - ratio) * myEfforts.getValue(time + inTT);
218  return true;
219  }
220  }
221  ret = myEfforts.getValue(time);
222  return true;
223  }
224  return false;
225 }
226 
227 
228 int
230  if (myAmSink) {
231  return 0;
232  }
233  return (int) myFollowingEdges.size();
234 }
235 
236 
237 int
239  if (myAmSource) {
240  return 0;
241  }
242  return (int) myApproachingEdges.size();
243 }
244 
245 
246 const ROEdge*
248  const ROEdge* result = this;
249  while (result->isInternal()) {
250  assert(myApproachingEdges.size() == 1);
251  result = myApproachingEdges.front();
252  }
253  return result;
254 }
255 
256 
257 const ROEdge*
259  const ROEdge* result = this;
260  while (result->isInternal()) {
261  assert(myFollowingEdges.size() == 1);
262  result = myFollowingEdges.front();
263  }
264  return result;
265 }
266 
267 
268 void
269 ROEdge::buildTimeLines(const std::string& measure, const bool boundariesOverride) {
270  if (myUsingETimeLine) {
271  double value = myLength / mySpeed;
273  if (measure == "CO") {
274  value = PollutantsInterface::compute(c, PollutantsInterface::CO, mySpeed, 0, 0) * value; // @todo: give correct slope
275  }
276  if (measure == "CO2") {
277  value = PollutantsInterface::compute(c, PollutantsInterface::CO2, mySpeed, 0, 0) * value; // @todo: give correct slope
278  }
279  if (measure == "HC") {
280  value = PollutantsInterface::compute(c, PollutantsInterface::HC, mySpeed, 0, 0) * value; // @todo: give correct slope
281  }
282  if (measure == "PMx") {
283  value = PollutantsInterface::compute(c, PollutantsInterface::PM_X, mySpeed, 0, 0) * value; // @todo: give correct slope
284  }
285  if (measure == "NOx") {
286  value = PollutantsInterface::compute(c, PollutantsInterface::NO_X, mySpeed, 0, 0) * value; // @todo: give correct slope
287  }
288  if (measure == "fuel") {
289  value = PollutantsInterface::compute(c, PollutantsInterface::FUEL, mySpeed, 0, 0) * value; // @todo: give correct slope
290  }
291  if (measure == "electricity") {
292  value = PollutantsInterface::compute(c, PollutantsInterface::ELEC, mySpeed, 0, 0) * value; // @todo: give correct slope
293  }
294  myEfforts.fillGaps(value, boundariesOverride);
295  }
296  if (myUsingTTTimeLine) {
297  myTravelTimes.fillGaps(myLength / mySpeed, boundariesOverride);
298  }
299 }
300 
301 
302 bool
303 ROEdge::allFollowersProhibit(const ROVehicle* const vehicle) const {
304  for (ROEdgeVector::const_iterator i = myFollowingEdges.begin(); i != myFollowingEdges.end(); ++i) {
305  if (!(*i)->prohibits(vehicle)) {
306  return false;
307  }
308  }
309  return true;
310 }
311 
312 
313 const ROEdgeVector&
315  return myEdges;
316 }
317 
318 
319 const ROEdgeVector&
321  if (vClass == SVC_IGNORING || !RONet::getInstance()->hasPermissions() || isTazConnector()) {
322  return myFollowingEdges;
323  }
324 #ifdef HAVE_FOX
325  FXMutexLock locker(myLock);
326 #endif
327  std::map<SUMOVehicleClass, ROEdgeVector>::const_iterator i = myClassesSuccessorMap.find(vClass);
328  if (i != myClassesSuccessorMap.end()) {
329  // can use cached value
330  return i->second;
331  }
332  // this vClass is requested for the first time. rebuild all successors
333  std::set<ROEdge*> followers;
334  for (const ROLane* const lane : myLanes) {
335  if ((lane->getPermissions() & vClass) != 0) {
336  for (const auto& next : lane->getOutgoingViaLanes()) {
337  if ((next.first->getPermissions() & vClass) != 0) {
338  followers.insert(&next.first->getEdge());
339  }
340  }
341  }
342  }
343  // also add district edges (they are not connected at the lane level
344  for (ROEdgeVector::const_iterator it = myFollowingEdges.begin(); it != myFollowingEdges.end(); ++it) {
345  if ((*it)->isTazConnector()) {
346  followers.insert(*it);
347  }
348  }
349  myClassesSuccessorMap[vClass].insert(myClassesSuccessorMap[vClass].begin(),
350  followers.begin(), followers.end());
351  return myClassesSuccessorMap[vClass];
352 }
353 
354 
357  if (vClass == SVC_IGNORING || !RONet::getInstance()->hasPermissions() || isTazConnector()) {
358  return myFollowingViaEdges;
359  }
360 #ifdef HAVE_FOX
361  FXMutexLock locker(myLock);
362 #endif
363  std::map<SUMOVehicleClass, ROConstEdgePairVector>::const_iterator i = myClassesViaSuccessorMap.find(vClass);
364  if (i != myClassesViaSuccessorMap.end()) {
365  // can use cached value
366  return i->second;
367  }
368  // this vClass is requested for the first time. rebuild all successors
369  std::set<std::pair<const ROEdge*, const ROEdge*> > followers;
370  for (const ROLane* const lane : myLanes) {
371  if ((lane->getPermissions() & vClass) != 0) {
372  for (const auto& next : lane->getOutgoingViaLanes()) {
373  if ((next.first->getPermissions() & vClass) != 0) {
374  followers.insert(std::make_pair(&next.first->getEdge(), next.second));
375  }
376  }
377  }
378  }
379  // also add district edges (they are not connected at the lane level
380  for (const ROEdge* e : myFollowingEdges) {
381  if (e->isTazConnector()) {
382  followers.insert(std::make_pair(e, e));
383  }
384  }
385  myClassesViaSuccessorMap[vClass].insert(myClassesViaSuccessorMap[vClass].begin(),
386  followers.begin(), followers.end());
387  return myClassesViaSuccessorMap[vClass];
388 }
389 
390 
391 bool
392 ROEdge::isConnectedTo(const ROEdge* const e, const ROVehicle* const vehicle) const {
393  const SUMOVehicleClass vClass = (vehicle == 0 ? SVC_IGNORING : vehicle->getVClass());
394  const ROEdgeVector& followers = getSuccessors(vClass);
395  return std::find(followers.begin(), followers.end(), e) != followers.end();
396 }
397 
398 
399 /****************************************************************************/
400 
void fillGaps(T value, bool extendOverBoundaries=false)
Sets a default value for all unset intervals.
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition: Boundary.cpp:223
static ROEdgeVector myEdges
Definition: ROEdge.h:544
std::map< SUMOVehicleClass, ROEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: ROEdge.h:548
SUMOVehicleClass getVClass() const
Definition: RORoutable.h:108
const Position & getPosition() const
Returns the position of the node.
Definition: RONode.h:67
double getSplitTime(double low, double high) const
Returns the time point at which the value changes.
bool isTazConnector() const
Definition: ROEdge.h:158
double myLength
The length of the edge.
Definition: ROEdge.h:499
void addTravelTime(double value, double timeBegin, double timeEnd)
Adds a travel time value.
Definition: ROEdge.cpp:130
A single lane the router may use.
Definition: ROLane.h:50
double mySpeed
The maximum speed allowed on this edge.
Definition: ROEdge.h:496
bool allFollowersProhibit(const ROVehicle *const vehicle) const
Returns whether this edge succeeding edges prohibit the given vehicle to pass them.
Definition: ROEdge.cpp:303
int getNumSuccessors() const
Returns the number of edges this edge is connected to.
Definition: ROEdge.cpp:229
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
double getLength() const
Returns the length of the lane.
Definition: ROLane.h:71
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:243
static bool myInterpolate
Information whether to interpolate at interval boundaries.
Definition: ROEdge.h:514
Boundary myTazBoundary
The bounding rectangle of incoming or outgoing edges for taz connectors.
Definition: ROEdge.h:542
std::vector< double > & getParameter()
Returns the parameters of this distribution.
const RONode * getFromJunction() const
Definition: ROEdge.h:457
virtual void addLane(ROLane *lane)
Adds a lane to the edge while loading.
Definition: ROEdge.cpp:87
bool describesTime(double time) const
Returns whether a value for the given time is known.
T MAX2(T a, T b)
Definition: StdDefs.h:76
ROConstEdgePairVector myFollowingViaEdges
Definition: ROEdge.h:524
bool myAmSource
Definition: ROEdge.h:502
double getEffort(const ROVehicle *const veh, double time) const
Returns the effort for this edge.
Definition: ROEdge.cpp:137
static double computeNoise(SUMOEmissionClass c, double v, double a)
Returns the noise produced by the a vehicle of the given type at the given speed. ...
const SVCPermissions SVCAll
all VClasses are allowed
const RONode * getToJunction() const
Definition: ROEdge.h:461
SVCPermissions myCombinedPermissions
The list of allowed vehicle classes combined across lanes.
Definition: ROEdge.h:539
void add(double begin, double end, T value)
Adds a value for a time interval into the container.
Definition: ValueTimeLine.h:62
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:242
static RONet * getInstance()
Returns the pointer to the unique instance of RONet (singleton).
Definition: RONet.cpp:55
double getMinimumTravelTime(const ROVehicle *const veh) const
Returns a lower bound for the travel time on this edge without using any stored timeLine.
Definition: ROEdge.h:408
ROEdgeVector myFollowingEdges
List of edges that may be approached from this edge.
Definition: ROEdge.h:522
int getNumPredecessors() const
Returns the number of edges connected to this edge.
Definition: ROEdge.cpp:238
double getDistanceTo(const ROEdge *other) const
optimistic distance heuristic for use in routing
Definition: ROEdge.cpp:147
bool hasLoadedTravelTime(double time) const
Returns whether a travel time for this edge was loaded.
Definition: ROEdge.cpp:162
A vehicle as used by router.
Definition: ROVehicle.h:53
double maxSpeed
The vehicle type&#39;s maximum speed [m/s].
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
void buildTimeLines(const std::string &measure, const bool boundariesOverride)
Builds the internal representation of the travel time/effort.
Definition: ROEdge.cpp:269
bool myUsingTTTimeLine
Information whether the time line shall be used instead of the length value.
Definition: ROEdge.h:506
T getValue(double time) const
Returns the value for the given time.
Definition: ValueTimeLine.h:96
const ROEdge * getNormalAfter() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself ...
Definition: ROEdge.cpp:258
static bool myHaveEWarned
Information whether the edge has reported missing weights.
Definition: ROEdge.h:517
int SUMOEmissionClass
bool myUsingETimeLine
Information whether the time line shall be used instead of the length value.
Definition: ROEdge.h:511
std::vector< ROEdge * > ROEdgeVector
Definition: RODFRouteDesc.h:36
void addEffort(double value, double timeBegin, double timeEnd)
Adds a weight value.
Definition: ROEdge.cpp:123
bool myAmSink
whether the edge is a source or a sink
Definition: ROEdge.h:502
bool getStoredEffort(double time, double &ret) const
Retrieves the stored effort.
Definition: ROEdge.cpp:204
T MIN2(T a, T b)
Definition: StdDefs.h:70
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
std::vector< std::pair< const ROEdge *, const ROEdge * > > ROConstEdgePairVector
Definition: ROEdge.h:57
SVCPermissions getPermissions() const
Returns the list of allowed vehicle classes.
Definition: ROLane.h:87
std::vector< ROLane * > myLanes
This edge&#39;s lanes.
Definition: ROEdge.h:536
ValueTimeLine< double > myEfforts
Container storing passing time varying over time for the edge.
Definition: ROEdge.h:509
virtual ~ROEdge()
Destructor.
Definition: ROEdge.cpp:79
A basic edge for routing applications.
Definition: ROEdge.h:72
Base class for objects which have an id.
Definition: Named.h:49
double getSpeed() const
Returns the maximum speed allowed on this lane.
Definition: ROLane.h:79
bool isInternal() const
return whether this edge is an internal edge
Definition: ROEdge.h:144
std::string myID
The name of the object.
Definition: Named.h:121
static double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const std::map< int, double > *param=0)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
const SUMOVTypeParameter * getType() const
Returns the type of the routable.
Definition: RORoutable.h:85
static SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc=SVC_IGNORING)
Checks whether the string describes a known vehicle class.
ROEdge(const std::string &id, RONode *from, RONode *to, int index, const int priority)
Constructor.
Definition: ROEdge.cpp:55
ROEdgeVector myApproachingEdges
List of edges that approached this edge.
Definition: ROEdge.h:527
bool isConnectedTo(const ROEdge *const e, const ROVehicle *const vehicle) const
returns the information whether this edge is directly connected to the given
Definition: ROEdge.cpp:392
virtual void addSuccessor(ROEdge *s, ROEdge *via=nullptr, std::string dir="")
Adds information about a connected edge.
Definition: ROEdge.cpp:100
std::map< SUMOVehicleClass, ROConstEdgePairVector > myClassesViaSuccessorMap
The successors with vias available for a given vClass.
Definition: ROEdge.h:551
static const ROEdgeVector & getAllEdges()
Returns all ROEdges.
Definition: ROEdge.cpp:314
double getTravelTime(const ROVehicle *const veh, double time) const
Returns the travel time for this edge.
Definition: ROEdge.cpp:168
const ROEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: ROEdge.cpp:320
static double getNoiseEffort(const ROEdge *const edge, const ROVehicle *const veh, double time)
Definition: ROEdge.cpp:193
ValueTimeLine< double > myTravelTimes
Container storing passing time varying over time for the edge.
Definition: ROEdge.h:504
const ROConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges including vias, restricted by vClass.
Definition: ROEdge.cpp:356
Base class for nodes used by the router.
Definition: RONode.h:46
static bool myHaveTTWarned
Information whether the edge has reported missing weights.
Definition: ROEdge.h:519
const ROEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself ...
Definition: ROEdge.cpp:247
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
Distribution_Parameterized speedFactor
The factor by which the maximum speed may deviate from the allowed max speed on the street...
SUMOEmissionClass emissionClass
The emission class of this vehicle.
vehicles ignoring classes