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.
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.
SUMOTime computeRandomDepartOffset() const
compute (optional) random offset to the departure time
int myTeleportsWrongLane
The number of teleports due to vehicles stuck on the wrong lane.
is a pedestrian
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:127
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.
Represents a generic random distribution.
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.
std::map< const MSEdge *const, std::vector< SUMOVehicle * > > myWaiting
the lists of waiting vehicles to a given edge
bool hasVTypeDistribution(const std::string &id) const
Asks for a vehicle type distribution.
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:64
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
int getQuota(double frac=-1) const
Returns the number of instances of the current vehicle that shall be emitted considering that "frac" ...
MSVehicleControl()
Constructor.
weights: time range begin
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:167
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.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
bool myDefaultVTypeMayBeDeleted
Whether no vehicle type was loaded.
bool hasVType(const std::string &id) const
Asks for existence of a vehicle type.
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
vehicle is a city rail
static std::mt19937 * getParsingRNG()
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)
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
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
void adaptIntermodalRouter(MSNet::MSIntermodalRouter &router) const
Representation of a vehicle.
Definition: SUMOVehicle.h:66
void registerOneWaiting(const bool isPerson)
increases the count of vehicles waiting for a transport to allow recognition of person / container re...
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
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
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.
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:211
int myRunningVehNo
The number of vehicles within the network (build and inserted but not removed)
virtual double getChosenSpeedFactor() const =0
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
vehicle is a passenger car (a "normal" car)
void insertVTypeIDs(std::vector< std::string > &into) const
Inserts ids of all known vehicle types and vehicle type distributions to the given vector...
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
bool addVTypeDistribution(const std::string &id, RandomDistributor< MSVehicleType *> *vehTypeDistribution)
Adds a vehicle type distribution.
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
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.
double computeChosenSpeedDeviation(std::mt19937 *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
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
int getTeleportCount() const
return the number of teleports (including collisions)
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.