LCOV - code coverage report
Current view: top level - src/microsim - MSLink.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 72 72
Test Date: 2025-11-13 15:38:19 Functions: - 0 0

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

Generated by: LCOV version 2.0-1