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