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