1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-2019 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 /****************************************************************************/
10 /// @file    ROEdge.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Christian Roessel
14 /// @author  Michael Behrisch
15 /// @author  Melanie Knocke
16 /// @author  Yun-Pang Floetteroed
17 /// @date    Sept 2002
18 /// @version $Id$
19 ///
20 // A basic edge for routing applications
21 /****************************************************************************/
22 #ifndef ROEdge_h
23 #define ROEdge_h
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #include <config.h>
30 
31 #include <string>
32 #include <map>
33 #include <vector>
34 #include <algorithm>
35 #include <utils/common/Named.h>
36 #include <utils/common/StdDefs.h>
37 #include <utils/common/ValueTimeLine.h>
38 #include <utils/common/SUMOVehicleClass.h>
39 #include <utils/common/RandHelper.h>
40 #include <utils/emissions/PollutantsInterface.h>
41 #include <utils/geom/Boundary.h>
42 #ifdef HAVE_FOX
43 #include <fx.h>
44 #endif
45 #include <utils/vehicle/SUMOVTypeParameter.h>
46 #include "RONode.h"
47 #include "ROVehicle.h"
48 
49 
50 // ===========================================================================
51 // class declarations
52 // ===========================================================================
53 class ROLane;
54 class ROEdge;
55 
56 typedef std::vector<ROEdge*> ROEdgeVector;
57 typedef std::vector<const ROEdge*> ConstROEdgeVector;
58 typedef std::vector<std::pair<const ROEdge*, const ROEdge*> > ROConstEdgePairVector;
59 
60 
61 // ===========================================================================
62 // class definitions
63 // ===========================================================================
64 /**
65  * @class ROEdge
66  * @brief A basic edge for routing applications
67  *
68  * The edge contains two time lines, one for the travel time and one for a second
69  *  measure which may be used for computing the costs of a route. After loading
70  *  the weights, it is needed to call "buildTimeLines" in order to initialise
71  *  these time lines.
72  */
73 class ROEdge : public Named {
74 public:
75     /** @brief Constructor
76      *
77      * @param[in] id The id of the edge
78      * @param[in] from The node the edge begins at
79      * @param[in] to The node the edge ends at
80      * @param[in] index The numeric id of the edge
81      */
82     ROEdge(const std::string& id, RONode* from, RONode* to, int index, const int priority);
83 
84 
85     /// Destructor
86     virtual ~ROEdge();
87 
88 
89     /// @name Set-up methods
90     //@{
91 
92     /** @brief Adds a lane to the edge while loading
93      *
94      * The lane's length is adapted. Additionally, the information about allowed/disallowed
95      *  vehicle classes is patched using the information stored in the lane.
96      *
97      * @param[in] lane The lane to add
98      * @todo What about vehicle-type aware connections?
99      */
100     virtual void addLane(ROLane* lane);
101 
102 
103     /** @brief Adds information about a connected edge
104      *
105      * The edge s is added to "myFollowingEdges" and this edge is added as predecessor to s.
106      * @param[in] s The edge to add
107      * @todo What about vehicle-type aware connections?
108      */
109     virtual void addSuccessor(ROEdge* s, ROEdge* via = nullptr, std::string dir = "");
110 
111 
112     /** @brief Sets the function of the edge
113     * @param[in] func The new function for the edge
114     */
setFunction(SumoXMLEdgeFunc func)115     inline void setFunction(SumoXMLEdgeFunc func) {
116         myFunction = func;
117     }
118 
119 
120     /** @brief Sets whether the edge is a source
121     * @param[in] func The new source functionality for the edge
122     */
123     inline void setSource(const bool isSource = true) {
124         myAmSource = isSource;
125     }
126 
127 
128     /** @brief Sets whether the edge is a sink
129     * @param[in] func The new sink functionality for the edge
130     */
131     inline void setSink(const bool isSink = true) {
132         myAmSink = isSink;
133     }
134 
135 
136     /** @brief Sets the vehicle class specific speed limits of the edge
137      * @param[in] restrictions The restrictions for the edge
138      */
setRestrictions(const std::map<SUMOVehicleClass,double> * restrictions)139     inline void setRestrictions(const std::map<SUMOVehicleClass, double>* restrictions) {
140         myRestrictions = restrictions;
141     }
142 
setTimePenalty(double value)143     inline void setTimePenalty(double value) {
144         myTimePenalty = value;
145     }
146 
147     /// @brief return whether this edge is an internal edge
isInternal()148     inline bool isInternal() const {
149         return myFunction == EDGEFUNC_INTERNAL;
150     }
151 
152     /// @brief return whether this edge is a pedestrian crossing
isCrossing()153     inline bool isCrossing() const {
154         return myFunction == EDGEFUNC_CROSSING;
155     }
156 
157     /// @brief return whether this edge is walking area
isWalkingArea()158     inline bool isWalkingArea() const {
159         return myFunction == EDGEFUNC_WALKINGAREA;
160     }
161 
isTazConnector()162     inline bool isTazConnector() const {
163         return myFunction == EDGEFUNC_CONNECTOR;
164     }
165 
166     /** @brief Builds the internal representation of the travel time/effort
167      *
168      * Should be called after weights / travel times have been loaded.
169      *
170      * In the case "weight-attribute" is one of "CO", "CO2", "HC", "NOx", "PMx", "fuel", or "electricity"
171      *  the proper value (departs/s) is computed and multiplied with the travel time.
172      *
173      * @param[in] measure The name of the measure to use.
174      */
175     void buildTimeLines(const std::string& measure, const bool boundariesOverride);
176     //@}
177 
178 
179 
180     /// @name Getter methods
181     //@{
182 
183     /** @brief Returns the function of the edge
184     * @return This edge's basic function
185     * @see SumoXMLEdgeFunc
186     */
getFunction()187     inline SumoXMLEdgeFunc getFunction() const {
188         return myFunction;
189     }
190 
191 
192     /** @brief Returns whether the edge acts as a sink
193     * @return whether the edge is a sink
194     */
isSink()195     inline bool isSink() const {
196         return myAmSink;
197     }
198 
199 
200     /** @brief Returns the length of the edge
201      * @return This edge's length
202      */
getLength()203     double getLength() const {
204         return myLength;
205     }
206 
207     /** @brief Returns the index (numeric id) of the edge
208      * @return This edge's numerical id
209      */
getNumericalID()210     int getNumericalID() const {
211         return myIndex;
212     }
213 
214 
215     /** @brief Returns the speed allowed on this edge
216      * @return The speed allowed on this edge
217      */
getSpeedLimit()218     double getSpeedLimit() const {
219         return mySpeed;
220     }
221 
222     /// @brief return a lower bound on shape.length() / myLength that is
223     // sufficient for the astar air-distance heuristic
224     double getLengthGeometryFactor() const;
225 
226     /** @brief Returns the lane's maximum speed, given a vehicle's speed limit adaptation
227      * @param[in] The vehicle to return the adapted speed limit for
228      * @return This lane's resulting max. speed
229      */
getVClassMaxSpeed(SUMOVehicleClass vclass)230     inline double getVClassMaxSpeed(SUMOVehicleClass vclass) const {
231         if (myRestrictions != 0) {
232             std::map<SUMOVehicleClass, double>::const_iterator r = myRestrictions->find(vclass);
233             if (r != myRestrictions->end()) {
234                 return r->second;
235             }
236         }
237         return mySpeed;
238     }
239 
240 
241     /** @brief Returns the number of lanes this edge has
242      * @return This edge's number of lanes
243      */
getNumLanes()244     int getNumLanes() const {
245         return (int) myLanes.size();
246     }
247 
248 
249     /** @brief returns the information whether this edge is directly connected to the given
250      *
251      * @param[in] e The edge which may be connected
252      * @param[in] vehicle The vehicle for which the connectivity is checked
253      * @return Whether the given edge is a direct successor to this one
254      */
255     bool isConnectedTo(const ROEdge* const e, const ROVehicle* const vehicle) const;
256 
257 
258     /** @brief Returns whether this edge prohibits the given vehicle to pass it
259      * @param[in] vehicle The vehicle for which the information has to be returned
260      * @return Whether the vehicle must not enter this edge
261      */
prohibits(const ROVehicle * const vehicle)262     inline bool prohibits(const ROVehicle* const vehicle) const {
263         const SUMOVehicleClass vclass = vehicle->getVClass();
264         return (myCombinedPermissions & vclass) != vclass;
265     }
266 
getPermissions()267     inline SVCPermissions getPermissions() const {
268         return myCombinedPermissions;
269     }
270 
271 
272     /** @brief Returns whether this edge succeeding edges prohibit the given vehicle to pass them
273      * @param[in] vehicle The vehicle for which the information has to be returned
274      * @return Whether the vehicle may continue its route on any of the following edges
275      */
276     bool allFollowersProhibit(const ROVehicle* const vehicle) const;
277     //@}
278 
279 
280 
281     /// @name Methods for getting/setting travel time and cost information
282     //@{
283 
284     /** @brief Adds a weight value
285      *
286      * @param[in] value The value to add
287      * @param[in] timeBegin The begin time of the interval the given value is valid for [s]
288      * @param[in] timeEnd The end time of the interval the given value is valid for [s]
289      */
290     void addEffort(double value, double timeBegin, double timeEnd);
291 
292 
293     /** @brief Adds a travel time value
294      *
295      * @param[in] value The value to add
296      * @param[in] timeBegin The begin time of the interval the given value is valid for [s]
297      * @param[in] timeEnd The end time of the interval the given value is valid for [s]
298      */
299     void addTravelTime(double value, double timeBegin, double timeEnd);
300 
301 
302     /** @brief Returns the number of edges this edge is connected to
303      *
304      * If this edge's type is set to "sink", 0 is returned, otherwise
305      *  the number of edges stored in "myFollowingEdges".
306      *
307      * @return The number of edges following this edge
308      */
309     int getNumSuccessors() const;
310 
311 
312     /** @brief Returns the following edges, restricted by vClass
313     * @param[in] vClass The vClass for which to restrict the successors
314     * @return The eligible following edges
315     */
316     const ROEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
317 
318     /** @brief Returns the following edges including vias, restricted by vClass
319     * @param[in] vClass The vClass for which to restrict the successors
320     * @return The eligible following edges
321     */
322     const ROConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
323 
324 
325     /** @brief Returns the number of edges connected to this edge
326      *
327      * If this edge's type is set to "source", 0 is returned, otherwise
328      *  the number of edges stored in "myApproachingEdges".
329      *
330      * @return The number of edges reaching into this edge
331      */
332     int getNumPredecessors() const;
333 
334 
335     /** @brief Returns the edge at the given position from the list of incoming edges
336      * @param[in] pos The position of the list within the list of incoming
337      * @return The incoming edge, stored at position pos
338      */
getPredecessors()339     const ROEdgeVector& getPredecessors() const {
340         return myApproachingEdges;
341     }
342 
343     /// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
344     const ROEdge* getNormalBefore() const;
345 
346     /// @brief if this edge is an internal edge, return its first normal successor, otherwise the edge itself
347     const ROEdge* getNormalAfter() const;
348 
349     /** @brief Returns the effort for this edge
350      *
351      * @param[in] veh The vehicle for which the effort on this edge shall be retrieved
352      * @param[in] time The tim for which the effort shall be returned [s]
353      * @return The effort needed by the given vehicle to pass the edge at the given time
354      * @todo Recheck whether the vehicle's maximum speed is considered
355      */
356     double getEffort(const ROVehicle* const veh, double time) const;
357 
358 
359     /** @brief Returns whether a travel time for this edge was loaded
360      *
361      * @param[in] time The time for which the travel time shall be returned [s]
362      * @return whether a value was loaded
363      */
364     bool hasLoadedTravelTime(double time) const;
365 
366 
367     /** @brief Returns the travel time for this edge
368      *
369      * @param[in] veh The vehicle for which the travel time on this edge shall be retrieved
370      * @param[in] time The time for which the travel time shall be returned [s]
371      * @return The travel time needed by the given vehicle to pass the edge at the given time
372      */
373     double getTravelTime(const ROVehicle* const veh, double time) const;
374 
375 
376     /** @brief Returns the effort for the given edge
377      *
378      * @param[in] edge The edge for which the effort shall be retrieved
379      * @param[in] veh The vehicle for which the effort on this edge shall be retrieved
380      * @param[in] time The time for which the effort shall be returned [s]
381      * @return The effort needed by the given vehicle to pass the edge at the given time
382      * @todo Recheck whether the vehicle's maximum speed is considered
383      */
getEffortStatic(const ROEdge * const edge,const ROVehicle * const veh,double time)384     static inline double getEffortStatic(const ROEdge* const edge, const ROVehicle* const veh, double time) {
385         return edge->getEffort(veh, time);
386     }
387 
388 
389     /** @brief Returns the travel time for the given edge
390      *
391      * @param[in] edge The edge for which the travel time shall be retrieved
392      * @param[in] veh The vehicle for which the travel time on this edge shall be retrieved
393      * @param[in] time The time for which the travel time shall be returned [s]
394      * @return The traveltime needed by the given vehicle to pass the edge at the given time
395      */
getTravelTimeStatic(const ROEdge * const edge,const ROVehicle * const veh,double time)396     static inline double getTravelTimeStatic(const ROEdge* const edge, const ROVehicle* const veh, double time) {
397         return edge->getTravelTime(veh, time);
398     }
399 
getTravelTimeStaticRandomized(const ROEdge * const edge,const ROVehicle * const veh,double time)400     static inline double getTravelTimeStaticRandomized(const ROEdge* const edge, const ROVehicle* const veh, double time) {
401         return edge->getTravelTime(veh, time) * RandHelper::rand(1., gWeightsRandomFactor);
402     }
403 
404 
405     /** @brief Returns a lower bound for the travel time on this edge without using any stored timeLine
406      *
407      * @param[in] veh The vehicle for which the effort on this edge shall be retrieved
408      * @param[in] time The time for which the effort shall be returned [s]
409      */
getMinimumTravelTime(const ROVehicle * const veh)410     inline double getMinimumTravelTime(const ROVehicle* const veh) const {
411         if (isTazConnector()) {
412             return 0;
413         } else if (veh != 0) {
414             return myLength / MIN2(veh->getType()->maxSpeed, veh->getChosenSpeedFactor() * mySpeed);
415         } else {
416             return myLength / mySpeed;
417         }
418     }
419 
420 
421     template<PollutantsInterface::EmissionType ET>
getEmissionEffort(const ROEdge * const edge,const ROVehicle * const veh,double time)422     static double getEmissionEffort(const ROEdge* const edge, const ROVehicle* const veh, double time) {
423         double ret = 0;
424         if (!edge->getStoredEffort(time, ret)) {
425             const SUMOVTypeParameter* const type = veh->getType();
426             const double vMax = MIN2(type->maxSpeed, edge->mySpeed);
427             const double accel = type->getCFParam(SUMO_ATTR_ACCEL, SUMOVTypeParameter::getDefaultAccel(type->vehicleClass)) * type->getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(type->vehicleClass)) / 2.;
428             ret = PollutantsInterface::computeDefault(type->emissionClass, ET, vMax, accel, 0, edge->getTravelTime(veh, time)); // @todo: give correct slope
429         }
430         return ret;
431     }
432 
433 
434     static double getNoiseEffort(const ROEdge* const edge, const ROVehicle* const veh, double time);
435     //@}
436 
437 
438     /// @brief optimistic distance heuristic for use in routing
439     double getDistanceTo(const ROEdge* other, const bool doBoundaryEstimate = false) const;
440 
441 
442     /** @brief Returns all ROEdges */
443     static const ROEdgeVector& getAllEdges();
444 
445     /// @brief Returns the number of edges
dictSize()446     static int dictSize() {
447         return (int)myEdges.size();
448     };
449 
setGlobalOptions(const bool interpolate)450     static void setGlobalOptions(const bool interpolate) {
451         myInterpolate = interpolate;
452     }
453 
454     /// @brief return the coordinates of the center of the given stop
455     static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);
456 
457     /// @brief get edge priority (road class)
getPriority()458     int getPriority() const {
459         return myPriority;
460     }
461 
getFromJunction()462     const RONode* getFromJunction() const {
463         return myFromJunction;
464     }
465 
getToJunction()466     const RONode* getToJunction() const {
467         return myToJunction;
468     }
469 
470 
471     /** @brief Returns this edge's lanes
472      *
473      * @return This edge's lanes
474      */
getLanes()475     const std::vector<ROLane*>& getLanes() const {
476         return myLanes;
477     }
478 protected:
479     /** @brief Retrieves the stored effort
480      *
481      * @param[in] veh The vehicle for which the effort on this edge shall be retrieved
482      * @param[in] time The tim for which the effort shall be returned
483      * @return Whether the effort is given
484      */
485     bool getStoredEffort(double time, double& ret) const;
486 
487 
488 
489 protected:
490     /// @brief the junctions for this edge
491     RONode* myFromJunction;
492     RONode* myToJunction;
493 
494     /// @brief The index (numeric id) of the edge
495     const int myIndex;
496 
497     /// @brief The edge priority (road class)
498     const int myPriority;
499 
500     /// @brief The maximum speed allowed on this edge
501     double mySpeed;
502 
503     /// @brief The length of the edge
504     double myLength;
505 
506     /// @brief whether the edge is a source or a sink
507     bool myAmSink, myAmSource;
508     /// @brief Container storing passing time varying over time for the edge
509     mutable ValueTimeLine<double> myTravelTimes;
510     /// @brief Information whether the time line shall be used instead of the length value
511     bool myUsingTTTimeLine;
512 
513     /// @brief Container storing passing time varying over time for the edge
514     mutable ValueTimeLine<double> myEfforts;
515     /// @brief Information whether the time line shall be used instead of the length value
516     bool myUsingETimeLine;
517 
518     /// @brief Information whether to interpolate at interval boundaries
519     static bool myInterpolate;
520 
521     /// @brief Information whether the edge has reported missing weights
522     static bool myHaveEWarned;
523     /// @brief Information whether the edge has reported missing weights
524     static bool myHaveTTWarned;
525 
526     /// @brief List of edges that may be approached from this edge
527     ROEdgeVector myFollowingEdges;
528 
529     ROConstEdgePairVector myFollowingViaEdges;
530 
531     /// @brief List of edges that approached this edge
532     ROEdgeVector myApproachingEdges;
533 
534     /// @brief The function of the edge
535     SumoXMLEdgeFunc myFunction;
536 
537     /// The vClass speed restrictions for this edge
538     const std::map<SUMOVehicleClass, double>* myRestrictions;
539 
540     /// @brief This edge's lanes
541     std::vector<ROLane*> myLanes;
542 
543     /// @brief The list of allowed vehicle classes combined across lanes
544     SVCPermissions myCombinedPermissions;
545 
546     /// @brief The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start and end node for normal edges
547     Boundary myBoundary;
548 
549     /// @brief flat penalty when computing traveltime
550     double myTimePenalty;
551 
552     static ROEdgeVector myEdges;
553 
554 
555     /// @brief The successors available for a given vClass
556     mutable std::map<SUMOVehicleClass, ROEdgeVector> myClassesSuccessorMap;
557 
558     /// @brief The successors with vias available for a given vClass
559     mutable std::map<SUMOVehicleClass, ROConstEdgePairVector> myClassesViaSuccessorMap;
560 
561 #ifdef HAVE_FOX
562     /// The mutex used to avoid concurrent updates of myClassesSuccessorMap
563     mutable FXMutex myLock;
564 #endif
565 
566 private:
567     /// @brief Invalidated copy constructor
568     ROEdge(const ROEdge& src);
569 
570     /// @brief Invalidated assignment operator
571     ROEdge& operator=(const ROEdge& src);
572 
573 };
574 
575 
576 #endif
577 
578 /****************************************************************************/
579 
580