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