1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2010-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    MSBaseVehicle.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Michael Behrisch
13 /// @author  Jakob Erdmann
14 /// @date    Mon, 8 Nov 2010
15 /// @version $Id$
16 ///
17 // A base class for vehicle implementations
18 /****************************************************************************/
19 #ifndef MSBaseVehicle_h
20 #define MSBaseVehicle_h
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <iostream>
29 #include <vector>
30 #include <set>
31 #include <utils/vehicle/SUMOVehicle.h>
32 #include <utils/common/StdDefs.h>
33 #include "MSRoute.h"
34 #include "MSMoveReminder.h"
35 #include "MSVehicleType.h"
36 
37 // ===========================================================================
38 // class declarations
39 // ===========================================================================
40 class MSLane;
41 class MSDevice_Transportable;
42 class MSVehicleDevice;
43 
44 
45 // ===========================================================================
46 // class definitions
47 // ===========================================================================
48 /**
49  * @class MSBaseVehicle
50  * @brief The base class for microscopic and mesoscopic vehicles
51  */
52 class MSBaseVehicle : public SUMOVehicle {
53 public:
54     // XXX: This definition was introduced to make the MSVehicle's previousSpeed
55     //      available in the context of MSMoveReminder::notifyMove(). Another solution
56     //      would be to modify notifyMove()'s interface to work with MSVehicle instead
57     //      of SUMOVehicle (it is only called with MSVehicles!). Refs. #2579
58     /** @brief Returns the vehicle's previous speed
59      * @return The vehicle's speed
60      */
61     double getPreviousSpeed() const;
62 
63     friend class GUIBaseVehicle;
64 
65     /** @brief Constructor
66      * @param[in] pars The vehicle description
67      * @param[in] route The vehicle's route
68      * @param[in] type The vehicle's type
69      * @param[in] speedFactor The factor for driven lane's speed limits
70      * @exception ProcessError If a value is wrong
71      */
72     MSBaseVehicle(SUMOVehicleParameter* pars, const MSRoute* route,
73                   MSVehicleType* type, const double speedFactor);
74 
75 
76     /// @brief Destructor
77     virtual ~MSBaseVehicle();
78 
isVehicle()79     bool isVehicle() const {
80         return true;
81     }
82 
83     /// Returns the name of the vehicle
84     const std::string& getID() const;
85 
86     /** @brief Returns the vehicle's parameter (including departure definition)
87      *
88      * @return The vehicle's parameter
89      */
90     const SUMOVehicleParameter& getParameter() const;
91 
92     /// @brief replace the vehicle parameter (deleting the old one)
93     void replaceParameter(const SUMOVehicleParameter* newParameter);
94 
95     /// @brief check whether the vehicle is equiped with a device of the given type
96     bool hasDevice(const std::string& deviceName) const;
97 
98     /// @brief create device of the given type
99     void createDevice(const std::string& deviceName);
100 
101     /// @brief try to retrieve the given parameter from any of the vehicles devices, raise InvalidArgument if no device parameter by that name exists
102     std::string getDeviceParameter(const std::string& deviceName, const std::string& key) const;
103 
104     /// @brief try to set the given parameter from any of the vehicles devices, raise InvalidArgument if no device parameter by that name exists
105     void setDeviceParameter(const std::string& deviceName, const std::string& key, const std::string& value);
106 
107     /** @brief Returns the current route
108      * @return The route the vehicle uses
109      */
getRoute()110     inline const MSRoute& getRoute() const {
111         return *myRoute;
112     }
113 
114 
115     /** @brief Returns the vehicle's type definition
116      * @return The vehicle's type definition
117      */
getVehicleType()118     inline const MSVehicleType& getVehicleType() const  {
119         return *myType;
120     }
121 
122 
123     /** @brief Returns the vehicle's access class
124      * @return The vehicle's access class
125      */
getVClass()126     inline SUMOVehicleClass getVClass() const {
127         return myType->getParameter().vehicleClass;
128     }
129 
130     /** @brief Returns the maximum speed
131      * @return The vehicle's maximum speed
132      */
133     double getMaxSpeed() const;
134 
135 
136     /** @brief Returns the nSuccs'th successor of edge the vehicle is currently at
137      *
138      * If the rest of the route (counted from the current edge) has less than nSuccs edges,
139      *  0 is returned.
140      * @param[in] nSuccs The number of edge to look forward
141      * @return The nSuccs'th following edge in the vehicle's route
142      */
143     const MSEdge* succEdge(int nSuccs) const;
144 
145     /** @brief Returns the edge the vehicle is currently at
146      *
147      * @return The current edge in the vehicle's route
148      */
149     const MSEdge* getEdge() const;
150 
151 
152     /** @brief Returns the information whether the vehicle is on a road (is simulated)
153      * @return Whether the vehicle is simulated
154      */
isOnRoad()155     virtual bool isOnRoad() const {
156         return true;
157     }
158 
159     /** @brief Returns the information whether the vehicle is fully controlled
160      * via TraCI
161      * @return Whether the vehicle is remote-controlled
162      */
isRemoteControlled()163     virtual bool isRemoteControlled() const {
164         return false;
165     }
166 
167     virtual bool wasRemoteControlled(SUMOTime lookBack = DELTA_T) const {
168         UNUSED_PARAMETER(lookBack);
169         return false;
170     }
171 
172     /** @brief Returns the information whether the front of the vehhicle is on the given lane
173      * @return Whether the vehicle's front is on that lane
174      */
isFrontOnLane(const MSLane *)175     virtual bool isFrontOnLane(const MSLane*) const {
176         return true;
177     }
178 
179     /** @brief Get the vehicle's lateral position on the lane
180      * @return The lateral position of the vehicle (in m relative to the
181      * centerline of the lane)
182      */
getLateralPositionOnLane()183     virtual double getLateralPositionOnLane() const {
184         return 0;
185     }
186 
187     /** @brief Returns the starting point for reroutes (usually the current edge)
188      *
189      * This differs from *myCurrEdge only if the vehicle is on an internal edge
190      * @return The rerouting start point
191      */
getRerouteOrigin()192     virtual const MSEdge* getRerouteOrigin() const {
193         return *myCurrEdge;
194     }
195 
196 
197     /** @brief Returns an iterator pointing to the current edge in this vehicles route
198      * @return The current route pointer
199      */
getCurrentRouteEdge()200     const MSRouteIterator& getCurrentRouteEdge() const {
201         return myCurrEdge;
202     }
203 
204 
205     /** @brief Performs a rerouting using the given router
206      *
207      * Tries to find a new route between the current edge and the destination edge, first.
208      * Tries to replace the current route by the new one using replaceRoute.
209      *
210      * @param[in] t The time for which the route is computed
211      * @param[in] router The router to use
212      * @see replaceRoute
213      */
214     void reroute(SUMOTime t, const std::string& info, SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, const bool onInit = false, const bool withTaz = false, const bool silent = false);
215 
216 
217     /** @brief Replaces the current route by the given edges
218      *
219      * It is possible that the new route is not accepted, if a) it does not
220      *  contain the vehicle's current edge, or b) something fails on insertion
221      *  into the routes container (see in-line comments).
222      *
223      * @param[in] edges The new list of edges to pass
224      * @param[in] onInit Whether the vehicle starts with this route
225      * @param[in] check Whether the route should be checked for validity
226      * @param[in] removeStops Whether stops should be removed if they do not fit onto the new route
227      * @return Whether the new route was accepted
228      */
229     bool replaceRouteEdges(ConstMSEdgeVector& edges, double cost, double savings, const std::string& info, bool onInit = false, bool check = false, bool removeStops = true);
230 
231 
232     /** @brief Returns the vehicle's acceleration
233      *
234      * This default implementation returns always 0.
235      * @return The acceleration
236      */
237     virtual double getAcceleration() const;
238 
239     /** @brief Returns the slope of the road at vehicle's position
240      *
241      * This default implementation returns always 0.
242      * @return The slope
243      */
244     virtual double getSlope() const;
245 
246     /** @brief Called when the vehicle is inserted into the network
247      *
248      * Sets optional information about departure time, informs the vehicle
249      *  control about a further running vehicle.
250      */
251     void onDepart();
252 
253     /** @brief Returns this vehicle's real departure time
254      * @return This vehicle's real departure time
255      */
getDeparture()256     inline SUMOTime getDeparture() const {
257         return myDeparture;
258     }
259 
260     /** @brief Returns the depart delay */
getDepartDelay()261     SUMOTime getDepartDelay() const {
262         return getDeparture() - getParameter().depart;
263     }
264 
265 
266     /** @brief Returns this vehicle's real departure position
267      * @return This vehicle's real departure position
268      */
getDepartPos()269     inline double getDepartPos() const {
270         return myDepartPos;
271     }
272 
273     /** @brief Returns this vehicle's desired arrivalPos for its current route
274      * (may change on reroute)
275      * @return This vehicle's real arrivalPos
276      */
getArrivalPos()277     virtual double getArrivalPos() const {
278         return myArrivalPos;
279     }
280 
281     /** @brief Sets this vehicle's desired arrivalPos for its current route
282      */
setArrivalPos(double arrivalPos)283     virtual void setArrivalPos(double arrivalPos) {
284         myArrivalPos = arrivalPos;
285     }
286 
287     /** @brief Returns whether this vehicle has already departed
288      */
289     bool hasDeparted() const;
290 
291     /** @brief Returns whether this vehicle has already arived
292      * (by default this is true if the vehicle has reached its final edge)
293      */
294     virtual bool hasArrived() const;
295 
296     /** @brief Returns the number of new routes this vehicle got
297      * @return the number of new routes this vehicle got
298      */
getNumberReroutes()299     inline int getNumberReroutes() const {
300         return myNumberReroutes;
301     }
302 
303     /// @brief Returns this vehicles impatience
304     double getImpatience() const;
305 
306     /** @brief Returns the number of persons
307      * @return The number of passengers on-board
308      */
309     int getPersonNumber() const;
310 
311     /** @brief Returns the list of persons
312      * @return The list of passengers on-board
313      */
314     std::vector<std::string> getPersonIDList() const;
315 
316     /** @brief Returns the number of containers
317      * @return The number of contaiers on-board
318      */
319     int getContainerNumber() const;
320 
321 
322     /** @brief Returns this vehicle's devices
323      * @return This vehicle's devices
324      */
getDevices()325     inline const std::vector<MSVehicleDevice*>& getDevices() const {
326         return myDevices;
327     }
328 
329     /** @brief Adds a person to this vehicle
330      *
331      * The default implementation does nothing since persons are not supported by default
332      *
333      * @param[in] person The person to add
334      */
335     virtual void addPerson(MSTransportable* person);
336 
337 
338     /** @brief Adds a container to this vehicle
339      *
340      * The default implementation does nothing since containers are not supported by default
341      *
342      * @param[in] container The container to add
343      */
344     virtual void addContainer(MSTransportable* container);
345 
346     /// @brief removes a person or container
347     void removeTransportable(MSTransportable* t);
348 
349     /// @brief retrieve riding persons
350     const std::vector<MSTransportable*>& getPersons() const;
351 
352     /// @brief retrieve riding containers
353     const std::vector<MSTransportable*>& getContainers() const;
354 
355 
356     /** @brief Validates the current or given route
357      * @param[out] msg Description why the route is not valid (if it is the case)
358      * @param[in] route The route to check (or 0 if the current route shall be checked)
359      * @return Whether the vehicle's current route is valid
360      */
361     bool hasValidRoute(std::string& msg, const MSRoute* route = 0) const;
362 
363     /** @brief Adds a MoveReminder dynamically
364      *
365      * @param[in] rem the reminder to add
366      * @see MSMoveReminder
367      */
368     void addReminder(MSMoveReminder* rem);
369 
370     /** @brief Removes a MoveReminder dynamically
371      *
372      * @param[in] rem the reminder to remove
373      * @see MSMoveReminder
374      */
375     void removeReminder(MSMoveReminder* rem);
376 
377     /** @brief "Activates" all current move reminder
378      *
379      * For all move reminder stored in "myMoveReminders", their method
380      *  "MSMoveReminder::notifyEnter" is called.
381      *
382      * @param[in] reason The reason for changing the reminders' states
383      * @param[in] enteredLane The lane, which is entered (if applicable)
384      * @see MSMoveReminder
385      * @see MSMoveReminder::notifyEnter
386      * @see MSMoveReminder::Notification
387      */
388     virtual void activateReminders(const MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
389 
390 
391     /** @brief Returns the vehicle's length
392      * @return vehicle's length
393      */
getLength()394     inline double getLength() const {
395         return myType->getLength();
396     }
397 
398 
399     /** @brief Returns the vehicle's width
400      * @return vehicle's width
401      */
getWidth()402     inline double getWidth() const {
403         return myType->getWidth();
404     }
405 
406 
407     /** @brief Returns the precomputed factor by which the driver wants to be faster than the speed limit
408      * @return Speed limit factor
409      */
getChosenSpeedFactor()410     inline double getChosenSpeedFactor() const {
411         return myChosenSpeedFactor;
412     }
413 
414     /** @brief Returns the precomputed factor by which the driver wants to be faster than the speed limit
415      * @return Speed limit factor
416      */
setChosenSpeedFactor(const double factor)417     inline void setChosenSpeedFactor(const double factor) {
418         myChosenSpeedFactor = factor;
419     }
420 
421     /// @brief Returns a device of the given type if it exists or 0
422     MSVehicleDevice* getDevice(const std::type_info& type) const;
423 
424 
425     /** @brief Replaces the current vehicle type by the one given
426      *
427      * If the currently used vehicle type is marked as being used by this vehicle
428      *  only, it is deleted, first. The new, given type is then assigned to
429      *  "myType".
430      * @param[in] type The new vehicle type
431      * @see MSBaseVehicle::myType
432      */
433     void replaceVehicleType(MSVehicleType* type);
434 
435 
436     /** @brief Replaces the current vehicle type with a new one used by this vehicle only
437      *
438      * If the currently used vehicle type is already marked as being used by this vehicle
439      *  only, no new type is created.
440      * @return The new modifiable vehicle type
441      * @see MSBaseVehicle::myType
442      */
443     MSVehicleType& getSingularType();
444 
445     /// @name state io
446     //@{
447 
448     /// Saves the (common) state of a vehicle
449     virtual void saveState(OutputDevice& out);
450 
451     //@}
452 
453     /** @brief Adds stops to the built vehicle
454      *
455      * This code needs to be separated from the MSBaseVehicle constructor
456      *  since it is not allowed to call virtual functions from a constructor
457      *
458      * @param[in] ignoreStopErrors whether invalid stops trigger a warning only
459      */
460     void addStops(const bool ignoreStopErrors);
461 
462     /// @brief whether this vehicle is selected in the GUI
isSelected()463     virtual bool isSelected() const {
464         return false;
465     }
466 
467     /// @brief @return The vehicle's associated RNG
468     std::mt19937* getRNG() const;
469 
getNumericalID()470     inline NumericalID getNumericalID() const {
471         return myNumericalID;
472     }
473 
getPersonDevice()474     const MSDevice_Transportable* getPersonDevice() const {
475         return myPersonDevice;
476     }
477 
getContainerDevice()478     const MSDevice_Transportable* getContainerDevice() const {
479         return myContainerDevice;
480     }
481 
482 protected:
483     /** @brief (Re-)Calculates the arrival position and lane from the vehicle parameters
484      */
485     void calculateArrivalParams();
486 
487     /** @brief Returns the list of still pending stop edges
488      */
489     virtual const ConstMSEdgeVector getStopEdges(double& firstPos, double& lastPos) const = 0;
490 
491 protected:
492     /// @brief This vehicle's parameter.
493     const SUMOVehicleParameter* myParameter;
494 
495     /// @brief This vehicle's route.
496     const MSRoute* myRoute;
497 
498     /// @brief This vehicle's type.
499     MSVehicleType* myType;
500 
501     /// @brief Iterator to current route-edge
502     MSRouteIterator myCurrEdge;
503 
504     /// @brief A precomputed factor by which the driver wants to be faster than the speed limit
505     double myChosenSpeedFactor;
506 
507 
508     /// @name Move reminder structures
509     /// @{
510 
511     /// @brief Definition of a move reminder container
512     //         The double value holds the relative position offset, i.e.,
513     //         offset + vehicle-position - moveReminder-position = distance,
514     //         i.e. the offset is counted up when the vehicle continues to a
515     //         succeeding lane.
516     typedef std::vector< std::pair<MSMoveReminder*, double> > MoveReminderCont;
517 
518     /// @brief Currently relevant move reminders
519     MoveReminderCont myMoveReminders;
520     /// @}
521 
522     /// @brief The devices this vehicle has
523     std::vector<MSVehicleDevice*> myDevices;
524 
525     /// @brief The passengers this vehicle may have
526     MSDevice_Transportable* myPersonDevice;
527 
528     /// @brief The containers this vehicle may have
529     MSDevice_Transportable* myContainerDevice;
530 
531     /// @brief The real departure time
532     SUMOTime myDeparture;
533 
534     /// @brief The real depart position
535     double myDepartPos;
536 
537     /// @brief The position on the destination lane where the vehicle stops
538     double myArrivalPos;
539 
540     /// @brief The destination lane where the vehicle stops
541     int myArrivalLane;
542 
543     /// @brief The number of reroutings
544     int myNumberReroutes;
545 
546     /* @brief magic value for undeparted vehicles
547      * @note: in previous versions this was -1
548      */
549     static const SUMOTime NOT_YET_DEPARTED;
550 
551     static std::vector<MSTransportable*> myEmptyTransportableVector;
552 
553 private:
554     const NumericalID myNumericalID;
555 
556     static NumericalID myCurrentNumericalIndex;
557 
558 private:
559     /// invalidated assignment operator
560     MSBaseVehicle& operator=(const MSBaseVehicle& s);
561 
562 #ifdef _DEBUG
563 public:
564     static void initMoveReminderOutput(const OptionsCont& oc);
565 
566 protected:
567     /// @brief optionally generate movereminder-output for this vehicle
568     void traceMoveReminder(const std::string& type, MSMoveReminder* rem, double pos, bool keep) const;
569 
570     /// @brief whether this vehicle shall trace its moveReminders
571     const bool myTraceMoveReminders;
572 private:
573     /// @brief vehicles which shall trace their move reminders
574     static std::set<std::string> myShallTraceMoveReminders;
575 #endif
576 
577 
578 };
579 
580 #endif
581 
582 /****************************************************************************/
583