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    MSVehicle.h
11 /// @author  Christian Roessel
12 /// @author  Jakob Erdmann
13 /// @author  Bjoern Hendriks
14 /// @author  Daniel Krajzewicz
15 /// @author  Thimor Bohn
16 /// @author  Friedemann Wesner
17 /// @author  Clemens Honomichl
18 /// @author  Michael Behrisch
19 /// @author  Axel Wegener
20 /// @author  Leonhard Luecken
21 /// @date    Mon, 12 Mar 2001
22 /// @version $Id$
23 ///
24 // Representation of a vehicle in the micro simulation
25 /****************************************************************************/
26 #ifndef MSVehicle_h
27 #define MSVehicle_h
28 
29 
30 // ===========================================================================
31 // included modules
32 // ===========================================================================
33 #include <config.h>
34 
35 #include <list>
36 #include <deque>
37 #include <map>
38 #include <set>
39 #include <string>
40 #include <vector>
41 #include <memory>
42 #include "MSGlobals.h"
43 #include "MSVehicleType.h"
44 #include "MSBaseVehicle.h"
45 #include "MSLink.h"
46 #include "MSLane.h"
47 #include "MSNet.h"
48 
49 #define INVALID_SPEED 299792458 + 1 // nothing can go faster than the speed of light! Refs. #2577
50 
51 // ===========================================================================
52 // class declarations
53 // ===========================================================================
54 class SUMOSAXAttributes;
55 class MSMoveReminder;
56 class MSLaneChanger;
57 class MSVehicleTransfer;
58 class MSAbstractLaneChangeModel;
59 class MSStoppingPlace;
60 class MSChargingStation;
61 class MSParkingArea;
62 class MSPerson;
63 class MSDevice;
64 class MSEdgeWeightsStorage;
65 class OutputDevice;
66 class Position;
67 class MSContainer;
68 class MSJunction;
69 class MSLeaderInfo;
70 class MSDevice_DriverState;
71 class MSSimpleDriverState;
72 
73 // ===========================================================================
74 // class definitions
75 // ===========================================================================
76 /**
77  * @class MSVehicle
78  * @brief Representation of a vehicle in the micro simulation
79  */
80 class MSVehicle : public MSBaseVehicle {
81 public:
82 
83     /// the lane changer sets myLastLaneChangeOffset
84     friend class MSLaneChanger;
85     friend class MSLaneChangerSublane;
86 
87     /** @class State
88      * @brief Container that holds the vehicles driving state (position+speed).
89      */
90     class State {
91         /// @brief vehicle sets states directly
92         friend class MSVehicle;
93         friend class MSLaneChanger;
94         friend class MSLaneChangerSublane;
95 
96     public:
97         /// Constructor.
98         State(double pos, double speed, double posLat, double backPos);
99 
100         /// Copy constructor.
101         State(const State& state);
102 
103         /// Assignment operator.
104         State& operator=(const State& state);
105 
106         /// Operator !=
107         bool operator!=(const State& state);
108 
109         /// Position of this state.
pos()110         double pos() const {
111             return myPos;
112         }
113 
114         /// Speed of this state
speed()115         double speed() const {
116             return mySpeed;
117         };
118 
119         /// Lateral Position of this state (m relative to the centerline of the lane).
posLat()120         double posLat() const {
121             return myPosLat;
122         }
123 
124         /// back Position of this state
backPos()125         double backPos() const {
126             return myBackPos;
127         }
128 
129         /// previous Speed of this state
lastCoveredDist()130         double lastCoveredDist() const {
131             return myLastCoveredDist;
132         }
133 
134 
135     private:
136         /// the stored position
137         double myPos;
138 
139         /// the stored speed (should be >=0 at any time)
140         double mySpeed;
141 
142         /// the stored lateral position
143         double myPosLat;
144 
145         /// @brief the stored back position
146         // if the vehicle occupies multiple lanes, this is the position relative
147         // to the lane occupied by its back
148         double myBackPos;
149 
150         /// the speed at the begin of the previous time step
151         double myPreviousSpeed;
152 
153         /// the distance covered in the last timestep
154         /// NOTE: In case of ballistic positional update, this is not necessarily given by
155         ///       myPos - SPEED2DIST(mySpeed + myPreviousSpeed)/2,
156         /// because a stop may have occurred within the last step.
157         double myLastCoveredDist;
158 
159     };
160 
161 
162     /** @class WaitingTimeCollector
163      * @brief Stores the waiting intervals over the previous seconds (memory is to be specified in ms.).
164      */
165     class WaitingTimeCollector {
166         friend class MSVehicle;
167 
168         typedef std::list<std::pair<SUMOTime, SUMOTime> > waitingIntervalList;
169 
170     public:
171         /// Constructor.
172         WaitingTimeCollector(SUMOTime memory = MSGlobals::gWaitingTimeMemory);
173 
174         /// Copy constructor.
175         WaitingTimeCollector(const WaitingTimeCollector& wt);
176 
177         /// Assignment operator.
178         WaitingTimeCollector& operator=(const WaitingTimeCollector& wt);
179 
180         /// Operator !=
181         bool operator!=(const WaitingTimeCollector& wt) const;
182 
183         /// Assignment operator (in place!)
184         WaitingTimeCollector& operator=(SUMOTime t);
185 
186         // return the waiting time within the last memory millisecs
187         SUMOTime cumulatedWaitingTime(SUMOTime memory = -1) const;
188 
189         // process time passing for dt millisecs
190         void passTime(SUMOTime dt, bool waiting);
191 
192         // maximal memory time stored
getMemorySize()193         SUMOTime getMemorySize() const {
194             return myMemorySize;
195         }
196 
197         // maximal memory time stored
getWaitingIntervals()198         const waitingIntervalList& getWaitingIntervals() const {
199             return myWaitingIntervals;
200         }
201 
202     private:
203         /// the maximal memory to store
204         SUMOTime myMemorySize;
205 
206         /// the stored waiting intervals within the last memory milliseconds
207         /// If the current (ongoing) waiting interval has begun at time t - dt (where t is the current time)
208         /// then waitingIntervalList[0]->first = 0., waitingIntervalList[0]->second = dt
209         waitingIntervalList myWaitingIntervals;
210 
211         /// append an amount of dt millisecs to the stored waiting times
212         void appendWaitingTime(SUMOTime dt);
213     };
214 
215 
216     /** @enum ChangeRequest
217      * @brief Requests set via TraCI
218      */
219     enum ChangeRequest {
220         /// @brief vehicle doesn't want to change
221         REQUEST_NONE,
222         /// @brief vehicle want's to change to left lane
223         REQUEST_LEFT,
224         /// @brief vehicle want's to change to right lane
225         REQUEST_RIGHT,
226         /// @brief vehicle want's to keep the current lane
227         REQUEST_HOLD
228     };
229 
230     /** @brief Constructor
231      * @param[in] pars The vehicle description
232      * @param[in] route The vehicle's route
233      * @param[in] type The vehicle's type
234      * @param[in] speedFactor The factor for driven lane's speed limits
235      * @exception ProcessError If a value is wrong
236      */
237     MSVehicle(SUMOVehicleParameter* pars, const MSRoute* route,
238               MSVehicleType* type, const double speedFactor);
239 
240     /// @brief Destructor.
241     virtual ~MSVehicle();
242 
243 
244     /// @name insertion/removal
245     //@{
246 
247     /** @brief Called when the vehicle is removed from the network.
248      *
249      * Moves along work reminders and
250      *  informs all devices about quitting. Calls "leaveLane" then.
251      *
252      * @param[in] reason why the vehicle leaves (reached its destination, parking, teleport)
253      */
254     void onRemovalFromNet(const MSMoveReminder::Notification reason);
255     //@}
256 
257 
258 
259     /// @name interaction with the route
260     //@{
261 
262     /** @brief Returns whether this vehicle has already arived
263      * (reached the arrivalPosition on its final edge)
264      */
265     bool hasArrived() const;
266 
267     /** @brief Replaces the current route by the given one
268      *
269      * It is possible that the new route is not accepted, if it does not
270      *  contain the vehicle's current edge.
271      *
272      * @param[in] route The new route to pass
273      * @param[in] info Information regarding the replacement
274      * @param[in] removeStops Whether stops should be removed if they do not fit onto the new route
275      * @return Whether the new route was accepted
276      */
277     bool replaceRoute(const MSRoute* route, const std::string& info, bool onInit = false, int offset = 0, bool addStops = true, bool removeStops = true);
278 
279 
280     /** @brief Returns whether the vehicle wil pass the given edge
281      * @param[in] The edge to find in the vehicle's current route
282      * @return Whether the given edge will be passed by the vehicle
283      * @todo Move to MSRoute?
284      */
285     bool willPass(const MSEdge* const edge) const;
286 
287     int getRoutePosition() const;
288     void resetRoutePosition(int index);
289 
290     /** @brief Returns the vehicle's internal edge travel times/efforts container
291      *
292      * If the vehicle does not have such a container, it is built.
293      * @return The vehicle's knowledge about edge weights
294      */
295     const MSEdgeWeightsStorage& getWeightsStorage() const;
296     MSEdgeWeightsStorage& getWeightsStorage();
297     //@}
298 
299 
300     /// @name Interaction with move reminders
301     //@{
302 
303     /** @brief Processes active move reminder
304      *
305      * This method goes through all active move reminder, both those for the current
306      *  lane, stored in "myMoveReminders" and those of prior lanes stored in
307      *  "myOldLaneMoveReminders" calling "MSMoveReminder::notifyMove".
308      *
309      * When processing move reminder from "myOldLaneMoveReminders",
310      *  the offsets (prior lane lengths) are used, which are stored in
311      *  "myOldLaneMoveReminderOffsets".
312      *
313      * Each move reminder which is no longer active is removed from the container.
314      *
315      * @param[in] oldPos The position the vehicle had before it has moved
316      * @param[in] newPos The position the vehicle has after it has moved
317      * @param[in] newSpeed The vehicle's speed within this move
318      * @see MSMoveReminder
319      */
320     void workOnMoveReminders(double oldPos, double newPos, double newSpeed);
321     //@}
322 
323 
324     /** @brief Returns whether the vehicle is supposed to take action in the current simulation step
325      *         Updates myActionStep and myLastActionTime in case that the current simstep is an action step
326      *
327      *  @param[in] t
328      */
329     bool checkActionStep(const SUMOTime t);
330 
331     /** @brief Resets the action offset for the vehicle
332      *
333      *  @param[in] timeUntilNextAction time interval from now for the next action, defaults to 0, which
334      *             implies an immediate action point in the current step.
335      */
336     void resetActionOffset(const SUMOTime timeUntilNextAction = 0);
337 
338 
339     /** @brief Process an updated action step length value (only affects the vehicle's *action offset*,
340      *         The actionStepLength is stored in the (singular) vtype)
341      *
342      *  @param[in] oldActionStepLength The action step length previous to the update
343      *  @param[in] actionStepLength The new action step length (stored in the vehicle's vtype).
344      *  @note      The current action step length is updated. This implies an immediate action
345      *             point, if the new step length is smaller than the length of the currently running
346      *             action interval (the difference between now and the last action time).
347      */
348     void updateActionOffset(const SUMOTime oldActionStepLength, const SUMOTime newActionStepLength);
349 
350 
351     /** @brief Compute safe velocities for the upcoming lanes based on positions and
352      * speeds from the last time step. Also registers
353      * ApproachingVehicleInformation for all links
354      *
355      * This method goes through the best continuation lanes of the current lane and
356      * computes the safe velocities for passing/stopping at the next link as a DriveProcessItem
357      *
358      * Afterwards it checks if any DriveProcessItem should be discarded to avoid
359      * blocking a junction (checkRewindLinkLanes).
360      *
361      * Finally the ApproachingVehicleInformation is registered for all links that
362      * shall be passed
363      *
364      * @param[in] t The current timeStep
365      * @param[in] ahead The leaders (may be 0)
366      * @param[in] lengthsInFront Sum of vehicle lengths in front of the vehicle
367      */
368     void planMove(const SUMOTime t, const MSLeaderInfo& ahead, const double lengthsInFront);
369 
370     /** @brief Register junction approaches for all link items in the current
371      * plan */
372     void setApproachingForAllLinks(const SUMOTime t);
373 
374 
375     /** @brief Executes planned vehicle movements with regards to right-of-way
376      *
377      * This method goes through all DriveProcessItems in myLFLinkLanes in order
378      * to find a speed that is safe for all upcoming links.
379      *
380      * Using this speed the position is updated and the vehicle is moved to the
381      * next lane (myLane is updated) if the end of the current lane is reached (this may happen
382      * multiple times in this method)
383      *
384      * The vehicle also sets the lanes it is in-lapping into and informs them about it.
385      * @return Whether the vehicle has moved to the next edge
386      */
387     bool executeMove();
388 
389     /** @brief calculates the distance covered in the next integration step given
390      *         an acceleration and assuming the current velocity. (gives different
391      *         results for different integration methods, e.g., euler vs. ballistic)
392      *  @param[in] accel the assumed acceleration
393      *  @return distance covered in next integration step
394      */
395     double getDeltaPos(const double accel) const;
396 
397 
398     /// @name state setter/getter
399     //@{
400 
401     /** @brief Get the vehicle's position along the lane
402      * @return The position of the vehicle (in m from the lane's begin)
403      */
getPositionOnLane()404     double getPositionOnLane() const {
405         return myState.myPos;
406     }
407 
408     /** @brief Get the distance the vehicle covered in the previous timestep
409      * @return The distance covered in the last timestep (in m)
410      */
getLastStepDist()411     double getLastStepDist() const {
412         return myState.lastCoveredDist();
413     }
414 
415     /** @brief Get the vehicle's front position relative to the given lane
416      * @return The front position of the vehicle (in m from the given lane's begin)
417      */
418     double getPositionOnLane(const MSLane* lane) const;
419 
420     /** @brief Get the vehicle's position relative to the given lane
421      * @return The back position of the vehicle (in m from the given lane's begin)
422      * @note It is assumed that this function is only called for a vehicle that has
423      *       a relation to the lane which makes it 'directly' relevant for
424      *       car-following behavior on that lane, i.e., either it occupies part of the
425      *       lanes surface (regular or partial vehicle for the lane), or (for the sublane
426      *       model) it issued a maneuver reservation for a lane change.
427      */
428     double getBackPositionOnLane(const MSLane* lane) const;
429 
430     /** @brief Get the vehicle's position relative to its current lane
431      * @return The back position of the vehicle (in m from the current lane's begin)
432      */
getBackPositionOnLane()433     double getBackPositionOnLane() const {
434         return getBackPositionOnLane(myLane);
435     }
436 
437     /** @brief Get the vehicle's lateral position on the lane
438      * @return The lateral position of the vehicle (in m relative to the
439      * centerline of the lane)
440      */
getLateralPositionOnLane()441     double getLateralPositionOnLane() const {
442         return myState.myPosLat;
443     }
444 
445     /** @brief Get the vehicle's lateral position on the lane:
446      * @return The lateral position of the vehicle (in m distance between right
447      * side of vehicle and ride side of the lane it is on
448      */
449     double getRightSideOnLane() const;
450 
451     /** @brief Get the minimal lateral distance required to move fully onto the lane at given offset
452      * @return The lateral distance to be covered to move the vehicle fully onto the lane (in m)
453      */
454     double lateralDistanceToLane(const int offset) const;
455 
456     /// @brief return the amount by which the vehicle extends laterally outside it's primary lane
457     double getLateralOverlap() const;
458     double getLateralOverlap(double posLat) const;
459 
460     /** @brief Get the vehicle's lateral position on the edge of the given lane
461      * (or its current edge if lane == 0)
462      * @return The lateral position of the vehicle (in m distance between right
463      * side of vehicle and ride side of edge
464      */
465     double getRightSideOnEdge(const MSLane* lane = 0) const;
466 
467     /** @brief Get the vehicle's lateral position on the edge of the given lane
468      * (or its current edge if lane == 0)
469      * @return The lateral position of the vehicle (in m distance between center
470      * of vehicle and ride side of edge
471      */
472     double getCenterOnEdge(const MSLane* lane = 0) const;
473 
474     /** @brief Get the offset that that must be added to interpret
475      * myState.myPosLat for the given lane
476      *  @note This means that latOffset + myPosLat should give the relative shift of the vehicle's center
477      *        wrt the centerline of the given lane.
478      */
479     double getLatOffset(const MSLane* lane) const;
480 
481     /** @brief Returns the vehicle's current speed
482      * @return The vehicle's speed
483      */
getSpeed()484     double getSpeed() const {
485         return myState.mySpeed;
486     }
487 
488 
489     /** @brief Returns the vehicle's speed before the previous time step
490      * @return The vehicle's speed before the previous time step
491      */
getPreviousSpeed()492     double getPreviousSpeed() const {
493         return myState.myPreviousSpeed;
494     }
495 
496 
497     /** @brief Returns the vehicle's acceleration in m/s
498      *         (this is computed as the last step's mean acceleration in case that a stop occurs within the middle of the time-step)
499      * @return The acceleration
500      */
getAcceleration()501     double getAcceleration() const {
502         return myAcceleration;
503     }
504 
505 
506     /** @brief Returns the vehicle's action step length in millisecs,
507      *         i.e. the interval between two action points.
508      * @return The current action step length in ms.
509      */
getActionStepLength()510     SUMOTime getActionStepLength() const {
511         return myType->getActionStepLength();
512     }
513 
514     /** @brief Returns the vehicle's action step length in secs,
515      *         i.e. the interval between two action points.
516      * @return The current action step length in s.
517      */
getActionStepLengthSecs()518     double getActionStepLengthSecs() const {
519         return myType->getActionStepLengthSecs();
520     }
521 
522 
523     /** @brief Returns the time of the vehicle's last action point.
524      * @return The time of the last action point
525      */
getLastActionTime()526     SUMOTime getLastActionTime() const {
527         return myLastActionTime;
528     }
529 
530     //@}
531 
532 
533 
534     /// @name Other getter methods
535     //@{
536 
537     /** @brief Returns the slope of the road at vehicle's position
538      * @return The slope
539      */
540     double getSlope() const;
541 
542 
543     /** @brief Return current position (x/y, cartesian)
544      *
545      * If the vehicle's myLane is 0, Position::INVALID.
546      * @param[in] offset optional offset in longitudinal direction
547      * @return The current position (in cartesian coordinates)
548      * @see myLane
549      */
550     Position getPosition(const double offset = 0) const;
551 
552 
553     /** @brief Return the (x,y)-position, which the vehicle would reach
554      *         if it continued along its best continuation lanes from the current
555      *         for a distance of offset m.
556      * @param offset
557      * @return (x,y)-Position
558      * @see getPosition()
559      */
560     Position getPositionAlongBestLanes(double offset) const;
561 
562 
563     /** @brief Returns the lane the vehicle is on
564      * @return The vehicle's current lane
565      */
getLane()566     MSLane* getLane() const {
567         return myLane;
568     }
569 
570 
571     /** @brief Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation,
572      *         i.e., not necessarily the allowed speed limit)
573      * @return The vehicle's max speed
574      */
575     double
getMaxSpeedOnLane()576     getMaxSpeedOnLane() const {
577         if (myLane != 0) {
578             return myLane->getVehicleMaxSpeed(this);
579         } else {
580             return myType->getMaxSpeed();
581         }
582     }
583 
584 
585     /** @brief Returns the information whether the vehicle is on a road (is simulated)
586      * @return Whether the vehicle is simulated
587      */
isOnRoad()588     inline bool isOnRoad() const {
589         return myAmOnNet;
590     }
591 
592 
593     /** @brief Returns whether the current simulation step is an action point for the vehicle
594      * @return Whether the vehicle has an action point in the current step.
595      */
isActive()596     inline bool isActive() const {
597         return myActionStep;
598     }
599 
600     /** @brief Returns whether the next simulation step will be an action point for the vehicle
601      * @return Whether the vehicle has scheduled an action point for the next step.
602      */
isActionStep(SUMOTime t)603     inline bool isActionStep(SUMOTime t) const {
604         return (t - myLastActionTime) % getActionStepLength() == 0;
605 //        return t%getActionStepLength() == 0; // synchronized actions for all vehicles with identical actionsteplengths
606     }
607 
608 
609     /** @brief Returns the information whether the front of the vehicle is on the given lane
610      * @return Whether the vehicle's front is on that lane
611      */
612     bool isFrontOnLane(const MSLane* lane) const;
613 
614 
615     /** @brief Returns the starting point for reroutes (usually the current edge)
616      *
617      * This differs from *myCurrEdge only if the vehicle is on an internal edge or
618      *  very close to the junction
619      * @return The rerouting start point
620      */
621     const MSEdge* getRerouteOrigin() const;
622 
623 
624     /** @brief Returns the SUMOTime waited (speed was lesser than 0.1m/s)
625      *
626      * The value is reset if the vehicle moves faster than 0.1m/s
627      * Intentional stopping does not count towards this time.
628      * @return The time the vehicle is standing
629      */
getWaitingTime()630     SUMOTime getWaitingTime() const {
631         return myWaitingTime;
632     }
633 
634     /** @brief Returns the SUMOTime lost (speed was lesser maximum speed)
635      *
636      * @note Intentional stopping does not count towards this time.
637     // @note speedFactor is included so time loss can never be negative.
638     // The value is that of a driver who compares his travel time when
639     // the road is clear (which includes speed factor) with the actual travel time.
640     // @note includes time lost due to low departSpeed and decelerating/accelerating for planned stops
641      * @return The time the vehicle lost due to various effects
642      */
getTimeLoss()643     SUMOTime getTimeLoss() const {
644         return TIME2STEPS(myTimeLoss);
645     }
646 
647 
648     /** @brief Returns the SUMOTime waited (speed was lesser than 0.1m/s) within the last t millisecs
649      *
650      * @return The time the vehicle was standing within the configured memory interval
651      */
getAccumulatedWaitingTime()652     SUMOTime getAccumulatedWaitingTime() const {
653         return myWaitingTimeCollector.cumulatedWaitingTime(MSGlobals::gWaitingTimeMemory);
654     }
655 
656     /** @brief Returns the number of seconds waited (speed was lesser than 0.1m/s)
657      *
658      * The value is reset if the vehicle moves faster than 0.1m/s
659      * Intentional stopping does not count towards this time.
660      * @return The time the vehicle is standing
661      */
getWaitingSeconds()662     double getWaitingSeconds() const {
663         return STEPS2TIME(myWaitingTime);
664     }
665 
666 
667     /** @brief Returns the number of seconds waited (speed was lesser than 0.1m/s) within the last millisecs
668      *
669      * @return The time the vehicle was standing within the last t millisecs
670      */
671 
getAccumulatedWaitingSeconds()672     double getAccumulatedWaitingSeconds() const {
673         return STEPS2TIME(getAccumulatedWaitingTime());
674     }
675 
676     /** @brief Returns the time loss in seconds
677      */
getTimeLossSeconds()678     double getTimeLossSeconds() const {
679         return myTimeLoss;
680     }
681 
682 
683     /** @brief Returns the vehicle's direction in radians
684      * @return The vehicle's current angle
685      */
getAngle()686     double getAngle() const {
687         return myAngle;
688     }
689 
690 
691     /** @brief Returns the vehicle's direction in radians
692      * @return The vehicle's current angle
693      */
getVelocityVector()694     Position getVelocityVector() const {
695         return Position(std::cos(myAngle) * myState.speed(), std::sin(myAngle) * myState.speed());
696     }
697     //@}
698 
699     /// @brief compute the current vehicle angle
700     double computeAngle() const;
701 
702     /// @brief Set a custom vehicle angle in rad, optionally updates furtherLanePosLat
703     void setAngle(double angle, bool straightenFurther = false);
704 
705     /** @brief Sets the action steplength of the vehicle
706      *
707      * @param actionStepLength New value
708      * @param resetActionOffset whether the action offset should be reset to zero,
709      *        i.e., the next action step should follow immediately.
710      */
711     void setActionStepLength(double actionStepLength, bool resetActionOffset = true);
712 
713     /** Returns true if the two vehicles overlap. */
overlap(const MSVehicle * veh1,const MSVehicle * veh2)714     static bool overlap(const MSVehicle* veh1, const MSVehicle* veh2) {
715         if (veh1->myState.myPos < veh2->myState.myPos) {
716             return veh2->myState.myPos - veh2->getVehicleType().getLengthWithGap() < veh1->myState.myPos;
717         }
718         return veh1->myState.myPos - veh1->getVehicleType().getLengthWithGap() < veh2->myState.myPos;
719     }
720 
721     /** Returns true if vehicle's speed is below 60km/h. This is only relevant
722         on highways. Overtaking on the right is allowed then. */
congested()723     bool congested() const {
724         return myState.mySpeed < double(60) / double(3.6);
725     }
726 
727 
728     /** @brief "Activates" all current move reminder
729      *
730      * For all move reminder stored in "myMoveReminders", their method
731      *  "MSMoveReminder::notifyEnter" is called.
732      *
733      * @param[in] reason The reason for changing the reminders' states
734      * @param[in] enteredLane The lane, which is entered (if applicable)
735      * @see MSMoveReminder
736      * @see MSMoveReminder::notifyEnter
737      * @see MSMoveReminder::Notification
738      */
739     void activateReminders(const MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
740 
741     /** @brief Update when the vehicle enters a new lane in the move step.
742      *
743      * @param[in] enteredLane The lane the vehicle enters
744      * @param[in] onTeleporting Whether the lane was entered while being teleported
745      * @return Whether the vehicle's route has ended (due to vaporization, or because the destination was reached)
746      */
747     bool enterLaneAtMove(MSLane* enteredLane, bool onTeleporting = false);
748 
749 
750 
751     /** @brief Update when the vehicle enters a new lane in the emit step
752      *
753      * @param[in] enteredLane The lane the vehicle enters
754      * @param[in] pos The position the vehicle was inserted into the lane
755      * @param[in] speed The speed with which the vehicle was inserted into the lane
756      * @param[in] posLat The lateral position the vehicle was inserted into the lane
757      * @param[in] notification The cause of insertion (i.e. departure, teleport, parking)
758      */
759     void enterLaneAtInsertion(MSLane* enteredLane, double pos, double speed, double posLat,
760                               MSMoveReminder::Notification notification);
761 
762     /** @brief set tentative lane and position during insertion to ensure that
763      * all cfmodels work (some of them require veh->getLane() to return a valid lane)
764      * Once the vehicle is sucessfully inserted the lane is set again (see enterLaneAtInsertion)
765      */
766     void setTentativeLaneAndPosition(MSLane* lane, double pos, double posLat = 0);
767 
768     /** @brief Update when the vehicle enters a new lane in the laneChange step.
769      *
770      * @param[in] enteredLane The lane the vehicle enters
771      */
772     void enterLaneAtLaneChange(MSLane* enteredLane);
773 
774 
775     /** @brief Update of members if vehicle leaves a new lane in the lane change step or at arrival. */
776     void leaveLane(const MSMoveReminder::Notification reason, const MSLane* approachedLane = 0);
777 
778     /** @brief Check whether the drive items (myLFLinkLanes) are up to date,
779      *         and update them if required.
780      *  @note  This is the case if a lane change was completed.
781      *         Only the links corresponding to the drive items are updated to the
782      *         corresponding parallel links.
783      */
784     void updateDriveItems();
785 
786     /** @brief Get the distance and direction of the next upcoming turn for the vehicle (within its look-ahead range)
787      *  @return The first entry of the returned pair is the distance for the upcoming turn, the second is the link direction
788      */
getNextTurn()789     const std::pair<double, LinkDirection>& getNextTurn() {
790         return myNextTurn;
791     }
792 
793 
794     MSAbstractLaneChangeModel& getLaneChangeModel();
795     const MSAbstractLaneChangeModel& getLaneChangeModel() const;
796 
getFurtherLanes()797     const std::vector<MSLane*>& getFurtherLanes() const {
798         return myFurtherLanes;
799     }
800 
getFurtherLanesPosLat()801     const std::vector<double>& getFurtherLanesPosLat() const {
802         return myFurtherLanesPosLat;
803     }
804 
805 
806     /// @brief whether this vehicle has its back (and no its front) on the given edge
807     bool onFurtherEdge(const MSEdge* edge) const;
808 
809     /// @name strategical/tactical lane choosing methods
810     /// @{
811 
812     //
813     /** @struct LaneQ
814      * @brief A structure representing the best lanes for continuing the current route starting at 'lane'
815      */
816     struct LaneQ {
817         /// @brief The described lane
818         MSLane* lane;
819         /// @brief The overall length which may be driven when using this lane without a lane change
820         double length;
821         /// @brief The length which may be driven on this lane
822         double currentLength;
823         /// @brief The overall vehicle sum on consecutive lanes which can be passed without a lane change
824         double occupation;
825         /// @brief As occupation, but without the first lane
826         double nextOccupation;
827         /// @brief The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive
828         int bestLaneOffset;
829         /// @brief Whether this lane allows to continue the drive
830         bool allowsContinuation;
831         /* @brief Longest sequence of (normal-edge) lanes that can be followed without a lane change
832          * The 'length' attribute is the sum of these lane lengths
833          * (There may be alternative sequences that have equal length)
834          * It is the 'best' in the strategic sense of reducing required lane-changes
835          */
836         std::vector<MSLane*> bestContinuations;
837     };
838 
839     /** @brief Returns the description of best lanes to use in order to continue the route
840      * @return The LaneQ for all lanes of the current edge
841      */
842     const std::vector<LaneQ>& getBestLanes() const;
843 
844     /** @brief computes the best lanes to use in order to continue the route
845      *
846      * The information is rebuilt if the vehicle is on a different edge than
847      *  the one stored in "myLastBestLanesEdge" or "forceRebuild" is true.
848      *
849      * Otherwise, only the density changes on the stored lanes are adapted to
850      *  the container only.
851      *
852      * A rebuild must be done if the vehicle leaves a stop; then, another lane may become
853      *  the best one.
854      *
855      * If no starting lane ("startLane") is given, the vehicle's current lane ("myLane")
856      *  is used as start of best lanes building.
857      *
858      * @param[in] forceRebuild Whether the best lanes container shall be rebuilt even if the vehicle's edge has not changed
859      * @param[in] startLane The lane the process shall start at ("myLane" will be used if ==0)
860      */
861     void updateBestLanes(bool forceRebuild = false, const MSLane* startLane = 0);
862 
863 
864     /** @brief Returns the best sequence of lanes to continue the route starting at myLane
865      * @return The bestContinuations of the LaneQ for myLane (see LaneQ)
866      */
867     const std::vector<MSLane*>& getBestLanesContinuation() const;
868 
869 
870     /** @brief Returns the best sequence of lanes to continue the route starting at the given lane
871      * @return The bestContinuations of the LaneQ for the given lane (see LaneQ)
872      */
873     const std::vector<MSLane*>& getBestLanesContinuation(const MSLane* const l) const;
874 
875     /* @brief returns the current signed offset from the lane that is most
876      * suited for continuing the current route (in the strategic sense of reducing lane-changes)
877      * - 0 if the vehicle is one it's best lane
878      * - negative if the vehicle should change to the right
879      * - positive if the vehicle should change to the left
880      */
881     int getBestLaneOffset() const;
882 
883     /// @brief update occupation from MSLaneChanger
884     void adaptBestLanesOccupation(int laneIndex, double density);
885 
886     /// @}
887 
888     /// @brief repair errors in vehicle position after changing between internal edges
889     void fixPosition();
890 
891 
892     /** @brief Returns the vehicle's car following model definition
893      *
894      * This is simply a wrapper around the vehicle type's car-following
895      *  model retrieval for a shorter access.
896      *
897      * @return The vehicle's car following model definition
898      */
getCarFollowModel()899     inline const MSCFModel& getCarFollowModel() const {
900         return myType->getCarFollowModel();
901     }
902 
903     /** @brief Returns the vehicle driver's state
904      *
905      * @return The vehicle driver's state
906      *
907      */
908 
909     std::shared_ptr<MSSimpleDriverState> getDriverState() const;
910 
911 
912     /** @brief Returns the vehicle's car following model variables
913      *
914      * @return The vehicle's car following model variables
915      */
getCarFollowVariables()916     inline MSCFModel::VehicleVariables* getCarFollowVariables() const {
917         return myCFVariables;
918     }
919 
920     /// @name vehicle stops definitions and i/o
921     //@{
922 
923     /** @class Stop
924      * @brief Definition of vehicle stop (position and duration)
925      */
926     class Stop {
927     public:
Stop(const SUMOVehicleParameter::Stop & par)928         Stop(const SUMOVehicleParameter::Stop& par) : pars(par) {}
929         /// @brief The edge in the route to stop at
930         MSRouteIterator edge;
931         /// @brief The lane to stop at
932         const MSLane* lane;
933         /// @brief (Optional) bus stop if one is assigned to the stop
934         MSStoppingPlace* busstop;
935         /// @brief (Optional) container stop if one is assigned to the stop
936         MSStoppingPlace* containerstop;
937         /// @brief (Optional) parkingArea if one is assigned to the stop
938         MSParkingArea* parkingarea;
939         /// @brief (Optional) charging station if one is assigned to the stop
940         MSStoppingPlace* chargingStation;
941         /// @brief The stop parameter
942         const SUMOVehicleParameter::Stop pars;
943         /// @brief The stopping duration
944         SUMOTime duration;
945         /// @brief whether an arriving person lets the vehicle continue
946         bool triggered;
947         /// @brief whether an arriving container lets the vehicle continue
948         bool containerTriggered;
949         /// @brief Information whether the stop has been reached
950         bool reached;
951         /// @brief The number of still expected persons
952         int numExpectedPerson;
953         /// @brief The number of still expected containers
954         int numExpectedContainer;
955         /// @brief The time at which the vehicle is able to board another person
956         SUMOTime timeToBoardNextPerson;
957         /// @brief The time at which the vehicle is able to load another container
958         SUMOTime timeToLoadNextContainer;
959         /// @brief Whether this stop was triggered by a collision
960         bool collision;
961 
962         /// @brief Write the current stop configuration (used for state saving)
963         void write(OutputDevice& dev) const;
964 
965         /// @brief return halting position for upcoming stop;
966         double getEndPos(const SUMOVehicle& veh) const;
967 
968         /// @brief get a short description for showing in the gui
969         std::string getDescription() const;
970     private:
971         /// @brief Invalidated assignment operator
972         Stop& operator=(const Stop& src);
973 
974     };
975 
976 
977     /** @brief Adds a stop
978      *
979      * The stop is put into the sorted list.
980      * @param[in] stop The stop to add
981      * @return Whether the stop could be added
982      */
983     bool addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset = 0, bool collision = false,
984                  MSRouteIterator* searchStart = 0);
985 
986     /** @brief replace the current parking area stop with a new stop with merge duration
987      */
988     bool replaceParkingArea(MSParkingArea* parkingArea, std::string& errorMsg);
989 
990     /** @brief get the upcoming parking area stop or nullptr
991      */
992     MSParkingArea* getNextParkingArea();
993 
994     /** @brief get the current  parking area stop or nullptr */
995     MSParkingArea* getCurrentParkingArea();
996 
997     /** @brief Returns whether the vehicle has to stop somewhere
998      * @return Whether the vehicle has to stop somewhere
999      */
hasStops()1000     bool hasStops() const {
1001         return !myStops.empty();
1002     }
1003 
1004     /** @brief Whether this vehicle is equipped with a MSDriverState
1005      */
hasDriverState()1006     inline bool hasDriverState() const {
1007         return myDriverState != nullptr;
1008     }
1009 
1010     /** @brief Returns whether the vehicle is at a stop
1011      * @return Whether the vehicle has stopped
1012      */
1013     bool isStopped() const;
1014 
1015     /// @brief Returns the remaining stop duration for a stopped vehicle or 0
1016     SUMOTime remainingStopDuration() const;
1017 
1018     /** @brief Returns whether the vehicle stops at the given stopping place */
1019     bool stopsAt(MSStoppingPlace* stop) const;
1020 
1021     /** @brief Returns whether the vehicle will stop on the current edge
1022      */
1023     bool willStop() const;
1024 
1025     //// @brief Returns whether the vehicle is at a stop and on the correct lane
1026     bool isStoppedOnLane() const;
1027 
1028     /** @brief Returns whether the vehicle is stopped and must continue to do so */
1029     bool keepStopping(bool afterProcessing = false) const;
1030 
1031     /** @brief Returns the remaining time a vehicle needs to stop due to a
1032      * collision. A negative value indicates that the vehicle is not stopping due to a collision (or at all)
1033      */
1034     SUMOTime collisionStopTime() const;
1035 
1036     /** @brief Returns whether the vehicle is parking
1037      * @return whether the vehicle is parking
1038      */
1039     bool isParking() const;
1040 
1041     /** @brief Returns the information whether the vehicle is fully controlled via TraCI
1042      * @return Whether the vehicle is remote-controlled
1043      */
1044     bool isRemoteControlled() const;
1045 
1046     /** @brief Returns the information whether the vehicle is fully controlled via TraCI
1047      * within the lookBack time
1048      */
1049     bool wasRemoteControlled(SUMOTime lookBack = DELTA_T) const;
1050 
1051     /// @brief return the distance to the next stop or doubleMax if there is none.
nextStopDist()1052     double nextStopDist() const {
1053         return myStopDist;
1054     }
1055 
1056     /** @brief Returns whether the vehicle is on a triggered stop
1057      * @return whether the vehicle is on a triggered stop
1058      */
1059     bool isStoppedTriggered() const;
1060 
1061     /** @brief return whether the given position is within range of the current stop
1062      */
1063     bool isStoppedInRange(double pos) const;
1064     /// @}
1065 
1066     int getLaneIndex() const;
1067 
1068     /**
1069      * Compute distance that will be covered, if the vehicle moves to a given position on its route,
1070      * starting at its current position.
1071      * @param destPos:  position on the destination edge that shall be reached
1072      * @param destEdge: destination edge that shall be reached
1073      * @return      distance from the vehicles current position to the destination position,
1074      *          or a near infinite real value if the destination position is not contained
1075      *          within the vehicles route or the vehicle is not active
1076      */
1077     double getDistanceToPosition(double destPos, const MSEdge* destEdge) const;
1078 
1079 
1080     /** @brief Processes stops, returns the velocity needed to reach the stop
1081      * @return The velocity in dependance to the next/current stop
1082      * @todo Describe more detailed
1083      * @see Stop
1084      * @see MSStoppingPlace
1085      * @see MSStoppingPlace
1086      */
1087     double processNextStop(double currentVelocity);
1088 
1089     /** @brief Returns the leader of the vehicle looking for a fixed distance.
1090      *
1091      * If the distance is not given it is calculated from the brake gap.
1092      * The gap returned does not include the minGap.
1093      * @param dist    up to which distance to look for a leader
1094      * @return The leading vehicle together with the gap; (0, -1) if no leader was found.
1095      */
1096     std::pair<const MSVehicle* const, double> getLeader(double dist = 0) const;
1097 
1098     /** @brief Returns the time gap in seconds to the leader of the vehicle on the same lane.
1099      *
1100      * If the distance is too big -1 is returned.
1101      * The gap returned takes the minGap into account.
1102      * @return The time gap in seconds; -1 if no leader was found or speed is 0.
1103      */
1104     double getTimeGapOnLane() const;
1105 
1106     /// @name Emission retrieval
1107     //@{
1108 
1109     /** @brief Returns CO2 emission of the current state
1110      * @return The current CO2 emission
1111      */
1112     double getCO2Emissions() const;
1113 
1114 
1115     /** @brief Returns CO emission of the current state
1116      * @return The current CO emission
1117      */
1118     double getCOEmissions() const;
1119 
1120 
1121     /** @brief Returns HC emission of the current state
1122      * @return The current HC emission
1123      */
1124     double getHCEmissions() const;
1125 
1126 
1127     /** @brief Returns NOx emission of the current state
1128      * @return The current NOx emission
1129      */
1130     double getNOxEmissions() const;
1131 
1132 
1133     /** @brief Returns PMx emission of the current state
1134      * @return The current PMx emission
1135      */
1136     double getPMxEmissions() const;
1137 
1138 
1139     /** @brief Returns fuel consumption of the current state
1140     * @return The current fuel consumption
1141     */
1142     double getFuelConsumption() const;
1143 
1144 
1145     /** @brief Returns electricity consumption of the current state
1146     * @return The current electricity consumption
1147     */
1148     double getElectricityConsumption() const;
1149 
1150 
1151     /** @brief Returns noise emissions of the current state
1152      * @return The noise produced
1153      */
1154     double getHarmonoise_NoiseEmissions() const;
1155     //@}
1156 
1157 
1158 
1159     /// @name Interaction with persons
1160     //@{
1161 
1162     /** @brief Adds a passenger
1163      * @param[in] person The person to add
1164      */
1165     void addPerson(MSTransportable* person);
1166 
1167     /// @name Interaction with containers
1168     //@{
1169 
1170     /** @brief Adds a container
1171      * @param[in] container The container to add
1172      */
1173     void addContainer(MSTransportable* container);
1174 
1175     /// @name Access to bool signals
1176     /// @{
1177 
1178     /** @enum Signalling
1179      * @brief Some boolean values which describe the state of some vehicle parts
1180      */
1181     enum Signalling {
1182         /// @brief Everything is switched off
1183         VEH_SIGNAL_NONE = 0,
1184         /// @brief Right blinker lights are switched on
1185         VEH_SIGNAL_BLINKER_RIGHT = 1,
1186         /// @brief Left blinker lights are switched on
1187         VEH_SIGNAL_BLINKER_LEFT = 2,
1188         /// @brief Blinker lights on both sides are switched on
1189         VEH_SIGNAL_BLINKER_EMERGENCY = 4,
1190         /// @brief The brake lights are on
1191         VEH_SIGNAL_BRAKELIGHT = 8,
1192         /// @brief The front lights are on (no visualisation)
1193         VEH_SIGNAL_FRONTLIGHT = 16,
1194         /// @brief The fog lights are on (no visualisation)
1195         VEH_SIGNAL_FOGLIGHT = 32,
1196         /// @brief The high beam lights are on (no visualisation)
1197         VEH_SIGNAL_HIGHBEAM = 64,
1198         /// @brief The backwards driving lights are on (no visualisation)
1199         VEH_SIGNAL_BACKDRIVE = 128,
1200         /// @brief The wipers are on
1201         VEH_SIGNAL_WIPER = 256,
1202         /// @brief One of the left doors is opened
1203         VEH_SIGNAL_DOOR_OPEN_LEFT = 512,
1204         /// @brief One of the right doors is opened
1205         VEH_SIGNAL_DOOR_OPEN_RIGHT = 1024,
1206         /// @brief A blue emergency light is on
1207         VEH_SIGNAL_EMERGENCY_BLUE = 2048,
1208         /// @brief A red emergency light is on
1209         VEH_SIGNAL_EMERGENCY_RED = 4096,
1210         /// @brief A yellow emergency light is on
1211         VEH_SIGNAL_EMERGENCY_YELLOW = 8192
1212     };
1213 
1214 
1215     /** @brief modes for resolving conflicts between external control (traci)
1216      * and vehicle control over lane changing. Each level of the lane-changing
1217      * hierarchy (strategic, cooperative, speedGain, keepRight) can be controlled
1218      * separately */
1219     enum LaneChangeMode {
1220         LC_NEVER      = 0,  // lcModel shall never trigger changes at this level
1221         LC_NOCONFLICT = 1,  // lcModel may trigger changes if not in conflict with TraCI request
1222         LC_ALWAYS     = 2   // lcModel may always trigger changes of this level regardless of requests
1223     };
1224 
1225 
1226     /// @brief modes for prioritizing traci lane change requests
1227     enum TraciLaneChangePriority {
1228         LCP_ALWAYS        = 0,  // change regardless of blockers, adapt own speed and speed of blockers
1229         LCP_NOOVERLAP     = 1,  // change unless overlapping with blockers, adapt own speed and speed of blockers
1230         LCP_URGENT        = 2,  // change if not blocked, adapt own speed and speed of blockers
1231         LCP_OPPORTUNISTIC = 3   // change if not blocked
1232     };
1233 
1234 
1235     /** @brief Switches the given signal on
1236      * @param[in] signal The signal to mark as being switched on
1237      */
switchOnSignal(int signal)1238     void switchOnSignal(int signal) {
1239         mySignals |= signal;
1240     }
1241 
1242 
1243     /** @brief Switches the given signal off
1244      * @param[in] signal The signal to mark as being switched off
1245      */
switchOffSignal(int signal)1246     void switchOffSignal(int signal) {
1247         mySignals &= ~signal;
1248     }
1249 
1250 
1251     /** @brief Returns the signals
1252      * @return The signals' states
1253      */
getSignals()1254     int getSignals() const {
1255         return mySignals;
1256     }
1257 
1258 
1259     /** @brief Returns whether the given signal is on
1260      * @param[in] signal The signal to return the value of
1261      * @return Whether the given signal is on
1262      */
signalSet(int which)1263     bool signalSet(int which) const {
1264         return (mySignals & which) != 0;
1265     }
1266     /// @}
1267 
1268 
1269     /// @brief whether the vehicle may safely move to the given lane with regard to upcoming links
1270     bool unsafeLinkAhead(const MSLane* lane) const;
1271 
1272     /// @brief decide whether the vehicle is passing a minor link or has comitted to do so
1273     bool passingMinor() const;
1274 
1275 
1276 
1277     /** @brief Returns the uninfluenced velocity
1278      *
1279      * If no influencer exists (myInfluencer==0) the vehicle's current speed is
1280      *  returned. Otherwise the speed returned from myInfluencer->getOriginalSpeed().
1281      * @return The vehicle's velocity as it would without an influence
1282      * @see Influencer::getOriginalSpeed
1283      */
1284     double getSpeedWithoutTraciInfluence() const;
1285 
1286     /**
1287      * reroute the vehicle to the new parking area, updating routes and passengers/containers associated trips
1288      * @param parkingAreaID    id of the new parking area
1289      */
1290     bool rerouteParkingArea(const std::string& parkingAreaID, std::string& errorMsg);
1291 
1292     /**
1293      * schedule a new stop for the vehicle; each time a stop is reached, the vehicle
1294      * will wait for the given duration before continuing on its route
1295      * @param lane     lane on wich to stop
1296      * @param startPos start position on the given lane at wich to stop
1297      * @param endPos   end position on the given lane at wich to stop
1298      * @param duration waiting time duration
1299      * @param until    time step at which the stop shall end
1300      * @param parking  a flag indicating whether the traci stop is used for parking or not
1301      * @param triggered a flag indicating whether the traci stop is triggered or not
1302      * @param containerTriggered a flag indicating whether the traci stop is triggered by a container or not
1303      */
1304     bool addTraciStop(MSLane* const lane, const double startPos, const double endPos, const SUMOTime duration, const SUMOTime until,
1305                       const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg);
1306 
1307     /**
1308      * schedule a new stop for the vehicle; each time a stop is reached, the vehicle
1309      * will wait for the given duration before continuing on its route
1310      * @param stopId    bus or container stop id
1311      * @param duration waiting time duration
1312      * @param until    time step at which the stop shall end
1313      * @param parking   a flag indicating whether the traci stop is used for parking or not
1314      * @param triggered a flag indicating whether the traci stop is triggered or not
1315      * @param containerTriggered a flag indicating whether the traci stop is triggered by a container or not
1316      * @param stoppingPlaceType a flag indicating the type of stopping place
1317      */
1318     bool addTraciStopAtStoppingPlace(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
1319                                      const bool triggered, const bool containerTriggered, const SumoXMLTag stoppingPlaceType, std::string& errorMsg);
1320 
1321     /**
1322     * returns the next imminent stop in the stop queue
1323     * @return the upcoming stop
1324     */
1325     Stop& getNextStop();
1326 
1327     /**
1328     * returns the list of stops not yet reached in the stop queue
1329     * @return the list of upcoming stops
1330     */
1331     std::list<Stop> getMyStops();
1332 
1333     /**
1334     * resumes a vehicle from stopping
1335     * @return true on success, the resuming fails if the vehicle wasn't parking in the first place
1336     */
1337     bool resumeFromStopping();
1338 
1339 
1340     /// @brief update a vector of further lanes and return the new backPos
1341     double updateFurtherLanes(std::vector<MSLane*>& furtherLanes,
1342                               std::vector<double>& furtherLanesPosLat,
1343                               const std::vector<MSLane*>& passedLanes);
1344 
1345     /// @brief get bounding rectangle
1346     PositionVector getBoundingBox() const;
1347 
1348     /// @brief get bounding polygon
1349     PositionVector getBoundingPoly() const;
1350 
1351     /** @class Influencer
1352      * @brief Changes the wished vehicle speed / lanes
1353      *
1354      * The class is used for passing velocities or velocity profiles obtained via TraCI to the vehicle.
1355      * The speed adaptation is controlled by the stored speedTimeLine
1356      * Additionally, the variables myConsiderSafeVelocity, myConsiderMaxAcceleration, and myConsiderMaxDeceleration
1357      * control whether the safe velocity, the maximum acceleration, and the maximum deceleration
1358      * have to be regarded.
1359      *
1360      * Furthermore this class is used to affect lane changing decisions according to
1361      * LaneChangeMode and any given laneTimeLine
1362      */
1363     class Influencer {
1364     private:
1365 
1366         /// @brief A static instance of this class in GapControlState deactivates gap control
1367         ///        for vehicles whose reference vehicle is removed from the road network
1368         class GapControlVehStateListener : public MSNet::VehicleStateListener {
1369             /** @brief Called if a vehicle changes its state
1370              * @param[in] vehicle The vehicle which changed its state
1371              * @param[in] to The state the vehicle has changed to
1372              * @param[in] info Additional information on the state change
1373              * @note This deactivates the corresponding gap control when a reference vehicle is removed.
1374              */
1375             void vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& info = "");
1376         };
1377 
1378 
1379         /// @brief Container for state and parameters of the gap control
1380         struct GapControlState {
1381             GapControlState();
1382             virtual ~GapControlState();
1383             /// @brief Static initalization (adds vehicle state listener)
1384             static void init();
1385             /// @brief Static cleanup (removes vehicle state listener)
1386             static void cleanup();
1387             /// @brief Start gap control with given params
1388             void activate(double tauOriginal, double tauTarget, double additionalGap, double duration, double changeRate, double maxDecel, const MSVehicle* refVeh);
1389             /// @brief Stop gap control
1390             void deactivate();
1391             /// @brief Original value for the desired headway (will be reset after duration has expired)
1392             double tauOriginal;
1393             /// @brief Current, interpolated value for the desired time headway
1394             double tauCurrent;
1395             /// @brief Target value for the desired time headway
1396             double tauTarget;
1397             /// @brief Current, interpolated value for the desired space headway
1398             double addGapCurrent;
1399             /// @brief Target value for the desired space headway
1400             double addGapTarget;
1401             /// @brief Remaining duration for keeping the target headway
1402             double remainingDuration;
1403             /// @brief Rate by which the current time and space headways are changed towards the target value.
1404             ///        (A rate of one corresponds to reaching the target value within one second)
1405             double changeRate;
1406             /// @brief Maximal deceleration to be applied due to the adapted headway
1407             double maxDecel;
1408             /// @brief reference vehicle for the gap - if it is null, the current leader on the ego's lane is used as a reference
1409             const MSVehicle* referenceVeh;
1410             /// @brief Whether the gap control is active
1411             bool active;
1412             /// @brief Whether the desired gap was attained during the current activity phase (induces the remaining duration to decrease)
1413             bool gapAttained;
1414             /// @brief The last recognized leader
1415             const MSVehicle* prevLeader;
1416             /// @brief Time of the last update of the gap control
1417             SUMOTime lastUpdate;
1418             /// @brief cache storage for the headway increments of the current operation
1419             double timeHeadwayIncrement, spaceHeadwayIncrement;
1420 
1421             /// @brief stores reference vehicles currently in use by a gapController
1422             static std::map<const MSVehicle*, GapControlState*> refVehMap;
1423 
1424         private:
1425             static GapControlVehStateListener vehStateListener;
1426         };
1427     public:
1428         /// @brief Constructor
1429         Influencer();
1430 
1431         /// @brief Destructor
1432         ~Influencer();
1433 
1434         /// @brief Static initalization
1435         static void init();
1436         /// @brief Static cleanup
1437         static void cleanup();
1438 
1439         /** @brief Sets a new velocity timeline
1440          * @param[in] speedTimeLine The time line of speeds to use
1441          */
1442         void setSpeedTimeLine(const std::vector<std::pair<SUMOTime, double> >& speedTimeLine);
1443 
1444         /** @brief Activates the gap control with the given parameters, @see GapControlState
1445          */
1446         void activateGapController(double originalTau, double newTimeHeadway, double newSpaceHeadway, double duration, double changeRate, double maxDecel, MSVehicle* refVeh = nullptr);
1447 
1448         /** @brief Deactivates the gap control
1449          */
1450         void deactivateGapController();
1451 
1452         /** @brief Sets a new lane timeline
1453          * @param[in] laneTimeLine The time line of lanes to use
1454          */
1455         void setLaneTimeLine(const std::vector<std::pair<SUMOTime, int> >& laneTimeLine);
1456 
1457         /** @brief Adapts lane timeline when moving to a new lane and the lane index changes
1458          * @param[in] indexShift The change in laneIndex
1459          */
1460         void adaptLaneTimeLine(int indexShift);
1461 
1462         /** @brief Sets a new sublane-change request
1463          * @param[in] latDist The lateral distance for changing
1464          */
1465         void setSublaneChange(double latDist);
1466 
1467         /// @brief return the current speed mode
1468         int getSpeedMode() const;
1469 
1470         /// @brief return the current lane change mode
1471         int getLaneChangeMode() const;
1472 
1473         /// @brief return the current routing mode
getRoutingMode()1474         int getRoutingMode() const {
1475             return myRoutingMode;
1476         }
1477         SUMOTime getLaneTimeLineDuration();
1478 
1479         SUMOTime getLaneTimeLineEnd();
1480 
1481         /** @brief Applies stored velocity information on the speed to use.
1482          *
1483          * The given speed is assumed to be the non-influenced speed from longitudinal control.
1484          *  It is stored for further usage in "myOriginalSpeed".
1485          * @param[in] currentTime The current simulation time
1486          * @param[in] speed The undisturbed speed
1487          * @param[in] vSafe The safe velocity
1488          * @param[in] vMin The minimum velocity
1489          * @param[in] vMax The maximum simulation time
1490          * @return The speed to use
1491          */
1492         double influenceSpeed(SUMOTime currentTime, double speed, double vSafe, double vMin, double vMax);
1493 
1494         /** @brief Applies gap control logic on the speed.
1495          *
1496          * The given speed is assumed to be the non-influenced speed from longitudinal control.
1497          *  It is stored for further usage in "myOriginalSpeed".
1498          * @param[in] currentTime The current simulation time
1499          * @param[in] veh The controlled vehicle
1500          * @param[in] speed The undisturbed speed
1501          * @param[in] vSafe The safe velocity
1502          * @param[in] vMin The minimum velocity
1503          * @param[in] vMax The maximum simulation time
1504          * @return The speed to use (<=speed)
1505          */
1506         double gapControlSpeed(SUMOTime currentTime, const SUMOVehicle* veh, double speed, double vSafe, double vMin, double vMax);
1507 
1508         /** @brief Applies stored LaneChangeMode information and laneTimeLine
1509          * @param[in] currentTime The current simulation time
1510          * @param[in] currentEdge The current edge the vehicle is on
1511          * @param[in] currentLaneIndex The index of the lane the vehicle is currently on
1512          * @param[in] state The LaneChangeAction flags as computed by the laneChangeModel
1513          * @return The new LaneChangeAction flags to use
1514          */
1515         int influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const int currentLaneIndex, int state);
1516 
1517 
1518         /** @brief Return the remaining number of seconds of the current
1519          * laneTimeLine assuming one exists
1520          * @param[in] currentTime The current simulation time
1521          * @return The remaining seconds to change lanes
1522          */
1523         double changeRequestRemainingSeconds(const SUMOTime currentTime) const;
1524 
1525         /** @brief Returns whether junction priority rules shall be respected
1526          * @return Whether junction priority rules be respected
1527          */
getRespectJunctionPriority()1528         inline bool getRespectJunctionPriority() const {
1529             return myRespectJunctionPriority;
1530         }
1531 
1532 
1533         /** @brief Returns whether red lights shall be a reason to brake
1534          * @return Whether red lights shall be a reason to brake
1535          */
getEmergencyBrakeRedLight()1536         inline bool getEmergencyBrakeRedLight() const {
1537             return myEmergencyBrakeRedLight;
1538         }
1539 
1540 
1541         /// @brief Returns whether safe velocities shall be considered
considerSafeVelocity()1542         bool considerSafeVelocity() const {
1543             return myConsiderSafeVelocity;
1544         }
1545 
1546         /** @brief Sets speed-constraining behaviors
1547          * @param[in] value a bitset controlling the different modes
1548          */
1549         void setSpeedMode(int speedMode);
1550 
1551         /** @brief Sets lane changing behavior
1552          * @param[in] value a bitset controlling the different modes
1553          */
1554         void setLaneChangeMode(int value);
1555 
1556         /** @brief Sets routing behavior
1557          * @param[in] value an enum value controlling the different modes
1558          */
setRoutingMode(int value)1559         void setRoutingMode(int value) {
1560             myRoutingMode = value;
1561         }
1562 
1563         /** @brief Returns the originally longitudinal speed to use
1564          * @return The speed given before influence or -1 if no influence is active
1565          */
1566         double getOriginalSpeed() const;
1567 
1568         void setRemoteControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t);
1569 
getLastAccessTimeStep()1570         SUMOTime getLastAccessTimeStep() const {
1571             return myLastRemoteAccess;
1572         }
1573 
1574         void postProcessRemoteControl(MSVehicle* v);
1575 
1576         /// @brief return the speed that is implicit in the new remote position
1577         double implicitSpeedRemote(const MSVehicle* veh, double oldSpeed);
1578 
1579         /// @brief return the change in longitudinal position that is implicit in the new remote position
1580         double implicitDeltaPosRemote(const MSVehicle* veh);
1581 
1582         bool isRemoteControlled() const;
1583 
1584         bool isRemoteAffected(SUMOTime t) const;
1585 
setSignals(int signals)1586         void setSignals(int signals) {
1587             myTraCISignals = signals;
1588         }
1589 
getSignals()1590         int getSignals() const {
1591             return myTraCISignals;
1592         }
1593 
getLatDist()1594         double getLatDist() const {
1595             return myLatDist;
1596         }
1597 
resetLatDist()1598         void resetLatDist() {
1599             myLatDist = 0.;
1600         }
1601 
ignoreOverlap()1602         bool ignoreOverlap() const {
1603             return myTraciLaneChangePriority == LCP_ALWAYS;
1604         }
1605 
1606         SUMOAbstractRouter<MSEdge, SUMOVehicle>& getRouterTT() const;
1607 
1608     private:
1609         /// @brief The velocity time line to apply
1610         std::vector<std::pair<SUMOTime, double> > mySpeedTimeLine;
1611 
1612         /// @brief The lane usage time line to apply
1613         std::vector<std::pair<SUMOTime, int> > myLaneTimeLine;
1614 
1615         /// @brief The gap control state
1616         std::shared_ptr<GapControlState> myGapControlState;
1617 
1618         /// @brief The velocity before influence
1619         double myOriginalSpeed;
1620 
1621         /// @brief The requested lateral change
1622         double myLatDist;
1623 
1624         /// @brief Whether influencing the speed has already started
1625         bool mySpeedAdaptationStarted;
1626 
1627         /// @brief Whether the safe velocity shall be regarded
1628         bool myConsiderSafeVelocity;
1629 
1630         /// @brief Whether the maximum acceleration shall be regarded
1631         bool myConsiderMaxAcceleration;
1632 
1633         /// @brief Whether the maximum deceleration shall be regarded
1634         bool myConsiderMaxDeceleration;
1635 
1636         /// @brief Whether the junction priority rules are respected
1637         bool myRespectJunctionPriority;
1638 
1639         /// @brief Whether red lights are a reason to brake
1640         bool myEmergencyBrakeRedLight;
1641 
1642         Position myRemoteXYPos;
1643         MSLane* myRemoteLane;
1644         double myRemotePos;
1645         double myRemotePosLat;
1646         double myRemoteAngle;
1647         int myRemoteEdgeOffset;
1648         ConstMSEdgeVector myRemoteRoute;
1649         SUMOTime myLastRemoteAccess;
1650 
1651         /// @name Flags for managing conflicts between the laneChangeModel and TraCI laneTimeLine
1652         //@{
1653         /// @brief lane changing which is necessary to follow the current route
1654         LaneChangeMode myStrategicLC;
1655         /// @brief lane changing with the intent to help other vehicles
1656         LaneChangeMode myCooperativeLC;
1657         /// @brief lane changing to travel with higher speed
1658         LaneChangeMode mySpeedGainLC;
1659         /// @brief changing to the rightmost lane
1660         LaneChangeMode myRightDriveLC;
1661         /// @brief changing to the prefered lateral alignment
1662         LaneChangeMode mySublaneLC;
1663         //@}
1664         ///* @brief flags for determining the priority of traci lane change requests
1665         TraciLaneChangePriority myTraciLaneChangePriority;
1666 
1667         // @brief the signals set via TraCI
1668         int myTraCISignals;
1669 
1670         ///@brief routing mode (see TraCIConstants.h)
1671         int myRoutingMode;
1672 
1673     };
1674 
1675 
1676     /** @brief Returns the velocity/lane influencer
1677      *
1678      * If no influencer was existing before, one is built, first
1679      * @return Reference to this vehicle's speed influencer
1680      */
1681     Influencer& getInfluencer();
1682 
1683     const Influencer* getInfluencer() const;
1684 
hasInfluencer()1685     bool hasInfluencer() const {
1686         return myInfluencer != nullptr;
1687     }
1688 
1689     /// @brief allow TraCI to influence a lane change decision
1690     int influenceChangeDecision(int state);
1691 
1692     /// @brief sets position outside the road network
1693     void setRemoteState(Position xyPos);
1694 
1695     /// @brief departure position where the vehicle fits fully onto the edge (if possible)
1696     double basePos(const MSEdge* edge) const;
1697 
1698     /// @brief compute safe speed for following the given leader
1699     double getSafeFollowSpeed(const std::pair<const MSVehicle*, double> leaderInfo,
1700                               const double seen, const MSLane* const lane, double distToCrossing) const;
1701 
1702     /// @brief get a numerical value for the priority of the  upcoming link
1703     static int nextLinkPriority(const std::vector<MSLane*>& conts);
1704 
1705     /// @brief whether the given vehicle must be followed at the given junction
1706     bool isLeader(const MSLink* link, const MSVehicle* veh) const;
1707 
1708     // @brief get the position of the back bumper;
1709     const Position getBackPosition() const;
1710 
1711     /// @name state io
1712     //@{
1713 
1714     /// Saves the states of a vehicle
1715     void saveState(OutputDevice& out);
1716 
1717     /** @brief Loads the state of this vehicle from the given description
1718      */
1719     void loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset);
1720     //@}
1721 
1722 protected:
1723 
1724     double getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const;
1725 
1726     /// @name Interaction with move reminders
1727     ///@{
1728 
1729     /** @brief Adapts the vehicle's entering of a new lane
1730      *
1731      * All offsets already stored in "myOldLaneMoveReminderOffsets" are increased by the
1732      *  length that has been left. All still active move reminders from "myMoveReminders"
1733      *  are put into "myOldLaneMoveReminders" and the offset to the last lane is added to
1734      *  "myOldLaneMoveReminderOffsets" for each of these.
1735      *
1736      * Move reminder from the given lane are set into "myMoveReminders".
1737      *
1738      * "myLane" must still be the left lane!
1739      *
1740      * @param[in] enteredLane
1741      * @see MSMoveReminder
1742      * @see MSLane::getMoveReminder
1743      */
1744     void adaptLaneEntering2MoveReminder(const MSLane& enteredLane);
1745     ///@}
1746 
1747 
1748     /** @brief This method iterates through the driveprocess items for the vehicle
1749      *         and adapts the given in/out parameters to the appropriate values.
1750      *
1751      *  @param[in/out] vSafe The maximal safe (or admissible) velocity.
1752      *  @param[in/out] vSafeMin The minimal safe (or admissible) velocity (used her for ensuring the clearing of junctions in time).
1753      *  @param[in/out] vSafeMinDist The distance to the next link, which should either be crossed this step, or in front of which the vehicle need to stop.
1754      */
1755     void processLinkApproaches(double& vSafe, double& vSafeMin, double& vSafeMinDist);
1756 
1757 
1758     /** @brief This method checks if the vehicle has advanced over one or several lanes
1759      *         along its route and triggers the corresponding actions for the lanes and the vehicle.
1760      *         and adapts the given in/out parameters to the appropriate values.
1761      *
1762      *  @param[out] passedLanes Lanes, which the vehicle touched at some moment of the executed simstep
1763      *  @param[out] moved Whether the vehicle did move to another lane
1764      *  @param[out] emergencyReason Reason for a possible emergency stop
1765      */
1766     void processLaneAdvances(std::vector<MSLane*>& passedLanes, bool& moved, std::string& emergencyReason);
1767 
1768 
1769     /** @brief Check for speed advices from the traci client and adjust the speed vNext in
1770      *         the current (euler) / after the current (ballistic) simstep accordingly.
1771      *
1772      *  @param[in] vSafe The maximal safe (or admissible) velocity as determined from stops, junction approaches, car following, lane changing, etc.
1773      *  @param[in] vNext The next speed (possibly subject to traci influence)
1774      *  @return updated vNext
1775      */
1776     double processTraCISpeedControl(double vSafe, double vNext);
1777 
1778 
1779     /** @brief Erase passed drive items from myLFLinkLanes (and unregister approaching information for
1780      *         corresponding links). Further, myNextDriveItem is reset.
1781      *  @note  This is called in planMove() if the vehicle has no actionstep. All items until the position
1782      *         myNextDriveItem are deleted. This can happen if myNextDriveItem was increased in processLaneAdvances()
1783      *         of the previous step.
1784      */
1785     void removePassedDriveItems();
1786 
1787     /** @brief Updates the vehicle's waiting time counters (accumulated and consecutive)
1788      */
1789     void updateWaitingTime(double vNext);
1790 
1791     /** @brief Updates the vehicle's time loss
1792      */
1793     void updateTimeLoss(double vNext);
1794 
1795     /// @brief whether the vehicle is a train that can reverse its direction at the current point in its route
1796     bool canReverse(double speedThreshold = SUMO_const_haltingSpeed) const;
1797 
1798     /** @brief sets the braking lights on/off
1799      */
1800     void setBrakingSignals(double vNext) ;
1801 
1802     /** @brief sets the blue flashing light for emergency vehicles
1803      */
1804     void setBlinkerInformation();
1805 
1806     /** @brief sets the blue flashing light for emergency vehicles
1807      */
1808     void setEmergencyBlueLight(SUMOTime currentTime);
1809 
1810     /// updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
1811     void updateOccupancyAndCurrentBestLane(const MSLane* startLane);
1812 
1813     /** @brief Returns the list of still pending stop edges
1814      * also returns the first and last stop position
1815      */
1816     const ConstMSEdgeVector getStopEdges(double& firstPos, double& lastPos) const;
1817 
1818     /// @brief return list of route indices for the remaining stops
1819     std::vector<std::pair<int, double> > getStopIndices() const;
1820 
1821     /// @brief get distance for coming to a stop (used for rerouting checks)
1822     double getBrakeGap() const;
1823 
1824     /// @brief ensure that a vehicle-relative position is not invalid
1825     Position validatePosition(Position result, double offset = 0) const;
1826 
1827     /// @brief register vehicle for drawing while outside the network
drawOutsideNetwork(bool)1828     virtual void drawOutsideNetwork(bool /*add*/) {};
1829 
1830     /// @brief The time the vehicle waits (is not faster than 0.1m/s) in seconds
1831     SUMOTime myWaitingTime;
1832     WaitingTimeCollector myWaitingTimeCollector;
1833 
1834     /// @brief the time loss in seconds due to driving with less than maximum speed
1835     double myTimeLoss;
1836 
1837     /// @brief This Vehicles driving state (pos and speed)
1838     State myState;
1839 
1840     /// @brief This vehicle's driver state @see MSDriverState
1841     MSDevice_DriverState* myDriverState;
1842 
1843     /// @brief The flag myActionStep indicates whether the current time step is an action point for the vehicle.
1844     bool myActionStep;
1845     /// @brief Action offset (actions are taken at time myActionOffset + N*getActionStepLength())
1846     ///        Initialized to 0, to be set at insertion.
1847     SUMOTime myLastActionTime;
1848 
1849 
1850 
1851     /// The lane the vehicle is on
1852     MSLane* myLane;
1853 
1854     MSAbstractLaneChangeModel* myLaneChangeModel;
1855 
1856     const MSEdge* myLastBestLanesEdge;
1857     const MSLane* myLastBestLanesInternalLane;
1858 
1859     /* @brief Complex data structure for keeping and updating LaneQ:
1860      * Each element of the outer vector corresponds to an upcoming edge on the vehicles route
1861      * The first element corresponds to the current edge and is returned in getBestLanes()
1862      * The other elements are only used as a temporary structure in updateBestLanes();
1863      */
1864     std::vector<std::vector<LaneQ> > myBestLanes;
1865 
1866     /* @brief iterator to speed up retrieval of the current lane's LaneQ in getBestLaneOffset() and getBestLanesContinuation()
1867      * This is updated in updateOccupancyAndCurrentBestLane()
1868      */
1869     std::vector<LaneQ>::iterator myCurrentLaneInBestLanes;
1870 
1871     static std::vector<MSLane*> myEmptyLaneVector;
1872 
1873     /// @brief The vehicle's list of stops
1874     std::list<Stop> myStops;
1875 
1876     /// @brief The current acceleration after dawdling in m/s
1877     double myAcceleration;
1878 
1879     /// @brief the upcoming turn for the vehicle
1880     /// @todo calculate during plan move
1881     std::pair<double, LinkDirection> myNextTurn;
1882 
1883     /// @brief The information into which lanes the vehicle laps into
1884     std::vector<MSLane*> myFurtherLanes;
1885     /// @brief lateral positions on further lanes
1886     std::vector<double> myFurtherLanesPosLat;
1887 
1888     /// @brief State of things of the vehicle that can be on or off
1889     int mySignals;
1890 
1891     /// @brief Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived)
1892     bool myAmOnNet;
1893 
1894     /// @brief Whether this vehicle is registered as waiting for a person (for deadlock-recognition)
1895     bool myAmRegisteredAsWaitingForPerson;
1896 
1897     /// @brief Whether this vehicle is registered as waiting for a container (for deadlock-recognition)
1898     bool myAmRegisteredAsWaitingForContainer;
1899 
1900     bool myHaveToWaitOnNextLink;
1901 
1902     /// @brief the angle in radians (@todo consider moving this into myState)
1903     double myAngle;
1904 
1905     /// @brief distance to the next stop or doubleMax if there is none
1906     double myStopDist;
1907 
1908     /// @brief amount of time for which the vehicle is immune from collisions
1909     SUMOTime myCollisionImmunity;
1910 
1911     mutable Position myCachedPosition;
1912 
1913     /// @brief time at which the current junction was entered
1914     SUMOTime myJunctionEntryTime;
1915     SUMOTime myJunctionEntryTimeNeverYield;
1916     SUMOTime myJunctionConflictEntryTime;
1917 
1918 protected:
1919 
1920     /// @brief Drive process items represent bounds on the safe velocity
1921     ///        corresponding to the upcoming links.
1922     /// @todo: improve documentation
1923     struct DriveProcessItem {
1924         MSLink* myLink;
1925         double myVLinkPass;
1926         double myVLinkWait;
1927         bool mySetRequest;
1928         SUMOTime myArrivalTime;
1929         double myArrivalSpeed;
1930         SUMOTime myArrivalTimeBraking;
1931         double myArrivalSpeedBraking;
1932         double myDistance;
1933         double accelV;
1934         bool hadStoppedVehicle;
1935         double availableSpace;
1936 
1937         DriveProcessItem(MSLink* link, double vPass, double vWait, bool setRequest,
1938                          SUMOTime arrivalTime, double arrivalSpeed,
1939                          SUMOTime arrivalTimeBraking, double arrivalSpeedBraking,
1940                          double distance,
1941                          double leaveSpeed = -1.) :
myLinkDriveProcessItem1942             myLink(link), myVLinkPass(vPass), myVLinkWait(vWait), mySetRequest(setRequest),
1943             myArrivalTime(arrivalTime), myArrivalSpeed(arrivalSpeed),
1944             myArrivalTimeBraking(arrivalTimeBraking), myArrivalSpeedBraking(arrivalSpeedBraking),
1945             myDistance(distance),
1946             accelV(leaveSpeed), hadStoppedVehicle(false), availableSpace(0) {
1947             assert(vWait >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
1948             assert(vPass >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
1949         };
1950 
1951 
1952         /// @brief constructor if the link shall not be passed
1953         DriveProcessItem(double vWait, double distance, double _availableSpace = 0) :
1954             myLink(0), myVLinkPass(vWait), myVLinkWait(vWait), mySetRequest(false),
1955             myArrivalTime(0), myArrivalSpeed(0),
1956             myArrivalTimeBraking(0), myArrivalSpeedBraking(0),
1957             myDistance(distance),
1958             accelV(-1), hadStoppedVehicle(false), availableSpace(_availableSpace) {
1959             assert(vWait >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
1960         };
1961 
1962 
adaptLeaveSpeedDriveProcessItem1963         inline void adaptLeaveSpeed(const double v) {
1964             if (accelV < 0) {
1965                 accelV = v;
1966             } else {
1967                 accelV = MIN2(accelV, v);
1968             }
1969         }
getLeaveSpeedDriveProcessItem1970         inline double getLeaveSpeed() const {
1971             return accelV < 0 ? myVLinkPass : accelV;
1972         }
1973     };
1974 
1975     /// Container for used Links/visited Lanes during planMove() and executeMove.
1976     // TODO: Consider making LFLinkLanes a std::deque for efficient front removal (needs refactoring in checkRewindLinkLanes()...)
1977     typedef std::vector< DriveProcessItem > DriveItemVector;
1978 
1979     /// @brief container for the planned speeds in the current step
1980     DriveItemVector myLFLinkLanes;
1981 
1982     /// @brief planned speeds from the previous step for un-registering from junctions after the new container is filled
1983     DriveItemVector myLFLinkLanesPrev;
1984 
1985     /** @brief iterator pointing to the next item in myLFLinkLanes
1986     *   @note  This is updated whenever the vehicle advances to a subsequent lane (see processLaneAdvances())
1987     *          and used for inter-actionpoint actualization of myLFLinkLanes (i.e. deletion of passed items)
1988     *          in planMove().
1989     */
1990     DriveItemVector::iterator myNextDriveItem;
1991 
1992     /// @todo: documentation
1993     void planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector& lfLinks, double& myStopDist, std::pair<double, LinkDirection>& myNextTurn) const;
1994 
1995     /// @brief runs heuristic for keeping the intersection clear in case of downstream jamming
1996     void checkRewindLinkLanes(const double lengthsInFront, DriveItemVector& lfLinks) const;
1997 
1998     /// @brief unregister approach from all upcoming links
1999     void removeApproachingInformation(const DriveItemVector& lfLinks) const;
2000 
2001 
2002     /// @brief estimate leaving speed when accelerating across a link
estimateLeaveSpeed(const MSLink * const link,const double vLinkPass)2003     inline double estimateLeaveSpeed(const MSLink* const link, const double vLinkPass) const {
2004         // estimate leave speed for passing time computation
2005         // l=linkLength, a=accel, t=continuousTime, v=vLeave
2006         // l=v*t + 0.5*a*t^2, solve for t and multiply with a, then add v
2007         return MIN2(link->getViaLaneOrLane()->getVehicleMaxSpeed(this),
2008                     getCarFollowModel().estimateSpeedAfterDistance(link->getLength(), vLinkPass, getVehicleType().getCarFollowModel().getMaxAccel()));
2009     }
2010 
2011 
2012     /* @brief adapt safe velocity in accordance to a moving obstacle:
2013      * - a leader vehicle
2014      * - a vehicle or pedestrian that crosses this vehicles path on an upcoming intersection
2015      * @param[in] leaderInfo The leading vehicle and the (virtual) distance to it
2016      * @param[in] seen the distance to the end of the current lane
2017      * @param[in] lastLink the lastLink index
2018      * @param[in] lane The current Lane the vehicle is on
2019      * @param[in,out] the safe velocity for driving
2020      * @param[in,out] the safe velocity for arriving at the next link
2021      * @param[in] distToCrossing The distance to the crossing point with the current leader where relevant or -1
2022      */
2023     void adaptToLeader(const std::pair<const MSVehicle*, double> leaderInfo,
2024                        const double seen, DriveProcessItem* const lastLink,
2025                        const MSLane* const lane, double& v, double& vLinkPass,
2026                        double distToCrossing = -1) const;
2027 
2028     /* @brief adapt safe velocity in accordance to multiple vehicles ahead:
2029      * @param[in] ahead The leader information according to the current lateral-resolution
2030      * @param[in] latOffset the lateral offset for locating the ego vehicle on the given lane
2031      * @param[in] seen the distance to the end of the current lane
2032      * @param[in] lastLink the lastLink index
2033      * @param[in] lane The current Lane the vehicle is on
2034      * @param[in,out] the safe velocity for driving
2035      * @param[in,out] the safe velocity for arriving at the next link
2036      */
2037     void adaptToLeaders(const MSLeaderInfo& ahead,
2038                         double latOffset,
2039                         const double seen, DriveProcessItem* const lastLink,
2040                         const MSLane* const lane, double& v, double& vLinkPass) const;
2041 
2042     /// @brief checks for link leaders on the given link
2043     void checkLinkLeader(const MSLink* link, const MSLane* lane, double seen,
2044                          DriveProcessItem* const lastLink, double& v, double& vLinkPass, double& vLinkWait, bool& setRequest,
2045                          bool isShadowLink = false) const;
2046 
2047     /// @brief checks for link leaders of the current link as well as the parallel link (if there is one)
2048     void checkLinkLeaderCurrentAndParallel(const MSLink* link, const MSLane* lane, double seen,
2049                                            DriveProcessItem* const lastLink, double& v, double& vLinkPass, double& vLinkWait, bool& setRequest) const;
2050 
2051 
2052     // @brief return the lane on which the back of this vehicle resides
2053     const MSLane* getBackLane() const;
2054 
2055     /** @brief updates the vehicles state, given a next value for its speed.
2056      *         This value can be negative in case of the ballistic update to indicate
2057      *         a stop within the next timestep. (You can call this a 'hack' to
2058      *         emulate reasoning based on accelerations: The assumed constant
2059      *         acceleration a within the next time step is then a = (vNext - vCurrent)/TS )
2060      *  @param[in] vNext speed in the next time step
2061      */
2062     void updateState(double vNext);
2063 
2064 
2065     /// @brief decide whether the given link must be kept clear
2066     bool keepClear(const MSLink* link) const;
2067 
2068     /// @brief decide whether a red (or yellow light) may be ignore
2069     bool ignoreRed(const MSLink* link, bool canBrake) const;
2070 
2071 
2072     /// @brief check whether all stop.edge MSRouteIterators are valid and in order
2073     bool haveValidStopEdges() const;
2074 
2075 private:
2076     /* @brief The vehicle's knowledge about edge efforts/travel times; @see MSEdgeWeightsStorage
2077      * @note member is initialized on first access */
2078     mutable MSEdgeWeightsStorage* myEdgeWeights;
2079 
2080     /// @brief The per vehicle variables of the car following model
2081     MSCFModel::VehicleVariables* myCFVariables;
2082 
2083     /// @brief An instance of a velocity/lane influencing instance; built in "getInfluencer"
2084     Influencer* myInfluencer;
2085 
2086 private:
2087     /// @brief invalidated default constructor
2088     MSVehicle();
2089 
2090     /// @brief invalidated copy constructor
2091     MSVehicle(const MSVehicle&);
2092 
2093     /// @brief invalidated assignment operator
2094     MSVehicle& operator=(const MSVehicle&);
2095 
2096     MSEdgeWeightsStorage& _getWeightsStorage() const;
2097 
2098 };
2099 
2100 
2101 #endif
2102 
2103 /****************************************************************************/
2104 
2105