1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2001-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 MSLane.h 11 /// @author Christian Roessel 12 /// @author Daniel Krajzewicz 13 /// @author Jakob Erdmann 14 /// @author Christoph Sommer 15 /// @author Tino Morenz 16 /// @author Michael Behrisch 17 /// @author Mario Krumnow 18 /// @author Leonhard Luecken 19 /// @date Mon, 12 Mar 2001 20 /// @version $Id$ 21 /// 22 // Representation of a lane in the micro simulation 23 /****************************************************************************/ 24 #ifndef MSLane_h 25 #define MSLane_h 26 27 28 // =========================================================================== 29 // included modules 30 // =========================================================================== 31 #include <config.h> 32 33 #include <memory> 34 #include <vector> 35 #include <map> 36 #include <deque> 37 #include <cassert> 38 #include <utils/common/Named.h> 39 #include <utils/common/Parameterised.h> 40 #include <utils/common/SUMOVehicleClass.h> 41 #include <utils/vehicle/SUMOVehicle.h> 42 #include <utils/common/NamedRTree.h> 43 #include <utils/geom/PositionVector.h> 44 #include "MSLinkCont.h" 45 #include "MSLeaderInfo.h" 46 #include "MSMoveReminder.h" 47 #include <libsumo/Helper.h> 48 49 #include <utils/foxtools/FXSynchQue.h> 50 #ifdef HAVE_FOX 51 #include <utils/foxtools/FXWorkerThread.h> 52 #endif 53 54 55 // =========================================================================== 56 // class declarations 57 // =========================================================================== 58 class MSEdge; 59 class MSVehicle; 60 class MSLaneChanger; 61 class MSLink; 62 class MSVehicleTransfer; 63 class MSVehicleControl; 64 class OutputDevice; 65 class MSLeaderInfo; 66 67 // =========================================================================== 68 // type definitions 69 // =========================================================================== 70 /// Coverage info 71 typedef std::map<const MSLane*, std::pair<double, double> > LaneCoverageInfo; // also declared in libsumo/Helper.h! 72 73 // =========================================================================== 74 // class definitions 75 // =========================================================================== 76 /** 77 * @class MSLane 78 * @brief Representation of a lane in the micro simulation 79 * 80 * Class which represents a single lane. Somekind of the main class of the 81 * simulation. Allows moving vehicles. 82 */ 83 class MSLane : public Named, public Parameterised { 84 public: 85 /// needs access to myTmpVehicles (this maybe should be done via double-buffering!!!) 86 friend class MSLaneChanger; 87 friend class MSLaneChangerSublane; 88 89 friend class MSQueueExport; 90 friend class AnyVehicleIterator; 91 92 /// Container for vehicles. 93 typedef std::vector<MSVehicle*> VehCont; 94 95 /** Function-object in order to find the vehicle, that has just 96 passed the detector. */ 97 struct VehPosition : public std::binary_function < const MSVehicle*, double, bool > { 98 /// compares vehicle position to the detector position 99 bool operator()(const MSVehicle* cmp, double pos) const; 100 }; 101 102 // TODO: Better documentation 103 /// @brief AnyVehicleIterator is a structure, which manages the iteration through all vehicles on the lane, 104 /// that may be of importance for the car-following dynamics along that lane. The relevant types of vehicles are: 105 /// 1) vehicles with their front on the lane (myVehicles), 106 /// 2) vehicles intersecting the lane but with front on another lane (myPartialVehicles) 107 /// 108 /// In the context of retrieving linkLeaders during lane changing a third group of vehicles is checked: 109 /// 3) vehicles processed during lane changing (myTmpVehicles) 110 class AnyVehicleIterator { 111 public: 112 AnyVehicleIterator( 113 const MSLane* lane, 114 int i1, 115 int i2, 116 int i3, 117 const int i1End, 118 const int i2End, 119 const int i3End, 120 bool downstream = true) : myLane(lane)121 myLane(lane), 122 myI1(i1), 123 myI2(i2), 124 myI3(i3), 125 myI1End(i1End), 126 myI2End(i2End), 127 myI3End(i3End), 128 myDownstream(downstream), 129 myDirection(downstream ? 1 : -1) { 130 } 131 132 bool operator== (AnyVehicleIterator const& other) const { 133 return (myI1 == other.myI1 134 && myI2 == other.myI2 135 && myI3 == other.myI3 136 && myI1End == other.myI1End 137 && myI2End == other.myI2End 138 && myI3End == other.myI3End); 139 } 140 141 bool operator!= (AnyVehicleIterator const& other) const { 142 return !(*this == other); 143 } 144 145 const MSVehicle* operator->() { 146 return **this; 147 } 148 149 const MSVehicle* operator*(); 150 151 AnyVehicleIterator& operator++(); 152 153 private: 154 bool nextIsMyVehicles() const; 155 156 /// @brief the lane that is being iterated 157 const MSLane* myLane; 158 /// @brief index for myVehicles 159 int myI1; 160 /// @brief index for myPartialVehicles 161 int myI2; 162 /// @brief index for myTmpVehicles 163 int myI3; 164 /// @brief end index for myVehicles 165 int myI1End; 166 /// @brief end index for myPartialVehicles 167 int myI2End; 168 /// @brief end index for myTmpVehicles 169 int myI3End; 170 /// @brief iteration direction 171 bool myDownstream; 172 /// @brief index delta 173 int myDirection; 174 175 }; 176 177 178 public: 179 /** @enum ChangeRequest 180 * @brief Requests set via TraCI 181 */ 182 enum CollisionAction { 183 COLLISION_ACTION_NONE, 184 COLLISION_ACTION_WARN, 185 COLLISION_ACTION_TELEPORT, 186 COLLISION_ACTION_REMOVE 187 }; 188 189 /** @brief Constructor 190 * 191 * @param[in] id The lane's id 192 * @param[in] maxSpeed The speed allowed on this lane 193 * @param[in] length The lane's length 194 * @param[in] edge The edge this lane belongs to 195 * @param[in] numericalID The numerical id of the lane 196 * @param[in] shape The shape of the lane 197 * @param[in] width The width of the lane 198 * @param[in] permissions Encoding of the Vehicle classes that may drive on this lane 199 * @param[in] index The index of this lane within its parent edge 200 * @param[in] isRampAccel Whether this lane is an acceleration lane 201 * @see SUMOVehicleClass 202 */ 203 MSLane(const std::string& id, double maxSpeed, double length, MSEdge* const edge, 204 int numericalID, const PositionVector& shape, double width, 205 SVCPermissions permissions, int index, bool isRampAccel); 206 207 208 /// @brief Destructor 209 virtual ~MSLane(); 210 211 /// @brief sets the associated RNG index setRNGIndex(const int rngIndex)212 void setRNGIndex(const int rngIndex) { 213 myRNGIndex = rngIndex; 214 } 215 216 /// @brief returns the associated RNG index getRNGIndex()217 int getRNGIndex() const { 218 return myRNGIndex; 219 } 220 221 /// @brief return the associated RNG getRNG()222 std::mt19937* getRNG() const { 223 return &myRNGs[myRNGIndex]; 224 } 225 226 /// @brief return the number of RNGs getNumRNGs()227 static int getNumRNGs() { 228 return (int)myRNGs.size(); 229 } 230 231 /// @name Additional initialisation 232 /// @{ 233 234 /** @brief Delayed initialization 235 * 236 * Not all lane-members are known at the time the lane is born, above all the pointers 237 * to other lanes, so we have to add them later. 238 * 239 * @param[in] link An outgoing link 240 */ 241 void addLink(MSLink* link); 242 243 /** @brief Adds a neighbor to this lane 244 * 245 * @param[in] id The lane's id 246 */ 247 void addNeigh(const std::string& id); 248 ///@} 249 250 251 252 /// @name interaction with MSMoveReminder 253 /// @{ 254 255 /** @brief Add a move-reminder to move-reminder container 256 * 257 * The move reminder will not be deleted by the lane. 258 * 259 * @param[in] rem The move reminder to add 260 */ 261 virtual void addMoveReminder(MSMoveReminder* rem); 262 263 264 /** @brief Return the list of this lane's move reminders 265 * @return Previously added move reminder 266 */ getMoveReminders()267 inline const std::vector< MSMoveReminder* >& getMoveReminders() const { 268 return myMoveReminders; 269 } 270 ///@} 271 272 273 274 /// @name Vehicle insertion 275 ///@{ 276 277 /** @brief Tries to insert the given vehicle 278 * 279 * The insertion position and speed are determined in dependence 280 * to the vehicle's departure definition, first. 281 * 282 * Then, the vehicle is tried to be inserted into the lane 283 * using these values by a call to "isInsertionSuccess". The result of 284 * "isInsertionSuccess" is returned. 285 * 286 * @param[in] v The vehicle to insert 287 * @return Whether the vehicle could be inserted 288 * @see isInsertionSuccess 289 * @see MSVehicle::getDepartureDefinition 290 * @see MSVehicle::DepartArrivalDefinition 291 */ 292 bool insertVehicle(MSVehicle& v); 293 294 295 /** @brief Tries to insert the given vehicle with the given state (speed and pos) 296 * 297 * Checks whether the vehicle can be inserted at the given position with the 298 * given speed so that no collisions with leader/follower occur and the speed 299 * does not cause unexpected behaviour on consecutive lanes. Returns false 300 * if the vehicle can not be inserted. 301 * 302 * If the insertion can take place, incorporateVehicle() is called and true is returned. 303 * 304 * @param[in] vehicle The vehicle to insert 305 * @param[in] speed The speed with which it shall be inserted 306 * @param[in] pos The position at which it shall be inserted 307 * @param[in] posLat The lateral position at which it shall be inserted 308 * @param[in] recheckNextLanes Forces patching the speed for not being too fast on next lanes 309 * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure 310 * @return Whether the vehicle could be inserted 311 * @see MSVehicle::enterLaneAtInsertion 312 */ 313 bool isInsertionSuccess(MSVehicle* vehicle, double speed, double pos, double posLat, 314 bool recheckNextLanes, 315 MSMoveReminder::Notification notification); 316 317 // XXX: Documentation? 318 bool checkFailure(const MSVehicle* aVehicle, double& speed, double& dist, const double nspeed, const bool patchSpeed, const std::string errorMsg) const; 319 320 /** @brief inserts vehicle as close as possible to the last vehicle on this 321 * lane (or at the end of the lane if there is no leader) 322 */ 323 bool lastInsertion(MSVehicle& veh, double mspeed, double posLat, bool patchSpeed); 324 325 /** @brief Tries to insert the given vehicle on any place 326 * 327 * @param[in] veh The vehicle to insert 328 * @param[in] speed The maximum insertion speed 329 * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure 330 * @return Whether the vehicle could be inserted 331 */ 332 bool freeInsertion(MSVehicle& veh, double speed, double posLat, 333 MSMoveReminder::Notification notification = MSMoveReminder::NOTIFICATION_DEPARTED); 334 335 336 /** @brief Inserts the given vehicle at the given position 337 * 338 * No checks are done, vehicle insertion using this method may 339 * generate collisions (possibly delayed). 340 * @param[in] veh The vehicle to insert 341 * @param[in] pos The position at which the vehicle shall be inserted 342 * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure 343 * @param[in] posLat The lateral position at which the vehicle shall be inserted 344 */ 345 void forceVehicleInsertion(MSVehicle* veh, double pos, MSMoveReminder::Notification notification, double posLat = 0); 346 /// @} 347 348 349 350 /// @name Handling vehicles lapping into several lanes (-> partial occupation) 351 /// or which committed a maneuver that will lead them into another (sublane case -> maneuver reservations) 352 /// @{ 353 /** @brief Sets the information about a vehicle lapping into this lane 354 * 355 * This vehicle is added to myVehicles and may be distinguished from regular 356 * vehicles by the disparity between this lane and v->getLane() 357 * @param[in] v The vehicle which laps into this lane 358 * @return This lane's length 359 */ 360 virtual double setPartialOccupation(MSVehicle* v); 361 362 /** @brief Removes the information about a vehicle lapping into this lane 363 * @param[in] v The vehicle which laps into this lane 364 */ 365 virtual void resetPartialOccupation(MSVehicle* v); 366 367 /** @brief Registers the lane change intentions (towards this lane) for the given vehicle 368 */ 369 virtual void setManeuverReservation(MSVehicle* v); 370 371 /** @brief Unregisters a vehicle, which previously registered for maneuvering into this lane 372 * @param[in] v The vehicle 373 */ 374 virtual void resetManeuverReservation(MSVehicle* v); 375 376 /** @brief Returns the last vehicles on the lane 377 * 378 * The information about the last vehicles in this lanes in all sublanes 379 * occupied by ego are 380 * returned. Partial occupators are included 381 * @param[in] ego The vehicle for which to restrict the returned leaderInfo 382 * @param[in] minPos The minimum position from which to start search for leaders 383 * @param[in] allowCached Whether the cached value may be used 384 * @return Information about the last vehicles 385 */ 386 const MSLeaderInfo getLastVehicleInformation(const MSVehicle* ego, double latOffset, double minPos = 0, bool allowCached = true) const; 387 388 /// @brief analogue to getLastVehicleInformation but in the upstream direction 389 const MSLeaderInfo getFirstVehicleInformation(const MSVehicle* ego, double latOffset, bool onlyFrontOnLane, double maxPos = std::numeric_limits<double>::max(), bool allowCached = true) const; 390 391 /// @} 392 393 /// @name Access to vehicles 394 /// @{ 395 396 /** @brief Returns the number of vehicles on this lane (for which this lane 397 * is responsible) 398 * @return The number of vehicles with their front on this lane 399 */ getVehicleNumber()400 int getVehicleNumber() const { 401 return (int)myVehicles.size(); 402 } 403 404 /** @brief Returns the number of vehicles on this lane (including partial 405 * occupators) 406 * @return The number of vehicles with intersecting this lane 407 */ getVehicleNumberWithPartials()408 int getVehicleNumberWithPartials() const { 409 return (int)myVehicles.size() + (int)myPartialVehicles.size(); 410 } 411 412 /** @brief Returns the number of vehicles partially on this lane (for which this lane 413 * is not responsible) 414 * @return The number of vehicles touching this lane but with their front on another lane 415 */ getPartialVehicleNumber()416 int getPartialVehicleNumber() const { 417 return (int)myPartialVehicles.size(); 418 } 419 420 421 /** @brief Returns the vehicles container; locks it for microsimulation 422 * 423 * Please note that it is necessary to release the vehicles container 424 * afterwards using "releaseVehicles". 425 * @return The vehicles on this lane 426 */ getVehiclesSecure()427 virtual const VehCont& getVehiclesSecure() const { 428 return myVehicles; 429 } 430 431 432 /// @brief begin iterator for iterating over all vehicles touching this lane in downstream direction anyVehiclesBegin()433 AnyVehicleIterator anyVehiclesBegin() const { 434 return AnyVehicleIterator(this, 0, 0, 0, 435 (int)myVehicles.size(), (int)myPartialVehicles.size(), (int)myTmpVehicles.size(), true); 436 } 437 438 /// @brief end iterator for iterating over all vehicles touching this lane in downstream direction anyVehiclesEnd()439 AnyVehicleIterator anyVehiclesEnd() const { 440 return AnyVehicleIterator(this, (int)myVehicles.size(), (int)myPartialVehicles.size(), (int)myTmpVehicles.size(), 441 (int)myVehicles.size(), (int)myPartialVehicles.size(), (int)myTmpVehicles.size(), true); 442 } 443 444 /// @brief begin iterator for iterating over all vehicles touching this lane in upstream direction anyVehiclesUpstreamBegin()445 AnyVehicleIterator anyVehiclesUpstreamBegin() const { 446 return AnyVehicleIterator(this, (int)myVehicles.size() - 1, (int)myPartialVehicles.size() - 1, (int)myTmpVehicles.size() - 1, 447 -1, -1, -1, false); 448 } 449 450 /// @brief end iterator for iterating over all vehicles touching this lane in upstream direction anyVehiclesUpstreamEnd()451 AnyVehicleIterator anyVehiclesUpstreamEnd() const { 452 return AnyVehicleIterator(this, -1, -1, -1, -1, -1, -1, false); 453 } 454 455 /** @brief Allows to use the container for microsimulation again 456 */ releaseVehicles()457 virtual void releaseVehicles() const { } 458 /// @} 459 460 461 462 /// @name Atomar value getter 463 /// @{ 464 465 466 /** @brief Returns this lane's numerical id 467 * @return This lane's numerical id 468 */ getNumericalID()469 inline int getNumericalID() const { 470 return myNumericalID; 471 } 472 473 474 /** @brief Returns this lane's shape 475 * @return This lane's shape 476 */ getShape()477 inline const PositionVector& getShape() const { 478 return myShape; 479 } 480 481 /// @brief return shape.length() / myLength getLengthGeometryFactor()482 inline double getLengthGeometryFactor() const { 483 return myLengthGeometryFactor; 484 } 485 486 /// @brief return whether this lane is an acceleration lane isAccelLane()487 inline bool isAccelLane() const { 488 return myIsRampAccel; 489 } 490 491 /* @brief fit the given lane position to a visibly suitable geometry position 492 * (lane length might differ from geometry length) */ interpolateLanePosToGeometryPos(double lanePos)493 inline double interpolateLanePosToGeometryPos(double lanePos) const { 494 return lanePos * myLengthGeometryFactor; 495 } 496 497 /* @brief fit the given lane position to a visibly suitable geometry position 498 * and return the coordinates */ 499 inline const Position geometryPositionAtOffset(double offset, double lateralOffset = 0) const { 500 return myShape.positionAtOffset(interpolateLanePosToGeometryPos(offset), lateralOffset); 501 } 502 503 /* @brief fit the given geomtry position to a valid lane position 504 * (lane length might differ from geometry length) */ interpolateGeometryPosToLanePos(double geometryPos)505 inline double interpolateGeometryPosToLanePos(double geometryPos) const { 506 return geometryPos / myLengthGeometryFactor; 507 } 508 509 /** @brief Returns the lane's maximum speed, given a vehicle's speed limit adaptation 510 * @param[in] The vehicle to return the adapted speed limit for 511 * @return This lane's resulting max. speed 512 */ getVehicleMaxSpeed(const SUMOTrafficObject * const veh)513 inline double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const { 514 if (myRestrictions != 0) { 515 std::map<SUMOVehicleClass, double>::const_iterator r = myRestrictions->find(veh->getVClass()); 516 if (r != myRestrictions->end()) { 517 return MIN2(veh->getMaxSpeed(), r->second * veh->getChosenSpeedFactor()); 518 } 519 } 520 return MIN2(veh->getMaxSpeed(), myMaxSpeed * veh->getChosenSpeedFactor()); 521 } 522 523 524 /** @brief Returns the lane's maximum allowed speed 525 * @return This lane's maximum allowed speed 526 */ getSpeedLimit()527 inline double getSpeedLimit() const { 528 return myMaxSpeed; 529 } 530 531 532 /** @brief Returns the lane's length 533 * @return This lane's length 534 */ getLength()535 inline double getLength() const { 536 return myLength; 537 } 538 539 540 /** @brief Returns the vehicle class permissions for this lane 541 * @return This lane's allowed vehicle classes 542 */ getPermissions()543 inline SVCPermissions getPermissions() const { 544 return myPermissions; 545 } 546 547 548 /** @brief Returns the lane's width 549 * @return This lane's width 550 */ getWidth()551 double getWidth() const { 552 return myWidth; 553 } 554 555 /** @brief Returns the lane's index 556 * @return This lane's index 557 */ getIndex()558 int getIndex() const { 559 return myIndex; 560 } 561 /// @} 562 563 /// @brief return the index of the link to the next crossing if this is walkingArea, else -1 564 int getCrossingIndex() const; 565 566 567 /// @name Vehicle movement (longitudinal) 568 /// @{ 569 570 /** @brief Compute safe velocities for all vehicles based on positions and 571 * speeds from the last time step. Also registers 572 * ApproachingVehicleInformation for all links 573 * 574 * This method goes through all vehicles calling their "planMove" method. 575 * @see MSVehicle::planMove 576 */ 577 virtual void planMovements(const SUMOTime t); 578 579 /** @brief Register junction approaches for all vehicles after velocities 580 * have been planned. 581 * 582 * This method goes through all vehicles calling their * "setApproachingForAllLinks" method. 583 */ 584 virtual void setJunctionApproaches(const SUMOTime t) const; 585 586 /** @brief This updates the MSLeaderInfo argument with respect to the given MSVehicle. 587 * All leader-vehicles on the same edge, which are relevant for the vehicle 588 * (i.e. with position > vehicle's position) and not already integrated into 589 * the LeaderInfo, are integrated. 590 * The given iterators vehPart and vehRes give access to these vehicles which are 591 * either partial occupators or have issued a maneuver reservation for the lane 592 * (the latter occurs only for the sublane model). 593 */ 594 void updateLeaderInfo(const MSVehicle* veh, VehCont::reverse_iterator& vehPart, VehCont::reverse_iterator& vehRes, MSLeaderInfo& ahead) const; 595 596 /** @brief Executes planned vehicle movements with regards to right-of-way 597 * 598 * This method goes through all vehicles calling their executeMove method 599 * which causes vehicles to update their positions and speeds. 600 * Vehicles wich move to the next lane are stored in the targets lane buffer 601 * 602 * @return Returns true, if all vehicles left the lane. 603 * 604 * @see MSVehicle::executeMove 605 */ 606 virtual void executeMovements(const SUMOTime t); 607 608 /// Insert buffered vehicle into the real lane. 609 virtual void integrateNewVehicles(); 610 611 /// @brief updated current vehicle length sum (delayed to avoid lane-order-dependency) 612 void updateLengthSum(); 613 ///@} 614 615 616 /// @brief short-circut collision check if nothing changed since the last check needsCollisionCheck()617 inline bool needsCollisionCheck() const { 618 return myNeedsCollisionCheck; 619 } 620 621 /// @brief require another collision check due to relevant changes in the simulation requireCollisionCheck()622 inline void requireCollisionCheck() { 623 myNeedsCollisionCheck = true; 624 } 625 626 /// Check if vehicles are too close. 627 virtual void detectCollisions(SUMOTime timestep, const std::string& stage); 628 629 630 /** Returns the information whether this lane may be used to continue 631 the current route */ 632 virtual bool appropriate(const MSVehicle* veh); 633 634 635 /// returns the container with all links !!! 636 const MSLinkCont& getLinkCont() const; 637 638 /// returns the link to the given lane or 0, if it is not connected 639 MSLink* getLinkTo(const MSLane*) const; 640 641 /// Returns the entry link if this is an internal lane, else 0 642 MSLink* getEntryLink() const; 643 644 645 /// Returns true if there is not a single vehicle on the lane. empty()646 bool empty() const { 647 assert(myVehBuffer.size() == 0); 648 return myVehicles.empty(); 649 } 650 651 /** @brief Sets a new maximum speed for the lane (used by TraCI and MSCalibrator) 652 * @param[in] val the new speed in m/s 653 */ 654 void setMaxSpeed(double val); 655 656 /** @brief Sets a new length for the lane (used by TraCI only) 657 * @param[in] val the new length in m 658 */ 659 void setLength(double val); 660 661 /** @brief Returns the lane's edge 662 * @return This lane's edge 663 */ getEdge()664 MSEdge& getEdge() const { 665 return *myEdge; 666 } 667 668 669 /** @brief Returns the lane's follower if it is an internal lane, the edge of the lane otherwise 670 * @return This lane's follower 671 */ 672 const MSEdge* getNextNormal() const; 673 674 675 /** @brief Returns 0 if the lane is not internal. Otherwise the first part of the 676 * connection (sequence of internal lanes along junction) corresponding to the lane 677 * is returned and the offset is set to the distance of the begin of this lane 678 * to the begin of the returned. 679 */ 680 const MSLane* getFirstInternalInConnection(double& offset) const; 681 682 683 /// @brief Static (sic!) container methods 684 /// { 685 686 /** @brief Inserts a MSLane into the static dictionary 687 * 688 * Returns true if the key id isn't already in the dictionary. 689 * Otherwise returns false. 690 * @param[in] id The id of the lane 691 * @param[in] lane The lane itself 692 * @return Whether the lane was added 693 * @todo make non-static 694 * @todo why is the id given? The lane is named 695 */ 696 static bool dictionary(const std::string& id, MSLane* lane); 697 698 699 /** @brief Returns the MSLane associated to the key id 700 * 701 * The lane is returned if exists, otherwise 0 is returned. 702 * @param[in] id The id of the lane 703 * @return The lane 704 */ 705 static MSLane* dictionary(const std::string& id); 706 707 708 /** @brief Clears the dictionary */ 709 static void clear(); 710 711 712 /** @brief Returns the number of stored lanes 713 * @return The number of stored lanes 714 */ dictSize()715 static int dictSize() { 716 return (int)myDict.size(); 717 } 718 719 720 /** @brief Adds the ids of all stored lanes into the given vector 721 * @param[in, filled] into The vector to add the IDs into 722 */ 723 static void insertIDs(std::vector<std::string>& into); 724 725 726 /** @brief Fills the given RTree with lane instances 727 * @param[in, filled] into The RTree to fill 728 * @see TraCILaneRTree 729 */ 730 template<class RTREE> 731 static void fill(RTREE& into); 732 733 734 /// @brief initialize rngs 735 static void initRNGs(const OptionsCont& oc); 736 /// @} 737 738 739 740 // XXX: succLink does not exist... Documentation? 741 /** Same as succLink, but does not throw any assertions when 742 the succeeding link could not be found; 743 Returns the myLinks.end() instead; Further, the number of edges to 744 look forward may be given */ 745 static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle& veh, 746 int nRouteSuccs, 747 const MSLane& succLinkSource, 748 const std::vector<MSLane*>& conts); 749 750 751 /** Returns the information whether the given link shows at the end 752 of the list of links (is not valid) */ 753 bool isLinkEnd(MSLinkCont::const_iterator& i) const; 754 755 /** Returns the information whether the given link shows at the end 756 of the list of links (is not valid) */ 757 bool isLinkEnd(MSLinkCont::iterator& i); 758 759 /** Returns the information whether the lane is has no vehicle and no 760 partial occupation*/ 761 bool isEmpty() const; 762 763 /** Returns whether the lane pertains to an internal edge*/ 764 bool isInternal() const; 765 766 /// @brief returns the last vehicle for which this lane is responsible or 0 767 MSVehicle* getLastFullVehicle() const; 768 769 /// @brief returns the first vehicle for which this lane is responsible or 0 770 MSVehicle* getFirstFullVehicle() const; 771 772 /// @brief returns the last vehicle that is fully or partially on this lane 773 MSVehicle* getLastAnyVehicle() const; 774 775 /// @brief returns the first vehicle that is fully or partially on this lane 776 MSVehicle* getFirstAnyVehicle() const; 777 778 /* @brief remove the vehicle from this lane 779 * @param[notify] whether moveReminders of the vehicle shall be triggered 780 */ 781 virtual MSVehicle* removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify = true); 782 783 void leftByLaneChange(MSVehicle* v); 784 void enteredByLaneChange(MSVehicle* v); 785 786 /** @brief Returns the lane with the given offset parallel to this one or 0 if it does not exist 787 * @param[in] offset The offset of the result lane 788 */ 789 MSLane* getParallelLane(int offset) const; 790 791 792 /** @brief Sets the permissions to the given value. If a transientID is given, the permissions are recored as temporary 793 * @param[in] permissions The new permissions 794 * @param[in] transientID The id of the permission-modification or the special value PERMANENT 795 */ 796 void setPermissions(SVCPermissions permissions, long long transientID); 797 void resetPermissions(long long transientID); 798 799 allowsVehicleClass(SUMOVehicleClass vclass)800 inline bool allowsVehicleClass(SUMOVehicleClass vclass) const { 801 return (myPermissions & vclass) == vclass; 802 } 803 804 void addIncomingLane(MSLane* lane, MSLink* viaLink); 805 806 807 struct IncomingLaneInfo { 808 MSLane* lane; 809 double length; 810 MSLink* viaLink; 811 }; 812 getIncomingLanes()813 const std::vector<IncomingLaneInfo>& getIncomingLanes() const { 814 return myIncomingLanes; 815 } 816 817 818 void addApproachingLane(MSLane* lane, bool warnMultiCon); 819 bool isApproachedFrom(MSEdge* const edge); 820 bool isApproachedFrom(MSEdge* const edge, MSLane* const lane); 821 822 /// @brief Returns vehicle class specific stopOffset for the vehicle 823 double getStopOffset(const MSVehicle* veh) const; 824 825 /// @brief Returns vehicle class specific stopOffsets getStopOffsets()826 const std::map<SVCPermissions, double>& getStopOffsets() const { 827 return myStopOffsets; 828 }; 829 830 /// @brief Set vehicle class specific stopOffsets setStopOffsets(std::map<SVCPermissions,double> stopOffsets)831 void setStopOffsets(std::map<SVCPermissions, double> stopOffsets) { 832 myStopOffsets = stopOffsets; 833 }; 834 835 /// @brief return the sublane followers with the largest missing rear gap among all predecessor lanes (within dist) 836 MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle* ego, double backOffset, 837 bool allSublanes, double searchDist = -1, bool ignoreMinorLinks = false) const; 838 839 /// @brief return by how much further the leader must be inserted to avoid rear end collisions 840 double getMissingRearGap(const MSVehicle* leader, double backOffset, double leaderSpeed) const; 841 842 /** @brief Returns the immediate leader of veh and the distance to veh 843 * starting on this lane 844 * 845 * Iterates over the current lane to find a leader and then uses 846 * getLeaderOnConsecutive() 847 * @param[in] veh The vehicle for which the information shall be computed 848 * @param[in] vehPos The vehicle position relative to this lane (may be negative) 849 * @param[in] bestLaneConts The succeding lanes that shall be checked (if any) 850 * @param[in] dist Optional distance to override default (ego stopDist) 851 * @param[in] checkTmpVehicles Whether myTmpVehicles should be used instead of myVehicles 852 * @return 853 */ 854 std::pair<MSVehicle* const, double> getLeader(const MSVehicle* veh, const double vehPos, const std::vector<MSLane*>& bestLaneConts, double dist = -1, bool checkTmpVehicles = false) const; 855 856 /** @brief Returns the immediate leader and the distance to him 857 * 858 * Goes along the vehicle's estimated used lanes (bestLaneConts). For each link, 859 * it is determined whether the vehicle will pass it. If so, the subsequent lane 860 * is investigated. If a vehicle (leader) is found, it is returned, together with the length 861 * of the investigated lanes until this vehicle's end, including the already seen 862 * place (seen). 863 * 864 * If no leading vehicle was found, <0, -1> is returned. 865 * 866 * Pretty slow, as it has to go along lanes. 867 * 868 * @todo: There are some oddities: 869 * - what about crossing a link at red, or if a link is closed? Has a following vehicle to be regarded or not? 870 * 871 * @param[in] dist The distance to investigate 872 * @param[in] seen The already seen place (normally the place in front on own lane) 873 * @param[in] speed The speed of the vehicle used for determining whether a subsequent link will be opened at arrival time 874 * @param[in] veh The vehicle for which the information shall be computed 875 * @param[in] bestLaneConts The lanes the vehicle will use in future 876 * @return 877 */ 878 std::pair<MSVehicle* const, double> getLeaderOnConsecutive(double dist, double seen, 879 double speed, const MSVehicle& veh, const std::vector<MSLane*>& bestLaneConts) const; 880 881 /// @brief Returns the immediate leaders and the distance to them (as getLeaderOnConsecutive but for the sublane case) 882 void getLeadersOnConsecutive(double dist, double seen, double speed, const MSVehicle* ego, 883 const std::vector<MSLane*>& bestLaneConts, MSLeaderDistanceInfo& result) const; 884 885 /** @brief Returns the most dangerous leader and the distance to him 886 * 887 * Goes along the vehicle's estimated used lanes (bestLaneConts). For each link, 888 * it is determined whether the ego vehicle will pass it. If so, the subsequent lane 889 * is investigated. Check all lanes up to the stopping distance of ego. 890 * Return the leader vehicle (and the gap) which puts the biggest speed constraint on ego. 891 * 892 * If no leading vehicle was found, <0, -1> is returned. 893 * 894 * Pretty slow, as it has to go along lanes. 895 * 896 * @param[in] dist The distance to investigate 897 * @param[in] seen The already seen place (normally the place in front on own lane) 898 * @param[in] speed The speed of the vehicle used for determining whether a subsequent link will be opened at arrival time 899 * @param[in] veh The (ego) vehicle for which the information shall be computed 900 * @return 901 */ 902 std::pair<MSVehicle* const, double> getCriticalLeader(double dist, double seen, double speed, const MSVehicle& veh) const; 903 904 /* @brief return the partial vehicle closest behind ego or 0 905 * if no such vehicle exists */ 906 MSVehicle* getPartialBehind(const MSVehicle* ego) const; 907 908 /// @brief get all vehicles that are inlapping from consecutive edges 909 MSLeaderInfo getPartialBeyond() const; 910 911 /// @brief Returns all vehicles closer than downstreamDist along the along the road network starting on the given 912 /// position. Predecessor lanes are searched upstream for the given upstreamDistance 913 /// @note Re-implementation of the corresponding method in MSDevice_SSM, which cannot be easily adapted, as it gathers 914 /// additional information for conflict lanes, etc. 915 /// @param[in] lanes - sequence of lanes to search along 916 /// @param[in] startPos - start position of the search on the first lane 917 /// @param[in] downstreamDist - distance to search downstream 918 /// @param[in] upstreamDist - distance to search upstream 919 /// @param[in/out] checkedLanes - lanes, which were already scanned (current lane is added, if not present, 920 /// otherwise the scan is aborted; TODO: this may disregard unscanned parts of the lane in specific circular set ups.) 921 /// @return vehs - List of vehicles found 922 std::set<MSVehicle*> getSurroundingVehicles(double startPos, double downstreamDist, double upstreamDist, std::shared_ptr<LaneCoverageInfo> checkedLanes) const; 923 924 /// @brief Returns all vehicles on the lane overlapping with the interval [a,b] 925 /// @note Does not consider vehs with front on subsequent lanes 926 std::set<MSVehicle*> getVehiclesInRange(const double a, const double b) const; 927 928 929 /// @brief Returns all upcoming junctions within given range along the given (non-internal) continuation lanes measured from given position 930 std::vector<const MSJunction*> getUpcomingJunctions(double pos, double range, const std::vector<MSLane*>& contLanes) const; 931 /// @brief Returns all upcoming junctions within given range along the given (non-internal) continuation lanes measured from given position 932 std::vector<const MSLink*> getUpcomingLinks(double pos, double range, const std::vector<MSLane*>& contLanes) const; 933 934 /** @brief get the most likely precedecessor lane (sorted using by_connections_to_sorter). 935 * The result is cached in myLogicalPredecessorLane 936 */ 937 MSLane* getLogicalPredecessorLane() const; 938 939 /** @brief get normal lane leading to this internal lane, for normal lanes, 940 * the lane itself is returned 941 */ 942 const MSLane* getNormalPredecessorLane() const; 943 944 /** @brief return the (first) predecessor lane from the given edge 945 */ 946 MSLane* getLogicalPredecessorLane(const MSEdge& fromEdge) const; 947 948 949 /** Return the main predecessor lane for the current. 950 * If there are several incoming lanes, the first attempt is to return the priorized. 951 * If this does not yield an unambiguous lane, the one with the least angle difference 952 * to the current is selected. 953 */ 954 MSLane* getCanonicalPredecessorLane() const; 955 956 957 /** Return the main successor lane for the current. 958 * If there are several outgoing lanes, the first attempt is to return the priorized. 959 * If this does not yield an unambiguous lane, the one with the least angle difference 960 * to the current is selected. 961 */ 962 MSLane* getCanonicalSuccessorLane() const; 963 964 /// @brief get the state of the link from the logical predecessor to this lane 965 LinkState getIncomingLinkState() const; 966 967 /// @brief get the list of outgoing lanes 968 const std::vector<std::pair<const MSLane*, const MSEdge*> > getOutgoingViaLanes() const; 969 970 /// @name Current state retrieval 971 //@{ 972 973 /** @brief Returns the mean speed on this lane 974 * @return The average speed of vehicles during the last step; default speed if no vehicle was on this lane 975 */ 976 double getMeanSpeed() const; 977 978 /** @brief Returns the overall waiting time on this lane 979 * @return The sum of the waiting time of all vehicles during the last step; 980 */ 981 double getWaitingSeconds() const; 982 983 984 /** @brief Returns the brutto (including minGaps) occupancy of this lane during the last step 985 * @return The occupancy during the last step 986 */ 987 double getBruttoOccupancy() const; 988 989 990 /** @brief Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps) 991 * @return The occupancy during the last step 992 */ 993 double getNettoOccupancy() const; 994 995 996 /** @brief Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the last step 997 * @return The sum of vehicle lengths of vehicles in the last step 998 */ getBruttoVehLenSum()999 inline double getBruttoVehLenSum() const { 1000 return myBruttoVehicleLengthSum; 1001 } 1002 1003 1004 /** @brief Returns the sum of last step CO2 emissions 1005 * @return CO2 emissions of vehicles on this lane during the last step 1006 */ 1007 double getCO2Emissions() const; 1008 1009 1010 /** @brief Returns the sum of last step CO emissions 1011 * @return CO emissions of vehicles on this lane during the last step 1012 */ 1013 double getCOEmissions() const; 1014 1015 1016 /** @brief Returns the sum of last step PMx emissions 1017 * @return PMx emissions of vehicles on this lane during the last step 1018 */ 1019 double getPMxEmissions() const; 1020 1021 1022 /** @brief Returns the sum of last step NOx emissions 1023 * @return NOx emissions of vehicles on this lane during the last step 1024 */ 1025 double getNOxEmissions() const; 1026 1027 1028 /** @brief Returns the sum of last step HC emissions 1029 * @return HC emissions of vehicles on this lane during the last step 1030 */ 1031 double getHCEmissions() const; 1032 1033 1034 /** @brief Returns the sum of last step fuel consumption 1035 * @return fuel consumption of vehicles on this lane during the last step 1036 */ 1037 double getFuelConsumption() const; 1038 1039 1040 /** @brief Returns the sum of last step electricity consumption 1041 * @return electricity consumption of vehicles on this lane during the last step 1042 */ 1043 double getElectricityConsumption() const; 1044 1045 1046 /** @brief Returns the sum of last step noise emissions 1047 * @return noise emissions of vehicles on this lane during the last step 1048 */ 1049 double getHarmonoise_NoiseEmissions() const; 1050 /// @} 1051 setRightSideOnEdge(double value,int rightmostSublane)1052 void setRightSideOnEdge(double value, int rightmostSublane) { 1053 myRightSideOnEdge = value; 1054 myRightmostSublane = rightmostSublane; 1055 } 1056 1057 /// @brief initialized vClass-specific speed limits 1058 void initRestrictions(); 1059 1060 void checkBufferType(); 1061 getRightSideOnEdge()1062 double getRightSideOnEdge() const { 1063 return myRightSideOnEdge; 1064 } 1065 getRightmostSublane()1066 int getRightmostSublane() const { 1067 return myRightmostSublane; 1068 } 1069 getCenterOnEdge()1070 double getCenterOnEdge() const { 1071 return myRightSideOnEdge + 0.5 * myWidth; 1072 } 1073 1074 /// @brief sorts myPartialVehicles 1075 void sortPartialVehicles(); 1076 1077 /// @brief sorts myManeuverReservations 1078 void sortManeuverReservations(); 1079 1080 /// @brief return the opposite direction lane for lane changing or 0 1081 MSLane* getOpposite() const; 1082 1083 /// @brief return the corresponding position on the opposite lane 1084 double getOppositePos(double pos) const; 1085 1086 /* @brief find leader for a vehicle depending on the relative driving direction 1087 * @param[in] ego The ego vehicle 1088 * @param[in] dist The look-ahead distance when looking at consecutive lanes 1089 * @param[in] oppositeDir Whether the lane has the opposite driving direction of ego 1090 * @return the leader vehicle and it's gap to ego 1091 */ 1092 std::pair<MSVehicle* const, double> getOppositeLeader(const MSVehicle* ego, double dist, bool oppositeDir) const; 1093 1094 /* @brief find follower for a vehicle that is located on the opposite of this lane 1095 * @param[in] ego The ego vehicle 1096 * @return the follower vehicle and it's gap to ego 1097 */ 1098 std::pair<MSVehicle* const, double> getOppositeFollower(const MSVehicle* ego) const; 1099 1100 1101 /** @brief Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane) 1102 * @param[in] ego The ego vehicle 1103 * @param[in] egoPos The ego position mapped to the current lane 1104 * @param[in] dist The look-back distance when looking at consecutive lanes 1105 * @param[in] ignoreMinorLinks Whether backward search should stop at minor links 1106 * @return the follower vehicle and it's gap to ego 1107 */ 1108 std::pair<MSVehicle* const, double> getFollower(const MSVehicle* ego, double egoPos, double dist, bool ignoreMinorLinks) const; 1109 1110 1111 ///@brief add parking vehicle. This should only used during state loading 1112 void addParking(MSVehicle* veh); 1113 1114 ///@brief remove parking vehicle. This must be syncrhonized when running with GUI 1115 virtual void removeParking(MSVehicle* veh); 1116 1117 /// @brief retrieve the parking vehicles (see GUIParkingArea) getParkingVehicles()1118 const std::set<const MSVehicle*>& getParkingVehicles() const { 1119 return myParkingVehicles; 1120 } 1121 1122 /// @brief whether this lane is selected in the GUI isSelected()1123 virtual bool isSelected() const { 1124 return false; 1125 } 1126 1127 /// @brief retrieve bidirectional lane or nullptr 1128 MSLane* getBidiLane() const; 1129 1130 /// @brief whether this lane must check for junction collisions 1131 bool mustCheckJunctionCollisions() const; 1132 1133 #ifdef HAVE_FOX getPlanMoveTask(const SUMOTime time)1134 FXWorkerThread::Task* getPlanMoveTask(const SUMOTime time) { 1135 mySimulationTask.init(&MSLane::planMovements, time); 1136 return &mySimulationTask; 1137 } 1138 getExecuteMoveTask(const SUMOTime time)1139 FXWorkerThread::Task* getExecuteMoveTask(const SUMOTime time) { 1140 mySimulationTask.init(&MSLane::executeMovements, time); 1141 return &mySimulationTask; 1142 } 1143 getLaneChangeTask(const SUMOTime time)1144 FXWorkerThread::Task* getLaneChangeTask(const SUMOTime time) { 1145 mySimulationTask.init(&MSLane::changeLanes, time); 1146 return &mySimulationTask; 1147 } 1148 #endif 1149 1150 void changeLanes(const SUMOTime time); 1151 1152 /// @name State saving/loading 1153 /// @{ 1154 1155 /** @brief Saves the state of this lane into the given stream 1156 * 1157 * Basically, a list of vehicle ids 1158 * 1159 * @param[in, filled] out The (possibly binary) device to write the state into 1160 * @todo What about throwing an IOError? 1161 */ 1162 void saveState(OutputDevice& out); 1163 1164 /** @brief Loads the state of this segment with the given parameters 1165 * 1166 * This method is called for every internal que the segment has. 1167 * Every vehicle is retrieved from the given MSVehicleControl and added to this 1168 * lane. 1169 * 1170 * @param[in] vehIDs The vehicle ids for the current que 1171 * @param[in] vc The vehicle control to retrieve references vehicles from 1172 * @todo What about throwing an IOError? 1173 * @todo What about throwing an error if something else fails (a vehicle can not be referenced)? 1174 */ 1175 void loadState(const std::vector<std::string>& vehIDs, MSVehicleControl& vc); 1176 /// @} 1177 1178 1179 /** @brief Callback for visiting the lane when traversing an RTree 1180 * 1181 * This is used in the TraCIServerAPI_Lane for context subscriptions. 1182 * 1183 * @param[in] cont The context doing all the work 1184 * @see libsumo::Helper::LaneStoringVisitor::add 1185 */ visit(const LaneStoringVisitor & cont)1186 void visit(const LaneStoringVisitor& cont) const { 1187 cont.add(this); 1188 } 1189 1190 static void initCollisionOptions(const OptionsCont& oc); 1191 teleportOnCollision()1192 static bool teleportOnCollision() { 1193 return myCollisionAction == COLLISION_ACTION_TELEPORT; 1194 } 1195 getCollisionAction()1196 static CollisionAction getCollisionAction() { 1197 return myCollisionAction; 1198 } 1199 1200 static const long CHANGE_PERMISSIONS_PERMANENT = 0; 1201 static const long CHANGE_PERMISSIONS_GUI = 1; 1202 1203 protected: 1204 /// moves myTmpVehicles int myVehicles after a lane change procedure 1205 virtual void swapAfterLaneChange(SUMOTime t); 1206 1207 /** @brief Inserts the vehicle into this lane, and informs it about entering the network 1208 * 1209 * Calls the vehicles enterLaneAtInsertion function, 1210 * updates statistics and modifies the active state as needed 1211 * @param[in] veh The vehicle to be incorporated 1212 * @param[in] pos The position of the vehicle 1213 * @param[in] speed The speed of the vehicle 1214 * @param[in] posLat The lateral position of the vehicle 1215 * @param[in] at 1216 * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure 1217 */ 1218 virtual void incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat, 1219 const MSLane::VehCont::iterator& at, 1220 MSMoveReminder::Notification notification = MSMoveReminder::NOTIFICATION_DEPARTED); 1221 1222 /// @brief detect whether a vehicle collids with pedestrians on the junction 1223 void detectPedestrianJunctionCollision(const MSVehicle* collider, const PositionVector& colliderBoundary, const MSLane* foeLane, 1224 SUMOTime timestep, const std::string& stage); 1225 1226 /// @brief detect whether there is a collision between the two vehicles 1227 bool detectCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim, 1228 std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove, 1229 std::set<const MSVehicle*>& toTeleport) const; 1230 1231 /// @brief take action upon collision 1232 void handleCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim, 1233 double gap, double latGap, 1234 std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove, 1235 std::set<const MSVehicle*>& toTeleport) const; 1236 1237 /// @brief compute maximum braking distance on this lane 1238 double getMaximumBrakeDist() const; 1239 1240 /* @brief determine depart speed and whether it may be patched 1241 * @param[in] veh The departing vehicle 1242 * @param[out] whether the speed may be patched to account for safety 1243 * @return the depart speed 1244 */ 1245 double getDepartSpeed(const MSVehicle& veh, bool& patchSpeed); 1246 1247 /* @brief determine the lateral depart position 1248 * @param[in] veh The departing vehicle 1249 * @return the lateral depart position 1250 */ 1251 double getDepartPosLat(const MSVehicle& veh); 1252 1253 /** @brief return the maximum safe speed for insertion behind leaders 1254 * (a negative value indicates that safe insertion is impossible) */ 1255 double safeInsertionSpeed(const MSVehicle* veh, double seen, const MSLeaderInfo& leaders, double speed); 1256 1257 /// @brief check whether pedestrians on this lane interfere with vehicle insertion 1258 bool checkForPedestrians(const MSVehicle* aVehicle, double& speed, double& dist, double pos, bool patchSpeed) const; 1259 1260 /// Unique numerical ID (set on reading by netload) 1261 int myNumericalID; 1262 1263 /// The shape of the lane 1264 PositionVector myShape; 1265 1266 /// The lane index 1267 int myIndex; 1268 1269 /** @brief The lane's vehicles. 1270 This container holds all vehicles that have their front (longitudinally) 1271 and their center (laterally) on this lane. 1272 These are the vehicles that this lane is 'responsibly' for (i.e. when executing movements) 1273 1274 The entering vehicles are inserted at the front 1275 of this container and the leaving ones leave from the back, e.g. the 1276 vehicle in front of the junction (often called first) is 1277 myVehicles.back() (if it exists). And if it is an iterator at a 1278 vehicle, ++it points to the vehicle in front. This is the interaction 1279 vehicle. */ 1280 VehCont myVehicles; 1281 1282 /** @brief The lane's partial vehicles. 1283 This container holds all vehicles that are partially on this lane but which are 1284 in myVehicles of another lane. 1285 Reasons for partial occupancies include the following 1286 - the back is still on this lane during regular movement 1287 - the vehicle is performing a continuous lane-change maneuver 1288 - sub-lane simulation where vehicles can freely move laterally among the lanes of an edge 1289 1290 The entering vehicles are inserted at the front 1291 of this container and the leaving ones leave from the back. */ 1292 VehCont myPartialVehicles; 1293 1294 /** @brief Container for lane-changing vehicles. After completion of lane-change- 1295 process, the containers will be swapped with myVehicles. */ 1296 VehCont myTmpVehicles; 1297 1298 /** @brief Buffer for vehicles that moved from their previous lane onto this one. 1299 * Integrated after all vehicles executed their moves*/ 1300 FXSynchQue<MSVehicle*, std::vector<MSVehicle*> > myVehBuffer; 1301 1302 /** @brief The vehicles which registered maneuvering into the lane within their current action step. 1303 * This is currently only relevant for sublane simulation, since continuous lanechanging 1304 * uses the partial vehicle mechanism. 1305 * 1306 * The entering vehicles are inserted at the front 1307 * of this container and the leaving ones leave from the back. */ 1308 VehCont myManeuverReservations; 1309 1310 /* @brief list of vehicles that are parking near this lane 1311 * (not necessarily on the road but having reached their stop on this lane) 1312 * */ 1313 std::set<const MSVehicle*> myParkingVehicles; 1314 1315 /// Lane length [m] 1316 double myLength; 1317 1318 /// Lane width [m] 1319 const double myWidth; 1320 1321 /// Lane's vClass specific stop offset [m]. The map is either of length 0, which means no 1322 /// special stopOffset was set, or of length 1, where the key is a bitset representing a subset 1323 /// of the SUMOVehicleClass Enum and the value is the offset in meters. 1324 std::map<SVCPermissions, double> myStopOffsets; 1325 1326 /// The lane's edge, for routing only. 1327 MSEdge* const myEdge; 1328 1329 /// Lane-wide speedlimit [m/s] 1330 double myMaxSpeed; 1331 1332 /// The vClass permissions for this lane 1333 SVCPermissions myPermissions; 1334 1335 /// The original vClass permissions for this lane (before temporary modifications) 1336 SVCPermissions myOriginalPermissions; 1337 1338 /// The vClass speed restrictions for this lane 1339 const std::map<SUMOVehicleClass, double>* myRestrictions; 1340 1341 /// All direct predecessor lanes 1342 std::vector<IncomingLaneInfo> myIncomingLanes; 1343 1344 /// 1345 mutable MSLane* myLogicalPredecessorLane; 1346 1347 /// Similar to LogicalPredecessorLane, @see getCanonicalPredecessorLane() 1348 mutable MSLane* myCanonicalPredecessorLane; 1349 1350 /// Main successor lane, @see getCanonicalSuccessorLane() 1351 mutable MSLane* myCanonicalSuccessorLane; 1352 1353 /// @brief The current length of all vehicles on this lane, including their minGaps 1354 double myBruttoVehicleLengthSum; 1355 1356 /// @brief The current length of all vehicles on this lane, excluding their minGaps 1357 double myNettoVehicleLengthSum; 1358 1359 /// @brief The length of all vehicles that have left this lane in the current step (this lane, including their minGaps) 1360 double myBruttoVehicleLengthSumToRemove; 1361 1362 /// @brief The length of all vehicles that have left this lane in the current step (this lane, excluding their minGaps) 1363 double myNettoVehicleLengthSumToRemove; 1364 1365 /** The lane's Links to it's succeeding lanes and the default 1366 right-of-way rule, i.e. blocked or not blocked. */ 1367 MSLinkCont myLinks; 1368 1369 /// All direct internal and direct (disregarding internal predecessors) non-internal predecessor lanes of this lane 1370 std::map<MSEdge*, std::vector<MSLane*> > myApproachingLanes; 1371 1372 /// @brief leaders on all sublanes as seen by approaching vehicles (cached) 1373 mutable MSLeaderInfo myLeaderInfo; 1374 /// @brief followers on all sublanes as seen by vehicles on consecutive lanes (cached) 1375 mutable MSLeaderInfo myFollowerInfo; 1376 1377 /// @brief time step for which myLeaderInfo was last updated 1378 mutable SUMOTime myLeaderInfoTime; 1379 /// @brief time step for which myFollowerInfo was last updated 1380 mutable SUMOTime myFollowerInfoTime; 1381 1382 /// @brief precomputed myShape.length / myLength 1383 const double myLengthGeometryFactor; 1384 1385 /// @brief whether this lane is an acceleration lane 1386 const bool myIsRampAccel; 1387 1388 /// @brief the combined width of all lanes with lower index on myEdge 1389 double myRightSideOnEdge; 1390 /// @brief the index of the rightmost sublane of this lane on myEdge 1391 int myRightmostSublane; 1392 1393 /// @brief whether a collision check is currently needed 1394 bool myNeedsCollisionCheck; 1395 1396 // @brief the ids of neighboring lanes 1397 std::vector<std::string> myNeighs; 1398 1399 // @brief transient changes in permissions 1400 std::map<long long, SVCPermissions> myPermissionChanges; 1401 1402 // @brief index of the associated thread-rng 1403 int myRNGIndex; 1404 1405 /// definition of the static dictionary type 1406 typedef std::map< std::string, MSLane* > DictType; 1407 1408 /// Static dictionary to associate string-ids with objects. 1409 static DictType myDict; 1410 1411 static std::vector<std::mt19937> myRNGs; 1412 1413 private: 1414 /// @brief This lane's move reminder 1415 std::vector< MSMoveReminder* > myMoveReminders; 1416 1417 /// @brief the action to take on collisions 1418 static CollisionAction myCollisionAction; 1419 static bool myCheckJunctionCollisions; 1420 static SUMOTime myCollisionStopTime; 1421 static double myCollisionMinGapFactor; 1422 1423 /** 1424 * @class vehicle_position_sorter 1425 * @brief Sorts vehicles by their position (descending) 1426 */ 1427 class vehicle_position_sorter { 1428 public: 1429 /// @brief Constructor vehicle_position_sorter(const MSLane * lane)1430 explicit vehicle_position_sorter(const MSLane* lane) : 1431 myLane(lane) { 1432 } 1433 1434 1435 /** @brief Comparing operator 1436 * @param[in] v1 First vehicle to compare 1437 * @param[in] v2 Second vehicle to compare 1438 * @return Whether the first vehicle is further on the lane than the second 1439 */ 1440 int operator()(MSVehicle* v1, MSVehicle* v2) const; 1441 1442 const MSLane* myLane; 1443 1444 }; 1445 1446 /** 1447 * @class vehicle_reverse_position_sorter 1448 * @brief Sorts vehicles by their position (ascending) 1449 */ 1450 class vehicle_natural_position_sorter { 1451 public: 1452 /// @brief Constructor vehicle_natural_position_sorter(const MSLane * lane)1453 explicit vehicle_natural_position_sorter(const MSLane* lane) : 1454 myLane(lane) { 1455 } 1456 1457 1458 /** @brief Comparing operator 1459 * @param[in] v1 First vehicle to compare 1460 * @param[in] v2 Second vehicle to compare 1461 * @return Whether the first vehicle is further on the lane than the second 1462 */ 1463 int operator()(MSVehicle* v1, MSVehicle* v2) const; 1464 1465 const MSLane* myLane; 1466 1467 }; 1468 1469 /** @class by_connections_to_sorter 1470 * @brief Sorts edges by their angle relative to the given edge (straight comes first) 1471 * 1472 */ 1473 class by_connections_to_sorter { 1474 public: 1475 /// @brief constructor 1476 explicit by_connections_to_sorter(const MSEdge* const e); 1477 1478 /// @brief comparing operator 1479 int operator()(const MSEdge* const e1, const MSEdge* const e2) const; 1480 1481 private: 1482 by_connections_to_sorter& operator=(const by_connections_to_sorter&); // just to avoid a compiler warning 1483 private: 1484 const MSEdge* const myEdge; 1485 double myLaneDir; 1486 }; 1487 1488 1489 1490 /** @class incoming_lane_priority_sorter 1491 * @brief Sorts lanes (IncomingLaneInfos) by their priority or, if this doesn't apply, 1492 * wrt. the angle difference magnitude relative to the target lane's angle (straight comes first) 1493 */ 1494 class incoming_lane_priority_sorter { 1495 public: 1496 /// @brief constructor 1497 explicit incoming_lane_priority_sorter(const MSLane* targetLane); 1498 1499 /// @brief comparing operator 1500 int operator()(const IncomingLaneInfo& lane1, const IncomingLaneInfo& lane2) const; 1501 1502 private: 1503 incoming_lane_priority_sorter& operator=(const incoming_lane_priority_sorter&); // just to avoid a compiler warning 1504 private: 1505 const MSLane* const myLane; 1506 double myLaneDir; 1507 }; 1508 1509 1510 /** @class outgoing_lane_priority_sorter 1511 * @brief Sorts lanes (their origin link) by the priority of their noninternal target edges or, if this doesn't yield an unambiguous result, 1512 * wrt. the angle difference magnitude relative to the target lane's angle (straight comes first) 1513 */ 1514 class outgoing_lane_priority_sorter { 1515 public: 1516 /// @brief constructor 1517 explicit outgoing_lane_priority_sorter(const MSLane* sourceLane); 1518 1519 /// @brief comparing operator 1520 int operator()(const MSLink* link1, const MSLink* link2) const; 1521 1522 private: 1523 outgoing_lane_priority_sorter& operator=(const outgoing_lane_priority_sorter&); // just to avoid a compiler warning 1524 private: 1525 const MSLane* const myLane; 1526 double myLaneDir; 1527 }; 1528 1529 /** 1530 * @class edge_finder 1531 */ 1532 class edge_finder { 1533 public: edge_finder(MSEdge * e)1534 edge_finder(MSEdge* e) : myEdge(e) {} operator()1535 bool operator()(const IncomingLaneInfo& ili) const { 1536 return &(ili.lane->getEdge()) == myEdge; 1537 } 1538 private: 1539 edge_finder& operator=(const edge_finder&); // just to avoid a compiler warning 1540 private: 1541 const MSEdge* const myEdge; 1542 }; 1543 1544 #ifdef HAVE_FOX 1545 /// Type of the function that is called for the simulation stage (e.g. planMovements). 1546 typedef void(MSLane::*Operation)(const SUMOTime); 1547 1548 /** 1549 * @class SimulationTask 1550 * @brief the routing task which mainly calls reroute of the vehicle 1551 */ 1552 class SimulationTask : public FXWorkerThread::Task { 1553 public: SimulationTask(MSLane & l,const SUMOTime time)1554 SimulationTask(MSLane& l, const SUMOTime time) 1555 : myLane(l), myTime(time) {} init(Operation operation,const SUMOTime time)1556 void init(Operation operation, const SUMOTime time) { 1557 myOperation = operation; 1558 myTime = time; 1559 } run(FXWorkerThread *)1560 void run(FXWorkerThread* /*context*/) { 1561 try { 1562 (myLane.*(myOperation))(myTime); 1563 } catch (ProcessError& e) { 1564 WRITE_ERROR(e.what()); 1565 } 1566 } 1567 private: 1568 Operation myOperation; 1569 MSLane& myLane; 1570 SUMOTime myTime; 1571 private: 1572 /// @brief Invalidated assignment operator. 1573 SimulationTask& operator=(const SimulationTask&) = delete; 1574 }; 1575 1576 SimulationTask mySimulationTask; 1577 /// @brief Mutex for access to the cached leader info value 1578 mutable FXMutex myLeaderInfoMutex; 1579 /// @brief Mutex for access to the cached follower info value 1580 mutable FXMutex myFollowerInfoMutex; 1581 #endif 1582 private: 1583 /// @brief invalidated copy constructor 1584 MSLane(const MSLane&); 1585 1586 /// @brief invalidated assignment operator 1587 MSLane& operator=(const MSLane&); 1588 1589 1590 }; 1591 1592 1593 #endif 1594 1595 /****************************************************************************/ 1596 1597