LCOV - code coverage report
Current view: top level - src/microsim - MSLane.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 98.1 % 105 103
Test Date: 2025-11-13 15:38:19 Functions: 88.9 % 18 16

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

Generated by: LCOV version 2.0-1