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