Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 5631975 : return myPos;
109 : }
110 :
111 : /// Speed of this state
112 : double speed() const {
113 12655758 : 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 9875520 : 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 arrived
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();
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 18489052922 : double getPositionOnLane() const {
375 18489052922 : 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 6743882545 : inline double getBackPositionOnLane(const MSLane* lane) const {
399 6743882545 : 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 406938774 : 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 11955769890 : double getLateralPositionOnLane() const {
414 11955769890 : return myState.myPosLat;
415 : }
416 :
417 : void setLateralPositionOnLane(double posLat) {
418 278232 : myState.myPosLat = posLat;
419 8 : }
420 :
421 : void invalidateCachedPosition() {
422 277070 : 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 25284139012 : double getSpeed() const {
491 25284139012 : 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 526303907 : double getPreviousSpeed() const {
499 526303907 : 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 6014615504 : double getAcceleration() const {
515 6014615504 : 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 4132613418 : 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 4414521074 : 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 1562495 : SUMOTime getLastActionTime() const {
542 1562495 : 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 12516761946 : const MSLane* getLane() const {
582 12516761946 : 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 706806342 : 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 4966170064 : inline bool isOnRoad() const {
606 4966170064 : 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 137556 : 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 14106762 : inline bool isIdling() const {
622 14106762 : 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 448946236 : 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 703203774 : 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 2511077144 : SUMOTime getWaitingTime(const bool accumulated = false) const {
671 2511077144 : if (!accumulated) {
672 2509648216 : return myWaitingTime;
673 : }
674 1428928 : 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 632948589 : 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 2871764 : SUMOTime getTimeLoss() const {
705 2871764 : 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 1422460 : return STEPS2TIME(getWaitingTime(true));
716 : }
717 :
718 : /** @brief Returns the time loss in seconds
719 : */
720 80 : double getTimeLossSeconds() const {
721 80 : 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 42922386 : double getAngle() const {
736 160751324 : return myAngle;
737 : }
738 :
739 :
740 : /** @brief Returns the vehicle's direction in radians
741 : * @return The vehicle's current angle
742 : */
743 12655758 : Position getVelocityVector() const {
744 12655758 : 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 2412846744 : 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 15274960215 : 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 384935464 : return myCFVariables;
992 : }
993 :
994 : /** @brief Whether this vehicle is equipped with a MSDriverState
995 : */
996 : inline bool hasDriverState() const {
997 4487479014 : 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 whether instant stopping is permitted
1006 : bool instantStopping() const;
1007 :
1008 : /** @brief Returns whether the vehicle will stop on the current edge
1009 : */
1010 : bool willStop() const;
1011 :
1012 : //// @brief Returns whether the vehicle is at a stop and on the correct lane
1013 : bool isStoppedOnLane() const;
1014 :
1015 : /** @brief Returns whether the vehicle is stopped and must continue to do so */
1016 : bool keepStopping(bool afterProcessing = false) const;
1017 :
1018 : /** @brief Returns the remaining time a vehicle needs to stop due to a
1019 : * collision. A negative value indicates that the vehicle is not stopping due to a collision (or at all)
1020 : */
1021 : SUMOTime collisionStopTime() const;
1022 :
1023 : /** @brief Returns how long the vehicle has been stopped already due to lack of energy.
1024 : */
1025 : bool brokeDown() const;
1026 :
1027 : /** @brief Returns the information whether the vehicle is fully controlled via TraCI
1028 : * @return Whether the vehicle is remote-controlled
1029 : */
1030 : bool isRemoteControlled() const;
1031 :
1032 : /** @brief Returns the information whether the vehicle is fully controlled via TraCI
1033 : * within the lookBack time
1034 : */
1035 : bool wasRemoteControlled(SUMOTime lookBack = DELTA_T) const;
1036 :
1037 : /// @brief return the distance to the next stop or doubleMax if there is none.
1038 : double nextStopDist() const {
1039 360307149 : return myStopDist;
1040 : }
1041 : /// @}
1042 :
1043 : int getLaneIndex() const;
1044 :
1045 : /**
1046 : * Compute distance that will be covered, if the vehicle moves to a given position on its route,
1047 : * starting at its current position.
1048 : * @param destPos: position on the destination edge that shall be reached
1049 : * @param destLane: destination lane that shall be reached
1050 : * @return distance from the vehicles current position to the destination position,
1051 : * or a near infinite real value if the destination position is not contained
1052 : * within the vehicles route or the vehicle is not active
1053 : */
1054 : double getDistanceToPosition(double destPos, const MSLane* destLane) const;
1055 :
1056 :
1057 : /** @brief Processes stops, returns the velocity needed to reach the stop
1058 : * @return The velocity in dependence to the next/current stop
1059 : * @todo Describe more detailed
1060 : * @see Stop
1061 : * @see MSStoppingPlace
1062 : * @see MSStoppingPlace
1063 : */
1064 : double processNextStop(double currentVelocity);
1065 :
1066 :
1067 : /** @brief Returns the leader of the vehicle looking for a fixed distance.
1068 : *
1069 : * If the distance is not given it is calculated from the brake gap.
1070 : * The gap returned does not include the minGap.
1071 : * @param dist up to which distance to look at least for a leader
1072 : * @param considerFoes Whether vehicles on foe links should be checked
1073 : * @return The leading vehicle together with the gap; (0, -1) if no leader was found.
1074 : */
1075 : std::pair<const MSVehicle* const, double> getLeader(double dist = 0, bool considerFoes = true) const;
1076 :
1077 : /** @brief Returns the follower of the vehicle looking for a fixed distance.
1078 : *
1079 : * If the distance is not given it is set to the value of MSCFModel::brakeGap(2*roadSpeed, 4.5, 0)
1080 : * The gap returned does not include the minGap.
1081 : * If there are multiple followers, the one that maximizes the term (getSecureGap - gap) is returned.
1082 : * @param dist up to which distance to look at least for a leader
1083 : * @return The leading vehicle together with the gap; (0, -1) if no leader was found.
1084 : */
1085 : std::pair<const MSVehicle* const, double> getFollower(double dist = 0) const;
1086 :
1087 : /** @brief Returns the time gap in seconds to the leader of the vehicle on the same lane.
1088 : *
1089 : * If the distance is too big -1 is returned.
1090 : * The gap returned takes the minGap into account.
1091 : * @return The time gap in seconds; -1 if no leader was found or speed is 0.
1092 : */
1093 : double getTimeGapOnLane() const;
1094 :
1095 :
1096 : /** @brief Adds a person or container to this vehicle
1097 : *
1098 : * @param[in] transportable The person/container to add
1099 : */
1100 : void addTransportable(MSTransportable* transportable);
1101 :
1102 : /// @name Access to bool signals
1103 : /// @{
1104 :
1105 : /** @enum Signalling
1106 : * @brief Some boolean values which describe the state of some vehicle parts
1107 : */
1108 : enum Signalling {
1109 : /// @brief Everything is switched off
1110 : VEH_SIGNAL_NONE = 0,
1111 : /// @brief Right blinker lights are switched on
1112 : VEH_SIGNAL_BLINKER_RIGHT = 1,
1113 : /// @brief Left blinker lights are switched on
1114 : VEH_SIGNAL_BLINKER_LEFT = 2,
1115 : /// @brief Blinker lights on both sides are switched on
1116 : VEH_SIGNAL_BLINKER_EMERGENCY = 4,
1117 : /// @brief The brake lights are on
1118 : VEH_SIGNAL_BRAKELIGHT = 8,
1119 : /// @brief The front lights are on (no visualisation)
1120 : VEH_SIGNAL_FRONTLIGHT = 16,
1121 : /// @brief The fog lights are on (no visualisation)
1122 : VEH_SIGNAL_FOGLIGHT = 32,
1123 : /// @brief The high beam lights are on (no visualisation)
1124 : VEH_SIGNAL_HIGHBEAM = 64,
1125 : /// @brief The backwards driving lights are on (no visualisation)
1126 : VEH_SIGNAL_BACKDRIVE = 128,
1127 : /// @brief The wipers are on
1128 : VEH_SIGNAL_WIPER = 256,
1129 : /// @brief One of the left doors is opened
1130 : VEH_SIGNAL_DOOR_OPEN_LEFT = 512,
1131 : /// @brief One of the right doors is opened
1132 : VEH_SIGNAL_DOOR_OPEN_RIGHT = 1024,
1133 : /// @brief A blue emergency light is on
1134 : VEH_SIGNAL_EMERGENCY_BLUE = 2048,
1135 : /// @brief A red emergency light is on
1136 : VEH_SIGNAL_EMERGENCY_RED = 4096,
1137 : /// @brief A yellow emergency light is on
1138 : VEH_SIGNAL_EMERGENCY_YELLOW = 8192
1139 : };
1140 :
1141 :
1142 : /** @brief modes for resolving conflicts between external control (traci)
1143 : * and vehicle control over lane changing. Each level of the lane-changing
1144 : * hierarchy (strategic, cooperative, speedGain, keepRight) can be controlled
1145 : * separately */
1146 : enum LaneChangeMode {
1147 : LC_NEVER = 0, // lcModel shall never trigger changes at this level
1148 : LC_NOCONFLICT = 1, // lcModel may trigger changes if not in conflict with TraCI request
1149 : LC_ALWAYS = 2 // lcModel may always trigger changes of this level regardless of requests
1150 : };
1151 :
1152 :
1153 : /// @brief modes for prioritizing traci lane change requests
1154 : enum TraciLaneChangePriority {
1155 : LCP_ALWAYS = 0, // change regardless of blockers, adapt own speed and speed of blockers
1156 : LCP_NOOVERLAP = 1, // change unless overlapping with blockers, adapt own speed and speed of blockers
1157 : LCP_URGENT = 2, // change if not blocked, adapt own speed and speed of blockers
1158 : LCP_OPPORTUNISTIC = 3 // change if not blocked
1159 : };
1160 :
1161 :
1162 : /** @brief Switches the given signal on
1163 : * @param[in] signal The signal to mark as being switched on
1164 : */
1165 : void switchOnSignal(int signal) {
1166 221648603 : mySignals |= signal;
1167 221609647 : }
1168 :
1169 :
1170 : /** @brief Switches the given signal off
1171 : * @param[in] signal The signal to mark as being switched off
1172 : */
1173 : void switchOffSignal(int signal) {
1174 695396832 : mySignals &= ~signal;
1175 560739306 : }
1176 :
1177 :
1178 : /** @brief Returns the signals
1179 : * @return The signals' states
1180 : */
1181 : int getSignals() const {
1182 14890 : return mySignals;
1183 : }
1184 :
1185 :
1186 : /** @brief Returns whether the given signal is on
1187 : * @param[in] signal The signal to return the value of
1188 : * @return Whether the given signal is on
1189 : */
1190 : bool signalSet(int which) const {
1191 52721226 : return (mySignals & which) != 0;
1192 : }
1193 : /// @}
1194 :
1195 :
1196 : /// @brief whether the vehicle may safely move to the given lane with regard to upcoming links
1197 : bool unsafeLinkAhead(const MSLane* lane, double zipperDist) const;
1198 :
1199 : /// @brief decide whether the vehicle is passing a minor link or has comitted to do so
1200 : bool passingMinor() const;
1201 :
1202 :
1203 :
1204 : /** @brief Returns the uninfluenced velocity
1205 : *
1206 : * If no influencer exists (myInfluencer==0) the vehicle's current speed is
1207 : * returned. Otherwise the speed returned from myInfluencer->getOriginalSpeed().
1208 : * @return The vehicle's velocity as it would without an influence
1209 : * @see Influencer::getOriginalSpeed
1210 : */
1211 : double getSpeedWithoutTraciInfluence() const;
1212 :
1213 : /**
1214 : * reroute the vehicle to the new parking area, updating routes and passengers/containers associated trips
1215 : * @param parkingAreaID id of the new parking area
1216 : */
1217 : bool rerouteParkingArea(const std::string& parkingAreaID, std::string& errorMsg);
1218 :
1219 : /**
1220 : * schedule a new stop for the vehicle; each time a stop is reached, the vehicle
1221 : * will wait for the given duration before continuing on its route
1222 : * @param[in] stop Stop parameters
1223 : * @param[out] errorMsg returned error message
1224 : */
1225 : bool addTraciStop(SUMOVehicleParameter::Stop stop, std::string& errorMsg);
1226 :
1227 : bool handleCollisionStop(MSStop& stop, const double distToStop);
1228 :
1229 : /**
1230 : * resumes a vehicle from stopping
1231 : * @return true on success, the resuming fails if the vehicle wasn't parking in the first place
1232 : */
1233 : bool resumeFromStopping();
1234 :
1235 : /// @brief update a vector of further lanes and return the new backPos
1236 : double updateFurtherLanes(std::vector<MSLane*>& furtherLanes,
1237 : std::vector<double>& furtherLanesPosLat,
1238 : const std::vector<MSLane*>& passedLanes);
1239 :
1240 : /// @brief get bounding rectangle
1241 : PositionVector getBoundingBox(double offset = 0) const;
1242 :
1243 : /// @brief get bounding polygon
1244 : PositionVector getBoundingPoly(double offset = 0) const;
1245 :
1246 : /** @enum ManoeuvreType
1247 : * @brief flag identifying which, if any, manoeuvre is in progress
1248 : */
1249 : enum ManoeuvreType {
1250 : /// @brief Manoeuvre into stopping place
1251 : MANOEUVRE_ENTRY,
1252 : /// @brief Manoeuvre out of stopping place
1253 : MANOEUVRE_EXIT,
1254 : /// @brief not manouevring
1255 : MANOEUVRE_NONE
1256 : };
1257 :
1258 : /// @brief accessor function to myManoeuvre equivalent
1259 : /// @note Setup of exit manoeuvre is invoked from MSVehicleTransfer
1260 : bool setExitManoeuvre();
1261 : /// @brief accessor function to myManoeuvre equivalent
1262 : void setManoeuvreType(const MSVehicle::ManoeuvreType mType);
1263 :
1264 : /// @brief accessor function to myManoeuvre equivalent
1265 : bool manoeuvreIsComplete() const;
1266 : /// @brief accessor function to myManoeuvre equivalent
1267 : MSVehicle::ManoeuvreType getManoeuvreType() const;
1268 :
1269 :
1270 : /** @class Manoeuvre
1271 : * @brief Container for manouevering time associated with stopping.
1272 : *
1273 : * Introduced to cater for lane blocking whilst entering stop/leaving stop
1274 : * and assure that emissions during manoeuvre are included in model
1275 : */
1276 4778308 : class Manoeuvre {
1277 :
1278 : public:
1279 : /// Constructor.
1280 : Manoeuvre();
1281 :
1282 : /// Copy constructor.
1283 : Manoeuvre(const Manoeuvre& manoeuvre);
1284 :
1285 : /// Assignment operator.
1286 : Manoeuvre& operator=(const Manoeuvre& manoeuvre);
1287 :
1288 : /// Operator !=
1289 : bool operator!=(const Manoeuvre& manoeuvre);
1290 :
1291 : /// @brief Setup the entry manoeuvre for this vehicle (Sets completion time and manoeuvre type)
1292 : bool configureEntryManoeuvre(MSVehicle* veh);
1293 :
1294 : /// @brief Setup the myManoeuvre for exiting (Sets completion time and manoeuvre type)
1295 : bool configureExitManoeuvre(MSVehicle* veh);
1296 :
1297 : /// @brief Configure an entry manoeuvre if nothing is configured - otherwise check if complete
1298 : bool entryManoeuvreIsComplete(MSVehicle* veh);
1299 :
1300 : /// @brief Check if specific manoeuver is ongoing and whether the completion time is beyond currentTime
1301 : bool
1302 : manoeuvreIsComplete(const ManoeuvreType checkType) const;
1303 :
1304 : /// @brief Check if any manoeuver is ongoing and whether the completion time is beyond currentTime
1305 : bool
1306 : manoeuvreIsComplete() const;
1307 :
1308 : /// @brief Accessor for GUI rotation step when parking (radians)
1309 : double getGUIIncrement() const;
1310 :
1311 : /// @brief Accessor (get) for manoeuvre type
1312 : MSVehicle::ManoeuvreType getManoeuvreType() const;
1313 :
1314 : /// @brief Accessor (set) for manoeuvre type
1315 : void setManoeuvreType(const MSVehicle::ManoeuvreType mType);
1316 :
1317 : private:
1318 : /// @brief The name of the vehicle associated with the Manoeuvre - for debug output
1319 : std::string myManoeuvreVehicleID;
1320 :
1321 : /// @brief The name of the stop associated with the Manoeuvre - for debug output
1322 : std::string myManoeuvreStop;
1323 :
1324 : /// @brief Time at which the Manoeuvre for this stop started
1325 : SUMOTime myManoeuvreStartTime;
1326 :
1327 : /// @brief Time at which this manoeuvre should complete
1328 : SUMOTime myManoeuvreCompleteTime;
1329 :
1330 : /// @brief Manoeuvre type - currently entry, exit or none
1331 : ManoeuvreType myManoeuvreType;
1332 :
1333 : // @brief Angle (radians) through which parking vehicle moves in each sim step
1334 : double myGUIIncrement;
1335 : };
1336 :
1337 : // Current or previous (completed) manoeuvre
1338 : Manoeuvre myManoeuvre;
1339 :
1340 : /** @class Influencer
1341 : * @brief Changes the wished vehicle speed / lanes
1342 : *
1343 : * The class is used for passing velocities or velocity profiles obtained via TraCI to the vehicle.
1344 : * The speed adaptation is controlled by the stored speedTimeLine
1345 : * Additionally, the variables myConsiderSafeVelocity, myConsiderMaxAcceleration, and myConsiderMaxDeceleration
1346 : * control whether the safe velocity, the maximum acceleration, and the maximum deceleration
1347 : * have to be regarded.
1348 : *
1349 : * Furthermore this class is used to affect lane changing decisions according to
1350 : * LaneChangeMode and any given laneTimeLine
1351 : */
1352 : class Influencer : public BaseInfluencer {
1353 : private:
1354 :
1355 : /// @brief A static instance of this class in GapControlState deactivates gap control
1356 : /// for vehicles whose reference vehicle is removed from the road network
1357 59 : class GapControlVehStateListener : public MSNet::VehicleStateListener {
1358 : /** @brief Called if a vehicle changes its state
1359 : * @param[in] vehicle The vehicle which changed its state
1360 : * @param[in] to The state the vehicle has changed to
1361 : * @param[in] info Additional information on the state change
1362 : * @note This deactivates the corresponding gap control when a reference vehicle is removed.
1363 : */
1364 : void vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& info = "");
1365 : };
1366 :
1367 :
1368 : /// @brief Container for state and parameters of the gap control
1369 : struct GapControlState {
1370 : GapControlState();
1371 : virtual ~GapControlState();
1372 : /// @brief Static initalization (adds vehicle state listener)
1373 : static void init();
1374 : /// @brief Static cleanup (removes vehicle state listener)
1375 : static void cleanup();
1376 : /// @brief Start gap control with given params
1377 : void activate(double tauOriginal, double tauTarget, double additionalGap, double duration, double changeRate, double maxDecel, const MSVehicle* refVeh);
1378 : /// @brief Stop gap control
1379 : void deactivate();
1380 : /// @brief Original value for the desired headway (will be reset after duration has expired)
1381 : double tauOriginal;
1382 : /// @brief Current, interpolated value for the desired time headway
1383 : double tauCurrent;
1384 : /// @brief Target value for the desired time headway
1385 : double tauTarget;
1386 : /// @brief Current, interpolated value for the desired space headway
1387 : double addGapCurrent;
1388 : /// @brief Target value for the desired space headway
1389 : double addGapTarget;
1390 : /// @brief Remaining duration for keeping the target headway
1391 : double remainingDuration;
1392 : /// @brief Rate by which the current time and space headways are changed towards the target value.
1393 : /// (A rate of one corresponds to reaching the target value within one second)
1394 : double changeRate;
1395 : /// @brief Maximal deceleration to be applied due to the adapted headway
1396 : double maxDecel;
1397 : /// @brief reference vehicle for the gap - if it is null, the current leader on the ego's lane is used as a reference
1398 : const MSVehicle* referenceVeh;
1399 : /// @brief Whether the gap control is active
1400 : bool active;
1401 : /// @brief Whether the desired gap was attained during the current activity phase (induces the remaining duration to decrease)
1402 : bool gapAttained;
1403 : /// @brief The last recognized leader
1404 : const MSVehicle* prevLeader;
1405 : /// @brief Time of the last update of the gap control
1406 : SUMOTime lastUpdate;
1407 : /// @brief cache storage for the headway increments of the current operation
1408 : double timeHeadwayIncrement, spaceHeadwayIncrement;
1409 :
1410 : /// @brief stores reference vehicles currently in use by a gapController
1411 : static std::map<const MSVehicle*, GapControlState*> refVehMap;
1412 :
1413 : private:
1414 : static GapControlVehStateListener* myVehStateListener;
1415 : };
1416 :
1417 :
1418 : public:
1419 : /// @brief Constructor
1420 : Influencer();
1421 :
1422 : /// @brief Destructor
1423 : ~Influencer();
1424 :
1425 : /// @brief Static cleanup
1426 : static void cleanup();
1427 :
1428 : /** @brief Sets a new velocity timeline
1429 : * @param[in] speedTimeLine The time line of speeds to use
1430 : */
1431 : void setSpeedTimeLine(const std::vector<std::pair<SUMOTime, double> >& speedTimeLine);
1432 :
1433 : bool hasSpeedTimeLine(SUMOTime t) const {
1434 20 : return !mySpeedTimeLine.empty() && mySpeedTimeLine.front().first >= t;
1435 : }
1436 :
1437 : /** @brief Activates the gap control with the given parameters, @see GapControlState
1438 : */
1439 : void activateGapController(double originalTau, double newTimeHeadway, double newSpaceHeadway, double duration, double changeRate, double maxDecel, MSVehicle* refVeh = nullptr);
1440 :
1441 : /** @brief Deactivates the gap control
1442 : */
1443 : void deactivateGapController();
1444 :
1445 : /** @brief Sets a new lane timeline
1446 : * @param[in] laneTimeLine The time line of lanes to use
1447 : */
1448 : void setLaneTimeLine(const std::vector<std::pair<SUMOTime, int> >& laneTimeLine);
1449 :
1450 : /** @brief Adapts lane timeline when moving to a new lane and the lane index changes
1451 : * @param[in] indexShift The change in laneIndex
1452 : */
1453 : void adaptLaneTimeLine(int indexShift);
1454 :
1455 : /** @brief Sets a new sublane-change request
1456 : * @param[in] latDist The lateral distance for changing
1457 : */
1458 : void setSublaneChange(double latDist);
1459 :
1460 : /// @brief return the current speed mode
1461 : int getSpeedMode() const;
1462 :
1463 : /// @brief return the current lane change mode
1464 : int getLaneChangeMode() const;
1465 :
1466 : SUMOTime getLaneTimeLineDuration();
1467 :
1468 : SUMOTime getLaneTimeLineEnd();
1469 :
1470 : /** @brief Applies stored velocity information on the speed to use.
1471 : *
1472 : * The given speed is assumed to be the non-influenced speed from longitudinal control.
1473 : * It is stored for further usage in "myOriginalSpeed".
1474 : * @param[in] currentTime The current simulation time
1475 : * @param[in] speed The undisturbed speed
1476 : * @param[in] vSafe The safe velocity
1477 : * @param[in] vMin The minimum velocity
1478 : * @param[in] vMax The maximum simulation time
1479 : * @return The speed to use
1480 : */
1481 : double influenceSpeed(SUMOTime currentTime, double speed, double vSafe, double vMin, double vMax);
1482 :
1483 : /** @brief Applies gap control logic on the speed.
1484 : *
1485 : * The given speed is assumed to be the non-influenced speed from longitudinal control.
1486 : * It is stored for further usage in "myOriginalSpeed".
1487 : * @param[in] currentTime The current simulation time
1488 : * @param[in] veh The controlled vehicle
1489 : * @param[in] speed The undisturbed speed
1490 : * @param[in] vSafe The safe velocity
1491 : * @param[in] vMin The minimum velocity
1492 : * @param[in] vMax The maximum simulation time
1493 : * @return The speed to use (<=speed)
1494 : */
1495 : double gapControlSpeed(SUMOTime currentTime, const SUMOVehicle* veh, double speed, double vSafe, double vMin, double vMax);
1496 :
1497 : /** @brief Applies stored LaneChangeMode information and laneTimeLine
1498 : * @param[in] currentTime The current simulation time
1499 : * @param[in] currentEdge The current edge the vehicle is on
1500 : * @param[in] currentLaneIndex The index of the lane the vehicle is currently on
1501 : * @param[in] state The LaneChangeAction flags as computed by the laneChangeModel
1502 : * @return The new LaneChangeAction flags to use
1503 : */
1504 : int influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const int currentLaneIndex, int state);
1505 :
1506 :
1507 : /** @brief Return the remaining number of seconds of the current
1508 : * laneTimeLine assuming one exists
1509 : * @param[in] currentTime The current simulation time
1510 : * @return The remaining seconds to change lanes
1511 : */
1512 : double changeRequestRemainingSeconds(const SUMOTime currentTime) const;
1513 :
1514 : /** @brief Returns whether junction priority rules shall be respected
1515 : * (concerns approaching vehicles outside the junction)
1516 : * @return Whether junction priority rules be respected
1517 : */
1518 : inline bool getRespectJunctionPriority() const {
1519 427034 : return myRespectJunctionPriority;
1520 : }
1521 :
1522 :
1523 : /** @brief Returns whether red lights shall be a reason to brake
1524 : * @return Whether red lights shall be a reason to brake
1525 : */
1526 : inline bool getEmergencyBrakeRedLight() const {
1527 1007566 : return myEmergencyBrakeRedLight;
1528 : }
1529 :
1530 : /** @brief Returns whether junction priority rules within the junction shall be respected
1531 : * (concerns vehicles within the junction)
1532 : * @return Whether within-junction priority rules be respected
1533 : */
1534 : inline bool getRespectJunctionLeaderPriority() const {
1535 461596 : return myRespectJunctionLeaderPriority;
1536 : }
1537 :
1538 :
1539 : /// @brief Returns whether safe velocities shall be considered
1540 : bool considerSafeVelocity() const {
1541 : return myConsiderSafeVelocity;
1542 : }
1543 :
1544 : /// @brief Returns whether speed limits shall be considered
1545 : bool considerSpeedLimit() const {
1546 : // backward compatibility (when we ignore safe velocity we implicitly ignore speed limits as well)
1547 896049 : return myConsiderSpeedLimit && myConsiderSafeVelocity;
1548 : }
1549 :
1550 : /// @brief Returns whether safe velocities shall be considered
1551 : bool considerMaxDeceleration() const {
1552 1151 : return myConsiderMaxDeceleration;
1553 : }
1554 :
1555 : /** @brief Sets speed-constraining behaviors
1556 : * @param[in] value a bitset controlling the different modes
1557 : */
1558 : void setSpeedMode(int speedMode);
1559 :
1560 : /** @brief Sets lane changing behavior
1561 : * @param[in] value a bitset controlling the different modes
1562 : */
1563 : void setLaneChangeMode(int value);
1564 :
1565 : /** @brief Returns the originally longitudinal speed to use
1566 : * @return The speed given before influence or -1 if no influence is active
1567 : */
1568 : double getOriginalSpeed() const;
1569 :
1570 : /** @brief Stores the originally longitudinal speed **/
1571 : void setOriginalSpeed(double speed);
1572 :
1573 : void setRemoteControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t);
1574 :
1575 : SUMOTime getLastAccessTimeStep() const {
1576 470 : return myLastRemoteAccess;
1577 : }
1578 :
1579 : /// @brief update route if provided by remote control
1580 : void updateRemoteControlRoute(MSVehicle* v);
1581 :
1582 : /// @brief update position from remote control
1583 : void postProcessRemoteControl(MSVehicle* v);
1584 :
1585 : /// @brief return the speed that is implicit in the new remote position
1586 : double implicitSpeedRemote(const MSVehicle* veh, double oldSpeed);
1587 :
1588 : /// @brief return the change in longitudinal position that is implicit in the new remote position
1589 : double implicitDeltaPosRemote(const MSVehicle* veh);
1590 :
1591 : bool isRemoteControlled() const;
1592 :
1593 : bool isRemoteAffected(SUMOTime t) const;
1594 :
1595 : void setSignals(int signals) {
1596 33 : myTraCISignals = signals;
1597 14 : }
1598 :
1599 : int getSignals() const {
1600 500197 : return myTraCISignals;
1601 : }
1602 :
1603 : double getLatDist() const {
1604 850284 : return myLatDist;
1605 : }
1606 :
1607 : void resetLatDist() {
1608 380 : myLatDist = 0.;
1609 15 : }
1610 :
1611 : bool ignoreOverlap() const {
1612 3464 : return myTraciLaneChangePriority == LCP_ALWAYS;
1613 : }
1614 :
1615 : private:
1616 :
1617 : /// @brief Static initalization
1618 : void init();
1619 :
1620 : private:
1621 : /// @brief The velocity time line to apply
1622 : std::vector<std::pair<SUMOTime, double> > mySpeedTimeLine;
1623 :
1624 : /// @brief The lane usage time line to apply
1625 : std::vector<std::pair<SUMOTime, int> > myLaneTimeLine;
1626 :
1627 : /// @brief The gap control state
1628 : std::shared_ptr<GapControlState> myGapControlState;
1629 :
1630 : /// @brief The velocity before influence
1631 : double myOriginalSpeed;
1632 :
1633 : /// @brief The requested lateral change
1634 : double myLatDist;
1635 :
1636 : /// @brief Whether influencing the speed has already started
1637 : bool mySpeedAdaptationStarted;
1638 :
1639 : /// @brief Whether the safe velocity shall be regarded
1640 : bool myConsiderSafeVelocity;
1641 :
1642 : /// @brief Whether the speed limit shall be regarded
1643 : bool myConsiderSpeedLimit;
1644 :
1645 : /// @brief Whether the maximum acceleration shall be regarded
1646 : bool myConsiderMaxAcceleration;
1647 :
1648 : /// @brief Whether the maximum deceleration shall be regarded
1649 : bool myConsiderMaxDeceleration;
1650 :
1651 : /// @brief Whether the junction priority rules are respected (approaching)
1652 : bool myRespectJunctionPriority;
1653 :
1654 : /// @brief Whether red lights are a reason to brake
1655 : bool myEmergencyBrakeRedLight;
1656 :
1657 : /// @brief Whether the junction priority rules are respected (within)
1658 : bool myRespectJunctionLeaderPriority;
1659 :
1660 : Position myRemoteXYPos;
1661 : MSLane* myRemoteLane;
1662 : double myRemotePos;
1663 : double myRemotePosLat;
1664 : double myRemoteAngle;
1665 : int myRemoteEdgeOffset;
1666 : ConstMSEdgeVector myRemoteRoute;
1667 : SUMOTime myLastRemoteAccess;
1668 :
1669 : /// @name Flags for managing conflicts between the laneChangeModel and TraCI laneTimeLine
1670 : //@{
1671 : /// @brief lane changing which is necessary to follow the current route
1672 : LaneChangeMode myStrategicLC;
1673 : /// @brief lane changing with the intent to help other vehicles
1674 : LaneChangeMode myCooperativeLC;
1675 : /// @brief lane changing to travel with higher speed
1676 : LaneChangeMode mySpeedGainLC;
1677 : /// @brief changing to the rightmost lane
1678 : LaneChangeMode myRightDriveLC;
1679 : /// @brief changing to the prefered lateral alignment
1680 : LaneChangeMode mySublaneLC;
1681 : //@}
1682 : ///* @brief flags for determining the priority of traci lane change requests
1683 : TraciLaneChangePriority myTraciLaneChangePriority;
1684 :
1685 : // @brief the signals set via TraCI
1686 : int myTraCISignals;
1687 :
1688 : };
1689 :
1690 :
1691 : /** @brief Returns the velocity/lane influencer
1692 : *
1693 : * If no influencer was existing before, one is built, first
1694 : * @return Reference to this vehicle's speed influencer
1695 : */
1696 : BaseInfluencer& getBaseInfluencer();
1697 : Influencer& getInfluencer();
1698 :
1699 : const BaseInfluencer* getBaseInfluencer() const;
1700 : const Influencer* getInfluencer() const;
1701 :
1702 7221180964 : bool hasInfluencer() const {
1703 7221180964 : return myInfluencer != nullptr;
1704 : }
1705 :
1706 : /// @brief allow TraCI to influence a lane change decision
1707 : int influenceChangeDecision(int state);
1708 :
1709 : /// @brief sets position outside the road network
1710 : void setRemoteState(Position xyPos);
1711 :
1712 : /// @brief get a numerical value for the priority of the upcoming link
1713 : static int nextLinkPriority(const std::vector<MSLane*>& conts);
1714 :
1715 : /// @brief whether the given vehicle must be followed at the given junction
1716 : bool isLeader(const MSLink* link, const MSVehicle* veh, const double gap) const;
1717 :
1718 : // @brief get the position of the back bumper;
1719 : const Position getBackPosition() const;
1720 :
1721 : /// @brief whether this vehicle is except from collision checks
1722 : bool ignoreCollision() const;
1723 :
1724 : /// @brief update state while parking
1725 : void updateParkingState();
1726 :
1727 : /** @brief Replaces the current vehicle type by the one given
1728 : * @param[in] type The new vehicle type
1729 : * @see MSBaseVehicle::replaceVehicleType
1730 : */
1731 : void replaceVehicleType(const MSVehicleType* type);
1732 :
1733 : /// @brief get distance for coming to a stop (used for rerouting checks)
1734 : double getBrakeGap(bool delayed = false) const;
1735 :
1736 : /// @name state io
1737 : //@{
1738 :
1739 : /// Saves the states of a vehicle
1740 : void saveState(OutputDevice& out);
1741 :
1742 : /** @brief Loads the state of this vehicle from the given description
1743 : */
1744 : void loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset);
1745 :
1746 : void loadPreviousApproaching(MSLink* link, bool setRequest,
1747 : SUMOTime arrivalTime, double arrivalSpeed,
1748 : double arrivalSpeedBraking,
1749 : double dist, double leaveSpeed);
1750 : //@}
1751 :
1752 : protected:
1753 :
1754 : /// @name Interaction with move reminders
1755 : ///@{
1756 :
1757 : /** @brief Adapts the vehicle's entering of a new lane
1758 : *
1759 : * All offsets already stored in "myOldLaneMoveReminderOffsets" are increased by the
1760 : * length that has been left. All still active move reminders from "myMoveReminders"
1761 : * are put into "myOldLaneMoveReminders" and the offset to the last lane is added to
1762 : * "myOldLaneMoveReminderOffsets" for each of these.
1763 : *
1764 : * Move reminder from the given lane are set into "myMoveReminders".
1765 : *
1766 : * "myLane" must still be the left lane!
1767 : *
1768 : * @param[in] enteredLane
1769 : * @see MSMoveReminder
1770 : * @see MSLane::getMoveReminder
1771 : */
1772 : void adaptLaneEntering2MoveReminder(const MSLane& enteredLane);
1773 : ///@}
1774 :
1775 :
1776 : /** @brief This method iterates through the driveprocess items for the vehicle
1777 : * and adapts the given in/out parameters to the appropriate values.
1778 : *
1779 : * @param[in/out] vSafe The maximal safe (or admissible) velocity.
1780 : * @param[in/out] vSafeMin The minimal safe (or admissible) velocity (used her for ensuring the clearing of junctions in time).
1781 : * @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.
1782 : */
1783 : void processLinkApproaches(double& vSafe, double& vSafeMin, double& vSafeMinDist);
1784 :
1785 :
1786 : /** @brief This method checks if the vehicle has advanced over one or several lanes
1787 : * along its route and triggers the corresponding actions for the lanes and the vehicle.
1788 : * and adapts the given in/out parameters to the appropriate values.
1789 : *
1790 : * @param[out] passedLanes Lanes, which the vehicle touched at some moment of the executed simstep
1791 : * @param[out] emergencyReason Reason for a possible emergency stop
1792 : */
1793 : void processLaneAdvances(std::vector<MSLane*>& passedLanes, std::string& emergencyReason);
1794 :
1795 :
1796 : /** @brief Check for speed advices from the traci client and adjust the speed vNext in
1797 : * the current (euler) / after the current (ballistic) simstep accordingly.
1798 : *
1799 : * @param[in] vSafe The maximal safe (or admissible) velocity as determined from stops, junction approaches, car following, lane changing, etc.
1800 : * @param[in] vNext The next speed (possibly subject to traci influence)
1801 : * @return updated vNext
1802 : */
1803 : double processTraCISpeedControl(double vSafe, double vNext);
1804 :
1805 :
1806 : /** @brief Erase passed drive items from myLFLinkLanes (and unregister approaching information for
1807 : * corresponding links). Further, myNextDriveItem is reset.
1808 : * @note This is called in planMove() if the vehicle has no actionstep. All items until the position
1809 : * myNextDriveItem are deleted. This can happen if myNextDriveItem was increased in processLaneAdvances()
1810 : * of the previous step.
1811 : */
1812 : void removePassedDriveItems();
1813 :
1814 : /** @brief Updates the vehicle's waiting time counters (accumulated and consecutive)
1815 : */
1816 : void updateWaitingTime(double vNext);
1817 :
1818 : /** @brief Updates the vehicle's time loss
1819 : */
1820 : void updateTimeLoss(double vNext);
1821 :
1822 : /* @brief Check whether the vehicle is a train that can reverse its direction at the current point in its route
1823 : * and return the speed in preparation for reversal
1824 : *
1825 : * @param[out] canReverse
1826 : * @param[in] speedThreshold
1827 : * @return speed for reversal
1828 : */
1829 : double checkReversal(bool& canReverse, double speedThreshold = SUMO_const_haltingSpeed, double seen = 0) const;
1830 :
1831 : /** @brief sets the braking lights on/off
1832 : */
1833 : void setBrakingSignals(double vNext) ;
1834 :
1835 : /** @brief sets the blue flashing light for emergency vehicles
1836 : */
1837 : void setBlinkerInformation();
1838 :
1839 : /** @brief sets the blue flashing light for emergency vehicles
1840 : */
1841 : void setEmergencyBlueLight(SUMOTime currentTime);
1842 :
1843 : /// updates myFurtherLanes on lane insertion or after collision
1844 : void computeFurtherLanes(MSLane* enteredLane, double pos, bool collision = false);
1845 :
1846 : /// updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
1847 : void updateOccupancyAndCurrentBestLane(const MSLane* startLane);
1848 :
1849 : /// @brief ensure that a vehicle-relative position is not invalid
1850 : Position validatePosition(Position result, double offset = 0) const;
1851 :
1852 : /// @brief register vehicle for drawing while outside the network
1853 209 : virtual void drawOutsideNetwork(bool /*add*/) {};
1854 :
1855 : /// @brief board persons and load transportables at the given stop
1856 : void boardTransportables(MSStop& stop);
1857 :
1858 : /// @brief try joining the given vehicle to the rear of this one (to resolve joinTriggered)
1859 : bool joinTrainPart(MSVehicle* veh);
1860 :
1861 : /// @brief try joining the given vehicle to the front of this one (to resolve joinTriggered)
1862 : bool joinTrainPartFront(MSVehicle* veh);
1863 :
1864 : /// @brief optionally return an upper bound on speed to stay within the schedule
1865 : double slowDownForSchedule(double vMinComfortable) const;
1866 :
1867 : /// @brief perform lateral z interpolation in elevated networks
1868 : void interpolateLateralZ(Position& pos, double offset, double posLat) const;
1869 :
1870 : /** @brief get the distance from the start of this lane to the start of the next normal lane
1871 : * (or 0 if this lane is a normal lane)
1872 : */
1873 : double getDistanceToLeaveJunction() const;
1874 :
1875 : protected:
1876 :
1877 : /// @brief The time the vehicle waits (is not faster than 0.1m/s) in seconds
1878 : SUMOTime myWaitingTime;
1879 : WaitingTimeCollector myWaitingTimeCollector;
1880 :
1881 : /// @brief the time loss in seconds due to driving with less than maximum speed
1882 : double myTimeLoss;
1883 :
1884 : /// @brief This Vehicles driving state (pos and speed)
1885 : State myState;
1886 :
1887 : /// @brief This vehicle's driver state @see MSDriverState
1888 : MSDevice_DriverState* myDriverState;
1889 :
1890 : /// @brief This vehicle's friction perception
1891 : MSDevice_Friction* myFrictionDevice;
1892 :
1893 : /// @brief The flag myActionStep indicates whether the current time step is an action point for the vehicle.
1894 : bool myActionStep;
1895 : /// @brief Action offset (actions are taken at time myActionOffset + N*getActionStepLength())
1896 : /// Initialized to 0, to be set at insertion.
1897 : SUMOTime myLastActionTime;
1898 :
1899 :
1900 :
1901 : /// The lane the vehicle is on
1902 : MSLane* myLane;
1903 :
1904 : MSAbstractLaneChangeModel* myLaneChangeModel;
1905 :
1906 : const MSEdge* myLastBestLanesEdge;
1907 : const MSLane* myLastBestLanesInternalLane;
1908 :
1909 : /* @brief Complex data structure for keeping and updating LaneQ:
1910 : * Each element of the outer vector corresponds to an upcoming edge on the vehicles route
1911 : * The first element corresponds to the current edge and is returned in getBestLanes()
1912 : * The other elements are only used as a temporary structure in updateBestLanes();
1913 : */
1914 : std::vector<std::vector<LaneQ> > myBestLanes;
1915 :
1916 : /* @brief iterator to speed up retrieval of the current lane's LaneQ in getBestLaneOffset() and getBestLanesContinuation()
1917 : * This is updated in updateOccupancyAndCurrentBestLane()
1918 : */
1919 : std::vector<LaneQ>::iterator myCurrentLaneInBestLanes;
1920 :
1921 : static std::vector<MSLane*> myEmptyLaneVector;
1922 :
1923 : /// @brief The current acceleration after dawdling in m/s
1924 : double myAcceleration;
1925 :
1926 : /// @brief the upcoming turn for the vehicle
1927 : /// @todo calculate during plan move
1928 : std::pair<double, const MSLink*> myNextTurn;
1929 :
1930 : /// @brief The information into which lanes the vehicle laps into
1931 : std::vector<MSLane*> myFurtherLanes;
1932 : /// @brief lateral positions on further lanes
1933 : std::vector<double> myFurtherLanesPosLat;
1934 :
1935 : /// @brief State of things of the vehicle that can be on or off
1936 : int mySignals;
1937 :
1938 : /// @brief Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived)
1939 : bool myAmOnNet;
1940 :
1941 : /// @brief Whether the vehicle is trying to enter the network (eg after parking so engine is running)
1942 : bool myAmIdling;
1943 :
1944 : bool myHaveToWaitOnNextLink;
1945 :
1946 : /// @brief the angle in radians (@todo consider moving this into myState)
1947 : double myAngle;
1948 :
1949 : /// @brief distance to the next stop or doubleMax if there is none
1950 : double myStopDist;
1951 :
1952 : /// @brief the speed that is needed for a scheduled stop or waypoint
1953 : double myStopSpeed;
1954 :
1955 : /// @brief amount of time for which the vehicle is immune from collisions
1956 : SUMOTime myCollisionImmunity;
1957 :
1958 : mutable Position myCachedPosition;
1959 :
1960 : /// @brief time at which the current junction was entered
1961 : SUMOTime myJunctionEntryTime;
1962 : SUMOTime myJunctionEntryTimeNeverYield;
1963 : SUMOTime myJunctionConflictEntryTime;
1964 :
1965 : /// @brief duration of driving (speed > SUMO_const_haltingSpeed) after the last halting episode
1966 : SUMOTime myTimeSinceStartup;
1967 : const MSLink* myHaveStoppedFor;
1968 :
1969 : protected:
1970 :
1971 : /// @brief Drive process items represent bounds on the safe velocity
1972 : /// corresponding to the upcoming links.
1973 : /// @todo: improve documentation
1974 : struct DriveProcessItem {
1975 : MSLink* myLink;
1976 : double myVLinkPass;
1977 : double myVLinkWait;
1978 : bool mySetRequest;
1979 : SUMOTime myArrivalTime;
1980 : double myArrivalSpeed;
1981 : double myArrivalSpeedBraking;
1982 : double myDistance;
1983 : double accelV;
1984 : bool hadStoppedVehicle;
1985 : double availableSpace;
1986 :
1987 : DriveProcessItem(MSLink* link, double vPass, double vWait, bool setRequest,
1988 : SUMOTime arrivalTime, double arrivalSpeed,
1989 : double arrivalSpeedBraking,
1990 : double distance,
1991 849291753 : double leaveSpeed) :
1992 849291753 : myLink(link), myVLinkPass(vPass), myVLinkWait(vWait), mySetRequest(setRequest),
1993 849291753 : myArrivalTime(arrivalTime), myArrivalSpeed(arrivalSpeed),
1994 849291753 : myArrivalSpeedBraking(arrivalSpeedBraking),
1995 849291753 : myDistance(distance),
1996 849291753 : accelV(leaveSpeed), hadStoppedVehicle(false), availableSpace(0) {
1997 : assert(vWait >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
1998 : assert(vPass >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
1999 : };
2000 :
2001 :
2002 : /// @brief constructor if the link shall not be passed
2003 353873194 : DriveProcessItem(double vWait, double distance, double _availableSpace = 0) :
2004 353873194 : myLink(0), myVLinkPass(vWait), myVLinkWait(vWait), mySetRequest(false),
2005 353873194 : myArrivalTime(0), myArrivalSpeed(0),
2006 353873194 : myArrivalSpeedBraking(0),
2007 353873194 : myDistance(distance),
2008 353873194 : accelV(-1), hadStoppedVehicle(false), availableSpace(_availableSpace) {
2009 : assert(vWait >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
2010 : };
2011 :
2012 :
2013 : inline void adaptLeaveSpeed(const double v) {
2014 1136151928 : if (accelV < 0) {
2015 96786 : accelV = v;
2016 : } else {
2017 1136055142 : accelV = MIN2(accelV, v);
2018 : }
2019 : }
2020 :
2021 : inline void adaptStopSpeed(const double v) {
2022 482089 : myVLinkWait = MIN2(myVLinkWait, v);
2023 : }
2024 :
2025 : inline double getLeaveSpeed() const {
2026 1507231087 : return accelV < 0 ? myVLinkPass : accelV;
2027 : }
2028 : };
2029 :
2030 : /// Container for used Links/visited Lanes during planMove() and executeMove.
2031 : // TODO: Consider making LFLinkLanes a std::deque for efficient front removal (needs refactoring in checkRewindLinkLanes()...)
2032 : typedef std::vector< DriveProcessItem > DriveItemVector;
2033 :
2034 : /// @brief container for the planned speeds in the current step
2035 : DriveItemVector myLFLinkLanes;
2036 :
2037 : /// @brief planned speeds from the previous step for un-registering from junctions after the new container is filled
2038 : DriveItemVector myLFLinkLanesPrev;
2039 :
2040 : /** @brief iterator pointing to the next item in myLFLinkLanes
2041 : * @note This is updated whenever the vehicle advances to a subsequent lane (see processLaneAdvances())
2042 : * and used for inter-actionpoint actualization of myLFLinkLanes (i.e. deletion of passed items)
2043 : * in planMove().
2044 : */
2045 : DriveItemVector::iterator myNextDriveItem;
2046 :
2047 : /// @todo: documentation
2048 : void planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector& lfLinks, double& myStopDist, double& newStopSpeed, std::pair<double, const MSLink*>& myNextTurn) const;
2049 :
2050 : /// @brief runs heuristic for keeping the intersection clear in case of downstream jamming
2051 : void checkRewindLinkLanes(const double lengthsInFront, DriveItemVector& lfLinks) const;
2052 :
2053 : /// @brief unregister approach from all upcoming links
2054 : void removeApproachingInformation(const DriveItemVector& lfLinks) const;
2055 :
2056 : /* @brief adapt safe velocity in accordance to a moving obstacle:
2057 : * - a leader vehicle
2058 : * - a vehicle or pedestrian that crosses this vehicles path on an upcoming intersection
2059 : * @param[in] leaderInfo The leading vehicle and the (virtual) distance to it
2060 : * @param[in] lastLink the lastLink index
2061 : * @param[in,out] the safe velocity for driving
2062 : * @param[in,out] the safe velocity for arriving at the next link
2063 : */
2064 : void adaptToLeader(const std::pair<const MSVehicle*, double> leaderInfo,
2065 : double seen,
2066 : DriveProcessItem* const lastLink,
2067 : double& v, double& vLinkPass) const;
2068 :
2069 : /// @brief handle width transitions
2070 : bool brakeForOverlap(const MSLink* link, const MSLane* lane) const;
2071 :
2072 : public:
2073 : void adaptToJunctionLeader(const std::pair<const MSVehicle*, double> leaderInfo,
2074 : const double seen, DriveProcessItem* const lastLink,
2075 : const MSLane* const lane, double& v, double& vLinkPass,
2076 : double distToCrossing = -1) const;
2077 :
2078 : void adaptToOncomingLeader(const std::pair<const MSVehicle*, double> leaderInfo,
2079 : DriveProcessItem* const lastLink,
2080 : double& v, double& vLinkPass) const;
2081 :
2082 : /// @brief decide whether a red (or yellow light) may be ignored
2083 : bool ignoreRed(const MSLink* link, bool canBrake) const;
2084 :
2085 : /// @brief decide whether a given foe object may be ignored
2086 : bool ignoreFoe(const SUMOTrafficObject* foe) const;
2087 :
2088 : /// @brief maximum acceleration to consider a vehicle as 'waiting' at low speed
2089 : inline double accelThresholdForWaiting() const {
2090 219707547 : return 0.5 * getCarFollowModel().getMaxAccel();
2091 : }
2092 :
2093 : /* @brief return the previous lane in this vehicles route including internal lanes
2094 : * @param[in] current The lane of which the predecessor should be returned
2095 : * @param[in,out] routeIndex The index of the current or previous non-internal edge in the route
2096 : */
2097 : const MSLane* getPreviousLane(const MSLane* current, int& furtherIndex) const;
2098 :
2099 : /// @brief checks for link leaders on the given link
2100 : void checkLinkLeader(const MSLink* link, const MSLane* lane, double seen,
2101 : DriveProcessItem* const lastLink, double& v, double& vLinkPass, double& vLinkWait, bool& setRequest,
2102 : bool isShadowLink = false) const;
2103 : protected:
2104 :
2105 : /* @brief adapt safe velocity in accordance to multiple vehicles ahead:
2106 : * @param[in] ahead The leader information according to the current lateral-resolution
2107 : * @param[in] latOffset the lateral offset for locating the ego vehicle on the given lane
2108 : * @param[in] seen the distance to the end of the current lane
2109 : * @param[in] lastLink the lastLink index
2110 : * @param[in] lane The current Lane the vehicle is on
2111 : * @param[in,out] the safe velocity for driving
2112 : * @param[in,out] the safe velocity for arriving at the next link
2113 : */
2114 : void adaptToLeaders(const MSLeaderInfo& ahead,
2115 : double latOffset,
2116 : const double seen, DriveProcessItem* const lastLink,
2117 : const MSLane* const lane, double& v, double& vLinkPass) const;
2118 :
2119 : void adaptToLeaderDistance(const MSLeaderDistanceInfo& ahead, double latOffset,
2120 : double seen,
2121 : DriveProcessItem* const lastLink,
2122 : double& v, double& vLinkPass) const;
2123 :
2124 :
2125 : /// @brief checks for link leaders of the current link as well as the parallel link (if there is one)
2126 : void checkLinkLeaderCurrentAndParallel(const MSLink* link, const MSLane* lane, double seen,
2127 : DriveProcessItem* const lastLink, double& v, double& vLinkPass, double& vLinkWait, bool& setRequest) const;
2128 :
2129 :
2130 : /** @brief updates the vehicles state, given a next value for its speed.
2131 : * This value can be negative in case of the ballistic update to indicate
2132 : * a stop within the next timestep. (You can call this a 'hack' to
2133 : * emulate reasoning based on accelerations: The assumed constant
2134 : * acceleration a within the next time step is then a = (vNext - vCurrent)/TS )
2135 : * @param[in] vNext speed in the next time step
2136 : */
2137 : void updateState(double vNext, bool parking = false);
2138 :
2139 :
2140 : /// @brief decide whether the given link must be kept clear
2141 : bool keepClear(const MSLink* link) const;
2142 :
2143 : /// @brief return time (s) and distance to the next stop
2144 : std::pair<double, double> estimateTimeToNextStop() const;
2145 :
2146 : /* @brief special considerations for opposite direction driving so that the
2147 : * result can be used directly by getPositionOnLane(...) */
2148 : double getBackPositionOnLane(const MSLane* lane, bool calledByGetPosition) const;
2149 :
2150 : /** @brief Returns whether this vehicle has already arived
2151 : * (reached the arrivalPosition on its final edge)
2152 : * method is called in the context of excecuteMove where opposite-direction
2153 : * vehicles are transformed temporarily to their forward lane and additional
2154 : * opposite-direction driving checks do not apply
2155 : */
2156 : bool hasArrivedInternal(bool oppositeTransformed = true) const;
2157 :
2158 :
2159 : SUMOTime getArrivalTime(SUMOTime t, double seen, double v, double arrivalSpeed) const;
2160 :
2161 : /// @brief whether the give lane is reverse direction of the current route or not
2162 : bool isOppositeLane(const MSLane* lane) const;
2163 :
2164 : /// @brief remove vehicle from further lanes (on leaving the network)
2165 : void cleanupFurtherLanes();
2166 :
2167 : /// @brief comparison between different continuations from the same lane
2168 : bool betterContinuation(const LaneQ* bestConnectedNext, const LaneQ& m) const;
2169 :
2170 : /// @brief reset rail signal approach information
2171 : void resetApproachOnReroute();
2172 :
2173 : private:
2174 : /// @brief The per vehicle variables of the car following model
2175 : MSCFModel::VehicleVariables* myCFVariables;
2176 :
2177 : /// @brief An instance of a velocity/lane influencing instance; built in "getInfluencer"
2178 : Influencer* myInfluencer;
2179 :
2180 :
2181 : private:
2182 : /// @brief invalidated default constructor
2183 : MSVehicle();
2184 :
2185 : /// @brief invalidated copy constructor
2186 : MSVehicle(const MSVehicle&);
2187 :
2188 : /// @brief invalidated assignment operator
2189 : MSVehicle& operator=(const MSVehicle&);
2190 :
2191 : };
|