SUMO - Simulation of Urban MObility
MSDevice_Routing.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // A device that performs vehicle rerouting based on current edge speeds
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
14 // Copyright (C) 2007-2015 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include "MSDevice_Routing.h"
35 #include <microsim/MSNet.h>
36 #include <microsim/MSLane.h>
37 #include <microsim/MSEdge.h>
38 #include <microsim/MSEdgeControl.h>
39 #include <microsim/MSGlobals.h>
45 #include <utils/vehicle/CHRouter.h>
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 // ===========================================================================
54 // static member variables
55 // ===========================================================================
56 std::vector<SUMOReal> MSDevice_Routing::myEdgeEfforts;
62 std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*> MSDevice_Routing::myCachedRoutes;
65 #ifdef HAVE_FOX
66 FXWorkerThread::Pool MSDevice_Routing::myThreadPool;
67 #endif
68 
69 
70 // ===========================================================================
71 // method definitions
72 // ===========================================================================
73 // ---------------------------------------------------------------------------
74 // static initialisation methods
75 // ---------------------------------------------------------------------------
76 void
78  insertDefaultAssignmentOptions("rerouting", "Routing", oc);
79 
80  oc.doRegister("device.rerouting.period", new Option_String("0", "TIME"));
81  oc.addSynonyme("device.rerouting.period", "device.routing.period", true);
82  oc.addDescription("device.rerouting.period", "Routing", "The period with which the vehicle shall be rerouted");
83 
84  oc.doRegister("device.rerouting.pre-period", new Option_String("1", "TIME"));
85  oc.addSynonyme("device.rerouting.pre-period", "device.routing.pre-period", true);
86  oc.addDescription("device.rerouting.pre-period", "Routing", "The rerouting period before depart");
87 
88  oc.doRegister("device.rerouting.adaptation-weight", new Option_Float(.5));
89  oc.addSynonyme("device.rerouting.adaptation-weight", "device.routing.adaptation-weight", true);
90  oc.addDescription("device.rerouting.adaptation-weight", "Routing", "The weight of prior edge weights");
91 
92  oc.doRegister("device.rerouting.adaptation-interval", new Option_String("1", "TIME"));
93  oc.addSynonyme("device.rerouting.adaptation-interval", "device.routing.adaptation-interval", true);
94  oc.addDescription("device.rerouting.adaptation-interval", "Routing", "The interval for updating the edge weights");
95 
96  oc.doRegister("device.rerouting.with-taz", new Option_Bool(false));
97  oc.addSynonyme("device.rerouting.with-taz", "device.routing.with-taz", true);
98  oc.addSynonyme("device.rerouting.with-taz", "with-taz");
99  oc.addDescription("device.rerouting.with-taz", "Routing", "Use zones (districts) as routing start- and endpoints");
100 
101  oc.doRegister("device.rerouting.init-with-loaded-weights", new Option_Bool(false));
102  oc.addDescription("device.rerouting.init-with-loaded-weights", "Routing", "Use given weight files for initializing edge weights");
103 
104  oc.doRegister("device.rerouting.shortest-path-file", new Option_FileName());
105  oc.addDescription("device.rerouting.shortest-path-file", "Routing", "Initialize lookup table for astar from the given distance matrix");
106 
107  oc.doRegister("device.rerouting.threads", new Option_Integer(0));
108  oc.addDescription("device.rerouting.threads", "Routing", "The number of parallel execution threads used for rerouting");
109 
110  oc.doRegister("device.rerouting.output", new Option_FileName());
111  oc.addDescription("device.rerouting.output", "Routing", "Save adapting weights to FILE");
112 
114  myEdgeEfforts.clear();
116  myLastAdaptation = -1;
117 }
118 
119 
120 void
121 MSDevice_Routing::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into) {
122  bool needRerouting = v.getParameter().wasSet(VEHPARS_FORCE_REROUTE);
124  if (!needRerouting && oc.getFloat("device.rerouting.probability") == 0 && !oc.isSet("device.rerouting.explicit")) {
125  // no route computation is modelled
126  return;
127  }
128  needRerouting |= equippedByDefaultAssignmentOptions(oc, "rerouting", v);
129  if (needRerouting) {
130  // route computation is enabled
131  myWithTaz = oc.getBool("device.rerouting.with-taz");
132  const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
133  const SUMOTime prePeriod = string2time(oc.getString("device.rerouting.pre-period"));
134  // initialise edge efforts if not done before
135  if (myEdgeEfforts.size() == 0) {
137  const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
138  const SUMOReal currentSecond = SIMTIME;
139  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
140  while ((*i)->getNumericalID() >= (int)myEdgeEfforts.size()) {
141  myEdgeEfforts.push_back(0);
142  }
143  if (useLoaded) {
144  myEdgeEfforts[(*i)->getNumericalID()] = MSNet::getTravelTime(*i, 0, currentSecond);
145  } else {
146  myEdgeEfforts[(*i)->getNumericalID()] = (*i)->getCurrentTravelTime();
147  }
148  }
150  myRandomizeWeightsFactor = oc.getFloat("weights.random-factor");
151  if (myRandomizeWeightsFactor < 1) {
152  WRITE_ERROR("weights.random-factor cannot be less than 1");
153  }
154 #ifndef HAVE_FOX
155  if (oc.getInt("device.rerouting.threads") > 1) {
156  WRITE_ERROR("Parallel routing is only possible when compiled with Fox.");
157  }
158 #endif
159  }
160  // make the weights be updated
161  if (myAdaptationInterval == -1) {
162  myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
163  if (myAdaptationInterval < 0) {
164  WRITE_ERROR("Negative value for device.rerouting.adaptation-interval!");
165  }
166  myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
167  if (myAdaptationWeight < 0. || myAdaptationWeight > 1.) {
168  WRITE_ERROR("The value for device.rerouting.adaptation-weight must be between 0 and 1!");
169  }
170  if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
174  } else if (period > 0) {
175  WRITE_WARNING("Rerouting is useless if the edge weights do not get updated!");
176  }
177  OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
178  }
179  // build the device
180  into.push_back(new MSDevice_Routing(v, "routing_" + v.getID(), period, prePeriod));
181  }
182 }
183 
184 
185 // ---------------------------------------------------------------------------
186 // MSDevice_Routing-methods
187 // ---------------------------------------------------------------------------
188 MSDevice_Routing::MSDevice_Routing(SUMOVehicle& holder, const std::string& id,
189  SUMOTime period, SUMOTime preInsertionPeriod)
190  : MSDevice(holder, id), myPeriod(period), myPreInsertionPeriod(preInsertionPeriod), myLastRouting(-1), mySkipRouting(-1), myRerouteCommand(0) {
191  // we do always a pre insertion reroute to fill the best lanes of the vehicle with somehow meaningful values (especially for deaprtLane="best")
193  // if we don't update the edge weights, we might as well reroute now and hopefully use our threads better
194  const SUMOTime execTime = myEdgeWeightSettingCommand == 0 ? 0 : holder.getParameter().depart;
196  myRerouteCommand, execTime,
198 }
199 
200 
202  // make the rerouting command invalid if there is one
203  if (myRerouteCommand != 0 && MSNet::getInstance()->getInsertionEvents() != 0) {
205  }
206 }
207 
208 
209 bool
212  // clean up pre depart rerouting
213  if (myPreInsertionPeriod > 0) {
215  }
216  myRerouteCommand = 0;
217  // build repetition trigger if routing shall be done more often
218  if (myPeriod > 0) {
221  myRerouteCommand, myPeriod + MSNet::getInstance()->getCurrentTimeStep(),
223  }
224  }
225  return false;
226 }
227 
228 
229 SUMOTime
231  if (mySkipRouting == currentTime) {
232  return DELTA_T;
233  }
234  const MSEdge* source = *myHolder.getRoute().begin();
235  const MSEdge* dest = myHolder.getRoute().getLastEdge();
237  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
238  if (myCachedRoutes.find(key) != myCachedRoutes.end()) {
240  return myPreInsertionPeriod;
241  }
242  }
243  reroute(currentTime, true);
244  return myPreInsertionPeriod;
245 }
246 
247 
248 SUMOTime
250  reroute(currentTime);
251  return myPeriod;
252 }
253 
254 
255 SUMOReal
256 MSDevice_Routing::getEffort(const MSEdge* const e, const SUMOVehicle* const v, SUMOReal) {
257  const int id = e->getNumericalID();
258  if (id < (int)myEdgeEfforts.size()) {
259  SUMOReal effort = MAX2(myEdgeEfforts[id], e->getMinimumTravelTime(v));
260  if (myRandomizeWeightsFactor != 1) {
262  }
263  return effort;
264  }
265  return 0;
266 }
267 
268 
269 SUMOTime
271  if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
272  return myAdaptationInterval;
273  }
274  std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*>::iterator it = myCachedRoutes.begin();
275  for (; it != myCachedRoutes.end(); ++it) {
276  it->second->release();
277  }
278  myCachedRoutes.clear();
279  const SUMOReal newWeightFactor = (SUMOReal)(1. - myAdaptationWeight);
281  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
282  const int id = (*i)->getNumericalID();
283  const SUMOReal currTT = (*i)->getCurrentTravelTime();
284  if (currTT != myEdgeEfforts[id]) {
285  myEdgeEfforts[id] = myEdgeEfforts[id] * myAdaptationWeight + currTT * newWeightFactor;
286  }
287  }
288  myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
289  if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
290  OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
292  dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
293  dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
295  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
296  const int id = (*i)->getNumericalID();
297  dev.openTag(SUMO_TAG_EDGE);
298  dev.writeAttr(SUMO_ATTR_ID, (*i)->getID());
299  dev.writeAttr("traveltime", myEdgeEfforts[id]);
300  dev.closeTag();
301  }
302  dev.closeTag();
303  }
304  return myAdaptationInterval;
305 }
306 
307 
308 void
309 MSDevice_Routing::reroute(const SUMOTime currentTime, const bool onInit) {
310  //check whether the weights did change since the last reroute
312  return;
313  }
314  myLastRouting = currentTime;
315 #ifdef HAVE_FOX
316  const bool needThread = (myRouter == 0 && myThreadPool.isFull());
317 #else
318  const bool needThread = true;
319 #endif
320  if (needThread && myRouter == 0) {
322  const std::string routingAlgorithm = oc.getString("routing-algorithm");
323  const bool mayHaveRestrictions = MSNet::getInstance()->hasPermissions() || oc.getInt("remote-port") != 0;
324  if (routingAlgorithm == "dijkstra") {
325  if (mayHaveRestrictions) {
328  } else {
331  }
332  } else if (routingAlgorithm == "astar") {
333  if (mayHaveRestrictions) {
335  const AStar::LookupTable* lookup = 0;
336  if (oc.isSet("device.rerouting.shortest-path-file")) {
337  lookup = AStar::createLookupTable(oc.getString("device.rerouting.shortest-path-file"), (int)MSEdge::numericalDictSize());
338  }
339  myRouter = new AStar(MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, lookup);
340  } else {
342  const AStar::LookupTable* lookup = 0;
343  if (oc.isSet("device.rerouting.shortest-path-file")) {
344  lookup = AStar::createLookupTable(oc.getString("device.rerouting.shortest-path-file"), (int)MSEdge::numericalDictSize());
345  }
346  myRouter = new AStar(MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, lookup);
347  }
348  } else if (routingAlgorithm == "CH") {
350  if (mayHaveRestrictions) {
353  } else {
355  MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, myHolder.getVClass(), weightPeriod, false);
356  }
357  } else if (routingAlgorithm == "CHWrapper") {
358  const SUMOTime begin = string2time(oc.getString("begin"));
361  MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, begin, weightPeriod);
362  } else {
363  throw ProcessError("Unknown routing algorithm '" + routingAlgorithm + "'!");
364  }
365  }
366 #ifdef HAVE_FOX
367  if (needThread) {
368  const int numThreads = OptionsCont::getOptions().getInt("device.rerouting.threads");
369  if (myThreadPool.size() < numThreads) {
370  new WorkerThread(myThreadPool, myRouter);
371  }
372  if (myThreadPool.size() < numThreads) {
373  myRouter = 0;
374  }
375  }
376  if (myThreadPool.size() > 0) {
377  myThreadPool.add(new RoutingTask(myHolder, currentTime, onInit));
378  return;
379  }
380 #endif
381  myHolder.reroute(currentTime, *myRouter, onInit, myWithTaz);
382 }
383 
384 
385 void
387 #ifdef HAVE_FOX
388  if (myThreadPool.size() > 0) {
389  // we cannot wait for the static destructor to do the cleanup
390  // because the output devices are gone by then
391  myThreadPool.clear();
392  // router deletion is done in thread destructor
393  myRouter = 0;
394  return;
395  }
396 #endif
397  delete myRouter;
398  myRouter = 0;
399 }
400 
401 
402 #ifdef HAVE_FOX
403 void
404 MSDevice_Routing::waitForAll() {
405  if (myThreadPool.size() > 0) {
406  myThreadPool.waitAll();
407  }
408 }
409 
410 
411 // ---------------------------------------------------------------------------
412 // MSDevice_Routing::RoutingTask-methods
413 // ---------------------------------------------------------------------------
414 void
415 MSDevice_Routing::RoutingTask::run(FXWorkerThread* context) {
416  myVehicle.reroute(myTime, static_cast<WorkerThread*>(context)->getRouter(), myOnInit, myWithTaz);
417  const MSEdge* source = *myVehicle.getRoute().begin();
418  const MSEdge* dest = myVehicle.getRoute().getLastEdge();
420  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
421  lock();
423  MSDevice_Routing::myCachedRoutes[key] = &myVehicle.getRoute();
424  myVehicle.getRoute().addReference();
425  }
426  unlock();
427  }
428 }
429 #endif
430 
431 
432 /****************************************************************************/
433 
Computes the shortest path through a contracted network.
Definition: CHRouter.h:74
SUMOTime myPeriod
The period with which a vehicle shall be rerouted.
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
Definition: OptionsCont.cpp:86
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
long long int SUMOTime
Definition: SUMOTime.h:43
const int VEHPARS_FORCE_REROUTE
SUMOTime mySkipRouting
The time for which routing may be skipped because we cannot be inserted.
static size_t numericalDictSize()
Returns the number of edges with a numerical id.
Definition: MSEdge.cpp:619
virtual const MSRoute & getRoute() const =0
Returns the current route.
static SUMOTime adaptEdgeEfforts(SUMOTime currentTime)
Adapt edge efforts by the current edge states.
SUMOVehicle & myHolder
The vehicle that stores the device.
Definition: MSDevice.h:153
static SUMOTime myAdaptationInterval
At which time interval the edge weights get updated.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:93
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
SUMOTime myLastRouting
The last time a routing took place.
MSDevice_Routing(SUMOVehicle &holder, const std::string &id, SUMOTime period, SUMOTime preInsertionPeriod)
Constructor.
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
Computes the shortest path through a network using the A* algorithm.
Definition: AStarRouter.h:71
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into)
Build devices for the given vehicle, if needed.
SUMOTime myPreInsertionPeriod
The period with which a vehicle shall be rerouted before insertion.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:162
T MAX2(T a, T b)
Definition: StdDefs.h:79
SUMOTime wrappedRerouteCommandExecute(SUMOTime currentTime)
Performs rerouting after a period.
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
static Command * myEdgeWeightSettingCommand
The weights adaptation/overwriting command.
Base (microsim) event class.
Definition: Command.h:61
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
Computes the shortest path through a network using the Dijkstra algorithm.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
#define SIMTIME
Definition: SUMOTime.h:96
void addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
A road/street connecting two junctions.
Definition: MSEdge.h:81
virtual SUMOVehicleClass getVClass() const =0
Returns the vehicle&#39;s access class.
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_Routing-options.
static bool myWithTaz
whether taz shall be used at initial rerouting
void reroute(const SUMOTime currentTime, const bool onInit=false)
initiate the rerouting, create router / thread pool on first use
#define max(a, b)
Definition: polyfonts.c:65
The edge is a district edge.
Definition: MSEdge.h:100
Representation of a vehicle.
Definition: SUMOVehicle.h:65
bool wasSet(int what) const
Returns whether the given parameter was set.
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:389
virtual void reroute(SUMOTime t, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false)=0
Performs a rerouting using the given router.
static SUMOReal getTravelTime(const MSEdge *const e, const SUMOVehicle *const v, SUMOReal t)
Returns the travel time to pass an edge.
Definition: MSNet.cpp:144
static std::map< std::pair< const MSEdge *, const MSEdge * >, const MSRoute * > myCachedRoutes
The container of pre-calculated routes.
SUMOTime depart
The vehicle&#39;s departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
A wrapper for a Command function.
Definition: StaticCommand.h:49
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:48
WrappingCommand< MSDevice_Routing > * myRerouteCommand
The (optional) command responsible for rerouting.
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc)
Adds common command options that allow to assign devices to vehicles.
Definition: MSDevice.cpp:88
virtual SUMOTime addEvent(Command *operation, SUMOTime execTimeStep, AdaptType type)
Adds an Event.
static SUMOReal getEffort(const MSEdge *const e, const SUMOVehicle *const v, SUMOReal t)
Returns the effort to pass an edge.
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
Definition: MSNet.h:399
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
Abstract in-vehicle device.
Definition: MSDevice.h:69
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, SUMOVehicle &v)
Determines whether a vehicle should get a certain device.
Definition: MSDevice.cpp:102
A pool of worker threads which distributes the tasks and collects the results.
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:235
The vehicle has departed (was inserted into the network)
static std::vector< SUMOReal > myEdgeEfforts
The container of edge efforts.
An integer-option.
Definition: Option.h:309
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:257
void deschedule()
Marks this Command as being descheduled.
static SUMOAbstractRouter< MSEdge, SUMOVehicle > * myRouter
The router to use.
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)
A storage for options typed value containers)
Definition: OptionsCont.h:108
virtual bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)=0
Replaces the current route by the given one.
MSEventControl * getInsertionEvents()
Returns the event control for insertion events.
Definition: MSNet.h:409
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason)
Computes a new route on vehicle insertion.
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
~MSDevice_Routing()
Destructor.
Patch the time in a way that it is at least as high as the simulation begin time. ...
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
static void cleanup()
deletes the router instance
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:214
SUMOReal getMinimumTravelTime(const SUMOVehicle *const veh) const
returns the minimum travel time for the given vehicle
Definition: MSEdge.h:410
A thread repeatingly calculating incoming tasks.
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:339
#define DELTA_T
Definition: SUMOTime.h:50
static SUMOReal myAdaptationWeight
Information which weight prior edge efforts have.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:78
static SUMOReal myRandomizeWeightsFactor
Whether to disturb edge weights dynamically.
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
bool hasPermissions() const
Returns whether the network has specific vehicle class permissions.
Definition: MSNet.h:175
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
static SUMOTime myLastAdaptation
Information when the last edge weight adaptation occured.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:75
SUMOTime preInsertionReroute(const SUMOTime currentTime)
Performs rerouting before insertion into the network.
const MSEdgeVector & getEdges() const
Returns loaded edges.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
Computes the shortest path through a contracted network.