/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2002-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file MSLink.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Sept 200218///19// A connection between lanes20/****************************************************************************/21#pragma once22#include <config.h>2324#include <vector>25#include <set>26#include <utils/common/SUMOTime.h>27#include <utils/common/SUMOVehicleClass.h>28#include <utils/vehicle/SUMOVehicle.h>29#include <utils/xml/SUMOXMLDefinitions.h>303132// ===========================================================================33// class declarations34// ===========================================================================35class MSLane;36class MSJunction;37class MSVehicle;38class MSPerson;39class OutputDevice;40class MSTrafficLightLogic;414243// ===========================================================================44// class definitions45// ===========================================================================46/**47* @class MSLinks48* @brief A connection between lanes49*50* A link is basically a connection between two lanes, stored within the51* originating (the one that is being left) lane and pointing to the52* approached lane. When using inner-junction simulation, additionally53* a "via-lane" is stored, the one that is used to cross the junction54* and which represents the links shape.55*56* Because right-of-way rules are controlled by the junctions, the link57* stores the information about where to write information about approaching58* vehicles (the "request") and where to get the information whether the59* vehicle really may drive (the "respond").60*61* Because a link is a connection over a junction, it basically also has a62* length. This length is needed to assure that vehicles have the correct halting63* distance before approaching the link. In the case of using internal lanes,64* the link's length is 0.65*/66class MSLink {67public:6869/** @enum LinkLeaderFlag70* @brief additional information for link leaders71*/72enum LinkLeaderFlag {73/// @brief vehicle is in the way74LL_IN_THE_WAY = 1 << 0,75/// @brief link leader is passing from left to right76LL_FROM_LEFT = 1 << 1,77/// @brief link leader is coming from the same (normal) lane78LL_SAME_SOURCE = 1 << 2,79/// @brief link leader is targeting the same outgoing lane80LL_SAME_TARGET = 1 << 381};8283struct LinkLeader {84LinkLeader(MSVehicle* _veh, double _gap, double _distToCrossing, int _llFlags = LL_FROM_LEFT, double _latOffst = 0) :85vehAndGap(std::make_pair(_veh, _gap)),86distToCrossing(_distToCrossing),87llFlags(_llFlags),88latOffset(_latOffst)89{ }9091inline bool fromLeft() const {92return (llFlags & LL_FROM_LEFT) != 0;93}94inline bool inTheWay() const {95return (llFlags & LL_IN_THE_WAY) != 0;96}97inline bool sameTarget() const {98return (llFlags & LL_SAME_TARGET) != 0;99}100inline bool sameSource() const {101return (llFlags & LL_SAME_SOURCE) != 0;102}103104std::pair<MSVehicle*, double> vehAndGap;105double distToCrossing;106int llFlags;107double latOffset;108109};110111typedef std::vector<LinkLeader> LinkLeaders;112113/** @struct ApproachingVehicleInformation114* @brief A structure holding the information about vehicles approaching a link115*/116struct ApproachingVehicleInformation {117/** @brief Constructor118* @param[in] waitingTime The time during which the vehicle is waiting at this link119* this needs to be placed here because MSVehicle::myWaitingTime is updated in between120* calls to opened() causing order dependencies121**/122ApproachingVehicleInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime,123const double _arrivalSpeed, const double _leaveSpeed,124const bool _willPass,125const double _arrivalSpeedBraking,126const SUMOTime _waitingTime,127const double _dist,128const double _speed,129const double _latOffset130) :131arrivalTime(_arrivalTime), leavingTime(_leavingTime),132arrivalSpeed(_arrivalSpeed), leaveSpeed(_leaveSpeed),133willPass(_willPass),134arrivalSpeedBraking(_arrivalSpeedBraking),135waitingTime(_waitingTime),136dist(_dist),137speed(_speed),138latOffset(_latOffset) {139}140141/// @brief The time the vehicle's front arrives at the link142const SUMOTime arrivalTime;143/// @brief The estimated time at which the vehicle leaves the link144const SUMOTime leavingTime;145/// @brief The estimated speed with which the vehicle arrives at the link (for headway computation)146const double arrivalSpeed;147/// @brief The estimated speed with which the vehicle leaves the link (for headway computation)148const double leaveSpeed;149/// @brief Whether the vehicle wants to pass the link (@todo: check semantics)150const bool willPass;151/// @brief The estimated speed with which the vehicle arrives at the link if it starts braking(for headway computation)152const double arrivalSpeedBraking;153/// @brief The waiting duration at the current link154const SUMOTime waitingTime;155/// @brief The distance up to the current link156const double dist;157/// @brief The current speed158const double speed;159/// @brief The lateral offset from the center of the entering lane160const double latOffset;161162};163164/** @struct ApproachingPersonInformation165* @brief A structure holding the information about persons approaching a pedestrian crossing link166*/167struct ApproachingPersonInformation {168/** @brief Constructor169* @param[in] waitingTime The time during which the vehicle is waiting at this link170* this needs to be placed here because MSVehicle::myWaitingTime is updated in between171* calls to opened() causing order dependencies172**/173ApproachingPersonInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime) :174arrivalTime(_arrivalTime), leavingTime(_leavingTime) {}175/// @brief The time the vehicle's front arrives at the link176const SUMOTime arrivalTime;177/// @brief The estimated time at which the vehicle leaves the link178const SUMOTime leavingTime;179};180181typedef std::map<const SUMOVehicle*, const ApproachingVehicleInformation, ComparatorNumericalIdLess> ApproachInfos;182typedef std::vector<const SUMOTrafficObject*> BlockingFoes;183typedef std::map<const MSPerson*, ApproachingPersonInformation> PersonApproachInfos;184185enum ConflictFlag {186CONFLICT_DEFAULT,187CONFLICT_DUMMY_MERGE,188CONFLICT_NO_INTERSECTION,189CONFLICT_STOP_AT_INTERNAL_JUNCTION,190CONFLICT_SIBLING_CONTINUATION191};192193/// @brief pre-computed information for conflict points194struct ConflictInfo {195196ConflictInfo(double lbc, double cs, ConflictFlag fl = CONFLICT_DEFAULT) :197foeConflictIndex(-1),198lengthBehindCrossing(lbc),199conflictSize(cs),200flag(fl)201{}202/// @brief the conflict from the perspective of the foe203int foeConflictIndex;204/// @brief length of internal lane after the crossing point205double lengthBehindCrossing;206/// @brief the length of the conflict space207double conflictSize;208209ConflictFlag flag;210211double getFoeLengthBehindCrossing(const MSLink* foeExitLink) const;212double getFoeConflictSize(const MSLink* foeExitLink) const;213double getLengthBehindCrossing(const MSLink* exitLink) const;214};215216/// @brief holds user defined conflict positions (must be interpreted for the correct exitLink)217struct CustomConflict {218CustomConflict(const MSLane* f, const MSLane* t, double s, double e) :219from(f), to(t), startPos(s), endPos(e) {}220const MSLane* from;221const MSLane* to;222double startPos;223double endPos;224};225226/** @brief Constructor for simulation which uses internal lanes227*228* @param[in] succLane The lane approached by this link229* @param[in] via The lane to use within the junction230* @param[in] dir The direction of this link231* @param[in] state The state of this link232* @param[in] length The length of this link233*/234MSLink(MSLane* predLane,235MSLane* succLane,236MSLane* via,237LinkDirection dir,238LinkState state,239double length,240double foeVisibilityDistance,241bool keepClear,242MSTrafficLightLogic* logic,243int tlLinkIdx,244bool indirect);245246247/// @brief Destructor248~MSLink();249250void addCustomConflict(const MSLane* from, const MSLane* to, double startPos, double endPos);251252/** @brief Sets the request information253*254* Because traffic lights and junction logics are loaded after links,255* we have to assign the information about the right-of-way256* requests and responses after the initialisation.257* @todo Unsecure!258*/259void setRequestInformation(int index, bool hasFoes, bool isCont,260const std::vector<MSLink*>& foeLinks, const std::vector<MSLane*>& foeLanes,261MSLane* internalLaneBefore = 0);262263/// @brief add walkingarea as foe (when entering the junction)264void addWalkingAreaFoe(const MSLane* lane) {265myWalkingAreaFoe = lane;266}267268/// @brief add walkingarea as foe (when leaving the junction)269void addWalkingAreaFoeExit(const MSLane* lane) {270myWalkingAreaFoeExit = lane;271}272273/// @brief get walkingarea as foes274const MSLane* getWalkingAreaFoe() {275return myWalkingAreaFoe;276}277const MSLane* getWalkingAreaFoeExit() {278return myWalkingAreaFoeExit;279}280281/** @brief Sets the information about an approaching vehicle282*283* The information is stored in myApproachingVehicles.284*/285void setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime,286const double arrivalSpeed, const double leaveSpeed, const bool setRequest,287const double arrivalSpeedBraking,288const SUMOTime waitingTime, double dist, double latOffset);289290/** @brief Sets the information about an approaching vehicle */291void setApproaching(const SUMOVehicle* approaching, ApproachingVehicleInformation ai);292293/** @brief Sets the information about an approaching person (only for a pedestrian crossing) */294void setApproachingPerson(const MSPerson* approaching, const SUMOTime arrivalTime, const SUMOTime leaveTime);295296/// @brief removes the vehicle from myApproachingVehicles297void removeApproaching(const SUMOVehicle* veh);298299/// @brief removes the person from myApproachingPersons300void removeApproachingPerson(const MSPerson* person);301302/* @brief return information about this vehicle if it is registered as303* approaching (dummy values otherwise)304* @note used for visualisation of link items */305ApproachingVehicleInformation getApproaching(const SUMOVehicle* veh) const;306const ApproachingVehicleInformation* getApproachingPtr(const SUMOVehicle* veh) const;307308/// @brief return all approaching vehicles309const ApproachInfos& getApproaching() const {310return myApproachingVehicles;311}312313/// @brief return all approaching vehicles314const PersonApproachInfos* getApproachingPersons() const {315return myApproachingPersons;316}317318/** @brief Remove all approaching vehicles before quick-loading state */319void clearState();320321/** @brief Returns the information whether the link may be passed322*323* Valid after the junctions have set their reponds324*325* @param[in] collectFoes If a vector is passed, all blocking foes are collected and inserted into this vector326* @return Whether this link may be passed.327*/328bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength,329double impatience, double decel, SUMOTime waitingTime,330double posLat = 0,331BlockingFoes* collectFoes = nullptr,332bool ignoreRed = false,333const SUMOTrafficObject* ego = nullptr,334double dist = -1) const;335336/** @brief Returns the information whether this link is blocked337* Valid after the vehicles have set their requests338* @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe339* @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe340* @param[in] arrivalSpeed The speed with which the checking vehicle plans to arrive at the link341* @param[in] leaveSpeed The speed with which the checking vehicle plans to leave the link342* @param[in] sameTargetLane Whether the link that calls this method has the same target lane as this link343* @param[in] impatience The impatience of the checking vehicle344* @param[in] decel The maximum deceleration of the checking vehicle345* @param[in] waitingTime The waiting time of the checking vehicle346* @param[in] collectFoes If a vector is passed the return value is always False, instead all blocking foes are collected and inserted into this vector347* @param[in] lastWasContRed Whether the link which is checked, is an internal junction link where the entry has red348* @return Whether this link is blocked349* @note Since this needs to be called without a SUMOVehicle (TraCI), we cannot simply pass the checking vehicle itself350**/351bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,352bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,353BlockingFoes* collectFoes = nullptr, const SUMOTrafficObject* ego = nullptr, bool lastWasContRed = false, double dist = -1) const;354355356/** @brief Returns the information whether a vehicle is approaching on one of the link's foe streams357*358* Valid after the vehicles have set their requests359* @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe360* @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe361* @param[in] speed The speed with which the checking vehicle plans to leave the link362* @param[in] decel The maximum deceleration of the checking vehicle363* @return Whether a foe of this link is approaching364*/365bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, double speed, double decel) const;366367/** @brief get the foe vehicle that is closest to the intersection or nullptr along with the foe link368* This function is used for finding circular deadlock at right_before_left junctions369* @param[in] wrapAround The link on which the ego vehicle wants to enter the junction370*/371std::pair<const SUMOVehicle*, const MSLink*> getFirstApproachingFoe(const MSLink* wrapAround) const;372373MSJunction* getJunction() const {374return myJunction;375}376377378/** @brief Returns the current state of the link379*380* @return The current state of this link381*/382LinkState getState() const {383return myState;384}385386387/** @brief Returns the off-state for the link388*389* @return The current state of this link390*/391LinkState getOffState() const {392return myOffState;393}394395/** @brief Returns the last green state of the link396*397* @return The last green state of this link398*/399LinkState getLastGreenState() const {400return myLastGreenState;401}402403404//@brief Returns the time of the last state change405inline SUMOTime getLastStateChange() const {406return myLastStateChange;407}408409410/** @brief Returns the direction the vehicle passing this link take411*412* @return The direction of this link413*/414inline LinkDirection getDirection() const {415return myDirection;416}417418419420/** @brief Sets the current tl-state421*422* @param[in] state The current state of the link423* @param[in] t The time of the state change424*/425void setTLState(LinkState state, SUMOTime t);426427/** @brief Sets the currently active tlLogic428* @param[in] logic The currently active logic429*/430void setTLLogic(const MSTrafficLightLogic* logic);431432/** @brief Returns the connected lane433*434* @return The lane approached by this link435*/436inline MSLane* getLane() const {437return myLane;438}439440441/** @brief Returns the respond index (for visualization)442*443* @return The respond index for this link444*/445inline int getIndex() const {446return myIndex;447}448449/** @brief Returns the TLS index */450inline int getTLIndex() const {451return myTLIndex;452}453454/** @brief Returns the TLS index */455inline const MSTrafficLightLogic* getTLLogic() const {456return myLogic;457}458459/** @brief Returns whether this link is a major link460* @return Whether the link has a large priority461*/462inline bool havePriority() const {463return myState >= 'A' && myState <= 'Z';464}465466inline bool haveOffPriority() const {467return myOffState >= 'A' && myOffState <= 'Z';468}469470/** @brief Returns whether this link is blocked by a red (or redyellow) traffic light471* @return Whether the link has a red light472*/473inline bool haveRed() const {474return myState == LINKSTATE_TL_RED || myState == LINKSTATE_TL_REDYELLOW;475}476477inline bool haveYellow() const {478return myState == LINKSTATE_TL_YELLOW_MINOR || myState == LINKSTATE_TL_YELLOW_MAJOR;479}480481inline bool haveGreen() const {482return myState == LINKSTATE_TL_GREEN_MAJOR || myState == LINKSTATE_TL_GREEN_MINOR;483}484485inline bool mustStop() const {486return myState == LINKSTATE_STOP || myState == LINKSTATE_ALLWAY_STOP;487}488489inline bool isTLSControlled() const {490return myLogic != 0;491}492493inline bool isTurnaround() const {494return myDirection == LinkDirection::TURN || myDirection == LinkDirection::TURN_LEFTHAND;495}496497/** @brief Returns the length of this link498*499* @return The length of this link500*/501double getLength() const {502return myLength;503}504505506/** @brief Returns the distance on the approaching lane from which an507* approaching vehicle is able to see all relevant foes and508* may accelerate if the link is minor and no foe is approaching.509*510* @return The foe-visibility-distance511*/512double getFoeVisibilityDistance() const {513return myFoeVisibilityDistance;514}515516double getDistToFoePedCrossing() const {517return myDistToFoePedCrossing;518}519520/** @brief Returns whether this link belongs to a junction where more than one edge is incoming521*522* @return Whether any foe links exist523*/524bool hasFoes() const {525return myHasFoes;526}527528// @brief return whether the vehicle may continute past this link to wait within the intersection529bool isCont() const;530531532/// @brief whether the junction after this link must be kept clear533bool keepClear() const {534return myKeepClear;535}536537/// @brief whether this link is the start of an indirect turn538bool isIndirect() const {539return myAmIndirect;540}541542/// @brief whether this is a link past an internal junction which currently has priority543bool lastWasContMajor() const;544545/// @brief whether this is a link past an internal junction where the entry to the junction currently has the given state546bool lastWasContState(LinkState linkState) const;547548/** @brief Returns the cumulative length of all internal lanes after this link549* @return sum of the lengths of all internal lanes following this link550*/551double getInternalLengthsAfter() const;552553/** @brief Returns the cumulative length of all internal lanes before this link554* @return sum of the lengths of all internal lanes before this link555*/556double getInternalLengthsBefore() const;557558/** @brief Returns the sum of the lengths along internal lanes following this link559* to the crossing with the given foe lane, if the lane is no foe560* lane to any of the internal lanes, INVALID_DOUBLE is returned.561* @see getLengthBeforeCrossing()562*/563double getLengthsBeforeCrossing(const MSLane* foeLane) const;564565566/** @brief Returns the internal length from the beginning of the link's internal lane before567* to the crossing with the given foe lane if applicable, if the lane is no foe568* lane to the link, INVALID_DOUBLE is returned.569* @see getLengthsBeforeCrossing()570*/571double getLengthBeforeCrossing(const MSLane* foeLane) const;572573574/** @brief Returns the following inner lane575*576* @return The inner lane to use to cross the junction577*/578inline MSLane* getViaLane() const {579return myInternalLane;580}581582/** @brief Returns all potential link leaders (vehicles on foeLanes)583* Valid during the planMove() phase584* @param[in] ego The ego vehicle that is looking for leaders585* @param[in] dist The distance of the vehicle who is asking about the leader to this link586* @param[out] blocking Return blocking pedestrians if a vector is given587* @param[in] isShadowLink whether this link is a shadowLink for ego588* @return The all vehicles on foeLanes and their (virtual) distances to the asking vehicle589*/590const LinkLeaders getLeaderInfo(const MSVehicle* ego, double dist, std::vector<const MSPerson*>* collectBlockers = 0, bool isShadowLink = false) const;591592/// @brief return the speed at which ego vehicle must approach the zipper link593double getZipperSpeed(const MSVehicle* ego, const double dist, double vSafe,594SUMOTime arrivalTime,595const BlockingFoes* foes) const;596597/// @brief return the via lane if it exists and the lane otherwise598inline MSLane* getViaLaneOrLane() const {599return myInternalLane != nullptr ? myInternalLane : myLane;600}601602603/// @brief return the internalLaneBefore if it exists and the laneBefore otherwise604inline const MSLane* getLaneBefore() const {605assert(myInternalLaneBefore == nullptr || myLaneBefore == myInternalLaneBefore); // lane before mismatch!606return myLaneBefore;607}608609/// @brief return myInternalLaneBefore (always 0 when compiled without internal lanes)610inline const MSLane* getInternalLaneBefore() const {611return myInternalLaneBefore;612}613614/// @brief return the expected time at which the given vehicle will clear the link615SUMOTime getLeaveTime(const SUMOTime arrivalTime, const double arrivalSpeed, const double leaveSpeed, const double vehicleLength) const;616617/// @brief write information about all approaching vehicles to the given output device618void writeApproaching(OutputDevice& od, const std::string fromLaneID) const;619620/// @brief return the link that is parallel to this lane or 0621MSLink* getParallelLink(int direction) const;622623/// @brief return the link that is the opposite entry link to this one624MSLink* getOppositeDirectionLink() const;625626/// @brief return whether the fromLane of this link is an internal lane627inline bool fromInternalLane() const {628return myInternalLaneBefore != nullptr;629}630631/// @brief return whether the toLane of this link is an internal lane and fromLane is a normal lane632bool isEntryLink() const;633634/// @brief return whether this link enters the conflict area (not a continuation link)635bool isConflictEntryLink() const;636637/// @brief return whether the fromLane of this link is an internal lane and toLane is a normal lane638bool isExitLink() const;639640/// @brief return whether the fromLane of this link is an internal lane and its incoming lane is also an internal lane641bool isExitLinkAfterInternalJunction() const;642643/// @brief returns the corresponding exit link for entryLinks to a junction.644const MSLink* getCorrespondingExitLink() const;645646/// @brief returns the corresponding entry link for exitLinks to a junction.647const MSLink* getCorrespondingEntryLink() const;648649/// @brief return whether the fromLane and the toLane of this link are internal lanes650bool isInternalJunctionLink() const;651652/** @brief Returns the time penalty for passing a tls-controlled link (meso) */653SUMOTime getMesoTLSPenalty() const {654return myMesoTLSPenalty;655}656657/** @brief Returns the average proportion of green time to cycle time */658double getGreenFraction() const {659return myGreenFraction;660}661662/** @brief Sets the time penalty for passing a tls-controlled link (meso) */663void setMesoTLSPenalty(const SUMOTime penalty) {664myMesoTLSPenalty = penalty;665}666667/** @brief Sets the green fraction for passing a tls-controlled link (meso) */668void setGreenFraction(const double fraction) {669myGreenFraction = fraction;670}671672const std::vector<const MSLane*>& getFoeLanes() const {673return myFoeLanes;674}675676const std::vector<ConflictInfo>& getConflicts() const {677return myConflicts;678}679680const std::vector<MSLink*>& getFoeLinks() const {681return myFoeLinks;682}683684/// @brief who may use this link685SVCPermissions getPermissions() const {686return myPermissions;687}688689/// @brief initialize parallel links (to be called after all links are loaded)690void initParallelLinks();691692/// @brief return lateral shift that must be applied when passing this link693inline double getLateralShift() const {694return myLateralShift;695}696697/// @brief get string description for this link698std::string getDescription() const;699700/// @brief get the closest vehicle approaching this link701std::pair<const SUMOVehicle* const, const ApproachingVehicleInformation> getClosest() const;702703inline bool hasFoeCrossing() const {704return myHavePedestrianCrossingFoe;705}706707/// @brief whether this link is for a railsignal that was passed in this step708bool railSignalWasPassed() const;709710/// @brief post-processing for legacy networks711static void recheckSetRequestInformation();712713static bool ignoreFoe(const SUMOTrafficObject* ego, const SUMOTrafficObject* foe);714715static const double NO_INTERSECTION;716717private:718/// @brief return whether the given vehicles may NOT merge safely719static inline bool unsafeMergeSpeeds(double leaderSpeed, double followerSpeed, double leaderDecel, double followerDecel) {720// XXX mismatch between continuous an discrete deceleration721return (leaderSpeed * leaderSpeed / leaderDecel) <= (followerSpeed * followerSpeed / followerDecel);722}723724/// @brief whether follower could stay behind leader (possibly by braking)725static bool couldBrakeForLeader(double followDist, double leaderDist, const MSVehicle* follow, const MSVehicle* leader);726727MSLink* computeParallelLink(int direction);728729/// @brief check for persons on walkingarea in the path of ego vehicle730void checkWalkingAreaFoe(const MSVehicle* ego, const MSLane* foeLane, std::vector<const MSPerson*>* collectBlockers, LinkLeaders& result) const;731732/// @brief whether the given person is in front of the car733bool isInFront(const MSVehicle* ego, const PositionVector& egoPath, const Position& pPos) const;734735/// @brief whether the given person is walking towards the car returned as a factor in [0, 1]736double isOnComingPed(const MSVehicle* ego, const MSPerson* p) const;737738/// @brief return extrapolated position of the given person after the given time739Position getFuturePosition(const MSPerson* p, double timeHorizon = 1) const;740741bool blockedByFoe(const SUMOVehicle* veh, const ApproachingVehicleInformation& avi,742SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,743bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,744const SUMOTrafficObject* ego) const;745746/// @brief figure out whether the cont status remains in effect when switching off the tls747bool checkContOff() const;748749/// @brief check if the lane intersects with a foe cont-lane750bool contIntersect(const MSLane* lane, const MSLane* foe);751752/// @brief compute point of divergence for geomatries with a common start or end753double computeDistToDivergence(const MSLane* lane, const MSLane* sibling, double minDist, bool sameSource, double siblingPredLength = 0) const;754755/// @brief compute arrival time if foe vehicle is braking for ego756static SUMOTime computeFoeArrivalTimeBraking(SUMOTime arrivalTime, const SUMOVehicle* foe, SUMOTime foeArrivalTime, double impatience, double dist, double& fasb);757758/// @brief check whether the given vehicle positions overlap laterally759static bool lateralOverlap(double posLat, double width, double posLat2, double width2);760761/// @brief return CustomConflict with foeLane if it is defined762const CustomConflict* getCustomConflict(const MSLane* foeLane) const;763764/// @brief add information about another pedestrian crossing765void updateDistToFoePedCrossing(double dist);766767private:768/// @brief The lane behind the junction approached by this link769MSLane* myLane;770771/// @brief The lane approaching this link772MSLane* myLaneBefore;773774ApproachInfos myApproachingVehicles;775PersonApproachInfos* myApproachingPersons;776777/// @brief The position within this respond778int myIndex;779780/// @brief the traffic light index781const int myTLIndex;782783/// @brief the controlling logic or 0784const MSTrafficLightLogic* myLogic;785786/// @brief The state of the link787LinkState myState;788/// @brief The last green state of the link (minor or major)789LinkState myLastGreenState;790/// @brief The state of the link when switching of traffic light control791const LinkState myOffState;792793/// @brief The time of the last state change794SUMOTime myLastStateChange;795796/// @brief An abstract (hopefully human readable) definition of the link's direction797LinkDirection myDirection;798799/// @brief The length of the link800/// @note This is not equal to the result of getInternalLengthsAfter for links with more than one internal lane.801double myLength;802803/// @brief distance from which an approaching vehicle is able to804/// see all relevant foes and may accelerate if the link is minor805/// and no foe is approaching. Defaults to 4.5m.806/// For zipper links (major) this is the distance at which zipper merging starts (and foes become "visible")807double myFoeVisibilityDistance;808809/// @brief distance from the stop line to the first pedestrian crossing or maxdouble810double myDistToFoePedCrossing;811812/// @brief Whether any foe links exist813bool myHasFoes;814815// @brief whether vehicles may continue past this link to wait within the intersection816bool myAmCont;817// @brief whether vehicles may continue past this link to wait within the intersection after switching of the traffic light at this intersection818bool myAmContOff;819820// @brief whether vehicles must keep the intersection clear if there is a downstream jam821bool myKeepClear;822823/// @brief The following junction-internal lane if used824MSLane* const myInternalLane;825826/* @brief The preceding junction-internal lane, only used at827* - exit links (from internal lane to normal lane)828* - internal junction links (from internal lane to internal lane)829*/830const MSLane* myInternalLaneBefore;831832/// @brief penalty time at tls for mesoscopic simulation833SUMOTime myMesoTLSPenalty;834/// @brief green fraction at tls for mesoscopic simulation835double myGreenFraction;836837/// @brief lateral shift to be applied when passing this link838double myLateralShift;839840/* @brief lengths after the crossing point with foeLane841* (index corresponds to myFoeLanes)842* empty vector for entry links843* */844std::vector<ConflictInfo> myConflicts;845846std::vector<CustomConflict> myCustomConflicts;847848// TODO: documentation849std::vector<MSLink*> myFoeLinks;850std::vector<const MSLane*> myFoeLanes;851852/* prioritized links when the traffic light is switched off (only needed for RightOfWay::ALLWAYSTOP)853* @note stored as a pointer to save space since it won't be used in most cases854*/855std::vector<MSLink*>* myOffFoeLinks;856857/// @brief walkingArea that must be checked when entering the intersection858const MSLane* myWalkingAreaFoe;859/// @brief walkingArea that must be checked when leaving the intersection860const MSLane* myWalkingAreaFoeExit;861862/// @brief whether on of myFoeLanes is a crossing863bool myHavePedestrianCrossingFoe;864865/* @brief Links with the same origin lane and the same destination edge that may866be in conflict for sublane simulation */867std::vector<MSLink*> mySublaneFoeLinks;868/* @brief Links with the same origin lane and different destination edge that may869be in conflict for sublane simulation */870std::vector<MSLink*> mySublaneFoeLinks2;871872/* @brief Internal Lanes with the same origin lane and the same destination edge that may873be in conflict for sublane simulation */874std::vector<MSLane*> mySublaneFoeLanes;875876static const SUMOTime myLookaheadTime;877static const SUMOTime myLookaheadTimeZipper;878879/// @brief links that need post processing after initialization (to deal with legacy networks)880static std::set<std::pair<MSLink*, MSLink*> > myRecheck;881882MSLink* myParallelRight;883MSLink* myParallelLeft;884885/// @brief whether this connection is an indirect turning movement886const bool myAmIndirect;887888/// @brief the turning radius for this link or doublemax for straight links889double myRadius;890891/// @brief who may drive on this link892SVCPermissions myPermissions;893894/// @brief the junction to which this link belongs895MSJunction* myJunction;896897/// invalidated copy constructor898MSLink(const MSLink& s);899900/// invalidated assignment operator901MSLink& operator=(const MSLink& s);902903};904905906