SUMO - Simulation of Urban MObility
MSVehicleControl.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
19 // The class responsible for building and deletion of vehicles
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include "MSVehicleControl.h"
33 #include "MSVehicle.h"
34 #include "MSLane.h"
35 #include "MSEdge.h"
36 #include "MSNet.h"
37 #include "MSRouteHandler.h"
40 #include <utils/common/RGBColor.h>
45 
46 
47 // ===========================================================================
48 // member method definitions
49 // ===========================================================================
51  myLoadedVehNo(0),
52  myRunningVehNo(0),
53  myEndedVehNo(0),
54  myDiscarded(0),
55  myCollisions(0),
56  myTeleportsJam(0),
57  myTeleportsYield(0),
58  myTeleportsWrongLane(0),
59  myEmergencyStops(0),
60  myTotalDepartureDelay(0),
61  myTotalTravelTime(0),
62  myDefaultVTypeMayBeDeleted(true),
63  myDefaultPedTypeMayBeDeleted(true),
64  myWaitingForPerson(0),
65  myWaitingForContainer(0),
66  myMaxSpeedFactor(1),
67  myMinDeceleration(SUMOVTypeParameter::getDefaultDecel(SVC_IGNORING)) {
74  myScale = oc.getFloat("scale");
75  myMaxRandomDepartOffset = string2time(oc.getString("random-depart-offset"));
76 }
77 
78 
80  // delete vehicles
81  for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
82  delete(*i).second;
83  }
84  myVehicleDict.clear();
85  // delete vehicle type distributions
86  for (VTypeDistDictType::iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
87  delete(*i).second;
88  }
89  myVTypeDistDict.clear();
90  // delete vehicle types
91  for (VTypeDictType::iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
92  //delete(*i).second;
93  }
94  myVTypeDict.clear();
95 }
96 
99  if (myMaxRandomDepartOffset > 0) {
100  // round to the closest usable simulation step
102  } else {
103  return 0;
104  }
105 }
106 
109  const MSRoute* route,
110  MSVehicleType* type,
111  const bool ignoreStopErrors, const bool fromRouteFile) {
112  myLoadedVehNo++;
113  if (fromRouteFile) {
115  }
116  MSVehicle* built = new MSVehicle(defs, route, type, type->computeChosenSpeedDeviation(fromRouteFile ? MSRouteHandler::getParsingRNG() : 0));
117  built->addStops(ignoreStopErrors);
119  return built;
120 }
121 
122 
123 void
125  assert(myRunningVehNo > 0);
126  myTotalTravelTime += STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - veh->getDeparture());
127  myRunningVehNo--;
129  for (std::vector<MSDevice*>::const_iterator i = veh->getDevices().begin(); i != veh->getDevices().end(); ++i) {
130  (*i)->generateOutput();
131  }
132  if (OptionsCont::getOptions().isSet("tripinfo-output")) {
133  // close tag after tripinfo (possibly including emissions from another device) have been written
134  OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
135  }
136  deleteVehicle(veh);
137 }
138 
139 
140 void
142  ++myRunningVehNo;
147  // only worry about deceleration of road users
149  }
150 }
151 
152 
153 void
154 MSVehicleControl::setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime) {
155  myRunningVehNo = runningVehNo;
156  myLoadedVehNo = loadedVehNo;
157  myEndedVehNo = endedVehNo;
158  myTotalDepartureDelay = totalDepartureDelay;
159  myTotalTravelTime = totalTravelTime;
160 }
161 
162 
163 void
165  out.openTag(SUMO_TAG_DELAY);
171  // save vehicle types
172  for (VTypeDictType::iterator it = myVTypeDict.begin(); it != myVTypeDict.end(); ++it) {
173  it->second->getParameter().write(out);
174  }
175  for (VTypeDistDictType::iterator it = myVTypeDistDict.begin(); it != myVTypeDistDict.end(); ++it) {
177  out.writeAttr(SUMO_ATTR_VTYPES, (*it).second->getVals());
178  out.writeAttr(SUMO_ATTR_PROBS, (*it).second->getProbs());
179  out.closeTag();
180  }
181  for (VehicleDictType::iterator it = myVehicleDict.begin(); it != myVehicleDict.end(); ++it) {
182  (*it).second->saveState(out);
183  }
184 }
185 
186 
187 bool
188 MSVehicleControl::addVehicle(const std::string& id, SUMOVehicle* v) {
189  VehicleDictType::iterator it = myVehicleDict.find(id);
190  if (it == myVehicleDict.end()) {
191  // id not in myVehicleDict.
192  myVehicleDict[id] = v;
193  const SUMOVehicleParameter& pars = v->getParameter();
195  const MSEdge* const firstEdge = v->getRoute().getEdges()[0];
196  if (!MSGlobals::gUseMesoSim) {
197  // position will be checked against person position later
198  static_cast<MSVehicle*>(v)->setTentativeLaneAndPosition(firstEdge->getLanes()[0], v->getParameter().departPos);
199  }
200  addWaiting(v->getRoute().getEdges().front(), v);
202  }
203  if (pars.line != "" && pars.repetitionNumber < 0) {
204  myPTVehicles.push_back(v);
205  }
206  return true;
207  }
208  return false;
209 }
210 
211 
213 MSVehicleControl::getVehicle(const std::string& id) const {
214  VehicleDictType::const_iterator it = myVehicleDict.find(id);
215  if (it == myVehicleDict.end()) {
216  return 0;
217  }
218  return it->second;
219 }
220 
221 
222 void
224  myEndedVehNo++;
225  if (discard) {
226  myDiscarded++;
227  }
228  if (veh != 0) {
229  myVehicleDict.erase(veh->getID());
230  }
231  delete veh;
232 }
233 
234 
235 bool
236 MSVehicleControl::checkVType(const std::string& id) {
237  if (id == DEFAULT_VTYPE_ID) {
239  delete myVTypeDict[id];
240  myVTypeDict.erase(myVTypeDict.find(id));
242  } else {
243  return false;
244  }
245  } else if (id == DEFAULT_PEDTYPE_ID) {
247  delete myVTypeDict[id];
248  myVTypeDict.erase(myVTypeDict.find(id));
250  } else {
251  return false;
252  }
253  } else {
254  if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
255  return false;
256  }
257  }
258  return true;
259 }
260 
261 bool
263  if (checkVType(vehType->getID())) {
264  myVTypeDict[vehType->getID()] = vehType;
265  return true;
266  }
267  return false;
268 }
269 
270 
271 void
273  assert(vehType != 0);
274  assert(myVTypeDict.find(vehType->getID()) != myVTypeDict.end());
275  myVTypeDict.erase(vehType->getID());
276  delete vehType;
277 }
278 
279 
280 bool
281 MSVehicleControl::addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution) {
282  if (checkVType(id)) {
283  myVTypeDistDict[id] = vehTypeDistribution;
284  return true;
285  }
286  return false;
287 }
288 
289 
290 bool
291 MSVehicleControl::hasVType(const std::string& id) const {
292  return myVTypeDict.count(id) > 0 || myVTypeDistDict.count(id) > 0;
293 }
294 
295 
296 bool
297 MSVehicleControl::hasVTypeDistribution(const std::string& id) const {
298  return myVTypeDistDict.count(id) > 0;
299 }
300 
301 
303 MSVehicleControl::getVType(const std::string& id, std::mt19937* rng) {
304  VTypeDictType::iterator it = myVTypeDict.find(id);
305  if (it == myVTypeDict.end()) {
306  VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
307  if (it2 == myVTypeDistDict.end()) {
308  return 0;
309  }
310  return it2->second->get(rng);
311  }
312  if (id == DEFAULT_VTYPE_ID) {
314  } else if (id == DEFAULT_PEDTYPE_ID) {
316  }
317  return it->second;
318 }
319 
320 
321 void
322 MSVehicleControl::insertVTypeIDs(std::vector<std::string>& into) const {
323  into.reserve(into.size() + myVTypeDict.size() + myVTypeDistDict.size());
324  for (VTypeDictType::const_iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
325  into.push_back((*i).first);
326  }
327  for (VTypeDistDictType::const_iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
328  into.push_back((*i).first);
329  }
330 }
331 
332 
333 void
334 MSVehicleControl::addWaiting(const MSEdge* const edge, SUMOVehicle* vehicle) {
335  if (myWaiting.find(edge) == myWaiting.end()) {
336  myWaiting[edge] = std::vector<SUMOVehicle*>();
337  }
338  myWaiting[edge].push_back(vehicle);
339 }
340 
341 
342 void
343 MSVehicleControl::removeWaiting(const MSEdge* const edge, SUMOVehicle* vehicle) {
344  if (myWaiting.find(edge) != myWaiting.end()) {
345  std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting[edge].begin(), myWaiting[edge].end(), vehicle);
346  if (it != myWaiting[edge].end()) {
347  myWaiting[edge].erase(it);
348  }
349  }
350 }
351 
352 
354 MSVehicleControl::getWaitingVehicle(const MSEdge* const edge, const std::set<std::string>& lines, const double position, const std::string ridingID) {
355  if (myWaiting.find(edge) != myWaiting.end()) {
356  // for every vehicle waiting vehicle at this edge
357  std::vector<SUMOVehicle*> waitingTooFarAway;
358  for (std::vector<SUMOVehicle*>::const_iterator it = myWaiting[edge].begin(); it != myWaiting[edge].end(); ++it) {
359  const std::string& line = (*it)->getParameter().line == "" ? (*it)->getParameter().id : (*it)->getParameter().line;
360  double vehiclePosition = (*it)->getPositionOnLane();
361  // if the line of the vehicle is contained in the set of given lines and the vehicle is stopped and is positioned
362  // in the interval [position - t, position + t] for a tolerance t=10
363  if (lines.count(line)) {
364  if ((position - 10 <= vehiclePosition) && (vehiclePosition <= position + 10)) {
365  return (*it);
366  } else if ((*it)->isStoppedTriggered() ||
367  (*it)->getParameter().departProcedure == DEPART_TRIGGERED) {
368  // maybe we are within the range of the stop
369  if ((*it)->isStoppedInRange(position)) {
370  return (*it);
371  } else {
372  waitingTooFarAway.push_back(*it);
373  }
374  }
375  }
376  }
377  for (std::vector<SUMOVehicle*>::iterator it = waitingTooFarAway.begin(); it != waitingTooFarAway.end(); ++it) {
378  WRITE_WARNING(ridingID + " at edge '" + edge->getID() + "' position " + toString(position) + " cannot use waiting vehicle '" + (*it)->getID() + "' at position " + toString((*it)->getPositionOnLane()) + " because it is too far away.");
379  }
380  }
381  return 0;
382 }
383 
384 
385 void
387  for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
388  WRITE_WARNING("Vehicle " + i->first + " aborted waiting for a person or a container that will never come.");
389  }
390 }
391 
392 
393 int
394 MSVehicleControl::getQuota(double frac) const {
395  frac = frac < 0 ? myScale : frac;
396  if (frac < 0 || frac == 1.) {
397  return 1;
398  }
399  // the vehicle in question has already been loaded, hence the '-1'
400  const int loaded = frac > 1. ? (int)(myLoadedVehNo / frac) : myLoadedVehNo - 1;
401  const int base = (int)frac;
402  const int resolution = 1000;
403  const int intFrac = (int)floor((frac - base) * resolution + 0.5);
404  // apply % twice to avoid integer overflow
405  if (((loaded % resolution) * intFrac) % resolution < intFrac) {
406  return base + 1;
407  }
408  return base;
409 }
410 
411 int
414 }
415 
416 
417 void
419  for (const SUMOVehicle* const veh : myPTVehicles) {
420  // add single vehicles with line attribute which are not part of a flow
421  router.addSchedule(veh->getParameter());
422  }
423 }
424 
425 
426 /****************************************************************************/
427 
The departure is person triggered.
The vehicle has departed (was inserted into the network)
Definition: MSNet.h:486
bool myDefaultPedTypeMayBeDeleted
Whether no pedestrian type was loaded.
bool checkVType(const std::string &id)
Checks whether the vehicle type (distribution) may be added.
int getTeleportCount() const
return the number of teleports (including collisions)
bool addVTypeDistribution(const std::string &id, RandomDistributor< MSVehicleType * > *vehTypeDistribution)
Adds a vehicle type distribution.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:260
void addWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Adds a vehicle to the list of waiting vehiclse to a given edge.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
int myTeleportsWrongLane
The number of teleports due to vehicles stuck on the wrong lane.
is a pedestrian
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
int myEndedVehNo
The number of removed vehicles.
static bool teleportOnCollision()
Definition: MSLane.h:1065
virtual const MSRoute & getRoute() const =0
Returns the current route.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:167
int myDiscarded
The number of vehicles which were discarded while loading.
vehicle is a not electrified rail
The departure is container triggered.
Structure representing possible vehicle parameter.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::map< const MSEdge *const, std::vector< SUMOVehicle * > > myWaiting
the lists of waiting vehicles to a given edge
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:64
MSVehicleControl()
Constructor.
weights: time range begin
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
T MAX2(T a, T b)
Definition: StdDefs.h:73
VehicleDictType myVehicleDict
Dictionary of vehicles.
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
VTypeDictType myVTypeDict
Dictionary of vehicle types.
int myTeleportsJam
The number of teleports due to jam.
void removeWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Removes a vehicle from the list of waiting vehicles to a given edge.
void insertVTypeIDs(std::vector< std::string > &into) const
Inserts ids of all known vehicle types and vehicle type distributions to the given vector...
bool myDefaultVTypeMayBeDeleted
Whether no vehicle type was loaded.
double myMaxSpeedFactor
The maximum speed factor for all vehicles in the network.
const std::string DEFAULT_VTYPE_ID
void setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime)
Sets the current state variables as loaded from the stream.
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
vehicle is a (possibly fast moving) electric rail
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
The car-following model and parameter.
Definition: MSVehicleType.h:72
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
double computeChosenSpeedDeviation(std::mt19937 *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
vehicle is a city rail
static std::mt19937 * getParsingRNG()
int getQuota(double frac=-1) const
Returns the number of instances of the current vehicle that shall be emitted considering that "frac" ...
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
const std::string & getID() const
Returns the id.
Definition: Named.h:65
A road/street connecting two junctions.
Definition: MSEdge.h:80
virtual SUMOVehicleClass getVClass() const =0
Returns the vehicle&#39;s access class.
#define STEPFLOOR(x)
Definition: SUMOTime.h:67
virtual const std::vector< MSDevice * > & getDevices() const =0
Returns this vehicle&#39;s devices.
void addSchedule(const SUMOVehicleParameter &pars, const std::vector< SUMOVehicleParameter::Stop > *addStops=0)
The vehicle arrived at his destination (is deleted)
Definition: MSNet.h:492
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
SUMOTime computeRandomDepartOffset() const
compute (optional) random offset to the departure time
Representation of a vehicle.
Definition: SUMOVehicle.h:66
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:211
void registerOneWaiting(const bool isPerson)
increases the count of vehicles waiting for a transport to allow recognition of person / container re...
void removeVType(const MSVehicleType *vehType)
double myTotalTravelTime
The aggregated time vehicles needed to aacomplish their route (in seconds)
SUMOTime depart
The vehicle&#39;s departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:64
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:127
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
int myLoadedVehNo
The number of build vehicles.
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:46
T MIN2(T a, T b)
Definition: StdDefs.h:67
SUMOVehicle * getWaitingVehicle(const MSEdge *const edge, const std::set< std::string > &lines, const double position, const std::string ridingID)
SUMOTime myMaxRandomDepartOffset
The maximum random offset to be added to vehicles departure times (non-negative)
void saveState(OutputDevice &out)
Saves the current state into the given stream.
bool hasVType(const std::string &id) const
Asks for existence of a vehicle type.
int myRunningVehNo
The number of vehicles within the network (build and inserted but not removed)
virtual double getChosenSpeedFactor() const =0
vehicle is a passenger car (a "normal" car)
std::string line
The vehicle&#39;s line (mainly for public transport)
is an arbitrary ship
void abortWaiting()
informes about all waiting vehicles (deletion in destructor)
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, std::mt19937 *rng=0)
Returns the named vehicle type or a sample from the named distribution.
int parametersSet
Information for the router which parameter were set.
The vehicle was built, but has not yet departed.
Definition: MSNet.h:484
bool addVType(MSVehicleType *vehType)
Adds a vehicle type.
double myTotalDepartureDelay
The aggregated time vehicles had to wait for departure (in seconds)
double departPos
(optional) The position the vehicle shall depart from
trigger: the time of the step
void addStops(const bool ignoreStopErrors)
Adds stops to the built vehicle.
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
Structure representing possible vehicle parameter.
VTypeDistDictType myVTypeDistDict
A distribution of vehicle types (probability->vehicle type)
virtual SUMOTime getDeparture() const =0
Returns this vehicle&#39;s real departure time.
int myCollisions
The number of collisions.
const std::string DEFAULT_PEDTYPE_ID
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
weights: time range end
virtual ~MSVehicleControl()
Destructor.
A storage for options typed value containers)
Definition: OptionsCont.h:98
void adaptIntermodalRouter(MSNet::MSIntermodalRouter &router) const
const std::string & getID() const
Returns the name of the vehicle type.
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to)
Informs all added listeners about a vehicle&#39;s state change.
Definition: MSNet.cpp:849
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
bool hasVTypeDistribution(const std::string &id) const
Asks for a vehicle type distribution.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
bool closeTag()
Closes the most recently opened tag.
long long int SUMOTime
Definition: TraCIDefs.h:51
void vehicleDeparted(const SUMOVehicle &v)
Informs this control about a vehicle&#39;s departure.
double myScale
The scaling factor (especially for inc-dua)
double myMinDeceleration
The minimum deceleration capability for all vehicles in the network.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
int myTeleportsYield
The number of teleports due to vehicles stuck on a minor road.
const int VTYPEPARS_VEHICLECLASS_SET
distribution of a vehicle type
static bool gUseMesoSim
Definition: MSGlobals.h:97
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
vehicles ignoring classes
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
std::vector< SUMOVehicle * > myPTVehicles
List of vehicles which belong to public transport.