LCOV - code coverage report
Current view: top level - src/microsim - MSLink.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 74 74
Test Date: 2026-03-26 16:31:35 Functions: - 0 0

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2002-2026 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSLink.h
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // A connection between lanes
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : 
      25              : #include <vector>
      26              : #include <set>
      27              : #include <utils/common/SUMOTime.h>
      28              : #include <utils/common/SUMOVehicleClass.h>
      29              : #include <utils/vehicle/SUMOVehicle.h>
      30              : #include <utils/xml/SUMOXMLDefinitions.h>
      31              : #include "MSLane.h"
      32              : 
      33              : 
      34              : // ===========================================================================
      35              : // class declarations
      36              : // ===========================================================================
      37              : class MSLane;
      38              : class MSJunction;
      39              : class MSVehicle;
      40              : class MSPerson;
      41              : class OutputDevice;
      42              : class MSTrafficLightLogic;
      43              : 
      44              : 
      45              : // ===========================================================================
      46              : // class definitions
      47              : // ===========================================================================
      48              : /**
      49              :  * @class MSLinks
      50              :  * @brief A connection between lanes
      51              :  *
      52              :  * A link is basically a connection between two lanes, stored within the
      53              :  *  originating (the one that is being left) lane and pointing to the
      54              :  *  approached lane. When using inner-junction simulation, additionally
      55              :  *  a "via-lane" is stored, the one that is used to cross the junction
      56              :  *  and which represents the links shape.
      57              :  *
      58              :  * Because right-of-way rules are controlled by the junctions, the link
      59              :  *  stores the information about where to write information about approaching
      60              :  *  vehicles (the "request") and where to get the information whether the
      61              :  *  vehicle really may drive (the "respond").
      62              :  *
      63              :  * Because a link is a connection over a junction, it basically also has a
      64              :  *  length. This length is needed to assure that vehicles have the correct halting
      65              :  *  distance before approaching the link. In the case of using internal lanes,
      66              :  *  the link's length is 0.
      67              :  */
      68              : class MSLink {
      69              : public:
      70              : 
      71              :     /** @enum LinkLeaderFlag
      72              :      * @brief additional information for link leaders
      73              :      */
      74              :     enum LinkLeaderFlag {
      75              :         /// @brief vehicle is in the way
      76              :         LL_IN_THE_WAY = 1 << 0,
      77              :         /// @brief link leader is passing from left to right
      78              :         LL_FROM_LEFT = 1 << 1,
      79              :         /// @brief link leader is coming from the same (normal) lane
      80              :         LL_SAME_SOURCE = 1 << 2,
      81              :         /// @brief link leader is targeting the same outgoing lane
      82              :         LL_SAME_TARGET = 1 << 3
      83              :     };
      84              : 
      85              :     struct LinkLeader {
      86     22269393 :         LinkLeader(MSVehicle* _veh, double _gap, double _distToCrossing, int _llFlags = LL_FROM_LEFT, double _latOffst = 0) :
      87     22269393 :             vehAndGap(std::make_pair(_veh, _gap)),
      88     22269393 :             distToCrossing(_distToCrossing),
      89     22269393 :             llFlags(_llFlags),
      90     22269393 :             latOffset(_latOffst)
      91              :         { }
      92              : 
      93              :         inline bool fromLeft() const {
      94       109620 :             return (llFlags & LL_FROM_LEFT) != 0;
      95              :         }
      96              :         inline bool inTheWay() const {
      97        67719 :             return (llFlags & LL_IN_THE_WAY) != 0;
      98              :         }
      99              :         inline bool sameTarget() const {
     100       863671 :             return (llFlags & LL_SAME_TARGET) != 0;
     101              :         }
     102              :         inline bool sameSource() const {
     103       520576 :             return (llFlags & LL_SAME_SOURCE) != 0;
     104              :         }
     105              : 
     106              :         std::pair<MSVehicle*, double> vehAndGap;
     107              :         double distToCrossing;
     108              :         int llFlags;
     109              :         double latOffset;
     110              : 
     111              :     };
     112              : 
     113              :     typedef std::vector<LinkLeader> LinkLeaders;
     114              : 
     115              :     /** @struct ApproachingVehicleInformation
     116              :      * @brief A structure holding the information about vehicles approaching a link
     117              :      */
     118              :     struct ApproachingVehicleInformation {
     119              :         /** @brief Constructor
     120              :          * @param[in] waitingTime The time during which the vehicle is waiting at this link
     121              :          *   this needs to be placed here because MSVehicle::myWaitingTime is updated in between
     122              :          *   calls to opened() causing order dependencies
     123              :          **/
     124              :         ApproachingVehicleInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime,
     125              :                                       const double _arrivalSpeed, const double _leaveSpeed,
     126              :                                       const bool _willPass,
     127              :                                       const double _arrivalSpeedBraking,
     128              :                                       const SUMOTime _waitingTime,
     129              :                                       const double _dist,
     130              :                                       const double _speed,
     131              :                                       const double _latOffset
     132    875158448 :                                      ) :
     133    875158448 :             arrivalTime(_arrivalTime), leavingTime(_leavingTime),
     134    875158448 :             arrivalSpeed(_arrivalSpeed), leaveSpeed(_leaveSpeed),
     135    875158448 :             willPass(_willPass),
     136    875158448 :             arrivalSpeedBraking(_arrivalSpeedBraking),
     137    875158448 :             waitingTime(_waitingTime),
     138    875158448 :             dist(_dist),
     139    875158448 :             speed(_speed),
     140    872237891 :             latOffset(_latOffset) {
     141      2920557 :         }
     142              : 
     143              :         /// @brief The time the vehicle's front arrives at the link
     144              :         const SUMOTime arrivalTime;
     145              :         /// @brief The estimated time at which the vehicle leaves the link
     146              :         const SUMOTime leavingTime;
     147              :         /// @brief The estimated speed with which the vehicle arrives at the link (for headway computation)
     148              :         const double arrivalSpeed;
     149              :         /// @brief The estimated speed with which the vehicle leaves the link (for headway computation)
     150              :         const double leaveSpeed;
     151              :         /// @brief Whether the vehicle wants to pass the link (@todo: check semantics)
     152              :         const bool willPass;
     153              :         /// @brief The estimated speed with which the vehicle arrives at the link if it starts braking(for headway computation)
     154              :         const double arrivalSpeedBraking;
     155              :         /// @brief The waiting duration at the current link
     156              :         const SUMOTime waitingTime;
     157              :         /// @brief The distance up to the current link
     158              :         const double dist;
     159              :         /// @brief The current speed
     160              :         const double speed;
     161              :         /// @brief The lateral offset from the center of the entering lane
     162              :         const double latOffset;
     163              : 
     164              :     };
     165              : 
     166              :     /** @struct ApproachingPersonInformation
     167              :      * @brief A structure holding the information about persons approaching a pedestrian crossing link
     168              :      */
     169              :     struct ApproachingPersonInformation {
     170              :         /** @brief Constructor
     171              :          * @param[in] waitingTime The time during which the vehicle is waiting at this link
     172              :          *   this needs to be placed here because MSVehicle::myWaitingTime is updated in between
     173              :          *   calls to opened() causing order dependencies
     174              :          **/
     175       487479 :         ApproachingPersonInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime) :
     176       487479 :             arrivalTime(_arrivalTime), leavingTime(_leavingTime) {}
     177              :         /// @brief The time the vehicle's front arrives at the link
     178              :         const SUMOTime arrivalTime;
     179              :         /// @brief The estimated time at which the vehicle leaves the link
     180              :         const SUMOTime leavingTime;
     181              :     };
     182              : 
     183              :     typedef std::map<const SUMOVehicle*, const ApproachingVehicleInformation, ComparatorNumericalIdLess> ApproachInfos;
     184              :     typedef std::vector<const SUMOTrafficObject*> BlockingFoes;
     185              :     typedef std::map<const MSPerson*, ApproachingPersonInformation> PersonApproachInfos;
     186              : 
     187              :     enum ConflictFlag {
     188              :         CONFLICT_DEFAULT,
     189              :         CONFLICT_DUMMY_MERGE,
     190              :         CONFLICT_NO_INTERSECTION,
     191              :         CONFLICT_STOP_AT_INTERNAL_JUNCTION,
     192              :         CONFLICT_SIBLING_CONTINUATION
     193              :     };
     194              : 
     195              :     /// @brief pre-computed information for conflict points
     196              :     struct ConflictInfo {
     197              : 
     198      4722243 :         ConflictInfo(double lbc, double cs, ConflictFlag fl = CONFLICT_DEFAULT) :
     199      4499784 :             foeConflictIndex(-1),
     200      4722243 :             lengthBehindCrossing(lbc),
     201      4722243 :             conflictSize(cs),
     202      4722243 :             flag(fl)
     203              :         {}
     204              :         /// @brief the conflict from the perspective of the foe
     205              :         int foeConflictIndex;
     206              :         /// @brief length of internal lane after the crossing point
     207              :         double lengthBehindCrossing;
     208              :         /// @brief the length of the conflict space
     209              :         double conflictSize;
     210              : 
     211              :         ConflictFlag flag;
     212              : 
     213              :         double getFoeLengthBehindCrossing(const MSLink* foeExitLink) const;
     214              :         double getFoeConflictSize(const MSLink* foeExitLink) const;
     215              :         double getLengthBehindCrossing(const MSLink* exitLink) const;
     216              :     };
     217              : 
     218              :     /// @brief holds user defined conflict positions (must be interpreted for the correct exitLink)
     219              :     struct CustomConflict {
     220            4 :         CustomConflict(const MSLane* f, const MSLane* t, double s, double e) :
     221            4 :             from(f), to(t), startPos(s), endPos(e) {}
     222              :         const MSLane* from;
     223              :         const MSLane* to;
     224              :         double startPos;
     225              :         double endPos;
     226              :     };
     227              : 
     228              :     /// @brief Function-object for stable sorting MSLinks with numerical lane ids
     229              :     struct ComparatorNumericalLaneIdLess {
     230              :         bool operator()(const MSLink* const a, const MSLink* const b) const {
     231              :             return (a->getLane()->getNumericalID() < b->getLane()->getNumericalID())
     232        27622 :                    || (a->getLane()->getNumericalID() == b->getLane()->getNumericalID() && a->getIndex() < b->getIndex());
     233              :         }
     234              :     };
     235              : 
     236              : 
     237              :     /** @brief Constructor for simulation which uses internal lanes
     238              :      *
     239              :      * @param[in] succLane The lane approached by this link
     240              :      * @param[in] via The lane to use within the junction
     241              :      * @param[in] dir The direction of this link
     242              :      * @param[in] state The state of this link
     243              :      * @param[in] length The length of this link
     244              :      */
     245              :     MSLink(MSLane* predLane,
     246              :            MSLane* succLane,
     247              :            MSLane* via,
     248              :            LinkDirection dir,
     249              :            LinkState state,
     250              :            double length,
     251              :            double foeVisibilityDistance,
     252              :            bool keepClear,
     253              :            MSTrafficLightLogic* logic,
     254              :            int tlLinkIdx,
     255              :            bool indirect);
     256              : 
     257              : 
     258              :     /// @brief Destructor
     259              :     ~MSLink();
     260              : 
     261              :     void addCustomConflict(const MSLane* from, const MSLane* to, double startPos, double endPos);
     262              : 
     263              :     /** @brief Sets the request information
     264              :      *
     265              :      * Because traffic lights and junction logics are loaded after links,
     266              :      *  we have to assign the information about the right-of-way
     267              :      *  requests and responses after the initialisation.
     268              :      * @todo Unsecure!
     269              :      */
     270              :     void setRequestInformation(int index, bool hasFoes, bool isCont,
     271              :                                const std::vector<MSLink*>& foeLinks, const std::vector<MSLane*>& foeLanes,
     272              :                                MSLane* internalLaneBefore = 0);
     273              : 
     274              :     /// @brief add walkingarea as foe (when entering the junction)
     275              :     void addWalkingAreaFoe(const MSLane* lane) {
     276         5612 :         myWalkingAreaFoe = lane;
     277         5612 :     }
     278              : 
     279              :     /// @brief add walkingarea as foe (when leaving the junction)
     280              :     void addWalkingAreaFoeExit(const MSLane* lane) {
     281         5694 :         myWalkingAreaFoeExit = lane;
     282         5694 :     }
     283              : 
     284              :     /// @brief get walkingarea as foes
     285              :     const MSLane* getWalkingAreaFoe() {
     286      3000761 :         return myWalkingAreaFoe;
     287              :     }
     288              :     const MSLane* getWalkingAreaFoeExit() {
     289      2999853 :         return myWalkingAreaFoeExit;
     290              :     }
     291              : 
     292              :     /** @brief Sets the information about an approaching vehicle
     293              :      *
     294              :      * The information is stored in myApproachingVehicles.
     295              :      */
     296              :     void setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime,
     297              :                         const double arrivalSpeed, const double leaveSpeed, const bool setRequest,
     298              :                         const double arrivalSpeedBraking,
     299              :                         const SUMOTime waitingTime, double dist, double latOffset);
     300              : 
     301              :     /** @brief Sets the information about an approaching vehicle */
     302              :     void setApproaching(const SUMOVehicle* approaching, ApproachingVehicleInformation ai);
     303              : 
     304              :     /** @brief Sets the information about an approaching person (only for a pedestrian crossing) */
     305              :     void setApproachingPerson(const MSPerson* approaching, const SUMOTime arrivalTime, const SUMOTime leaveTime);
     306              : 
     307              :     /// @brief removes the vehicle from myApproachingVehicles
     308              :     void removeApproaching(const SUMOVehicle* veh);
     309              : 
     310              :     /// @brief removes the person from myApproachingPersons
     311              :     void removeApproachingPerson(const MSPerson* person);
     312              : 
     313              :     /* @brief return information about this vehicle if it is registered as
     314              :      * approaching (dummy values otherwise)
     315              :      * @note used for visualisation of link items */
     316              :     ApproachingVehicleInformation getApproaching(const SUMOVehicle* veh) const;
     317              :     const ApproachingVehicleInformation* getApproachingPtr(const SUMOVehicle* veh) const;
     318              : 
     319              :     /// @brief return all approaching vehicles
     320              :     const ApproachInfos& getApproaching() const {
     321              :         return myApproachingVehicles;
     322              :     }
     323              : 
     324              :     /// @brief return all approaching vehicles
     325              :     const PersonApproachInfos* getApproachingPersons() const {
     326        81181 :         return myApproachingPersons;
     327              :     }
     328              : 
     329              :     /** @brief Remove all approaching vehicles before quick-loading state */
     330              :     void clearState();
     331              : 
     332              :     /** @brief Returns the information whether the link may be passed
     333              :      *
     334              :      * Valid after the junctions have set their reponds
     335              :      *
     336              :      * @param[in] collectFoes If a vector is passed, all blocking foes are collected and inserted into this vector
     337              :      * @return Whether this link may be passed.
     338              :      */
     339              :     bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength,
     340              :                 double impatience, double decel, SUMOTime waitingTime,
     341              :                 double posLat = 0,
     342              :                 BlockingFoes* collectFoes = nullptr,
     343              :                 bool ignoreRed = false,
     344              :                 const SUMOTrafficObject* ego = nullptr,
     345              :                 double dist = -1) const;
     346              : 
     347              :     /** @brief Returns the information whether this link is blocked
     348              :      * Valid after the vehicles have set their requests
     349              :      * @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe
     350              :      * @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe
     351              :      * @param[in] arrivalSpeed The speed with which the checking vehicle plans to arrive at the link
     352              :      * @param[in] leaveSpeed The speed with which the checking vehicle plans to leave the link
     353              :      * @param[in] sameTargetLane Whether the link that calls this method has the same target lane as this link
     354              :      * @param[in] impatience The impatience of the checking vehicle
     355              :      * @param[in] decel The maximum deceleration of the checking vehicle
     356              :      * @param[in] waitingTime The waiting time of the checking vehicle
     357              :      * @param[in] collectFoes If a vector is passed the return value is always False, instead all blocking foes are collected and inserted into this vector
     358              :      * @param[in] lastWasContRed Whether the link which is checked, is an internal junction link where the entry has red
     359              :      * @return Whether this link is blocked
     360              :      * @note Since this needs to be called without a SUMOVehicle (TraCI), we cannot simply pass the checking vehicle itself
     361              :      **/
     362              :     bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
     363              :                        bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
     364              :                        BlockingFoes* collectFoes = nullptr, const SUMOTrafficObject* ego = nullptr, bool lastWasContRed = false, double dist = -1) const;
     365              : 
     366              : 
     367              :     /** @brief Returns the information whether a vehicle is approaching on one of the link's foe streams
     368              :      *
     369              :      * Valid after the vehicles have set their requests
     370              :      * @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe
     371              :      * @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe
     372              :      * @param[in] speed The speed with which the checking vehicle plans to leave the link
     373              :      * @param[in] decel The maximum deceleration of the checking vehicle
     374              :      * @return Whether a foe of this link is approaching
     375              :      */
     376              :     bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, double speed, double decel) const;
     377              : 
     378              :     /** @brief get the foe vehicle that is closest to the intersection or nullptr along with the foe link
     379              :      * This function is used for finding circular deadlock at right_before_left junctions
     380              :      * @param[in] wrapAround The link on which the ego vehicle wants to enter the junction
     381              :     */
     382              :     std::pair<const SUMOVehicle*, const MSLink*>  getFirstApproachingFoe(const MSLink* wrapAround) const;
     383              : 
     384              :     MSJunction* getJunction() const {
     385      5350997 :         return myJunction;
     386              :     }
     387              : 
     388              : 
     389              :     /** @brief Returns the current state of the link
     390              :      *
     391              :      * @return The current state of this link
     392              :      */
     393              :     LinkState getState() const {
     394   1698688916 :         return myState;
     395              :     }
     396              : 
     397              : 
     398              :     /** @brief Returns the off-state for the link
     399              :      *
     400              :      * @return The current state of this link
     401              :      */
     402              :     LinkState getOffState() const {
     403      3264289 :         return myOffState;
     404              :     }
     405              : 
     406              :     /** @brief Returns the last green state of the link
     407              :      *
     408              :      * @return The last green state of this link
     409              :      */
     410              :     LinkState getLastGreenState() const {
     411      1260708 :         return myLastGreenState;
     412              :     }
     413              : 
     414              : 
     415              :     //@brief Returns the time of the last state change
     416              :     inline SUMOTime getLastStateChange() const {
     417       122716 :         return myLastStateChange;
     418              :     }
     419              : 
     420              : 
     421              :     /** @brief Returns the direction the vehicle passing this link take
     422              :      *
     423              :      * @return The direction of this link
     424              :      */
     425              :     inline LinkDirection getDirection() const {
     426    200510423 :         return myDirection;
     427              :     }
     428              : 
     429              : 
     430              : 
     431              :     /** @brief Sets the current tl-state
     432              :      *
     433              :      * @param[in] state The current state of the link
     434              :      * @param[in] t The time of the state change
     435              :      */
     436              :     void setTLState(LinkState state, SUMOTime t);
     437              : 
     438              :     /** @brief Sets the currently active tlLogic
     439              :      * @param[in] logic The currently active logic
     440              :      */
     441              :     void setTLLogic(const MSTrafficLightLogic* logic);
     442              : 
     443              :     /** @brief Returns the connected lane
     444              :      *
     445              :      * @return The lane approached by this link
     446              :      */
     447              :     inline MSLane* getLane() const {
     448   4022149635 :         return myLane;
     449              :     }
     450              : 
     451              : 
     452              :     /** @brief Returns the respond index (for visualization)
     453              :      *
     454              :      * @return The respond index for this link
     455              :      */
     456              :     inline int getIndex() const {
     457      2687756 :         return myIndex;
     458              :     }
     459              : 
     460              :     /** @brief Returns the TLS index */
     461              :     inline int getTLIndex() const {
     462     34428119 :         return myTLIndex;
     463              :     }
     464              : 
     465              :     /** @brief Returns the TLS index */
     466              :     inline const MSTrafficLightLogic* getTLLogic() const {
     467     20362519 :         return myLogic;
     468              :     }
     469              : 
     470              :     /** @brief Returns whether this link is a major link
     471              :      * @return Whether the link has a large priority
     472              :      */
     473              :     inline bool havePriority() const {
     474   4421426037 :         return myState >= 'A' && myState <= 'Z';
     475              :     }
     476              : 
     477              :     inline bool haveOffPriority() const {
     478           40 :         return myOffState >= 'A' && myOffState <= 'Z';
     479              :     }
     480              : 
     481              :     /** @brief Returns whether this link is blocked by a red (or redyellow) traffic light
     482              :      * @return Whether the link has a red light
     483              :      */
     484              :     inline bool haveRed() const {
     485   1549371279 :         return myState == LINKSTATE_TL_RED || myState == LINKSTATE_TL_REDYELLOW;
     486              :     }
     487              : 
     488              :     inline bool haveYellow() const {
     489   1480149206 :         return myState == LINKSTATE_TL_YELLOW_MINOR || myState == LINKSTATE_TL_YELLOW_MAJOR;
     490              :     }
     491              : 
     492              :     inline bool haveGreen() const {
     493    105157215 :         return myState == LINKSTATE_TL_GREEN_MAJOR || myState == LINKSTATE_TL_GREEN_MINOR;
     494              :     }
     495              : 
     496              :     inline bool mustStop() const {
     497    635265358 :         return myState == LINKSTATE_STOP || myState == LINKSTATE_ALLWAY_STOP;
     498              :     }
     499              : 
     500              :     inline bool isTLSControlled() const {
     501      1976427 :         return myLogic != 0;
     502              :     }
     503              : 
     504              :     inline bool isTurnaround() const {
     505     83267163 :         return myDirection == LinkDirection::TURN || myDirection == LinkDirection::TURN_LEFTHAND;
     506              :     }
     507              : 
     508              :     /** @brief Returns the length of this link
     509              :      *
     510              :      * @return The length of this link
     511              :      */
     512              :     double getLength() const {
     513   2353280740 :         return myLength;
     514              :     }
     515              : 
     516              : 
     517              :     /** @brief Returns the distance on the approaching lane from which an
     518              :      *         approaching vehicle is able to see all relevant foes and
     519              :      *         may accelerate if the link is minor and no foe is approaching.
     520              :      *
     521              :      * @return The foe-visibility-distance
     522              :      */
     523              :     double getFoeVisibilityDistance() const {
     524   2327500899 :         return myFoeVisibilityDistance;
     525              :     }
     526              : 
     527              :     double getDistToFoePedCrossing() const {
     528     41557465 :         return myDistToFoePedCrossing;
     529              :     }
     530              : 
     531              :     /** @brief Returns whether this link belongs to a junction where more than one edge is incoming
     532              :      *
     533              :      * @return Whether any foe links exist
     534              :      */
     535              :     bool hasFoes() const {
     536    519071656 :         return myHasFoes;
     537              :     }
     538              : 
     539              :     // @brief return whether the vehicle may continute past this link to wait within the intersection
     540              :     bool isCont() const;
     541              : 
     542              : 
     543              :     /// @brief whether the junction after this link must be kept clear
     544              :     bool keepClear() const {
     545    165667168 :         return myKeepClear;
     546              :     }
     547              : 
     548              :     /// @brief whether this link is the start of an indirect turn
     549              :     bool isIndirect() const {
     550      1189766 :         return myAmIndirect;
     551              :     }
     552              : 
     553              :     /// @brief whether this is a link past an internal junction which currently has priority
     554              :     bool lastWasContMajor() const;
     555              : 
     556              :     /// @brief whether this is a link past an internal junction where the entry to the junction currently has the given state
     557              :     bool lastWasContState(LinkState linkState) const;
     558              : 
     559              :     /** @brief Returns the cumulative length of all internal lanes after this link
     560              :      *  @return sum of the lengths of all internal lanes following this link
     561              :      */
     562              :     double getInternalLengthsAfter() const;
     563              : 
     564              :     /** @brief Returns the cumulative length of all internal lanes before this link
     565              :      *  @return sum of the lengths of all internal lanes before this link
     566              :      */
     567              :     double getInternalLengthsBefore() const;
     568              : 
     569              :     /** @brief Returns the sum of the lengths along internal lanes following this link
     570              :      *         to the crossing with the given foe lane, if the lane is no foe
     571              :      *         lane to any of the internal lanes, INVALID_DOUBLE is returned.
     572              :      *  @see getLengthBeforeCrossing()
     573              :      */
     574              :     double getLengthsBeforeCrossing(const MSLane* foeLane) const;
     575              : 
     576              : 
     577              :     /** @brief Returns the internal length from the beginning of the link's internal lane before
     578              :      *         to the crossing with the given foe lane if applicable, if the lane is no foe
     579              :      *         lane to the link, INVALID_DOUBLE is returned.
     580              :      *  @see getLengthsBeforeCrossing()
     581              :      */
     582              :     double getLengthBeforeCrossing(const MSLane* foeLane) const;
     583              : 
     584              : 
     585              :     /** @brief Returns the following inner lane
     586              :      *
     587              :      * @return The inner lane to use to cross the junction
     588              :      */
     589              :     inline MSLane* getViaLane() const {
     590   3677963472 :         return myInternalLane;
     591              :     }
     592              : 
     593              :     /** @brief Returns all potential link leaders (vehicles on foeLanes)
     594              :      * Valid during the planMove() phase
     595              :      * @param[in] ego The ego vehicle that is looking for leaders
     596              :      * @param[in] dist The distance of the vehicle who is asking about the leader to this link
     597              :      * @param[out] blocking Return blocking pedestrians if a vector is given
     598              :      * @param[in] isShadowLink whether this link is a shadowLink for ego
     599              :      * @return The all vehicles on foeLanes and their (virtual) distances to the asking vehicle
     600              :      */
     601              :     const LinkLeaders getLeaderInfo(const MSVehicle* ego, double dist, std::vector<const MSPerson*>* collectBlockers = 0, bool isShadowLink = false) const;
     602              : 
     603              :     /// @brief return the speed at which ego vehicle must approach the zipper link
     604              :     double getZipperSpeed(const MSVehicle* ego, const double dist, double vSafe,
     605              :                           SUMOTime arrivalTime,
     606              :                           const BlockingFoes* foes) const;
     607              : 
     608              :     /// @brief return the via lane if it exists and the lane otherwise
     609              :     inline MSLane* getViaLaneOrLane() const {
     610   1934677119 :         return  myInternalLane != nullptr ? myInternalLane : myLane;
     611              :     }
     612              : 
     613              : 
     614              :     /// @brief return the internalLaneBefore if it exists and the laneBefore otherwise
     615              :     inline const MSLane* getLaneBefore() const {
     616              :         assert(myInternalLaneBefore == nullptr || myLaneBefore == myInternalLaneBefore);  // lane before mismatch!
     617    772253853 :         return myLaneBefore;
     618              :     }
     619              : 
     620              :     /// @brief return myInternalLaneBefore (always 0 when compiled without internal lanes)
     621              :     inline const MSLane* getInternalLaneBefore() const {
     622    756002673 :         return myInternalLaneBefore;
     623              :     }
     624              : 
     625              :     /// @brief return the expected time at which the given vehicle will clear the link
     626              :     SUMOTime getLeaveTime(const SUMOTime arrivalTime, const double arrivalSpeed, const double leaveSpeed, const double vehicleLength) const;
     627              : 
     628              :     /// @brief write information about all approaching vehicles to the given output device
     629              :     void writeApproaching(OutputDevice& od, const std::string fromLaneID) const;
     630              : 
     631              :     /// @brief return the link that is parallel to this link or 0
     632              :     MSLink* getParallelLink(int direction) const;
     633              : 
     634              :     /// @brief return the link that is the opposite entry link to this one
     635              :     MSLink* getOppositeDirectionLink() const;
     636              : 
     637              :     /// @brief return whether the fromLane of this link is an internal lane
     638              :     inline bool fromInternalLane() const {
     639    874640333 :         return myInternalLaneBefore != nullptr;
     640              :     }
     641              : 
     642              :     /// @brief return whether the toLane of this link is an internal lane and fromLane is a normal lane
     643              :     bool isEntryLink() const;
     644              : 
     645              :     /// @brief return whether this link enters the conflict area (not a continuation link)
     646              :     bool isConflictEntryLink() const;
     647              : 
     648              :     /// @brief return whether the fromLane of this link is an internal lane and toLane is a normal lane
     649              :     bool isExitLink() const;
     650              : 
     651              :     /// @brief return whether the fromLane of this link is an internal lane and its incoming lane is also an internal lane
     652              :     bool isExitLinkAfterInternalJunction() const;
     653              : 
     654              :     /// @brief returns the corresponding exit link for entryLinks to a junction.
     655              :     const MSLink* getCorrespondingExitLink() const;
     656              : 
     657              :     /// @brief returns the corresponding entry link for exitLinks to a junction.
     658              :     const MSLink* getCorrespondingEntryLink() const;
     659              : 
     660              :     /// @brief return whether the fromLane and the toLane of this link are internal lanes
     661              :     bool isInternalJunctionLink() const;
     662              : 
     663              :     /** @brief Returns the time penalty for passing a tls-controlled link (meso) */
     664              :     SUMOTime getMesoTLSPenalty() const {
     665        52022 :         return myMesoTLSPenalty;
     666              :     }
     667              : 
     668              :     /** @brief Returns the average proportion of green time to cycle time */
     669              :     double getGreenFraction() const {
     670        49540 :         return myGreenFraction;
     671              :     }
     672              : 
     673              :     /** @brief Sets the time penalty for passing a tls-controlled link (meso) */
     674              :     void setMesoTLSPenalty(const SUMOTime penalty) {
     675       182978 :         myMesoTLSPenalty = penalty;
     676              :     }
     677              : 
     678              :     /** @brief Sets the green fraction for passing a tls-controlled link (meso) */
     679              :     void setGreenFraction(const double fraction) {
     680       182818 :         myGreenFraction = fraction;
     681              :     }
     682              : 
     683              :     const std::vector<const MSLane*>& getFoeLanes() const {
     684              :         return myFoeLanes;
     685              :     }
     686              : 
     687              :     const std::vector<ConflictInfo>& getConflicts() const {
     688              :         return myConflicts;
     689              :     }
     690              : 
     691              :     const std::vector<MSLink*>& getFoeLinks() const {
     692         8056 :         return myFoeLinks;
     693              :     }
     694              : 
     695              :     /// @brief who may use this link
     696              :     SVCPermissions getPermissions() const {
     697        13452 :         return myPermissions;
     698              :     }
     699              : 
     700              :     /// @brief initialize parallel links (to be called after all links are loaded)
     701              :     void initParallelLinks();
     702              : 
     703              :     /// @brief return lateral shift that must be applied when passing this link
     704              :     inline double getLateralShift() const {
     705    984357533 :         return myLateralShift;
     706              :     }
     707              : 
     708              :     /// @brief get string description for this link
     709              :     std::string  getDescription() const;
     710              : 
     711              :     /// @brief get the closest vehicle approaching this link
     712              :     std::pair<const SUMOVehicle* const, const ApproachingVehicleInformation> getClosest() const;
     713              : 
     714              :     inline bool hasFoeCrossing() const {
     715        89348 :         return myHavePedestrianCrossingFoe;
     716              :     }
     717              : 
     718              :     /// @brief whether this link is for a railsignal that was passed in this step
     719              :     bool railSignalWasPassed() const;
     720              : 
     721              :     /// @brief post-processing for legacy networks
     722              :     static void recheckSetRequestInformation();
     723              : 
     724              :     static bool ignoreFoe(const SUMOTrafficObject* ego, const SUMOTrafficObject* foe);
     725              : 
     726              :     static const double NO_INTERSECTION;
     727              : 
     728              : private:
     729              :     /// @brief return whether the given vehicles may NOT merge safely
     730              :     static inline bool unsafeMergeSpeeds(double leaderSpeed, double followerSpeed, double leaderDecel, double followerDecel) {
     731              :         // XXX mismatch between continuous an discrete deceleration
     732     23849669 :         return (leaderSpeed * leaderSpeed / leaderDecel) <= (followerSpeed * followerSpeed / followerDecel);
     733              :     }
     734              : 
     735              :     /// @brief whether follower could stay behind leader (possibly by braking)
     736              :     static bool couldBrakeForLeader(double followDist, double leaderDist, const MSVehicle* follow, const MSVehicle* leader);
     737              : 
     738              :     MSLink* computeParallelLink(int direction);
     739              : 
     740              :     /// @brief check for persons on walkingarea in the path of ego vehicle
     741              :     void checkWalkingAreaFoe(const MSVehicle* ego, const MSLane* foeLane, std::vector<const MSPerson*>* collectBlockers, LinkLeaders& result) const;
     742              : 
     743              :     /// @brief whether the given person is in front of the car
     744              :     bool isInFront(const MSVehicle* ego, const PositionVector& egoPath, const Position& pPos) const;
     745              : 
     746              :     /// @brief whether the given person is walking towards the car returned as a factor in [0, 1]
     747              :     double isOnComingPed(const MSVehicle* ego, const MSPerson* p) const;
     748              : 
     749              :     /// @brief return extrapolated position of the given person after the given time
     750              :     Position getFuturePosition(const MSPerson* p, double timeHorizon = 1) const;
     751              : 
     752              :     bool blockedByFoe(const SUMOVehicle* veh, const ApproachingVehicleInformation& avi,
     753              :                       SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
     754              :                       bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
     755              :                       const SUMOTrafficObject* ego) const;
     756              : 
     757              :     /// @brief figure out whether the cont status remains in effect when switching off the tls
     758              :     bool checkContOff() const;
     759              : 
     760              :     /// @brief check if the lane intersects with a foe cont-lane
     761              :     bool contIntersect(const MSLane* lane, const MSLane* foe);
     762              : 
     763              :     /// @brief compute point of divergence for geomatries with a common start or end
     764              :     double computeDistToDivergence(const MSLane* lane, const MSLane* sibling, double minDist, bool sameSource, double siblingPredLength = 0) const;
     765              : 
     766              :     /// @brief compute arrival time if foe vehicle is braking for ego
     767              :     static SUMOTime computeFoeArrivalTimeBraking(SUMOTime arrivalTime, const SUMOVehicle* foe, SUMOTime foeArrivalTime, double impatience, double dist, double& fasb);
     768              : 
     769              :     /// @brief check whether the given vehicle positions overlap laterally
     770              :     static bool lateralOverlap(double posLat, double width, double posLat2, double width2);
     771              : 
     772              :     /// @brief return CustomConflict with foeLane if it is defined
     773              :     const CustomConflict* getCustomConflict(const MSLane* foeLane) const;
     774              : 
     775              :     /// @brief add information about another pedestrian crossing
     776              :     void updateDistToFoePedCrossing(double dist);
     777              : 
     778              : private:
     779              :     /// @brief The lane behind the junction approached by this link
     780              :     MSLane* myLane;
     781              : 
     782              :     /// @brief The lane approaching this link
     783              :     MSLane* myLaneBefore;
     784              : 
     785              :     ApproachInfos myApproachingVehicles;
     786              :     PersonApproachInfos* myApproachingPersons;
     787              : 
     788              :     /// @brief The position within this respond
     789              :     int myIndex;
     790              : 
     791              :     /// @brief the traffic light index
     792              :     const int myTLIndex;
     793              : 
     794              :     /// @brief the controlling logic or 0
     795              :     const MSTrafficLightLogic* myLogic;
     796              : 
     797              :     /// @brief The state of the link
     798              :     LinkState myState;
     799              :     /// @brief The last green state of the link (minor or major)
     800              :     LinkState myLastGreenState;
     801              :     /// @brief The state of the link when switching of traffic light control
     802              :     const LinkState myOffState;
     803              : 
     804              :     /// @brief The time of the last state change
     805              :     SUMOTime myLastStateChange;
     806              : 
     807              :     /// @brief An abstract (hopefully human readable) definition of the link's direction
     808              :     LinkDirection myDirection;
     809              : 
     810              :     /// @brief The length of the link
     811              :     /// @note This is not equal to the result of getInternalLengthsAfter for links with more than one internal lane.
     812              :     double myLength;
     813              : 
     814              :     /// @brief distance from which an approaching vehicle is able to
     815              :     ///        see all relevant foes and may accelerate if the link is minor
     816              :     ///        and no foe is approaching. Defaults to 4.5m.
     817              :     ///        For zipper links (major) this is the distance at which zipper merging starts (and foes become "visible")
     818              :     double myFoeVisibilityDistance;
     819              : 
     820              :     /// @brief distance from the stop line to the first pedestrian crossing or maxdouble
     821              :     double myDistToFoePedCrossing;
     822              : 
     823              :     /// @brief Whether any foe links exist
     824              :     bool myHasFoes;
     825              : 
     826              :     // @brief whether vehicles may continue past this link to wait within the intersection
     827              :     bool myAmCont;
     828              :     // @brief whether vehicles may continue past this link to wait within the intersection after switching of the traffic light at this intersection
     829              :     bool myAmContOff;
     830              : 
     831              :     // @brief whether vehicles must keep the intersection clear if there is a downstream jam
     832              :     bool myKeepClear;
     833              : 
     834              :     /// @brief The following junction-internal lane if used
     835              :     MSLane* const myInternalLane;
     836              : 
     837              :     /* @brief The preceding junction-internal lane, only used at
     838              :      * - exit links (from internal lane to normal lane)
     839              :      * - internal junction links (from internal lane to internal lane)
     840              :      */
     841              :     const MSLane* myInternalLaneBefore;
     842              : 
     843              :     /// @brief penalty time at tls for mesoscopic simulation
     844              :     SUMOTime myMesoTLSPenalty;
     845              :     /// @brief green fraction at tls for mesoscopic simulation
     846              :     double myGreenFraction;
     847              : 
     848              :     /// @brief lateral shift to be applied when passing this link
     849              :     double myLateralShift;
     850              : 
     851              :     /* @brief lengths after the crossing point with foeLane
     852              :      * (index corresponds to myFoeLanes)
     853              :      * empty vector for entry links
     854              :      * */
     855              :     std::vector<ConflictInfo> myConflicts;
     856              : 
     857              :     std::vector<CustomConflict> myCustomConflicts;
     858              : 
     859              :     // TODO: documentation
     860              :     std::vector<MSLink*> myFoeLinks;
     861              :     std::vector<const MSLane*> myFoeLanes;
     862              : 
     863              :     /* prioritized links when the traffic light is switched off (only needed for RightOfWay::ALLWAYSTOP)
     864              :      * @note stored as a pointer to save space since it won't be used in most cases
     865              :      */
     866              :     std::vector<MSLink*>* myOffFoeLinks;
     867              : 
     868              :     /// @brief walkingArea that must be checked when entering the intersection
     869              :     const MSLane* myWalkingAreaFoe;
     870              :     /// @brief walkingArea that must be checked when leaving the intersection
     871              :     const MSLane* myWalkingAreaFoeExit;
     872              : 
     873              :     /// @brief whether on of myFoeLanes is a crossing
     874              :     bool myHavePedestrianCrossingFoe;
     875              : 
     876              :     /* @brief Links with the same origin lane and the same destination edge that may
     877              :        be in conflict for sublane simulation */
     878              :     std::vector<MSLink*> mySublaneFoeLinks;
     879              :     /* @brief Links with the same origin lane and different destination edge that may
     880              :        be in conflict for sublane simulation */
     881              :     std::vector<MSLink*> mySublaneFoeLinks2;
     882              : 
     883              :     /* @brief Internal Lanes with the same origin lane and the same destination edge that may
     884              :        be in conflict for sublane simulation */
     885              :     std::vector<MSLane*> mySublaneFoeLanes;
     886              : 
     887              :     static const SUMOTime myLookaheadTime;
     888              :     static const SUMOTime myLookaheadTimeZipper;
     889              : 
     890              :     /// @brief links that need post processing after initialization (to deal with legacy networks)
     891              :     static std::set<std::pair<MSLink*, MSLink*> > myRecheck;
     892              : 
     893              :     MSLink* myParallelRight;
     894              :     MSLink* myParallelLeft;
     895              : 
     896              :     /// @brief whether this connection is an indirect turning movement
     897              :     const bool myAmIndirect;
     898              : 
     899              :     /// @brief the turning radius for this link or doublemax for straight links
     900              :     double myRadius;
     901              : 
     902              :     /// @brief who may drive on this link
     903              :     SVCPermissions myPermissions;
     904              : 
     905              :     /// @brief the junction to which this link belongs
     906              :     MSJunction* myJunction;
     907              : 
     908              :     /// invalidated copy constructor
     909              :     MSLink(const MSLink& s);
     910              : 
     911              :     /// invalidated assignment operator
     912              :     MSLink& operator=(const MSLink& s);
     913              : 
     914              : };
        

Generated by: LCOV version 2.0-1