Eclipse SUMO - Simulation of Urban MObility
MSInsertionControl.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-2023 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/****************************************************************************/
22// Inserts vehicles into the network when their departure time is reached
23/****************************************************************************/
24#include <config.h>
25
26#include <iostream>
27#include <algorithm>
28#include <cassert>
29#include <iterator>
33#include "MSGlobals.h"
34#include "MSVehicle.h"
35#include "MSVehicleControl.h"
36#include "MSLane.h"
37#include "MSEdge.h"
38#include "MSNet.h"
39#include "MSRouteHandler.h"
40#include "MSInsertionControl.h"
41
42
43// ===========================================================================
44// member method definitions
45// ===========================================================================
47 SUMOTime maxDepartDelay,
48 bool eagerInsertionCheck,
49 int maxVehicleNumber,
50 SUMOTime randomDepartOffset) :
51 myVehicleControl(vc),
52 myMaxDepartDelay(maxDepartDelay),
53 myEagerInsertionCheck(eagerInsertionCheck),
54 myMaxVehicleNumber(maxVehicleNumber),
55 myPendingEmitsUpdateTime(SUMOTime_MIN),
56 myFlowRNG("flow") {
57 myMaxRandomDepartOffset = randomDepartOffset;
59}
60
61
63 for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end(); ++i) {
64 delete (i->pars);
65 }
66}
67
68
69void
71 myAllVeh.add(veh);
72}
73
74
75bool
77 const bool loadingFromState = index >= 0;
78 if (myFlowIDs.count(pars->id) > 0) {
79 return false;
80 } else {
81 Flow flow;
82 flow.pars = pars;
83 flow.index = loadingFromState ? index : 0;
84 flow.scale = initScale(pars->vtypeid);
85 if (!loadingFromState && pars->repetitionProbability < 0 && pars->repetitionOffset < 0) {
86 // init poisson flow (but only the timing)
87 flow.pars->incrementFlow(flow.scale, &myFlowRNG);
88 flow.pars->repetitionsDone--;
89 }
90 myFlows.push_back(flow);
91 myFlowIDs.insert(pars->id);
92 return true;
93 }
94}
95
96
97double
98MSInsertionControl::initScale(const std::string vtypeid) {
100 if (vc.hasVTypeDistribution(vtypeid)) {
101 double result = -1;
103 for (const MSVehicleType* t : dist->getVals()) {
104 if (result == -1) {
105 result = t->getParameter().scale;
106 } else if (result != t->getParameter().scale) {
107 // unequal scales in distribution
108 return -1;
109 }
110 }
111 return result;
112 } else {
113 // rng is not used since vtypeid is not a distribution
114 return vc.getVType(vtypeid, nullptr, true)->getParameter().scale;
115 }
116}
117
118
119int
121 // check whether any vehicles shall be emitted within this time step
122 const bool havePreChecked = MSRoutingEngine::isEnabled();
123 if (myPendingEmits.empty() || (havePreChecked && myEmitCandidates.empty())) {
124 return 0;
125 }
126 int numEmitted = 0;
127 // we use buffering for the refused emits to save time
128 // for this, we have two lists; one contains previously refused emits, the second
129 // will be used to append those vehicles that will not be able to depart in this
130 // time step
132
133 // go through the list of previously refused vehicles, first
134 MSVehicleContainer::VehicleVector::const_iterator veh;
135 for (veh = myPendingEmits.begin(); veh != myPendingEmits.end(); veh++) {
136 if (havePreChecked && (myEmitCandidates.count(*veh) == 0)) {
137 refusedEmits.push_back(*veh);
138 } else {
139 numEmitted += tryInsert(time, *veh, refusedEmits);
140 }
141 }
142 myEmitCandidates.clear();
143 myPendingEmits = refusedEmits;
144 return numEmitted;
145}
146
147
148int
150 MSVehicleContainer::VehicleVector& refusedEmits) {
151 assert(veh->getParameter().depart <= time);
152 const MSEdge& edge = *veh->getEdge();
153 if (veh->isOnRoad()) {
154 return 1;
155 }
156 if ((myMaxVehicleNumber < 0 || (int)MSNet::getInstance()->getVehicleControl().getRunningVehicleNo() < myMaxVehicleNumber)
157 && edge.insertVehicle(*veh, time, false, myEagerInsertionCheck)) {
158 // Successful insertion
159 return 1;
160 }
161 if (myMaxDepartDelay >= 0 && time - veh->getParameter().depart > myMaxDepartDelay) {
162 // remove vehicles waiting too long for departure
164 } else if (edge.isVaporizing()) {
165 // remove vehicles if the edge shall be empty
167 } else if (myAbortedEmits.count(veh) > 0) {
168 // remove vehicles which shall not be inserted for some reason
169 myAbortedEmits.erase(veh);
171 } else if ((veh->getRouteValidity(false) & (
175 } else {
176 // let the vehicle wait one step, we'll retry then
177 refusedEmits.push_back(veh);
178 }
180 return 0;
181}
182
183
184void
186 while (myAllVeh.anyWaitingBefore(time)) {
188 copy(top.begin(), top.end(), back_inserter(myPendingEmits));
189 myAllVeh.pop();
190 }
191 if (preCheck) {
192 MSVehicleContainer::VehicleVector::const_iterator veh;
193 for (veh = myPendingEmits.begin(); veh != myPendingEmits.end(); veh++) {
194 SUMOVehicle* const v = *veh;
195 const MSEdge* const edge = v->getEdge();
196 if (edge->insertVehicle(*v, time, true, myEagerInsertionCheck)) {
197 myEmitCandidates.insert(v);
198 } else {
199 MSDevice_Routing* dev = static_cast<MSDevice_Routing*>(v->getDevice(typeid(MSDevice_Routing)));
200 if (dev != nullptr) {
201 dev->skipRouting(time);
202 }
203 }
204 }
205 }
206}
207
208
209void
212 // for equidistant vehicles, up-scaling is done via repetitionOffset
213 for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end();) {
214 MSVehicleType* vtype = nullptr;
215 SUMOVehicleParameter* pars = i->pars;
216 double typeScale = i->scale;
217 if (typeScale < 0) {
218 // must sample from distribution to determine scale value
219 vtype = vehControl.getVType(pars->vtypeid, MSRouteHandler::getParsingRNG());
220 typeScale = vtype->getParameter().scale;
221 }
222 double scale = vehControl.getScale() * typeScale;
223 bool tryEmitByProb = pars->repetitionProbability > 0;
224 while (scale > 0 && ((pars->repetitionProbability < 0
225 && pars->repetitionsDone < pars->repetitionNumber * scale
226 && pars->depart + pars->repetitionTotalOffset <= time)
227 || (tryEmitByProb
228 && pars->depart <= time
229 && pars->repetitionEnd > time
230 // only call rand if all other conditions are met
232 )) {
233 tryEmitByProb = false; // only emit one per step
234 SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
235 newPars->id = pars->id + "." + toString(i->index);
236 newPars->depart = pars->repetitionProbability > 0 ? time : pars->depart + pars->repetitionTotalOffset + computeRandomDepartOffset();
237 pars->incrementFlow(scale, &myFlowRNG);
238 //std::cout << SIMTIME << " flow=" << pars->id << " done=" << pars->repetitionsDone << " totalOffset=" << STEPS2TIME(pars->repetitionTotalOffset) << "\n";
239 // try to build the vehicle
240 if (vehControl.getVehicle(newPars->id) == nullptr) {
241 ConstMSRoutePtr const route = MSRoute::dictionary(pars->routeid);
242 if (vtype == nullptr) {
243 vtype = vehControl.getVType(pars->vtypeid, MSRouteHandler::getParsingRNG());
244 }
245 SUMOVehicle* const vehicle = vehControl.buildVehicle(newPars, route, vtype, !MSGlobals::gCheckRoutes);
246 // for equidistant vehicles, all scaling is done via repetitionOffset (to avoid artefacts, #11441)
247 // for probabilistic vehicles, we use the quota
248 int quota = pars->repetitionProbability < 0 ? 1 : vehControl.getQuota(scale);
249 if (quota > 0) {
250 vehControl.addVehicle(newPars->id, vehicle);
252 add(vehicle);
253 }
254 i->index++;
255 while (--quota > 0) {
256 SUMOVehicleParameter* const quotaPars = new SUMOVehicleParameter(*pars);
257 quotaPars->id = pars->id + "." + toString(i->index);
258 quotaPars->depart = pars->repetitionProbability > 0 ? time :
260 SUMOVehicle* const quotaVehicle = vehControl.buildVehicle(quotaPars, route, vtype, !MSGlobals::gCheckRoutes);
261 vehControl.addVehicle(quotaPars->id, quotaVehicle);
263 add(quotaVehicle);
264 }
265 pars->repetitionsDone++;
266 i->index++;
267 }
268 } else {
269 vehControl.deleteVehicle(vehicle, true);
270 }
271 } else {
274 break;
275 }
276 throw ProcessError(TLF("Another vehicle with the id '%' exists.", newPars->id));
277 }
278 vtype = nullptr;
279 }
280 if (time >= pars->repetitionEnd ||
281 (pars->repetitionNumber != std::numeric_limits<int>::max()
282 && pars->repetitionsDone >= (int)(pars->repetitionNumber * scale + 0.5))) {
283 i = myFlows.erase(i);
285 delete pars;
286 } else {
287 ++i;
288 }
289 }
291}
292
293
294int
296 return (int)myPendingEmits.size();
297}
298
299
300int
302 return (int)myFlows.size();
303}
304
305
306void
308 myAbortedEmits.insert(veh);
309}
310
311void
313 myAbortedEmits.erase(veh);
314}
315
316
317void
319 myPendingEmits.erase(std::remove(myPendingEmits.begin(), myPendingEmits.end(), veh), myPendingEmits.end());
320 myAllVeh.remove(veh);
321}
322
323
324void
326 //clear out the refused vehicle list, deleting the vehicles entirely
327 MSVehicleContainer::VehicleVector::iterator veh;
328 for (veh = myPendingEmits.begin(); veh != myPendingEmits.end();) {
329 if ((*veh)->getRoute().getID() == route || route == "") {
331 veh = myPendingEmits.erase(veh);
332 } else {
333 ++veh;
334 }
335 }
336}
337
338
339int
341 if (MSNet::getInstance()->getCurrentTimeStep() != myPendingEmitsUpdateTime) {
342 // updated pending emits (only once per time step)
343 myPendingEmitsForLane.clear();
344 for (const SUMOVehicle* const veh : myPendingEmits) {
345 const MSLane* const vlane = veh->getLane();
346 if (vlane != nullptr) {
347 myPendingEmitsForLane[vlane]++;
348 } else {
349 // no (tentative) departLane was set, increase count for all
350 // lanes of the depart edge
351 for (const MSLane* const l : veh->getEdge()->getLanes()) {
353 }
354 }
355 }
357 }
358 return myPendingEmitsForLane[lane];
359}
360
361
362void
364 // fill the public transport router with pre-parsed public transport lines
365 for (const Flow& f : myFlows) {
366 if (f.pars->line != "") {
367 ConstMSRoutePtr const route = MSRoute::dictionary(f.pars->routeid);
368 router.getNetwork()->addSchedule(*f.pars, route == nullptr ? nullptr : &route->getStops());
369 }
370 }
371}
372
373
374void
376 // save flow states
377 for (const Flow& flow : myFlows) {
378 flow.pars->write(out, OptionsCont::getOptions(), SUMO_TAG_FLOWSTATE,
379 flow.pars->vtypeid == DEFAULT_VTYPE_ID ? "" : flow.pars->vtypeid);
380 if (flow.pars->repetitionEnd == SUMOTime_MAX) {
381 out.writeAttr(SUMO_ATTR_NUMBER, flow.pars->repetitionNumber);
382 }
383 if (flow.pars->repetitionProbability > 0) {
384 out.writeAttr(SUMO_ATTR_PROB, flow.pars->repetitionProbability);
385 } else {
386 out.writeAttr(SUMO_ATTR_PERIOD, STEPS2TIME(flow.pars->repetitionOffset));
387 out.writeAttr(SUMO_ATTR_NEXT, STEPS2TIME(flow.pars->repetitionTotalOffset));
388 }
389 if (flow.pars->repetitionEnd != SUMOTime_MAX) {
390 out.writeAttr(SUMO_ATTR_END, STEPS2TIME(flow.pars->repetitionEnd));
391 };
392 out.writeAttr(SUMO_ATTR_ROUTE, flow.pars->routeid);
393 out.writeAttr(SUMO_ATTR_DONE, flow.pars->repetitionsDone);
394 out.writeAttr(SUMO_ATTR_INDEX, flow.index);
395 if (flow.pars->wasSet(VEHPARS_FORCE_REROUTE)) {
396 out.writeAttr(SUMO_ATTR_REROUTE, true);
397 }
398 out.closeTag();
399 }
400}
401
402void
404 for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end(); ++i) {
405 delete (i->pars);
406 }
407 myFlows.clear();
408 myFlowIDs.clear();
410 myPendingEmits.clear();
411 myEmitCandidates.clear();
412 myAbortedEmits.clear();
413 // myPendingEmitsForLane must not be cleared since it updates itself on the next call
414}
415
416
419 if (myMaxRandomDepartOffset > 0) {
420 // round to the closest usable simulation step
422 }
423 return 0;
424}
425
426
427/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define TLF(string,...)
Definition: MsgHandler.h:285
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition: Route.h:32
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
#define SUMOTime_MAX
Definition: SUMOTime.h:33
#define SUMOTime_MIN
Definition: SUMOTime.h:34
#define TS
Definition: SUMOTime.h:41
const std::string DEFAULT_VTYPE_ID
const int VEHPARS_FORCE_REROUTE
@ BEGIN
The departure is at simulation start.
@ GIVEN
The time is given.
@ SUMO_TAG_FLOWSTATE
a flow state definition (used when saving and loading simulatino state)
@ SUMO_ATTR_DONE
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_NEXT
succesor phase index
@ SUMO_ATTR_REROUTE
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_PROB
@ SUMO_ATTR_ROUTE
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void addSchedule(const SUMOVehicleParameter &pars, const std::vector< SUMOVehicleParameter::Stop > *addStops=nullptr)
Network * getNetwork() const
@ ROUTE_START_INVALID_LANE
Definition: MSBaseVehicle.h:78
@ ROUTE_START_INVALID_PERMISSIONS
Definition: MSBaseVehicle.h:76
A device that performs vehicle rerouting based on current edge speeds.
void skipRouting(const SUMOTime currentTime)
Labels the current time step as "unroutable".
A road/street connecting two junctions.
Definition: MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:431
bool insertVehicle(SUMOVehicle &v, SUMOTime time, const bool checkOnly=false, const bool forceCheck=false) const
Tries to insert the given vehicle into the network.
Definition: MSEdge.cpp:675
void setLastFailedInsertionTime(SUMOTime time) const
Sets the last time a vehicle could not be inserted.
Definition: MSEdge.h:580
static bool gCheckRoutes
Definition: MSGlobals.h:88
static bool gStateLoaded
Information whether a state has been loaded.
Definition: MSGlobals.h:100
std::vector< Flow > myFlows
Container for periodical vehicle parameters.
int getWaitingVehicleNo() const
Returns the number of waiting vehicles.
void clearPendingVehicles(const std::string &route)
clears out all pending vehicles from a route, "" for all routes
std::map< const MSLane *, int > myPendingEmitsForLane
the number of pending emits for each edge in the current time step
int tryInsert(SUMOTime time, SUMOVehicle *veh, MSVehicleContainer::VehicleVector &refusedEmits)
Tries to emit the vehicle.
bool myEagerInsertionCheck
Whether an edge on which a vehicle could not depart should be ignored in the same step.
int emitVehicles(SUMOTime time)
Emits vehicles that want to depart at the given time.
int getPendingEmits(const MSLane *lane)
return the number of pending emits for the given lane
bool addFlow(SUMOVehicleParameter *const pars, int index=-1)
Adds parameter for a vehicle flow for departure.
SUMOTime myPendingEmitsUpdateTime
Last time at which pending emits for each edge where counted.
void retractDescheduleDeparture(const SUMOVehicle *veh)
reverts a previous call to descheduleDeparture (only needed for departPos="random_free")
std::set< SUMOVehicle * > myEmitCandidates
Buffer for vehicles that may be inserted in the current step.
void alreadyDeparted(SUMOVehicle *veh)
stops trying to emit the given vehicle (because it already departed)
SUMOTime myMaxRandomDepartOffset
The maximum random offset to be added to vehicles departure times (non-negative)
MSVehicleContainer::VehicleVector myPendingEmits
Buffers for vehicles that could not be inserted.
MSInsertionControl(MSVehicleControl &vc, SUMOTime maxDepartDelay, bool checkEdgesOnce, int maxVehicleNumber, SUMOTime randomDepartOffset)
Constructor.
MSVehicleControl & myVehicleControl
The assigned vehicle control (needed for vehicle re-insertion and deletion)
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
void determineCandidates(SUMOTime time)
Checks for all vehicles whether they can be emitted.
void checkCandidates(SUMOTime time, const bool preCheck)
Adds all vehicles that should have been emitted earlier to the refuse container.
int getPendingFlowCount() const
Returns the number of flows that are still active.
std::set< const SUMOVehicle * > myAbortedEmits
Set of vehicles which shall not be inserted anymore.
std::set< std::string > myFlowIDs
Cache for periodical vehicle ids for quicker checking.
void adaptIntermodalRouter(MSNet::MSIntermodalRouter &router) const
void clearState()
Remove all vehicles before quick-loading state.
int myMaxVehicleNumber
Storage for maximum vehicle number.
void saveState(OutputDevice &out)
Saves the current state into the given stream.
SUMOTime myMaxDepartDelay
The maximum waiting time; vehicles waiting longer are deleted (-1: no deletion)
void descheduleDeparture(const SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
MSVehicleContainer myAllVeh
All loaded vehicles sorted by their departure time.
~MSInsertionControl()
Destructor.
SUMOTime computeRandomDepartOffset() const
compute (optional) random offset to the departure time
SumoRNG myFlowRNG
A random number generator for probabilistic flows.
static double initScale(const std::string vtypeid)
init scale value of flow
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:745
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:378
static SumoRNG * getParsingRNG()
get parsing RNG
static bool dictionary(const std::string &id, ConstMSRoutePtr route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:109
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:187
static bool isEnabled()
returns whether any routing actions take place
bool anyWaitingBefore(SUMOTime time) const
Returns the information whether any vehicles want to depart before the given time.
void remove(SUMOVehicle *veh)
Removes a single vehicle.
void add(SUMOVehicle *veh)
Adds a single vehicle.
void pop()
Removes the uppermost vehicle vector.
std::vector< SUMOVehicle * > VehicleVector
definition of a list of vehicles which have the same departure time
void clearState()
Remove all vehicles before quick-loading state.
const VehicleVector & top()
Returns the uppermost vehicle vector.
The class responsible for building and deletion of vehicles.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, ConstMSRoutePtr route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true, bool addRouteStops=true)
Builds a vehicle, increases the number of built vehicles.
double getScale() const
sets the demand scaling factor
bool hasVTypeDistribution(const std::string &id) const
Asks for a vehicle type distribution.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
int getQuota(double frac=-1, int loaded=-1) const
Returns the number of instances of the current vehicle that shall be emitted considering that "frac" ...
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
const RandomDistributor< MSVehicleType * > * getVTypeDistribution(const std::string &typeDistID) const
return the vehicle type distribution with the given id
The car-following model and parameter.
Definition: MSVehicleType.h:63
const SUMOVTypeParameter & getParameter() const
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:59
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
static void initRandGlobal(SumoRNG *which=nullptr)
Reads the given random number options and initialises the random number generator in accordance.
Definition: RandHelper.cpp:87
const std::vector< T > & getVals() const
Returns the members of the distribution.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
double scale
individual scaling factor (-1 for undefined)
Representation of a vehicle.
Definition: SUMOVehicle.h:62
virtual int getRouteValidity(bool update=true, bool silent=false, std::string *msgReturn=nullptr)=0
computes validity attributes for the current route
virtual bool isOnRoad() const =0
Returns the information whether the vehicle is on a road (is simulated)
virtual MSVehicleDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.
Structure representing possible vehicle parameter.
double repetitionProbability
The probability for emitting a vehicle per second.
void incrementFlow(double scale, SumoRNG *rng=nullptr)
increment flow
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
int repetitionsDone
The number of times the vehicle was already inserted.
SUMOTime repetitionTotalOffset
The offset between depart and the time for the next vehicle insertions.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
Definition of vehicle flow with the current index for vehicle numbering.
int index
the running index
SUMOVehicleParameter * pars
The parameters.
double scale
the type scaling of this flow. Negative value indicates inhomogenous type distribution