LCOV - code coverage report
Current view: top level - src/microsim - MSLane.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 98.1 % 103 101
Test Date: 2024-11-22 15:46:21 Functions: 88.2 % 17 15

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 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       122954 :             : 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   1332289140 :             bool downstream = true) :
     140   1332289140 :             myLane(lane),
     141   1332289140 :             myI1(i1),
     142   1332289140 :             myI2(i2),
     143   1332289140 :             myI3(i3),
     144   1332289140 :             myI1End(i1End),
     145   1332289140 :             myI2End(i2End),
     146   1332289140 :             myI3End(i3End),
     147   1332289140 :             myDownstream(downstream),
     148   1332289140 :             myDirection(downstream ? 1 : -1) {
     149              :         }
     150              : 
     151              :         bool operator== (AnyVehicleIterator const& other) const {
     152              :             return (myI1 == other.myI1
     153   9948612191 :                     && myI2 == other.myI2
     154              :                     && myI3 == other.myI3
     155   2836373258 :                     && myI1End == other.myI1End
     156              :                     && myI2End == other.myI2End
     157   1118988494 :                     && 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     24751297 :         return myRNGIndex;
     243              :     }
     244              : 
     245              :     /// @brief return the associated RNG
     246              :     SumoRNG* getRNG() const {
     247    672023405 :         return &myRNGs[myRNGIndex];
     248              :     }
     249              : 
     250              :     /// @brief return the number of RNGs
     251              :     static int getNumRNGs() {
     252          774 :         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         1632 :     virtual double getLengthGeometryFactor(bool /*secondaryShape*/) const {
     291         1632 :         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);
     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    489246391 :         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     54510490 :         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   1302862300 :     virtual const VehCont& getVehiclesSecure() const {
     484   1302862300 :         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    933547319 :                                   (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   9869743434 :                                   (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    369575004 :                                   -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   1302862296 :     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    259503380 :         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     19601498 :         return myShape;
     535              :     }
     536              : 
     537              :     /// @brief return shape.length() / myLength
     538              :     inline double getLengthGeometryFactor() const {
     539      2722559 :         return myLengthGeometryFactor;
     540              :     }
     541              : 
     542              :     /// @brief return whether this lane is an acceleration lane
     543              :     inline bool isAccelLane() const {
     544       379412 :         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      4582147 :         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   1421775270 :         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      7100813 :         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   5018221926 :     inline double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const {
     575   5018221926 :         if (myRestrictions != nullptr) {
     576      4839443 :             std::map<SUMOVehicleClass, double>::const_iterator r = myRestrictions->find(veh->getVClass());
     577      4839443 :             if (r != myRestrictions->end()) {
     578      4630717 :                 if (mySpeedByVSS || mySpeedByTraCI) {
     579        34172 :                     return MIN2(myMaxSpeed, MIN2(veh->getMaxSpeed(), r->second * veh->getChosenSpeedFactor()));
     580              :                 } else {
     581      4613631 :                     return MIN2(veh->getMaxSpeed(), r->second * veh->getChosenSpeedFactor());
     582              :                 }
     583              :             }
     584              :         }
     585   5013591209 :         return MIN2(veh->getMaxSpeed(), myMaxSpeed * veh->getChosenSpeedFactor());
     586              :     }
     587              : 
     588              : 
     589              :     /** @brief Returns the lane's maximum allowed speed
     590              :      * @return This lane's maximum allowed speed
     591              :      */
     592              :     inline double getSpeedLimit() const {
     593    518655076 :         return myMaxSpeed;
     594              :     }
     595              : 
     596              :     /** @brief Returns the lane's friction coefficient
     597              :     * @return This lane's friction coefficient
     598              :     */
     599            0 :     inline double getFrictionCoefficient() const {
     600         4032 :         return myFrictionCoefficient;
     601              :     }
     602              : 
     603              :     /** @brief Returns the lane's length
     604              :      * @return This lane's length
     605              :      */
     606              :     inline double getLength() const {
     607  32836098279 :         return myLength;
     608              :     }
     609              : 
     610              : 
     611              :     /** @brief Returns the vehicle class permissions for this lane
     612              :      * @return This lane's allowed vehicle classes
     613              :      */
     614              :     inline SVCPermissions getPermissions() const {
     615     71300381 :         return myPermissions;
     616              :     }
     617              : 
     618              :     /** @brief Returns the vehicle class permissions for changing to the left neighbour lane
     619              :      * @return The vehicle classes allowed to change to the left neighbour lane
     620              :      */
     621              :     inline SVCPermissions getChangeLeft() const {
     622           18 :         return myChangeLeft;
     623              :     }
     624              : 
     625              :     /** @brief Returns the vehicle class permissions for changing to the right neighbour lane
     626              :      * @return The vehicle classes allowed to change to the right neighbour lane
     627              :      */
     628              :     inline SVCPermissions getChangeRight() const {
     629           18 :         return myChangeRight;
     630              :     }
     631              : 
     632              :     /** @brief Returns the lane's width
     633              :      * @return This lane's width
     634              :      */
     635              :     double getWidth() const {
     636   4059766113 :         return myWidth;
     637              :     }
     638              : 
     639              :     /** @brief Returns the lane's index
     640              :      * @return This lane's index
     641              :      */
     642              :     int getIndex() const {
     643   2727940905 :         return myIndex;
     644              :     }
     645              :     /// @}
     646              : 
     647              :     /// @brief return the index of the link to the next crossing if this is walkingArea, else -1
     648              :     int getCrossingIndex() const;
     649              : 
     650              : 
     651              :     /// @name Vehicle movement (longitudinal)
     652              :     /// @{
     653              : 
     654              :     /** @brief Compute safe velocities for all vehicles based on positions and
     655              :      * speeds from the last time step. Also registers
     656              :      * ApproachingVehicleInformation for all links
     657              :      *
     658              :      * This method goes through all vehicles calling their "planMove" method.
     659              :      * @see MSVehicle::planMove
     660              :      */
     661              :     virtual void planMovements(const SUMOTime t);
     662              : 
     663              :     /** @brief Register junction approaches for all vehicles after velocities
     664              :      * have been planned.
     665              :      *
     666              :      * This method goes through all vehicles calling their * "setApproachingForAllLinks" method.
     667              :      */
     668              :     virtual void setJunctionApproaches(const SUMOTime t) const;
     669              : 
     670              :     /** @brief This updates the MSLeaderInfo argument with respect to the given MSVehicle.
     671              :      *         All leader-vehicles on the same edge, which are relevant for the vehicle
     672              :      *         (i.e. with position > vehicle's position) and not already integrated into
     673              :      *         the LeaderInfo, are integrated.
     674              :      *         The given iterators vehPart and vehRes give access to these vehicles which are
     675              :      *         either partial occupators or have issued a maneuver reservation for the lane
     676              :      *         (the latter occurs only for the sublane model).
     677              :      */
     678              :     void updateLeaderInfo(const MSVehicle* veh, VehCont::reverse_iterator& vehPart, VehCont::reverse_iterator& vehRes, MSLeaderInfo& ahead) const;
     679              : 
     680              :     /** @brief Executes planned vehicle movements with regards to right-of-way
     681              :      *
     682              :      * This method goes through all vehicles calling their executeMove method
     683              :      * which causes vehicles to update their positions and speeds.
     684              :      * Vehicles wich move to the next lane are stored in the targets lane buffer
     685              :      *
     686              :      * @return Returns true, if all vehicles left the lane.
     687              :      *
     688              :      * @see MSVehicle::executeMove
     689              :      */
     690              :     virtual void executeMovements(const SUMOTime t);
     691              : 
     692              :     /// Insert buffered vehicle into the real lane.
     693              :     virtual void integrateNewVehicles();
     694              : 
     695              :     /** @brief Set a flag to recalculate the brutto (including minGaps) occupancy of this lane (used if mingap is changed)
     696              :      */
     697              :     void markRecalculateBruttoSum();
     698              : 
     699              :     /// @brief updated current vehicle length sum (delayed to avoid lane-order-dependency)
     700              :     void updateLengthSum();
     701              :     ///@}
     702              : 
     703              : 
     704              :     /// @brief short-circut collision check if nothing changed since the last check
     705              :     inline bool needsCollisionCheck() const {
     706    316936045 :         return myNeedsCollisionCheck;
     707              :     }
     708              : 
     709              :     /// @brief require another collision check due to relevant changes in the simulation
     710              :     inline void requireCollisionCheck() {
     711      4207724 :         myNeedsCollisionCheck = true;
     712       974830 :     }
     713              : 
     714              :     /// Check if vehicles are too close.
     715              :     virtual void detectCollisions(SUMOTime timestep, const std::string& stage);
     716              : 
     717              : 
     718              :     /** Returns the information whether this lane may be used to continue
     719              :         the current route */
     720              :     virtual bool appropriate(const MSVehicle* veh) const;
     721              : 
     722              : 
     723              :     /// returns the container with all links !!!
     724              :     const std::vector<MSLink*>& getLinkCont() const {
     725          881 :         return myLinks;
     726              :     }
     727              : 
     728              :     /// returns the link to the given lane or nullptr, if it is not connected
     729              :     const MSLink* getLinkTo(const MSLane* const) const;
     730              : 
     731              :     /// returns the internal lane leading to the given lane or nullptr, if there is none
     732              :     const MSLane* getInternalFollowingLane(const MSLane* const) const;
     733              : 
     734              :     /// Returns the entry link if this is an internal lane, else nullptr
     735              :     const MSLink* getEntryLink() const;
     736              : 
     737              : 
     738              :     /// Returns true if there is not a single vehicle on the lane.
     739              :     bool empty() const {
     740              :         assert(myVehBuffer.size() == 0);
     741              :         return myVehicles.empty();
     742              :     }
     743              : 
     744              :     /** @brief Sets a new maximum speed for the lane (used by TraCI and MSCalibrator)
     745              :      * @param[in] val the new speed in m/s
     746              :      * @param[in] whether a variable speed sign (VSS) imposes the speed limit
     747              :      * @param[in] whether TraCI imposes the speed limit
     748              :      */
     749              :     void setMaxSpeed(double val, bool byVSS = false, bool byTraCI = false, double jamThreshold = -1);
     750              : 
     751              :     /** @brief Sets a new friction coefficient for the lane [*to be later (used by TraCI and MSCalibrator)*]
     752              :     * @param[in] val the new friction coefficient [0..1]
     753              :     */
     754              :     void setFrictionCoefficient(double val);
     755              : 
     756              :     /** @brief Sets a new length for the lane (used by TraCI only)
     757              :      * @param[in] val the new length in m
     758              :      */
     759              :     void setLength(double val);
     760              : 
     761              :     /** @brief Returns the lane's edge
     762              :      * @return This lane's edge
     763              :      */
     764              :     MSEdge& getEdge() const {
     765  39467055788 :         return *myEdge;
     766              :     }
     767              : 
     768              : 
     769              :     /** @brief Returns the lane's follower if it is an internal lane, the edge of the lane otherwise
     770              :      * @return This lane's follower
     771              :      */
     772              :     const MSEdge* getNextNormal() const;
     773              : 
     774              : 
     775              :     /** @brief Returns 0 if the lane is not internal. Otherwise the first part of the
     776              :      *         connection (sequence of internal lanes along junction) corresponding to the lane
     777              :      *         is returned and the offset is set to the distance of the begin of this lane
     778              :      *         to the begin of the returned.
     779              :      */
     780              :     const MSLane* getFirstInternalInConnection(double& offset) const;
     781              : 
     782              : 
     783              :     /// @brief Static (sic!) container methods
     784              :     /// {
     785              : 
     786              :     /** @brief Inserts a MSLane into the static dictionary
     787              :      *
     788              :      * Returns true if the key id isn't already in the dictionary.
     789              :      *  Otherwise returns false.
     790              :      * @param[in] id The id of the lane
     791              :      * @param[in] lane The lane itself
     792              :      * @return Whether the lane was added
     793              :      * @todo make non-static
     794              :      * @todo why is the id given? The lane is named
     795              :      */
     796              :     static bool dictionary(const std::string& id, MSLane* lane);
     797              : 
     798              : 
     799              :     /** @brief Returns the MSLane associated to the key id
     800              :      *
     801              :      * The lane is returned if exists, otherwise 0 is returned.
     802              :      * @param[in] id The id of the lane
     803              :      * @return The lane
     804              :      */
     805              :     static MSLane* dictionary(const std::string& id);
     806              : 
     807              : 
     808              :     /** @brief Clears the dictionary */
     809              :     static void clear();
     810              : 
     811              : 
     812              :     /** @brief Returns the number of stored lanes
     813              :      * @return The number of stored lanes
     814              :      */
     815              :     static int dictSize() {
     816        42566 :         return (int)myDict.size();
     817              :     }
     818              : 
     819              : 
     820              :     /** @brief Adds the ids of all stored lanes into the given vector
     821              :      * @param[in, filled] into The vector to add the IDs into
     822              :      */
     823              :     static void insertIDs(std::vector<std::string>& into);
     824              : 
     825              : 
     826              :     /** @brief Fills the given RTree with lane instances
     827              :      * @param[in, filled] into The RTree to fill
     828              :      * @see TraCILaneRTree
     829              :      */
     830              :     template<class RTREE>
     831              :     static void fill(RTREE& into);
     832              : 
     833              : 
     834              :     /// @brief initialize rngs
     835              :     static void initRNGs(const OptionsCont& oc);
     836              :     /// @}
     837              : 
     838              : 
     839              : 
     840              :     // XXX: succLink does not exist... Documentation?
     841              :     /** Same as succLink, but does not throw any assertions when
     842              :         the succeeding link could not be found;
     843              :         Returns the myLinks.end() instead; Further, the number of edges to
     844              :         look forward may be given */
     845              :     static std::vector<MSLink*>::const_iterator succLinkSec(const SUMOVehicle& veh,
     846              :             int nRouteSuccs,
     847              :             const MSLane& succLinkSource,
     848              :             const std::vector<MSLane*>& conts);
     849              : 
     850              : 
     851              :     /** Returns the information whether the given link shows at the end
     852              :         of the list of links (is not valid) */
     853              :     inline bool isLinkEnd(std::vector<MSLink*>::const_iterator& i) const {
     854              :         return i == myLinks.end();
     855              :     }
     856              : 
     857              :     /** Returns the information whether the given link shows at the end
     858              :         of the list of links (is not valid) */
     859              :     inline bool isLinkEnd(std::vector<MSLink*>::iterator& i) {
     860              :         return i == myLinks.end();
     861              :     }
     862              : 
     863              :     /** Returns the information whether the lane is has no vehicle and no
     864              :         partial occupation*/
     865              :     inline bool isEmpty() const {
     866       192786 :         return myVehicles.empty() && myPartialVehicles.empty();
     867              :     }
     868              : 
     869              :     /** Returns whether the lane pertains to an internal edge*/
     870              :     bool isInternal() const;
     871              : 
     872              :     /** Returns whether the lane pertains to a normal edge*/
     873              :     bool isNormal() const;
     874              : 
     875              :     /** Returns whether the lane pertains to a crossing edge*/
     876              :     bool isCrossing() const;
     877              : 
     878              :     /** Returns whether the lane pertains to a walkingarea*/
     879              :     bool isWalkingArea() const;
     880              : 
     881              :     /// @brief returns the last vehicle for which this lane is responsible or 0
     882              :     MSVehicle* getLastFullVehicle() const;
     883              : 
     884              :     /// @brief returns the first vehicle for which this lane is responsible or 0
     885              :     MSVehicle* getFirstFullVehicle() const;
     886              : 
     887              :     /// @brief returns the last vehicle that is fully or partially on this lane
     888              :     MSVehicle* getLastAnyVehicle() const;
     889              : 
     890              :     /// @brief returns the first vehicle that is fully or partially on this lane
     891              :     MSVehicle* getFirstAnyVehicle() const;
     892              : 
     893              :     /* @brief remove the vehicle from this lane
     894              :      * @param[notify] whether moveReminders of the vehicle shall be triggered
     895              :      */
     896              :     virtual MSVehicle* removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify = true);
     897              : 
     898              :     void leftByLaneChange(MSVehicle* v);
     899              :     void enteredByLaneChange(MSVehicle* v);
     900              : 
     901              :     /** @brief Returns the lane with the given offset parallel to this one or 0 if it does not exist
     902              :      * @param[in] offset The offset of the result lane
     903              :      */
     904              :     MSLane* getParallelLane(int offset, bool includeOpposite = true) const;
     905              : 
     906              : 
     907              :     /** @brief Sets the permissions to the given value. If a transientID is given, the permissions are recored as temporary
     908              :      * @param[in] permissions The new permissions
     909              :      * @param[in] transientID The id of the permission-modification or the special value PERMANENT
     910              :      */
     911              :     void setPermissions(SVCPermissions permissions, long long transientID);
     912              :     void resetPermissions(long long transientID);
     913              :     bool hadPermissionChanges() const;
     914              : 
     915              :     /** @brief Sets the permissions for changing to the left neighbour lane
     916              :      * @param[in] permissions The new permissions
     917              :      */
     918              :     void setChangeLeft(SVCPermissions permissions);
     919              : 
     920              :     /** @brief Sets the permissions for changing to the right neighbour lane
     921              :      * @param[in] permissions The new permissions
     922              :      */
     923              :     void setChangeRight(SVCPermissions permissions);
     924              : 
     925              :     inline bool allowsVehicleClass(SUMOVehicleClass vclass) const {
     926   5759262897 :         return (myPermissions & vclass) == vclass;
     927              :     }
     928              : 
     929              :     bool allowsVehicleClass(SUMOVehicleClass vclass, int routingMode) const;
     930              : 
     931              :     /** @brief Returns whether the given vehicle class may change left from this lane */
     932              :     inline bool allowsChangingLeft(SUMOVehicleClass vclass) const {
     933    251262730 :         return (myChangeLeft & vclass) == vclass;
     934              :     }
     935              : 
     936              :     /** @brief Returns whether the given vehicle class may change left from this lane */
     937              :     inline bool allowsChangingRight(SUMOVehicleClass vclass) const {
     938    215474256 :         return (myChangeRight & vclass) == vclass;
     939              :     }
     940              : 
     941              :     void addIncomingLane(MSLane* lane, MSLink* viaLink);
     942              : 
     943              : 
     944              :     struct IncomingLaneInfo {
     945              :         MSLane* lane;
     946              :         double length;
     947              :         MSLink* viaLink;
     948              :     };
     949              : 
     950              :     const std::vector<IncomingLaneInfo>& getIncomingLanes() const {
     951      1255598 :         return myIncomingLanes;
     952              :     }
     953              : 
     954              : 
     955              :     void addApproachingLane(MSLane* lane, bool warnMultiCon);
     956              :     inline bool isApproachedFrom(MSEdge* const edge) {
     957              :         return myApproachingLanes.find(edge) != myApproachingLanes.end();
     958              :     }
     959              :     bool isApproachedFrom(MSEdge* const edge, MSLane* const lane);
     960              : 
     961              :     /// @brief Returns vehicle class specific stopOffset for the vehicle
     962              :     double getVehicleStopOffset(const MSVehicle* veh) const;
     963              : 
     964              :     /// @brief Returns vehicle class specific stopOffsets
     965              :     const StopOffset& getLaneStopOffsets() const;
     966              : 
     967              :     /// @brief Set vehicle class specific stopOffsets
     968              :     void setLaneStopOffset(const StopOffset& stopOffset);
     969              : 
     970              :     /** @enum MinorLinkMode
     971              :      * @brief determine whether/how getFollowers looks upstream beyond minor links
     972              :      */
     973              :     enum MinorLinkMode {
     974              :         FOLLOW_NEVER = 0,
     975              :         FOLLOW_ALWAYS = 1,
     976              :         FOLLOW_ONCOMING = 2,
     977              :     };
     978              : 
     979              :     /// @brief return the sublane followers with the largest missing rear gap among all predecessor lanes (within dist)
     980              :     MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle* ego, double backOffset,
     981              :             bool allSublanes, double searchDist = -1, MinorLinkMode mLinkMode = FOLLOW_ALWAYS) const;
     982              : 
     983              :     /// @brief return by how much further the leader must be inserted to avoid rear end collisions
     984              :     double getMissingRearGap(const MSVehicle* leader, double backOffset, double leaderSpeed) const;
     985              : 
     986              :     /** @brief Returns the immediate leader of veh and the distance to veh
     987              :      * starting on this lane
     988              :      *
     989              :      * Iterates over the current lane to find a leader and then uses
     990              :      * getLeaderOnConsecutive()
     991              :      * @param[in] veh The vehicle for which the information shall be computed
     992              :      * @param[in] vehPos The vehicle position relative to this lane (may be negative)
     993              :      * @param[in] bestLaneConts The succeding lanes that shall be checked (if any)
     994              :      * @param[in] dist Optional distance to override default (ego stopDist)
     995              :      * @param[in] checkTmpVehicles Whether myTmpVehicles should be used instead of myVehicles
     996              :      * @return
     997              :      */
     998              :     std::pair<MSVehicle* const, double> getLeader(const MSVehicle* veh, const double vehPos, const std::vector<MSLane*>& bestLaneConts, double dist = -1, bool checkTmpVehicles = false) const;
     999              : 
    1000              :     /** @brief Returns the immediate leader and the distance to him
    1001              :      *
    1002              :      * Goes along the vehicle's estimated used lanes (bestLaneConts). For each link,
    1003              :      *  it is determined whether the vehicle will pass it. If so, the subsequent lane
    1004              :      *  is investigated. If a vehicle (leader) is found, it is returned, together with the length
    1005              :      *  of the investigated lanes until this vehicle's end, including the already seen
    1006              :      *  place (seen).
    1007              :      *
    1008              :      * If no leading vehicle was found, <0, -1> is returned.
    1009              :      *
    1010              :      * Pretty slow, as it has to go along lanes.
    1011              :      *
    1012              :      * @todo: There are some oddities:
    1013              :      * - what about crossing a link at red, or if a link is closed? Has a following vehicle to be regarded or not?
    1014              :      *
    1015              :      * @param[in] dist The distance to investigate
    1016              :      * @param[in] seen The already seen place (normally the place in front on own lane)
    1017              :      * @param[in] speed The speed of the vehicle used for determining whether a subsequent link will be opened at arrival time
    1018              :      * @param[in] veh The vehicle for which the information shall be computed
    1019              :      * @param[in] bestLaneConts The lanes the vehicle will use in future
    1020              :      * @return
    1021              :      */
    1022              :     std::pair<MSVehicle* const, double> getLeaderOnConsecutive(double dist, double seen,
    1023              :             double speed, const MSVehicle& veh, const std::vector<MSLane*>& bestLaneConts) const;
    1024              : 
    1025              :     /// @brief Returns the immediate leaders and the distance to them (as getLeaderOnConsecutive but for the sublane case)
    1026              :     void getLeadersOnConsecutive(double dist, double seen, double speed, const MSVehicle* ego,
    1027              :                                  const std::vector<MSLane*>& bestLaneConts, MSLeaderDistanceInfo& result, bool oppositeDirection = false) const;
    1028              : 
    1029              : 
    1030              :     /// @brief get leaders for ego on the given lane
    1031              :     void addLeaders(const MSVehicle* vehicle, double vehPos, MSLeaderDistanceInfo& result, bool oppositeDirection = false);
    1032              : 
    1033              : 
    1034              :     /** @brief Returns the most dangerous leader and the distance to him
    1035              :      *
    1036              :      * Goes along the vehicle's estimated used lanes (bestLaneConts). For each link,
    1037              :      *  it is determined whether the ego vehicle will pass it. If so, the subsequent lane
    1038              :      *  is investigated. Check all lanes up to the stopping distance of ego.
    1039              :      *  Return the leader vehicle (and the gap) which puts the biggest speed constraint on ego.
    1040              :      *
    1041              :      * If no leading vehicle was found, <0, -1> is returned.
    1042              :      *
    1043              :      * Pretty slow, as it has to go along lanes.
    1044              :      *
    1045              :      * @param[in] dist The distance to investigate
    1046              :      * @param[in] seen The already seen place (normally the place in front on own lane)
    1047              :      * @param[in] speed The speed of the vehicle used for determining whether a subsequent link will be opened at arrival time
    1048              :      * @param[in] veh The (ego) vehicle for which the information shall be computed
    1049              :      * @return
    1050              :      */
    1051              :     std::pair<MSVehicle* const, double> getCriticalLeader(double dist, double seen, double speed, const MSVehicle& veh) const;
    1052              : 
    1053              :     /* @brief return the partial vehicle closest behind ego or 0
    1054              :      * if no such vehicle exists */
    1055              :     MSVehicle* getPartialBehind(const MSVehicle* ego) const;
    1056              : 
    1057              :     /// @brief get all vehicles that are inlapping from consecutive edges
    1058              :     MSLeaderInfo getPartialBeyond() const;
    1059              : 
    1060              :     /// @brief Returns all vehicles closer than downstreamDist along the road network starting on the given
    1061              :     ///        position. Predecessor lanes are searched upstream for the given upstreamDistance.
    1062              :     /// @note  Re-implementation of the corresponding method in MSDevice_SSM, which cannot be easily adapted, as it gathers
    1063              :     ///        additional information for conflict lanes, etc.
    1064              :     /// @param[in] startPos - start position of the search on the first lane
    1065              :     /// @param[in] downstreamDist - distance to search downstream
    1066              :     /// @param[in] upstreamDist - distance to search upstream
    1067              :     /// @param[in/out] checkedLanes - lanes, which were already scanned (current lane is added, if not present,
    1068              :     ///                otherwise the scan is aborted; TODO: this may disregard unscanned parts of the lane in specific circular set ups.)
    1069              :     /// @return    vehs - List of vehicles found
    1070              :     std::set<MSVehicle*> getSurroundingVehicles(double startPos, double downstreamDist, double upstreamDist, std::shared_ptr<LaneCoverageInfo> checkedLanes) const;
    1071              : 
    1072              :     /// @brief Returns all vehicles on the lane overlapping with the interval [a,b]
    1073              :     /// @note  Does not consider vehs with front on subsequent lanes
    1074              :     std::set<MSVehicle*> getVehiclesInRange(const double a, const double b) const;
    1075              : 
    1076              :     /// @brief Returns all upcoming junctions within given range along the given (non-internal) continuation lanes measured from given position
    1077              :     std::vector<const MSJunction*> getUpcomingJunctions(double pos, double range, const std::vector<MSLane*>& contLanes) const;
    1078              : 
    1079              :     /// @brief Returns all upcoming links within given range along the given (non-internal) continuation lanes measured from given position
    1080              :     std::vector<const MSLink*> getUpcomingLinks(double pos, double range, const std::vector<MSLane*>& contLanes) const;
    1081              : 
    1082              :     /** @brief get the most likely precedecessor lane (sorted using by_connections_to_sorter).
    1083              :      * The result is cached in myLogicalPredecessorLane
    1084              :      */
    1085              :     MSLane* getLogicalPredecessorLane() const;
    1086              : 
    1087              :     /** @brief get normal lane leading to this internal lane, for normal lanes,
    1088              :      * the lane itself is returned
    1089              :      */
    1090              :     const MSLane* getNormalPredecessorLane() const;
    1091              : 
    1092              :     /** @brief get normal lane following this internal lane, for normal lanes,
    1093              :      * the lane itself is returned
    1094              :      */
    1095              :     const MSLane* getNormalSuccessorLane() const;
    1096              : 
    1097              :     /** @brief return the (first) predecessor lane from the given edge
    1098              :      */
    1099              :     MSLane* getLogicalPredecessorLane(const MSEdge& fromEdge) const;
    1100              : 
    1101              : 
    1102              :     /** Return the main predecessor lane for the current.
    1103              :      * If there are several incoming lanes, the first attempt is to return the priorized.
    1104              :      * If this does not yield an unambiguous lane, the one with the least angle difference
    1105              :      * to the current is selected.
    1106              :      */
    1107              :     MSLane* getCanonicalPredecessorLane() const;
    1108              : 
    1109              : 
    1110              :     /** Return the main successor lane for the current.
    1111              :      * If there are several outgoing lanes, the first attempt is to return the priorized.
    1112              :      * If this does not yield an unambiguous lane, the one with the least angle difference
    1113              :      * to the current is selected.
    1114              :      */
    1115              :     MSLane* getCanonicalSuccessorLane() const;
    1116              : 
    1117              :     /// @brief get the state of the link from the logical predecessor to this lane
    1118              :     LinkState getIncomingLinkState() const;
    1119              : 
    1120              :     /// @brief get the list of outgoing lanes
    1121              :     const std::vector<std::pair<const MSLane*, const MSEdge*> > getOutgoingViaLanes() const;
    1122              : 
    1123              :     /// @brief get the list of all direct (disregarding internal predecessors) non-internal predecessor lanes of this lane
    1124              :     std::vector<const MSLane*> getNormalIncomingLanes() const;
    1125              : 
    1126              :     /// @name Current state retrieval
    1127              :     //@{
    1128              : 
    1129              :     /** @brief Returns the mean speed on this lane
    1130              :      * @return The average speed of vehicles during the last step; default speed if no vehicle was on this lane
    1131              :      */
    1132              :     double getMeanSpeed() const;
    1133              : 
    1134              :     /// @brief get the mean speed of all bicycles on this lane
    1135              :     double getMeanSpeedBike() const;
    1136              : 
    1137              :     /** @brief Returns the overall waiting time on this lane
    1138              :     * @return The sum of the waiting time of all vehicles during the last step;
    1139              :     */
    1140              :     double getWaitingSeconds() const;
    1141              : 
    1142              : 
    1143              :     /** @brief Returns the brutto (including minGaps) occupancy of this lane during the last step
    1144              :      * @return The occupancy during the last step
    1145              :      */
    1146              :     double getBruttoOccupancy() const;
    1147              : 
    1148              : 
    1149              :     /** @brief Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)
    1150              :      * @return The occupancy during the last step
    1151              :      */
    1152              :     double getNettoOccupancy() const;
    1153              : 
    1154              : 
    1155              :     /** @brief Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the last step
    1156              :      * @return The sum of vehicle lengths of vehicles in the last step
    1157              :      */
    1158              :     inline double getBruttoVehLenSum() const {
    1159   2573116198 :         return myBruttoVehicleLengthSum;
    1160              :     }
    1161              : 
    1162              : 
    1163              :     /** @brief Returns the sum of last step emissions
    1164              :      * The value is always per 1s, so multiply by step length if necessary.
    1165              :      * @return emissions of vehicles on this lane during the last step
    1166              :      */
    1167              :     template<PollutantsInterface::EmissionType ET>
    1168       309301 :     double getEmissions() const {
    1169              :         double ret = 0;
    1170       313441 :         for (MSVehicle* const v : getVehiclesSecure()) {
    1171         4140 :             ret += v->getEmissions<ET>();
    1172              :         }
    1173       309301 :         releaseVehicles();
    1174       309301 :         return ret;
    1175              :     }
    1176              : 
    1177              : 
    1178              :     /** @brief Returns the sum of last step noise emissions
    1179              :      * @return noise emissions of vehicles on this lane during the last step
    1180              :      */
    1181              :     double getHarmonoise_NoiseEmissions() const;
    1182              :     /// @}
    1183              : 
    1184              :     void setRightSideOnEdge(double value, int rightmostSublane) {
    1185      2159984 :         myRightSideOnEdge = value;
    1186      2159984 :         myRightmostSublane = rightmostSublane;
    1187              :     }
    1188              : 
    1189              :     /// @brief initialized vClass-specific speed limits
    1190              :     void initRestrictions();
    1191              : 
    1192              :     void checkBufferType();
    1193              : 
    1194              :     double getRightSideOnEdge() const {
    1195   4488318417 :         return myRightSideOnEdge;
    1196              :     }
    1197              : 
    1198              :     int getRightmostSublane() const {
    1199     92954878 :         return myRightmostSublane;
    1200              :     }
    1201              : 
    1202              :     double getCenterOnEdge() const {
    1203        24980 :         return myRightSideOnEdge + 0.5 * myWidth;
    1204              :     }
    1205              : 
    1206              :     /// @brief sorts myPartialVehicles
    1207              :     void sortPartialVehicles();
    1208              : 
    1209              :     /// @brief sorts myManeuverReservations
    1210              :     void sortManeuverReservations();
    1211              : 
    1212              :     /// @brief return the neighboring opposite direction lane for lane changing or nullptr
    1213              :     MSLane* getOpposite() const;
    1214              : 
    1215              :     /// @brief return the opposite direction lane of this lanes edge or nullptr
    1216              :     MSLane* getParallelOpposite() const;
    1217              : 
    1218              :     /// @brief return the corresponding position on the opposite lane
    1219              :     double getOppositePos(double pos) const;
    1220              : 
    1221              :     /* @brief find leader for a vehicle depending on the relative driving direction
    1222              :      * @param[in] ego The ego vehicle
    1223              :      * @param[in] dist The look-ahead distance when looking at consecutive lanes
    1224              :      * @param[in] oppositeDir Whether the lane has the opposite driving direction of ego
    1225              :      * @return the leader vehicle and its gap to ego
    1226              :      */
    1227              :     std::pair<MSVehicle* const, double> getOppositeLeader(const MSVehicle* ego, double dist, bool oppositeDir, MinorLinkMode mLinkMode = MinorLinkMode::FOLLOW_NEVER) const;
    1228              : 
    1229              :     /* @brief find follower for a vehicle that is located on the opposite of this lane
    1230              :      * @param[in] ego The ego vehicle
    1231              :      * @return the follower vehicle and its gap to ego
    1232              :      */
    1233              :     std::pair<MSVehicle* const, double> getOppositeFollower(const MSVehicle* ego) const;
    1234              : 
    1235              : 
    1236              :     /** @brief Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane)
    1237              :      * @param[in] ego The ego vehicle
    1238              :      * @param[in] egoPos The ego position mapped to the current lane
    1239              :      * @param[in] dist The look-back distance when looking at consecutive lanes
    1240              :      * @param[in] ignoreMinorLinks Whether backward search should stop at minor links
    1241              :      * @return the follower vehicle and its gap to ego
    1242              :      */
    1243              :     std::pair<MSVehicle* const, double> getFollower(const MSVehicle* ego, double egoPos, double dist, MinorLinkMode mLinkMode) const;
    1244              : 
    1245              : 
    1246              :     ///@brief add parking vehicle. This should only used during state loading
    1247              :     void addParking(MSBaseVehicle* veh);
    1248              : 
    1249              :     ///@brief remove parking vehicle. This must be syncrhonized when running with GUI
    1250              :     virtual void removeParking(MSBaseVehicle* veh);
    1251              : 
    1252              :     /// @brief retrieve the parking vehicles (see GUIParkingArea)
    1253              :     const std::set<const MSBaseVehicle*>& getParkingVehicles() const {
    1254              :         return myParkingVehicles;
    1255              :     }
    1256              : 
    1257              :     /// @brief whether this lane is selected in the GUI
    1258      1010971 :     virtual bool isSelected() const {
    1259      1010971 :         return false;
    1260              :     }
    1261              : 
    1262              :     /// @brief retrieve bidirectional lane or nullptr
    1263              :     MSLane* getBidiLane() const;
    1264              : 
    1265              :     /// @brief whether this lane must check for junction collisions
    1266              :     bool mustCheckJunctionCollisions() const;
    1267              : 
    1268              : #ifdef HAVE_FOX
    1269              :     MFXWorkerThread::Task* getPlanMoveTask(const SUMOTime time) {
    1270              :         mySimulationTask.init(&MSLane::planMovements, time);
    1271     12120174 :         return &mySimulationTask;
    1272              :     }
    1273              : 
    1274              :     MFXWorkerThread::Task* getExecuteMoveTask(const SUMOTime time) {
    1275              :         mySimulationTask.init(&MSLane::executeMovements, time);
    1276     12120174 :         return &mySimulationTask;
    1277              :     }
    1278              : 
    1279              :     MFXWorkerThread::Task* getLaneChangeTask(const SUMOTime time) {
    1280              :         mySimulationTask.init(&MSLane::changeLanes, time);
    1281              :         return &mySimulationTask;
    1282              :     }
    1283              : #endif
    1284              : 
    1285              :     std::vector<StopWatch<std::chrono::nanoseconds> >& getStopWatch() {
    1286              :         return myStopWatch;
    1287              :     }
    1288              : 
    1289              :     void changeLanes(const SUMOTime time);
    1290              : 
    1291              :     /// @name State saving/loading
    1292              :     /// @{
    1293              : 
    1294              :     /** @brief Saves the state of this lane into the given stream
    1295              :      *
    1296              :      * Basically, a list of vehicle ids
    1297              :      *
    1298              :      * @param[in, filled] out The (possibly binary) device to write the state into
    1299              :      * @todo What about throwing an IOError?
    1300              :      */
    1301              :     void saveState(OutputDevice& out);
    1302              : 
    1303              :     /** @brief Remove all vehicles before quick-loading state */
    1304              :     void clearState();
    1305              : 
    1306              :     /** @brief Loads the state of this segment with the given parameters
    1307              :      *
    1308              :      * This method is called for every internal que the segment has.
    1309              :      *  Every vehicle is retrieved from the given MSVehicleControl and added to this
    1310              :      *  lane.
    1311              :      *
    1312              :      * @param[in] vehIDs The vehicle ids for the current que
    1313              :      * @param[in] vc The vehicle control to retrieve references vehicles from
    1314              :      * @todo What about throwing an IOError?
    1315              :      * @todo What about throwing an error if something else fails (a vehicle can not be referenced)?
    1316              :      */
    1317              :     void loadState(const std::vector<std::string>& vehIDs, MSVehicleControl& vc);
    1318              : 
    1319              : 
    1320              :     /* @brief helper function for state saving: checks whether any outgoing
    1321              :      * links are being approached */
    1322              :     bool hasApproaching() const;
    1323              : 
    1324              :     /// @}
    1325              : 
    1326              : 
    1327              :     /** @brief Callback for visiting the lane when traversing an RTree
    1328              :      *
    1329              :      * This is used in the TraCIServerAPI_Lane for context subscriptions.
    1330              :      *
    1331              :      * @param[in] cont The context doing all the work
    1332              :      * @see libsumo::Helper::LaneStoringVisitor::add
    1333              :      */
    1334      1686868 :     void visit(const MSLane::StoringVisitor& cont) const {
    1335      1686868 :         cont.add(this);
    1336      1686868 :     }
    1337              : 
    1338              :     /// @brief whether the lane has pedestrians on it
    1339              :     bool hasPedestrians() const;
    1340              : 
    1341              :     /// This is just a wrapper around MSPModel::nextBlocking. You should always check using hasPedestrians before calling this method.
    1342              :     std::pair<const MSPerson*, double> nextBlocking(double minPos, double minRight, double maxLeft, double stopTime = 0, bool bidi = false) const;
    1343              : 
    1344              :     /// @brief return the empty space up to the last standing vehicle or the empty space on the whole lane if no vehicle is standing
    1345              :     double getSpaceTillLastStanding(const MSVehicle* ego, bool& foundStopped) const;
    1346              : 
    1347              :     /// @brief compute maximum braking distance on this lane
    1348              :     double getMaximumBrakeDist() const;
    1349              : 
    1350              :     inline const PositionVector* getOutlineShape() const {
    1351              :         return myOutlineShape;
    1352              :     }
    1353              : 
    1354              :     static void initCollisionOptions(const OptionsCont& oc);
    1355              :     static void initCollisionAction(const OptionsCont& oc, const std::string& option, CollisionAction& myAction);
    1356              : 
    1357              :     static CollisionAction getCollisionAction() {
    1358         5537 :         return myCollisionAction;
    1359              :     }
    1360              : 
    1361              :     static CollisionAction getIntermodalCollisionAction() {
    1362              :         return myIntermodalCollisionAction;
    1363              :     }
    1364              : 
    1365              :     static const long CHANGE_PERMISSIONS_PERMANENT = 0;
    1366              :     static const long CHANGE_PERMISSIONS_GUI = 1;
    1367              : 
    1368              : protected:
    1369              :     /// moves myTmpVehicles int myVehicles after a lane change procedure
    1370              :     virtual void swapAfterLaneChange(SUMOTime t);
    1371              : 
    1372              :     /** @brief Inserts the vehicle into this lane, and informs it about entering the network
    1373              :      *
    1374              :      * Calls the vehicles enterLaneAtInsertion function,
    1375              :      *  updates statistics and modifies the active state as needed
    1376              :      * @param[in] veh The vehicle to be incorporated
    1377              :      * @param[in] pos The position of the vehicle
    1378              :      * @param[in] speed The speed of the vehicle
    1379              :      * @param[in] posLat The lateral position of the vehicle
    1380              :      * @param[in] at
    1381              :      * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure
    1382              :      */
    1383              :     virtual void incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat,
    1384              :                                     const MSLane::VehCont::iterator& at,
    1385              :                                     MSMoveReminder::Notification notification = MSMoveReminder::NOTIFICATION_DEPARTED);
    1386              : 
    1387              :     /// @brief detect whether a vehicle collids with pedestrians on the junction
    1388              :     void detectPedestrianJunctionCollision(const MSVehicle* collider, const PositionVector& colliderBoundary, const MSLane* foeLane,
    1389              :                                            SUMOTime timestep, const std::string& stage,
    1390              :                                            std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
    1391              :                                            std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport);
    1392              : 
    1393              :     /// @brief detect whether there is a collision between the two vehicles
    1394              :     bool detectCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim,
    1395              :                                 std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
    1396              :                                 std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport) const;
    1397              : 
    1398              :     /// @brief take action upon collision
    1399              :     void handleCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim,
    1400              :                                 double gap, double latGap,
    1401              :                                 std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
    1402              :                                 std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport) const;
    1403              : 
    1404              :     void handleIntermodalCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSTransportable* victim,
    1405              :                                           double gap, const std::string& collisionType,
    1406              :                                           std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
    1407              :                                           std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport) const;
    1408              : 
    1409              :     /* @brief determine depart speed and whether it may be patched
    1410              :      * @param[in] veh The departing vehicle
    1411              :      * @param[out] whether the speed may be patched to account for safety
    1412              :      * @return the depart speed
    1413              :      */
    1414              :     double getDepartSpeed(const MSVehicle& veh, bool& patchSpeed);
    1415              : 
    1416              :     /* @brief determine the lateral depart position
    1417              :      * @param[in] veh The departing vehicle
    1418              :      * @return the lateral depart position
    1419              :      */
    1420              :     double getDepartPosLat(const MSVehicle& veh);
    1421              : 
    1422              :     /** @brief return the maximum safe speed for insertion behind leaders
    1423              :      * (a negative value indicates that safe insertion is impossible) */
    1424              :     double safeInsertionSpeed(const MSVehicle* veh, double seen, const MSLeaderInfo& leaders, double speed);
    1425              : 
    1426              :     /// @brief check whether pedestrians on this lane interfere with vehicle insertion
    1427              :     bool checkForPedestrians(const MSVehicle* aVehicle, double& speed, double& dist, double pos, bool patchSpeed) const;
    1428              : 
    1429              :     /// @brief check whether any of the outgoing links are being approached
    1430              :     bool hasApproaching(const std::vector<MSLink*>& links) const;
    1431              : 
    1432              :     /// @brief return length of fractional vehicles on this lane
    1433              :     double getFractionalVehicleLength(bool brutto) const;
    1434              : 
    1435              :     /// Unique numerical ID (set on reading by netload)
    1436              :     int myNumericalID;
    1437              : 
    1438              :     /// The shape of the lane
    1439              :     PositionVector myShape;
    1440              : 
    1441              :     /// @brief the outline of the lane (optional)
    1442              :     PositionVector* myOutlineShape = nullptr;
    1443              : 
    1444              :     /// The lane index
    1445              :     int myIndex;
    1446              : 
    1447              :     /** @brief The lane's vehicles.
    1448              :         This container holds all vehicles that have their front (longitudinally)
    1449              :         and their center (laterally) on this lane.
    1450              :         These are the vehicles that this lane is 'responsibly' for (i.e. when executing movements)
    1451              : 
    1452              :         The entering vehicles are inserted at the front
    1453              :         of  this container and the leaving ones leave from the back, e.g. the
    1454              :         vehicle in front of the junction (often called first) is
    1455              :         myVehicles.back() (if it exists). And if it is an iterator at a
    1456              :         vehicle, ++it points to the vehicle in front. This is the interaction
    1457              :         vehicle. */
    1458              :     VehCont myVehicles;
    1459              : 
    1460              :     /** @brief The lane's partial vehicles.
    1461              :         This container holds all vehicles that are partially on this lane but which are
    1462              :         in myVehicles of another lane.
    1463              :         Reasons for partial occupancies include the following
    1464              :         - the back is still on this lane during regular movement
    1465              :         - the vehicle is performing a continuous lane-change maneuver
    1466              :         - sub-lane simulation where vehicles can freely move laterally among the lanes of an edge
    1467              : 
    1468              :         The entering vehicles are inserted at the front
    1469              :         of this container and the leaving ones leave from the back. */
    1470              :     VehCont myPartialVehicles;
    1471              : 
    1472              :     /** @brief Container for lane-changing vehicles. After completion of lane-change-
    1473              :         process, the containers will be swapped with myVehicles. */
    1474              :     VehCont myTmpVehicles;
    1475              : 
    1476              :     /** @brief Buffer for vehicles that moved from their previous lane onto this one.
    1477              :      * Integrated after all vehicles executed their moves*/
    1478              :     MFXSynchQue<MSVehicle*, std::vector<MSVehicle*> > myVehBuffer;
    1479              : 
    1480              :     /** @brief The vehicles which registered maneuvering into the lane within their current action step.
    1481              :      *         This is currently only relevant for sublane simulation, since continuous lanechanging
    1482              :      *         uses the partial vehicle mechanism.
    1483              :      *
    1484              :      *   The entering vehicles are inserted at the front
    1485              :      *   of this container and the leaving ones leave from the back. */
    1486              :     VehCont myManeuverReservations;
    1487              : 
    1488              :     /* @brief list of vehicles that are parking near this lane
    1489              :      * (not necessarily on the road but having reached their stop on this lane)
    1490              :      * */
    1491              :     std::set<const MSBaseVehicle*> myParkingVehicles;
    1492              : 
    1493              :     /// Lane length [m]
    1494              :     double myLength;
    1495              : 
    1496              :     /// Lane width [m]
    1497              :     const double myWidth;
    1498              : 
    1499              :     /// Lane's vClass specific stop offset [m]. The map is either of length 0, which means no
    1500              :     /// special stopOffset was set, or of length 1, where the key is a bitset representing a subset
    1501              :     /// of the SUMOVehicleClass Enum and the value is the offset in meters.
    1502              :     StopOffset myLaneStopOffset;
    1503              : 
    1504              :     /// The lane's edge, for routing only.
    1505              :     MSEdge* const myEdge;
    1506              : 
    1507              :     /// Lane-wide speed limit [m/s]
    1508              :     double myMaxSpeed;
    1509              :     /// Lane-wide friction coefficient [0..1]
    1510              :     double myFrictionCoefficient;
    1511              : 
    1512              :     /// @brief Whether the current speed limit is set by a variable speed sign (VSS)
    1513              :     bool mySpeedByVSS;
    1514              : 
    1515              :     /// @brief Whether the current speed limit has been set through TraCI
    1516              :     bool mySpeedByTraCI;
    1517              : 
    1518              :     /// The vClass permissions for this lane
    1519              :     SVCPermissions myPermissions;
    1520              : 
    1521              :     /// The vClass permissions for changing from this lane
    1522              :     SVCPermissions myChangeLeft;
    1523              :     SVCPermissions myChangeRight;
    1524              : 
    1525              :     /// The original vClass permissions for this lane (before temporary modifications)
    1526              :     SVCPermissions myOriginalPermissions;
    1527              : 
    1528              :     /// The vClass speed restrictions for this lane
    1529              :     const std::map<SUMOVehicleClass, double>* myRestrictions;
    1530              : 
    1531              :     /// All direct predecessor lanes
    1532              :     std::vector<IncomingLaneInfo> myIncomingLanes;
    1533              : 
    1534              :     ///
    1535              :     mutable MSLane* myLogicalPredecessorLane;
    1536              : 
    1537              :     /// Similar to LogicalPredecessorLane, @see getCanonicalPredecessorLane()
    1538              :     mutable MSLane* myCanonicalPredecessorLane;
    1539              : 
    1540              :     /// Main successor lane, @see getCanonicalSuccessorLane()
    1541              :     mutable MSLane* myCanonicalSuccessorLane;
    1542              : 
    1543              :     /// @brief The current length of all vehicles on this lane, including their minGaps
    1544              :     double myBruttoVehicleLengthSum;
    1545              : 
    1546              :     /// @brief The current length of all vehicles on this lane, excluding their minGaps
    1547              :     double myNettoVehicleLengthSum;
    1548              : 
    1549              :     /// @brief The length of all vehicles that have left this lane in the current step (this lane, including their minGaps)
    1550              :     double myBruttoVehicleLengthSumToRemove;
    1551              : 
    1552              :     /// @brief The length of all vehicles that have left this lane in the current step (this lane, excluding their minGaps)
    1553              :     double myNettoVehicleLengthSumToRemove;
    1554              : 
    1555              :     /// @brief Flag to recalculate the occupancy (including minGaps) after a change in minGap
    1556              :     bool myRecalculateBruttoSum;
    1557              : 
    1558              :     /** The lane's Links to its succeeding lanes and the default
    1559              :         right-of-way rule, i.e. blocked or not blocked. */
    1560              :     std::vector<MSLink*> myLinks;
    1561              : 
    1562              :     /// All direct internal and direct (disregarding internal predecessors) non-internal predecessor lanes of this lane
    1563              :     std::map<MSEdge*, std::vector<MSLane*> > myApproachingLanes;
    1564              : 
    1565              :     /// @brief leaders on all sublanes as seen by approaching vehicles (cached)
    1566              :     mutable MSLeaderInfo myLeaderInfo;
    1567              :     /// @brief followers on all sublanes as seen by vehicles on consecutive lanes (cached)
    1568              :     mutable MSLeaderInfo myFollowerInfo;
    1569              : 
    1570              :     /// @brief time step for which myLeaderInfo was last updated
    1571              :     mutable SUMOTime myLeaderInfoTime;
    1572              :     /// @brief time step for which myFollowerInfo was last updated
    1573              :     mutable SUMOTime myFollowerInfoTime;
    1574              : 
    1575              :     /// @brief precomputed myShape.length / myLength
    1576              :     const double myLengthGeometryFactor;
    1577              : 
    1578              :     /// @brief whether this lane is an acceleration lane
    1579              :     const bool myIsRampAccel;
    1580              : 
    1581              :     /// @brief the type of this lane
    1582              :     const std::string myLaneType;
    1583              : 
    1584              :     /// @brief the combined width of all lanes with lower index on myEdge
    1585              :     double myRightSideOnEdge;
    1586              :     /// @brief the index of the rightmost sublane of this lane on myEdge
    1587              :     int myRightmostSublane;
    1588              : 
    1589              :     /// @brief whether a collision check is currently needed
    1590              :     bool myNeedsCollisionCheck;
    1591              : 
    1592              :     // @brief the neighboring opposite direction or nullptr
    1593              :     MSLane* myOpposite;
    1594              : 
    1595              :     // @brief bidi lane or nullptr
    1596              :     MSLane* myBidiLane;
    1597              : 
    1598              :     // @brief transient changes in permissions
    1599              :     std::map<long long, SVCPermissions> myPermissionChanges;
    1600              : 
    1601              :     // @brief index of the associated thread-rng
    1602              :     int myRNGIndex;
    1603              : 
    1604              :     /// definition of the static dictionary type
    1605              :     typedef std::map< std::string, MSLane* > DictType;
    1606              : 
    1607              :     /// Static dictionary to associate string-ids with objects.
    1608              :     static DictType myDict;
    1609              : 
    1610              :     static std::vector<SumoRNG> myRNGs;
    1611              : 
    1612              : private:
    1613              :     /// @brief This lane's move reminder
    1614              :     std::vector< MSMoveReminder* > myMoveReminders;
    1615              : 
    1616              :     /// @brief the action to take on collisions
    1617              :     static CollisionAction myCollisionAction;
    1618              :     static CollisionAction myIntermodalCollisionAction;
    1619              :     static bool myCheckJunctionCollisions;
    1620              :     static double myCheckJunctionCollisionMinGap;
    1621              :     static SUMOTime myCollisionStopTime;
    1622              :     static SUMOTime myIntermodalCollisionStopTime;
    1623              :     static double myCollisionMinGapFactor;
    1624              :     static bool myExtrapolateSubstepDepart;
    1625              : 
    1626              :     static int getInsertionChecks(const MSVehicle* veh);
    1627              : 
    1628              :     /**
    1629              :      * @class vehicle_position_sorter
    1630              :      * @brief Sorts vehicles by their position (descending)
    1631              :      */
    1632              :     class vehicle_position_sorter {
    1633              :     public:
    1634              :         /// @brief Constructor
    1635              :         explicit vehicle_position_sorter(const MSLane* lane) :
    1636              :             myLane(lane) {
    1637              :         }
    1638              : 
    1639              : 
    1640              :         /** @brief Comparing operator
    1641              :          * @param[in] v1 First vehicle to compare
    1642              :          * @param[in] v2 Second vehicle to compare
    1643              :          * @return Whether the first vehicle is further on the lane than the second
    1644              :          */
    1645              :         int operator()(MSVehicle* v1, MSVehicle* v2) const;
    1646              : 
    1647              :         const MSLane* myLane;
    1648              : 
    1649              :     };
    1650              : 
    1651              :     /**
    1652              :      * @class vehicle_reverse_position_sorter
    1653              :      * @brief Sorts vehicles by their position (ascending)
    1654              :      */
    1655              :     class vehicle_natural_position_sorter {
    1656              :     public:
    1657              :         /// @brief Constructor
    1658              :         explicit vehicle_natural_position_sorter(const MSLane* lane) :
    1659              :             myLane(lane) {
    1660              :         }
    1661              : 
    1662              : 
    1663              :         /** @brief Comparing operator
    1664              :          * @param[in] v1 First vehicle to compare
    1665              :          * @param[in] v2 Second vehicle to compare
    1666              :          * @return Whether the first vehicle is further on the lane than the second
    1667              :          */
    1668              :         int operator()(MSVehicle* v1, MSVehicle* v2) const;
    1669              : 
    1670              :         const MSLane* myLane;
    1671              : 
    1672              :     };
    1673              : 
    1674              :     /** @class by_connections_to_sorter
    1675              :      * @brief Sorts edges by their angle relative to the given edge (straight comes first)
    1676              :      *
    1677              :      */
    1678              :     class by_connections_to_sorter {
    1679              :     public:
    1680              :         /// @brief constructor
    1681              :         explicit by_connections_to_sorter(const MSEdge* const e);
    1682              : 
    1683              :         /// @brief comparing operator
    1684              :         int operator()(const MSEdge* const e1, const MSEdge* const e2) const;
    1685              : 
    1686              :     private:
    1687              :         const MSEdge* const myEdge;
    1688              :         double myLaneDir;
    1689              :     };
    1690              : 
    1691              : 
    1692              : 
    1693              :     /** @class incoming_lane_priority_sorter
    1694              :      * @brief Sorts lanes (IncomingLaneInfos) by their priority or, if this doesn't apply,
    1695              :      *         wrt. the angle difference magnitude relative to the target lane's angle (straight comes first)
    1696              :      */
    1697              :     class incoming_lane_priority_sorter {
    1698              :     public:
    1699              :         /// @brief constructor
    1700              :         explicit incoming_lane_priority_sorter(const MSLane* targetLane);
    1701              : 
    1702              :         /// @brief comparing operator
    1703              :         int operator()(const IncomingLaneInfo& lane1, const IncomingLaneInfo& lane2) const;
    1704              : 
    1705              :     private:
    1706              :         const MSLane* const myLane;
    1707              :         double myLaneDir;
    1708              :     };
    1709              : 
    1710              : 
    1711              :     /** @class outgoing_lane_priority_sorter
    1712              :      * @brief Sorts lanes (their origin link) by the priority of their noninternal target edges or, if this doesn't yield an unambiguous result,
    1713              :      *         wrt. the angle difference magnitude relative to the target lane's angle (straight comes first)
    1714              :      */
    1715              :     class outgoing_lane_priority_sorter {
    1716              :     public:
    1717              :         /// @brief constructor
    1718              :         explicit outgoing_lane_priority_sorter(const MSLane* sourceLane);
    1719              : 
    1720              :         /// @brief comparing operator
    1721              :         int operator()(const MSLink* link1, const MSLink* link2) const;
    1722              : 
    1723              :     private:
    1724              :         double myLaneDir;
    1725              :     };
    1726              : 
    1727              :     /**
    1728              :      * @class edge_finder
    1729              :      */
    1730              :     class edge_finder {
    1731              :     public:
    1732      5452709 :         edge_finder(MSEdge* e) : myEdge(e) {}
    1733              :         bool operator()(const IncomingLaneInfo& ili) const {
    1734      1956355 :             return &(ili.lane->getEdge()) == myEdge;
    1735              :         }
    1736              :     private:
    1737              :         const MSEdge* const myEdge;
    1738              :     };
    1739              : 
    1740              : #ifdef HAVE_FOX
    1741              :     /// Type of the function that is called for the simulation stage (e.g. planMovements).
    1742              :     typedef void(MSLane::*Operation)(const SUMOTime);
    1743              : 
    1744              :     /**
    1745              :      * @class SimulationTask
    1746              :      * @brief the routing task which mainly calls reroute of the vehicle
    1747              :      */
    1748      1991973 :     class SimulationTask : public MFXWorkerThread::Task {
    1749              :     public:
    1750              :         SimulationTask(MSLane& l, const SUMOTime time)
    1751      2160064 :             : myLane(l), myTime(time) {}
    1752              :         void init(Operation operation, const SUMOTime time) {
    1753     24240348 :             myOperation = operation;
    1754     24240348 :             myTime = time;
    1755              :         }
    1756     24240348 :         void run(MFXWorkerThread* /*context*/) {
    1757              :             try {
    1758     24240348 :                 (myLane.*(myOperation))(myTime);
    1759            2 :             } catch (ProcessError& e) {
    1760            2 :                 WRITE_ERROR(e.what());
    1761            2 :             }
    1762     24240348 :         }
    1763              :     private:
    1764              :         Operation myOperation = nullptr;
    1765              :         MSLane& myLane;
    1766              :         SUMOTime myTime;
    1767              :     private:
    1768              :         /// @brief Invalidated assignment operator.
    1769              :         SimulationTask& operator=(const SimulationTask&) = delete;
    1770              :     };
    1771              : 
    1772              :     SimulationTask mySimulationTask;
    1773              :     /// @brief Mutex for access to the cached leader info value
    1774              :     mutable FXMutex myLeaderInfoMutex;
    1775              :     /// @brief Mutex for access to the cached follower info value
    1776              :     mutable FXMutex myFollowerInfoMutex;
    1777              :     /// @brief Mutex for access to the cached follower info value
    1778              :     mutable FXMutex myPartialOccupatorMutex;
    1779              : #endif
    1780              :     std::vector<StopWatch<std::chrono::nanoseconds> > myStopWatch;
    1781              : 
    1782              : private:
    1783              :     /// @brief invalidated copy constructor
    1784              :     MSLane(const MSLane&) = delete;
    1785              : 
    1786              :     /// @brief invalidated assignment operator
    1787              :     MSLane& operator=(const MSLane&) = delete;
    1788              : 
    1789              : 
    1790              : };
    1791              : 
    1792              : // specialized implementation for speedup and avoiding warnings
    1793              : #define LANE_RTREE_QUAL RTree<MSLane*, MSLane, float, 2, MSLane::StoringVisitor>
    1794              : 
    1795              : template<>
    1796              : inline float LANE_RTREE_QUAL::RectSphericalVolume(Rect* a_rect) {
    1797              :     ASSERT(a_rect);
    1798       585273 :     const float extent0 = a_rect->m_max[0] - a_rect->m_min[0];
    1799       585273 :     const float extent1 = a_rect->m_max[1] - a_rect->m_min[1];
    1800       413267 :     return .78539816f * (extent0 * extent0 + extent1 * extent1);
    1801              : }
    1802              : 
    1803              : template<>
    1804              : inline LANE_RTREE_QUAL::Rect LANE_RTREE_QUAL::CombineRect(Rect* a_rectA, Rect* a_rectB) {
    1805              :     ASSERT(a_rectA && a_rectB);
    1806              :     Rect newRect;
    1807       589254 :     newRect.m_min[0] = rtree_min(a_rectA->m_min[0], a_rectB->m_min[0]);
    1808       589254 :     newRect.m_max[0] = rtree_max(a_rectA->m_max[0], a_rectB->m_max[0]);
    1809       589254 :     newRect.m_min[1] = rtree_min(a_rectA->m_min[1], a_rectB->m_min[1]);
    1810       589254 :     newRect.m_max[1] = rtree_max(a_rectA->m_max[1], a_rectB->m_max[1]);
    1811              :     return newRect;
    1812              : }
        

Generated by: LCOV version 2.0-1