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