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>
46 #include <utils/vehicle/CHRouter.h>
48 
49 #ifdef CHECK_MEMORY_LEAKS
50 #include <foreign/nvwa/debug_new.h>
51 #endif // CHECK_MEMORY_LEAKS
52 
53 
54 // ===========================================================================
55 // static member variables
56 // ===========================================================================
57 std::vector<SUMOReal> MSDevice_Routing::myEdgeEfforts;
63 std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*> MSDevice_Routing::myCachedRoutes;
66 #ifdef HAVE_FOX
67 FXWorkerThread::Pool MSDevice_Routing::myThreadPool;
68 #endif
69 
70 
71 // ===========================================================================
72 // method definitions
73 // ===========================================================================
74 // ---------------------------------------------------------------------------
75 // static initialisation methods
76 // ---------------------------------------------------------------------------
77 void
79  insertDefaultAssignmentOptions("rerouting", "Routing", oc);
80 
81  oc.doRegister("device.rerouting.period", new Option_String("0", "TIME"));
82  oc.addSynonyme("device.rerouting.period", "device.routing.period", true);
83  oc.addDescription("device.rerouting.period", "Routing", "The period with which the vehicle shall be rerouted");
84 
85  oc.doRegister("device.rerouting.pre-period", new Option_String("1", "TIME"));
86  oc.addSynonyme("device.rerouting.pre-period", "device.routing.pre-period", true);
87  oc.addDescription("device.rerouting.pre-period", "Routing", "The rerouting period before depart");
88 
89  oc.doRegister("device.rerouting.adaptation-weight", new Option_Float(.5));
90  oc.addSynonyme("device.rerouting.adaptation-weight", "device.routing.adaptation-weight", true);
91  oc.addDescription("device.rerouting.adaptation-weight", "Routing", "The weight of prior edge weights");
92 
93  oc.doRegister("device.rerouting.adaptation-interval", new Option_String("1", "TIME"));
94  oc.addSynonyme("device.rerouting.adaptation-interval", "device.routing.adaptation-interval", true);
95  oc.addDescription("device.rerouting.adaptation-interval", "Routing", "The interval for updating the edge weights");
96 
97  oc.doRegister("device.rerouting.with-taz", new Option_Bool(false));
98  oc.addSynonyme("device.rerouting.with-taz", "device.routing.with-taz", true);
99  oc.addSynonyme("device.rerouting.with-taz", "with-taz");
100  oc.addDescription("device.rerouting.with-taz", "Routing", "Use zones (districts) as routing end points");
101 
102  oc.doRegister("device.rerouting.init-with-loaded-weights", new Option_Bool(false));
103  oc.addDescription("device.rerouting.init-with-loaded-weights", "Routing", "Use given weight files for initializing edge weights");
104 
105  oc.doRegister("device.rerouting.shortest-path-file", new Option_FileName());
106  oc.addDescription("device.rerouting.shortest-path-file", "Routing", "Initialize lookup table for astar from the given distance matrix");
107 
108 #ifdef HAVE_FOX
109  oc.doRegister("device.rerouting.threads", new Option_Integer(0));
110  oc.addDescription("device.rerouting.threads", "Routing", "The number of parallel execution threads used for rerouting");
111 #endif
112 
113  oc.doRegister("device.rerouting.output", new Option_FileName());
114  oc.addDescription("device.rerouting.output", "Routing", "Save adapting weights to FILE");
115 
117  myEdgeEfforts.clear();
119  myLastAdaptation = -1;
120 }
121 
122 
123 void
124 MSDevice_Routing::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into) {
125  bool needRerouting = v.getParameter().wasSet(VEHPARS_FORCE_REROUTE);
127  if (!needRerouting && oc.getFloat("device.rerouting.probability") == 0 && !oc.isSet("device.rerouting.explicit")) {
128  // no route computation is modelled
129  return;
130  }
131  needRerouting |= equippedByDefaultAssignmentOptions(OptionsCont::getOptions(), "rerouting", v);
132  if (needRerouting) {
133  // route computation is enabled
134  myWithTaz = oc.getBool("device.rerouting.with-taz");
135  const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
136  const SUMOTime prePeriod = string2time(oc.getString("device.rerouting.pre-period"));
137  // initialise edge efforts if not done before
138  if (myEdgeEfforts.size() == 0) {
140  const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
141  const SUMOReal currentSecond = SIMTIME;
142  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
143  while ((*i)->getNumericalID() >= (int)myEdgeEfforts.size()) {
144  myEdgeEfforts.push_back(0);
145  }
146  if (useLoaded) {
147  myEdgeEfforts[(*i)->getNumericalID()] = MSNet::getTravelTime(*i, 0, currentSecond);
148  } else {
149  myEdgeEfforts[(*i)->getNumericalID()] = (*i)->getCurrentTravelTime();
150  }
151  }
153  myRandomizeWeightsFactor = oc.isSet("weights.random-factor") ? oc.getFloat("weights.random-factor") : 1;
154  if (myRandomizeWeightsFactor < 1) {
155  WRITE_ERROR("weights.random-factor cannot be less than 1");
156  }
157  }
158  // make the weights be updated
159  if (myAdaptationInterval == -1) {
160  myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
161  if (myAdaptationInterval < 0) {
162  WRITE_ERROR("Negative value for device.rerouting.adaptation-interval!");
163  }
164  myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
165  if (myAdaptationWeight < 0. || myAdaptationWeight > 1.) {
166  WRITE_ERROR("The value for device.rerouting.adaptation-weight must be between 0 and 1!");
167  }
168  if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
172  } else if (period > 0) {
173  WRITE_WARNING("Rerouting is useless if the edge weights do not get updated!");
174  }
175  OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
176  }
177  // build the device
178  into.push_back(new MSDevice_Routing(v, "routing_" + v.getID(), period, prePeriod));
179  }
180 }
181 
182 
183 // ---------------------------------------------------------------------------
184 // MSDevice_Routing-methods
185 // ---------------------------------------------------------------------------
186 MSDevice_Routing::MSDevice_Routing(SUMOVehicle& holder, const std::string& id,
187  SUMOTime period, SUMOTime preInsertionPeriod)
188  : MSDevice(holder, id), myPeriod(period), myPreInsertionPeriod(preInsertionPeriod), myLastRouting(-1), mySkipRouting(-1), myRerouteCommand(0) {
189  // we do always a pre insertion reroute to fill the best lanes of the vehicle with somehow meaningful values (especially for deaprtLane="best")
191  // if we don't update the edge weights, we might as well reroute now and hopefully use our threads better
192  const SUMOTime execTime = myEdgeWeightSettingCommand == 0 ? 0 : holder.getParameter().depart;
194  myRerouteCommand, execTime,
196 }
197 
198 
200  // make the rerouting command invalid if there is one
201  if (myRerouteCommand != 0 && MSNet::getInstance()->getInsertionEvents() != 0) {
203  }
204 }
205 
206 
207 bool
210  // clean up pre depart rerouting
211  if (myPreInsertionPeriod > 0) {
213  }
214  myRerouteCommand = 0;
215  // build repetition trigger if routing shall be done more often
216  if (myPeriod > 0) {
219  myRerouteCommand, myPeriod + MSNet::getInstance()->getCurrentTimeStep(),
221  }
222  }
223  return false;
224 }
225 
226 
227 SUMOTime
229  if (mySkipRouting == currentTime) {
230  return DELTA_T;
231  }
232  const MSEdge* source = *myHolder.getRoute().begin();
233  const MSEdge* dest = myHolder.getRoute().getLastEdge();
235  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
236  if (myCachedRoutes.find(key) != myCachedRoutes.end()) {
238  return myPreInsertionPeriod;
239  }
240  }
241  reroute(currentTime, true);
242  return myPreInsertionPeriod;
243 }
244 
245 
246 SUMOTime
248  reroute(currentTime);
249  return myPeriod;
250 }
251 
252 
253 SUMOReal
254 MSDevice_Routing::getEffort(const MSEdge* const e, const SUMOVehicle* const v, SUMOReal) {
255  const int id = e->getNumericalID();
256  if (id < (int)myEdgeEfforts.size()) {
257  SUMOReal effort = MAX2(myEdgeEfforts[id], e->getMinimumTravelTime(v));
258  if (myRandomizeWeightsFactor != 1) {
260  }
261  return effort;
262  }
263  return 0;
264 }
265 
266 
267 SUMOTime
269  if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
270  return myAdaptationInterval;
271  }
272  std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*>::iterator it = myCachedRoutes.begin();
273  for (; it != myCachedRoutes.end(); ++it) {
274  it->second->release();
275  }
276  myCachedRoutes.clear();
277  const SUMOReal newWeightFactor = (SUMOReal)(1. - myAdaptationWeight);
279  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
280  const int id = (*i)->getNumericalID();
281  const SUMOReal currTT = (*i)->getCurrentTravelTime();
282  if (currTT != myEdgeEfforts[id]) {
283  myEdgeEfforts[id] = myEdgeEfforts[id] * myAdaptationWeight + currTT * newWeightFactor;
284  }
285  }
286  myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
287  if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
288  OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
290  dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
291  dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
293  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
294  const int id = (*i)->getNumericalID();
295  dev.openTag(SUMO_TAG_EDGE);
296  dev.writeAttr(SUMO_ATTR_ID, (*i)->getID());
297  dev.writeAttr("traveltime", myEdgeEfforts[id]);
298  dev.closeTag();
299  }
300  dev.closeTag();
301  }
302  return myAdaptationInterval;
303 }
304 
305 
306 void
307 MSDevice_Routing::reroute(const SUMOTime currentTime, const bool onInit) {
308  //check whether the weights did change since the last reroute
310  return;
311  }
312  myLastRouting = currentTime;
313 #ifdef HAVE_FOX
314  const bool needThread = (myRouter == 0 && myThreadPool.isFull());
315 #else
316  const bool needThread = true;
317 #endif
318  if (needThread && myRouter == 0) {
320  const std::string routingAlgorithm = oc.getString("routing-algorithm");
321  const bool mayHaveRestrictions = MSNet::getInstance()->hasRestrictions() || oc.getInt("remote-port") != 0;
322  if (routingAlgorithm == "dijkstra") {
323  if (mayHaveRestrictions) {
326  } else {
329  }
330  } else if (routingAlgorithm == "astar") {
331  if (mayHaveRestrictions) {
333  const AStar::LookupTable* lookup = 0;
334  if (oc.isSet("device.rerouting.shortest-path-file")) {
335  lookup = AStar::createLookupTable(oc.getString("device.rerouting.shortest-path-file"), (int)MSEdge::numericalDictSize());
336  }
337  myRouter = new AStar(MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, lookup);
338  } else {
340  const AStar::LookupTable* lookup = 0;
341  if (oc.isSet("device.rerouting.shortest-path-file")) {
342  lookup = AStar::createLookupTable(oc.getString("device.rerouting.shortest-path-file"), (int)MSEdge::numericalDictSize());
343  }
344  myRouter = new AStar(MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, lookup);
345  }
346  } else if (routingAlgorithm == "CH") {
348  if (mayHaveRestrictions) {
351  } else {
353  MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, myHolder.getVClass(), weightPeriod, false);
354  }
355  } else if (routingAlgorithm == "CHWrapper") {
356  const SUMOTime begin = string2time(oc.getString("begin"));
359  MSEdge::numericalDictSize(), true, &MSDevice_Routing::getEffort, begin, weightPeriod);
360  } else {
361  throw ProcessError("Unknown routing algorithm '" + routingAlgorithm + "'!");
362  }
363  }
364 #ifdef HAVE_FOX
365  if (needThread) {
366  const int numThreads = OptionsCont::getOptions().getInt("device.rerouting.threads");
367  if (myThreadPool.size() < numThreads) {
368  new WorkerThread(myThreadPool, myRouter);
369  }
370  if (myThreadPool.size() < numThreads) {
371  myRouter = 0;
372  }
373  }
374  if (myThreadPool.size() > 0) {
375  myThreadPool.add(new RoutingTask(myHolder, currentTime, onInit));
376  return;
377  }
378 #endif
379  myHolder.reroute(currentTime, *myRouter, onInit, myWithTaz);
380 }
381 
382 
383 void
385 #ifdef HAVE_FOX
386  if (myThreadPool.size() > 0) {
387  // we cannot wait for the static destructor to do the cleanup
388  // because the output devices are gone by then
389  myThreadPool.clear();
390  // router deletion is done in thread destructor
391  myRouter = 0;
392  return;
393  }
394 #endif
395  delete myRouter;
396  myRouter = 0;
397 }
398 
399 
400 #ifdef HAVE_FOX
401 void
402 MSDevice_Routing::waitForAll() {
403  if (myThreadPool.size() > 0) {
404  myThreadPool.waitAll();
405  }
406 }
407 
408 
409 // ---------------------------------------------------------------------------
410 // MSDevice_Routing::RoutingTask-methods
411 // ---------------------------------------------------------------------------
412 void
413 MSDevice_Routing::RoutingTask::run(FXWorkerThread* context) {
414  myVehicle.reroute(myTime, static_cast<WorkerThread*>(context)->getRouter(), myOnInit, myWithTaz);
415  const MSEdge* source = *myVehicle.getRoute().begin();
416  const MSEdge* dest = myVehicle.getRoute().getLastEdge();
418  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
419  lock();
421  MSDevice_Routing::myCachedRoutes[key] = &myVehicle.getRoute();
422  myVehicle.getRoute().addReference();
423  }
424  unlock();
425  }
426 }
427 #endif
428 
429 
430 /****************************************************************************/
431 
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:84
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
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:571
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 Dijkstra 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:159
T MAX2(T a, T b)
Definition: StdDefs.h:74
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:235
#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:67
#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'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:369
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:141
static std::map< std::pair< const MSEdge *, const MSEdge * >, const MSRoute * > myCachedRoutes
The container of pre-calculated routes.
SUMOTime depart
The vehicle'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:85
virtual SUMOTime addEvent(Command *operation, SUMOTime execTimeStep, AdaptType type)
Adds an Event.
bool hasRestrictions() const
Returns whether the network has vehicle class restrictions.
Definition: MSNet.h:171
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:379
#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:99
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'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.
int SUMOTime
Definition: SUMOTime.h:43
MSEventControl * getInsertionEvents()
Returns the event control for insertion events.
Definition: MSNet.h:389
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:218
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:319
#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.
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'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.