1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-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    MSVehicleControl.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Michael Behrisch
14 /// @date    Wed, 10. Dec 2003
15 /// @version $Id$
16 ///
17 // The class responsible for building and deletion of vehicles
18 /****************************************************************************/
19 #ifndef MSVehicleControl_h
20 #define MSVehicleControl_h
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <cmath>
29 #include <string>
30 #include <map>
31 #include <set>
32 #ifdef HAVE_FOX
33 #include <fx.h>
34 #include <utils/foxtools/FXSynchQue.h>
35 #endif
36 #include <utils/distribution/RandomDistributor.h>
37 #include <utils/common/SUMOTime.h>
38 #include <utils/common/SUMOVehicleClass.h>
39 #include "MSNet.h"
40 
41 
42 // ===========================================================================
43 // class declarations
44 // ===========================================================================
45 class SUMOVehicle;
46 class SUMOVehicleParameter;
47 class MSVehicle;
48 class MSRoute;
49 class MSVehicleType;
50 class OutputDevice;
51 class MSEdge;
52 
53 
54 // ===========================================================================
55 // class definitions
56 // ===========================================================================
57 /**
58  * @class MSVehicleControl
59  * @brief The class responsible for building and deletion of vehicles
60  *
61  * This class is responsible for vehicle building and deletion. It stores
62  *  vehicle types, vehicles and statistics about the last.
63  *
64  * This class also realizes the tripinfos and the vehroutes - outputs, both
65  *  generated when a vehicle is removed from the simulation, see
66  *  scheduleVehicleRemoval.
67  *
68  * Use this class for the pure microsim and GUIVehicleControl within the gui.
69  *
70  * @see GUIVehicleControl
71  */
72 class MSVehicleControl {
73 public:
74     /// @brief Definition of the internal vehicles map iterator
75     typedef std::map<std::string, SUMOVehicle*>::const_iterator constVehIt;
76 
77 public:
78     /// @brief Constructor
79     MSVehicleControl();
80 
81 
82     /// @brief Destructor
83     virtual ~MSVehicleControl();
84 
85 
86     /// @name Vehicle creation
87     /// @{
88 
89     /** @brief Builds a vehicle, increases the number of built vehicles
90      *
91      * Builds a MSVehicle instance using the given parameter.
92      *  Increases the number of loaded vehicles ("myLoadedVehNo").
93      *
94      * @param[in] defs The parameter defining the vehicle
95      * @param[in] route The route of this vehicle
96      * @param[in] type The type of this vehicle
97      * @param[in] ignoreStopErrors whether invalid stops trigger a warning only
98      * @param[in] fromRouteFile whether we are just reading the route file or creating via trigger, traci, ...
99      * @return The built vehicle (MSVehicle instance)
100      */
101     virtual SUMOVehicle* buildVehicle(SUMOVehicleParameter* defs, const MSRoute* route,
102                                       MSVehicleType* type,
103                                       const bool ignoreStopErrors, const bool fromRouteFile = true);
104     /// @}
105 
106 
107 
108     /// @name Insertion, deletion and retrieval of vehicles
109     /// @{
110 
111     /** @brief Tries to insert the vehicle into the internal vehicle container
112      *
113      * Checks whether another vehicle with the same id exists; returns false
114      *  if so. Otherwise, the vehicle is added to "myVehicleDict".
115      *  It also checks whether the vehicle has a "triggered" departure
116      *  and registers it accordingly.
117      *
118      * The vehicle control gets responsible for vehicle deletion.
119      *
120      * @param[in] id The id of the vehicle
121      * @param[in] v The vehicle
122      * @return Whether the vehicle could be inserted (no other vehicle with the same id was inserted before)
123      */
124     virtual bool addVehicle(const std::string& id, SUMOVehicle* v);
125 
126 
127     /** @brief Returns the vehicle with the given id
128      *
129      * If no vehicle with the given id is store din "myVehicleDict", 0
130      *  is returned.
131      *
132      * @param[in] id The id of the vehicle to retrieve
133      * @return The vehicle with the given id, 0 if no such vehicle exists
134      */
135     SUMOVehicle* getVehicle(const std::string& id) const;
136 
137 
138     /** @brief Deletes the vehicle
139      *
140      * @param[in] v The vehicle to delete
141      * @param[discard] Whether the vehicle is discard during loading (scale < 1)
142      * @todo Isn't this quite insecure?
143      */
144     virtual void deleteVehicle(SUMOVehicle* v, bool discard = false);
145 
146 
147     /** @brief Removes a vehicle after it has ended
148      *
149      * Writes output to tripinfos and vehroutes if wished; decrements
150      *  the number of running vehicles and increments the number of ended
151      *  vehicles. Then deletes the vehicle using "deleteVehicle".
152      *
153      * This method should be called for each vehicle that was inserted
154      *  into the network and quits its ride.
155      *
156      * @param[in] veh The vehicle to remove
157      */
158     void scheduleVehicleRemoval(SUMOVehicle* veh);
159 
160 
161     /** @brief Removes a vehicle after it has ended
162      *
163      * Writes output to tripinfos and vehroutes if wished; decrements
164      *  the number of running vehicles and increments the number of ended
165      *  vehicles. Then deletes the vehicle using "deleteVehicle".
166      *
167      * This method should be called for each vehicle that was inserted
168      *  into the network and quits its ride.
169      *
170      * @param[in] veh The vehicle to remove
171      */
172     void removePending();
173 
174 
175     /** @brief Returns the begin of the internal vehicle map
176      * @return The begin of the internal vehicle map
177      */
loadedVehBegin()178     constVehIt loadedVehBegin() const {
179         return myVehicleDict.begin();
180     }
181 
182 
183     /** @brief Returns the end of the internal vehicle map
184      * @return The end of the internal vehicle map
185      */
loadedVehEnd()186     constVehIt loadedVehEnd() const {
187         return myVehicleDict.end();
188     }
189     /// @}
190 
191 
192 
193     /// @name Setting vehicle statistics
194     /// @{
195 
196     /** @brief Informs this control about a vehicle's departure
197      *
198      * If the mean waiting time shall be computed (f.e. for summary-output),
199      *  the absolut waiting time is increased by the waiting time of the given
200      *  vehicle.
201      * @param[in] v The inserted vehicle
202      */
203     void vehicleDeparted(const SUMOVehicle& v);
204     /// @}
205 
206 
207 
208     /// @name Retrieval of vehicle statistics (always accessable)
209     /// @{
210 
211     /** @brief Returns the number of build vehicles
212      * @return The number of loaded (build) vehicles
213      */
getLoadedVehicleNo()214     int getLoadedVehicleNo() const {
215         return myLoadedVehNo;
216     }
217 
218 
219     /** @brief Returns the number of halting vehicles
220      * @return The number of halting vehicles
221      */
222     virtual int getHaltingVehicleNo() const;
223 
224     /// @brief get current absolute and relative mean vehicle speed in the network
225     virtual std::pair<double, double> getVehicleMeanSpeeds() const;
getVehicleMeanSpeed()226     double getVehicleMeanSpeed() const {
227         return getVehicleMeanSpeeds().first;
228     }
getVehicleMeanSpeedRelative()229     double getVehicleMeanSpeedRelative() const {
230         return getVehicleMeanSpeeds().second;
231     }
232 
233     /** @brief Returns the number of removed vehicles
234      * @return The number of vehicles that have left the simulation
235      */
getEndedVehicleNo()236     int getEndedVehicleNo() const {
237         return myEndedVehNo;
238     }
239 
240     /** @brief Returns the number of arrived vehicles
241      * @return The number of vehicles that have arrived at their destination
242      */
getArrivedVehicleNo()243     int getArrivedVehicleNo() const {
244         return myEndedVehNo - myDiscarded;
245     }
246 
247     /** @brief Returns the number of discarded vehicles
248      * @return The number of vehicles that could not be inserted and were permantently discarded
249      */
getDiscardedVehicleNo()250     int getDiscardedVehicleNo() const {
251         return myDiscarded;
252     }
253 
254 
255     /** @brief Returns the number of build and inserted, but not yet deleted vehicles
256      * @return The number simulated vehicles (including those in teleporter)
257      */
getRunningVehicleNo()258     int getRunningVehicleNo() const {
259         return myRunningVehNo;
260     }
261 
262 
263     /** @brief Returns the number of inserted vehicles
264      * @return The number of vehicles that have entered the simulation so far
265      */
getDepartedVehicleNo()266     int getDepartedVehicleNo() const {
267         return myRunningVehNo + myEndedVehNo - myDiscarded;
268     }
269 
270 
271     /** @brief Returns the number of instances of the current vehicle that shall be emitted
272      * considering that "frac" of all vehicles shall be emitted overall
273      * if a negative fraction is given the demand scaling factor is used
274      * (--scale)
275      * @return the number of vehicles to create (something between 0 and ceil(frac))
276      */
277     int getQuota(double frac = -1) const;
278 
279 
280     /** @brief Returns the number of build vehicles that have not been removed or
281      * need to wait for a passenger or a container
282      * @return Number of active vehicles
283      */
getActiveVehicleCount()284     int getActiveVehicleCount() const {
285         return myLoadedVehNo - (myWaitingForPerson + myWaitingForContainer + myEndedVehNo);
286     }
287 
288 
289     /// @brief return the number of collisions
getCollisionCount()290     int getCollisionCount() const {
291         return myCollisions;
292     }
293 
294     /// @brief return the number of teleports due to jamming
getTeleportsJam()295     int getTeleportsJam() const {
296         return myTeleportsJam;
297     }
298 
299     /// @brief return the number of teleports due to vehicles stuck on a minor road
getTeleportsYield()300     int getTeleportsYield() const {
301         return myTeleportsYield;
302     }
303 
304     /// @brief return the number of teleports due to vehicles stuck on the wrong lane
getTeleportsWrongLane()305     int getTeleportsWrongLane() const {
306         return myTeleportsWrongLane;
307     }
308 
309     /// @brief return the number of teleports (including collisions)
310     int getTeleportCount() const;
311 
312     /// @brief return the number of emergency stops
getEmergencyStops()313     int getEmergencyStops() const {
314         return myEmergencyStops;
315     }
316 
317     /** @brief Returns the total departure delay
318      * @return Sum of steps vehicles had to wait until being inserted
319      */
getTotalDepartureDelay()320     double getTotalDepartureDelay() const {
321         return myTotalDepartureDelay;
322     }
323 
324 
325     /** @brief Returns the total travel time
326      * @return Sum of travel times of arrived vehicles
327      */
getTotalTravelTime()328     double getTotalTravelTime() const {
329         return myTotalTravelTime;
330     }
331     /// @}
332 
333 
334 
335     /// @name Insertion and retrieval of vehicle types
336     /// @{
337 
338     /** @brief Adds a vehicle type
339      *
340      * If another vehicle type (or distribution) with the same id exists, false is returned.
341      *  Otherwise, the vehicle type is added to the internal vehicle type
342      *  container "myVTypeDict".
343      *
344      * This control get responsible for deletion of the added vehicle
345      *  type.
346      *
347      * @param[in] vehType The vehicle type to add
348      * @return Whether the vehicle type could be added
349      */
350     bool addVType(MSVehicleType* vehType);
351 
352     /*
353      * @param[in] vehType The vehicle type to remove
354      * @return Whether the vehicle type could be removed
355      */
356     void removeVType(const MSVehicleType* vehType);
357 
358 
359     /** @brief Adds a vehicle type distribution
360      *
361      * If another vehicle type (or distribution) with the same id exists, false is returned.
362      *  Otherwise, the vehicle type distribution is added to the internal vehicle type distribution
363      *  container "myVTypeDistDict".
364      *
365      * This control get responsible for deletion of the added vehicle
366      *  type distribution.
367      *
368      * @param[in] id The id of the distribution to add
369      * @param[in] vehTypeDistribution The vehicle type distribution to add
370      * @return Whether the vehicle type could be added
371      */
372     bool addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution);
373 
374 
375     /** @brief Asks for existence of a vehicle type
376      *
377      * If vehicle type or distribution with the id exists, true is returned, false otherwise.
378      *
379      * @param[in] id The id of the type or distribution
380      * @return Whether the vehicle type or distribution exists
381      */
382     bool hasVType(const std::string& id) const;
383 
384 
385     /** @brief Asks for a vehicle type distribution
386      *
387      * If vehicle type distribution with the id exists, true is returned, false otherwise.
388      *
389      * @param[in] id The id of the distribution
390      * @return Whether the vehicle type distribution exists
391      */
392     bool hasVTypeDistribution(const std::string& id) const;
393 
394 
395     /** @brief Returns the named vehicle type or a sample from the named distribution
396      * @param[in] id The id of the vehicle type to return. If left out, the default type is returned.
397      * @return The named vehicle type, or 0 if no such type exists
398      */
399     MSVehicleType* getVType(const std::string& id = DEFAULT_VTYPE_ID, std::mt19937* rng = 0);
400 
401 
402     /** @brief Inserts ids of all known vehicle types and vehicle type distributions to the given vector
403      * @param[in] into The vector to fill with ids
404      */
405     void insertVTypeIDs(std::vector<std::string>& into) const;
406 
407 
408     /** @brief Return the distribution IDs the vehicle type is a member of
409     * @param[in] vehType The vehicle type to look for membership in distributions
410     */
411     std::set<std::string> getVTypeDistributionMembership(const std::string& id) const;
412 
413     /// @}
414 
415     /// @brief Adds a vehicle to the list of waiting vehiclse to a given edge
416     void addWaiting(const MSEdge* const edge, SUMOVehicle* vehicle);
417 
418     /// @brief Removes a vehicle from the list of waiting vehicles to a given edge
419     void removeWaiting(const MSEdge* const edge, const SUMOVehicle* vehicle);
420 
421     /* @brief returns a vehicle of the given lines that is waiting for a for a person or a container at this edge at the given positions
422      * @param[in] edge The edge at which the vehicle is positioned.
423      * @param[in] lines The set of lines from which at least one must correspond to the line of the vehicle
424      * @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance
425      * @param[in] ridingID The id of the person or container that wants to ride
426      */
427     SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const MSEdge* const edge, const double position);
428 
429     /** @brief increases the count of vehicles waiting for a transport to allow recognition of person / container related deadlocks
430      */
registerOneWaiting(const bool isPerson)431     void registerOneWaiting(const bool isPerson) {
432         if (isPerson) {
433             myWaitingForPerson++;
434         } else {
435             myWaitingForContainer++;
436         }
437     }
438 
439     /** @brief decreases the count of vehicles waiting for a transport to allow recognition of person / container related deadlocks
440      */
unregisterOneWaiting(const bool isPerson)441     void unregisterOneWaiting(const bool isPerson) {
442         if (isPerson) {
443             myWaitingForPerson--;
444         } else {
445             myWaitingForContainer--;
446         }
447     }
448 
449     /// @brief registers one collision-related teleport
registerCollision()450     void registerCollision() {
451         myCollisions++;
452     }
453 
454     /// @brief register one non-collision-related teleport
registerTeleportJam()455     void registerTeleportJam() {
456         myTeleportsJam++;
457     }
458 
459     /// @brief register one non-collision-related teleport
registerTeleportYield()460     void registerTeleportYield() {
461         myTeleportsYield++;
462     }
463 
464     /// @brief register one non-collision-related teleport
registerTeleportWrongLane()465     void registerTeleportWrongLane() {
466         myTeleportsWrongLane++;
467     }
468 
469     /// @brief register emergency stop
registerEmergencyStop()470     void registerEmergencyStop() {
471         myEmergencyStops++;
472     }
473 
474     /// @name State I/O
475     /// @{
476 
477     /** @brief Sets the current state variables as loaded from the stream
478      */
479     void setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime);
480 
481     /** @brief Saves the current state into the given stream
482      */
483     void saveState(OutputDevice& out);
484     /// @}
485 
486     /// @brief avoid counting a vehicle twice if it was loaded from state and route input
487     void discountStateLoaded(bool removed = false) {
488         if (removed) {
489             myRunningVehNo--;
490             myDiscarded++;
491             myEndedVehNo++;
492         } else {
493             myLoadedVehNo--;
494         }
495     }
496 
497 
498     /** @brief informes about all waiting vehicles (deletion in destructor)
499      */
500     void abortWaiting();
501 
502     /// @brief return the maximum speed factor for all vehicles that ever entered the network
getMaxSpeedFactor()503     double getMaxSpeedFactor() const {
504         return myMaxSpeedFactor;
505     }
506 
507     /// @brief return the minimum deceleration capability for all vehicles that ever entered the network
getMinDeceleration()508     double getMinDeceleration() const {
509         return myMinDeceleration;
510     }
511 
512     void adaptIntermodalRouter(MSNet::MSIntermodalRouter& router) const;
513 
514     /// @brief sets the demand scaling factor
setScale(double scale)515     void setScale(double scale) {
516         myScale = scale;
517     }
518 
519 private:
520     /** @brief Checks whether the vehicle type (distribution) may be added
521      *
522      * This method checks also whether the default type may still be replaced
523      * @param[in] id The id of the vehicle type (distribution) to add
524      * @return Whether the type (distribution) may be added
525      */
526     bool checkVType(const std::string& id);
527 
528 protected:
529     /// @name Vehicle statistics (always accessible)
530     /// @{
531 
532     /// @brief The number of build vehicles
533     int myLoadedVehNo;
534 
535 private:
536     /// @brief The number of vehicles within the network (build and inserted but not removed)
537     int myRunningVehNo;
538 
539     /// @brief The number of removed vehicles
540     int myEndedVehNo;
541 
542     /// @brief The number of vehicles which were discarded while loading
543     int myDiscarded;
544 
545     /// @brief The number of collisions
546     int myCollisions;
547 
548     /// @brief The number of teleports due to jam
549     int myTeleportsJam;
550 
551     /// @brief The number of teleports due to vehicles stuck on a minor road
552     int myTeleportsYield;
553 
554     /// @brief The number of teleports due to vehicles stuck on the wrong lane
555     int myTeleportsWrongLane;
556 
557     /// @brief The number of emergency stops
558     int myEmergencyStops;
559 
560     /// @}
561 
562 
563     /// @name Vehicle statistics
564     /// @{
565 
566     /// @brief The aggregated time vehicles had to wait for departure (in seconds)
567     double myTotalDepartureDelay;
568 
569     /// @brief The aggregated time vehicles needed to aacomplish their route (in seconds)
570     double myTotalTravelTime;
571     /// @}
572 
573 
574 protected:
575     /// @name Vehicle container
576     /// @{
577 
578     /// @brief Vehicle dictionary type
579     typedef std::map< std::string, SUMOVehicle* > VehicleDictType;
580     /// @brief Dictionary of vehicles
581     VehicleDictType myVehicleDict;
582     /// @}
583 
584 
585 private:
586     /// @name Vehicle type container
587     /// @{
588 
589     /// @brief Vehicle type dictionary type
590     typedef std::map< std::string, MSVehicleType* > VTypeDictType;
591     /// @brief Dictionary of vehicle types
592     VTypeDictType myVTypeDict;
593 
594     /// @brief Vehicle type distribution dictionary type
595     typedef std::map< std::string, RandomDistributor<MSVehicleType*>* > VTypeDistDictType;
596     /// @brief A distribution of vehicle types (probability->vehicle type)
597     VTypeDistDictType myVTypeDistDict;
598 
599     /// @brief Inverse lookup from vehicle type to distributions it is a member of
600     std::map<std::string, std::set<std::string>> myVTypeToDist;
601 
602     /// @brief Whether the default vehicle type was already used or can still be replaced
603     bool myDefaultVTypeMayBeDeleted;
604 
605     /// @brief Whether the default pedestrian type was already used or can still be replaced
606     bool myDefaultPedTypeMayBeDeleted;
607 
608     /// @brief Whether the default bicycle type was already used or can still be replaced
609     bool myDefaultBikeTypeMayBeDeleted;
610 
611     /// the lists of waiting vehicles to a given edge
612     std::map<const MSEdge* const, std::vector<SUMOVehicle*> > myWaiting;
613 
614     /// the number of vehicles wainting for persons contained in myWaiting which can only continue by being triggered
615     int myWaitingForPerson;
616 
617     /// the number of vehicles wainting for containers contained in myWaiting which can only continue by being triggered
618     int myWaitingForContainer;
619 
620     /// @brief The scaling factor (especially for inc-dua)
621     double myScale;
622 
623     /// @brief The maximum speed factor for all vehicles in the network
624     double myMaxSpeedFactor;
625 
626     /// @brief The minimum deceleration capability for all vehicles in the network
627     double myMinDeceleration;
628 
629     /// @brief List of vehicles which belong to public transport
630     std::vector<SUMOVehicle*> myPTVehicles;
631 
632     /// @brief List of vehicles which are going to be removed
633 #ifdef HAVE_FOX
634     FXSynchQue<SUMOVehicle*, std::vector<SUMOVehicle*> > myPendingRemovals;
635 #else
636     std::vector<SUMOVehicle*> myPendingRemovals;
637 #endif
638 
639 private:
640     /// @brief invalidated copy constructor
641     MSVehicleControl(const MSVehicleControl& s);
642 
643     /// @brief invalidated assignment operator
644     MSVehicleControl& operator=(const MSVehicleControl& s);
645 
646 
647 };
648 
649 
650 #endif
651 
652 /****************************************************************************/
653 
654