Eclipse SUMO - Simulation of Urban MObility
MSDevice_Routing.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2007-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
19 // A device that performs vehicle rerouting based on current edge speeds
20 /****************************************************************************/
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <microsim/MSNet.h>
28 #include <microsim/MSLane.h>
29 #include <microsim/MSEdge.h>
30 #include <microsim/MSEdgeControl.h>
32 #include <microsim/MSGlobals.h>
39 #include "MSRoutingEngine.h"
40 #include "MSDevice_Routing.h"
41 
42 
43 // ===========================================================================
44 // method definitions
45 // ===========================================================================
46 // ---------------------------------------------------------------------------
47 // static initialisation methods
48 // ---------------------------------------------------------------------------
49 void
51  insertDefaultAssignmentOptions("rerouting", "Routing", oc);
52 
53  oc.doRegister("device.rerouting.period", new Option_String("0", "TIME"));
54  oc.addSynonyme("device.rerouting.period", "device.routing.period", true);
55  oc.addDescription("device.rerouting.period", "Routing", "The period with which the vehicle shall be rerouted");
56 
57  oc.doRegister("device.rerouting.pre-period", new Option_String("60", "TIME"));
58  oc.addSynonyme("device.rerouting.pre-period", "device.routing.pre-period", true);
59  oc.addDescription("device.rerouting.pre-period", "Routing", "The rerouting period before depart");
60 
61  oc.doRegister("device.rerouting.adaptation-weight", new Option_Float(0));
62  oc.addSynonyme("device.rerouting.adaptation-weight", "device.routing.adaptation-weight", true);
63  oc.addDescription("device.rerouting.adaptation-weight", "Routing", "The weight of prior edge weights for exponential moving average");
64 
65  oc.doRegister("device.rerouting.adaptation-steps", new Option_Integer(180));
66  oc.addSynonyme("device.rerouting.adaptation-steps", "device.routing.adaptation-steps", true);
67  oc.addDescription("device.rerouting.adaptation-steps", "Routing", "The number of steps for moving average weight of prior edge weights");
68 
69  oc.doRegister("device.rerouting.adaptation-interval", new Option_String("1", "TIME"));
70  oc.addSynonyme("device.rerouting.adaptation-interval", "device.routing.adaptation-interval", true);
71  oc.addDescription("device.rerouting.adaptation-interval", "Routing", "The interval for updating the edge weights");
72 
73  oc.doRegister("device.rerouting.with-taz", new Option_Bool(false));
74  oc.addSynonyme("device.rerouting.with-taz", "device.routing.with-taz", true);
75  oc.addSynonyme("device.rerouting.with-taz", "with-taz");
76  oc.addDescription("device.rerouting.with-taz", "Routing", "Use zones (districts) as routing start- and endpoints");
77 
78  oc.doRegister("device.rerouting.init-with-loaded-weights", new Option_Bool(false));
79  oc.addDescription("device.rerouting.init-with-loaded-weights", "Routing", "Use weight files given with option --weight-files for initializing edge weights");
80 
81  oc.doRegister("device.rerouting.threads", new Option_Integer(0));
82  oc.addDescription("device.rerouting.threads", "Routing", "The number of parallel execution threads used for rerouting");
83 
84  oc.doRegister("device.rerouting.synchronize", new Option_Bool(false));
85  oc.addDescription("device.rerouting.synchronize", "Routing", "Let rerouting happen at the same time for all vehicles");
86 
87  oc.doRegister("device.rerouting.output", new Option_FileName());
88  oc.addDescription("device.rerouting.output", "Routing", "Save adapting weights to FILE");
89 }
90 
91 
92 bool
94  bool ok = true;
95  if (!oc.isDefault("device.rerouting.adaptation-steps") && !oc.isDefault("device.rerouting.adaptation-weight")) {
96  WRITE_ERROR("Only one of the options 'device.rerouting.adaptation-steps' or 'device.rerouting.adaptation-weight' may be given.");
97  ok = false;
98  }
99  if (oc.getFloat("weights.random-factor") < 1) {
100  WRITE_ERROR("weights.random-factor cannot be less than 1");
101  ok = false;
102  }
103  if (string2time(oc.getString("device.rerouting.adaptation-interval")) < 0) {
104  WRITE_ERROR("Negative value for device.rerouting.adaptation-interval!");
105  ok = false;
106  }
107  if (oc.getFloat("device.rerouting.adaptation-weight") < 0. ||
108  oc.getFloat("device.rerouting.adaptation-weight") > 1.) {
109  WRITE_ERROR("The value for device.rerouting.adaptation-weight must be between 0 and 1!");
110  ok = false;
111  }
112 #ifndef HAVE_FOX
113  if (oc.getInt("device.rerouting.threads") > 1) {
114  WRITE_ERROR("Parallel routing is only possible when compiled with Fox.");
115  ok = false;
116  }
117 #endif
118  return ok;
119 }
120 
121 
122 void
123 MSDevice_Routing::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
124  const OptionsCont& oc = OptionsCont::getOptions();
125  const bool equip = equippedByDefaultAssignmentOptions(oc, "rerouting", v, false);
126  if (v.getParameter().wasSet(VEHPARS_FORCE_REROUTE) || equip) {
127  // route computation is enabled
128  // for implicitly equipped vehicles (trips, flows), option probability
129  // can still be used to disable periodic rerouting after insertion for
130  // parts of the fleet
131  const SUMOTime period = equip || oc.isDefault("device.rerouting.probability") ? string2time(oc.getString("device.rerouting.period")) : 0;
132  const SUMOTime prePeriod = string2time(oc.getString("device.rerouting.pre-period"));
134  // build the device
135  into.push_back(new MSDevice_Routing(v, "routing_" + v.getID(), period, prePeriod));
136  }
137 }
138 
139 
140 // ---------------------------------------------------------------------------
141 // MSDevice_Routing-methods
142 // ---------------------------------------------------------------------------
143 MSDevice_Routing::MSDevice_Routing(SUMOVehicle& holder, const std::string& id,
144  SUMOTime period, SUMOTime preInsertionPeriod)
145  : MSVehicleDevice(holder, id), myPeriod(period), myPreInsertionPeriod(preInsertionPeriod), myLastRouting(-1), mySkipRouting(-1), myRerouteCommand(nullptr) {
147  // we do always a pre insertion reroute for trips to fill the best lanes of the vehicle with somehow meaningful values (especially for deaprtLane="best")
149  // if we don't update the edge weights, we might as well reroute now and hopefully use our threads better
150  const SUMOTime execTime = MSRoutingEngine::hasEdgeUpdates() ? holder.getParameter().depart : -1;
152  }
153 }
154 
155 
157  // make the rerouting command invalid if there is one
158  if (myRerouteCommand != nullptr) {
160  }
161 }
162 
163 
164 bool
167  // clean up pre depart rerouting
168  if (myRerouteCommand != nullptr) {
170  }
171  myRerouteCommand = nullptr;
172  // build repetition trigger if routing shall be done more often
173  if (myPeriod > 0) {
176  if (OptionsCont::getOptions().getBool("device.rerouting.synchronize")) {
177  start -= start % myPeriod;
178  }
180  }
181  }
182  return false;
183 }
184 
185 
186 SUMOTime
188  if (mySkipRouting == currentTime) {
189  return DELTA_T;
190  }
191  if (myPreInsertionPeriod == 0) {
192  // the event will deschedule and destroy itself so it does not need to be stored
193  myRerouteCommand = nullptr;
194  }
195  const MSEdge* source = *myHolder.getRoute().begin();
196  const MSEdge* dest = myHolder.getRoute().getLastEdge();
197  if (source->isTazConnector() && dest->isTazConnector()) {
198  const MSRoute* cached = MSRoutingEngine::getCachedRoute(std::make_pair(source, dest));
199  if (cached != nullptr && cached->size() > 2) {
200  myHolder.replaceRoute(cached, "device.rerouting", true);
201  return myPreInsertionPeriod;
202  }
203  }
204  try {
205  reroute(currentTime, true);
206  } catch (ProcessError&) {
207  myRerouteCommand = nullptr;
208  throw;
209  }
210  return myPreInsertionPeriod;
211 }
212 
213 
214 SUMOTime
216  reroute(currentTime);
217  return myPeriod;
218 }
219 
220 
221 void
222 MSDevice_Routing::reroute(const SUMOTime currentTime, const bool onInit) {
224  //check whether the weights did change since the last reroute
226  return;
227  }
228  myLastRouting = currentTime;
229  MSRoutingEngine::reroute(myHolder, currentTime, onInit);
230 }
231 
232 
233 std::string
234 MSDevice_Routing::getParameter(const std::string& key) const {
235  if (StringUtils::startsWith(key, "edge:")) {
236  const std::string edgeID = key.substr(5);
237  const MSEdge* edge = MSEdge::dictionary(edgeID);
238  if (edge == nullptr) {
239  throw InvalidArgument("Edge '" + edgeID + "' is invalid for parameter retrieval of '" + deviceName() + "'");
240  }
241  return toString(MSRoutingEngine::getEffort(edge, &myHolder, 0));
242  } else if (key == "period") {
243  return time2string(myPeriod);
244  }
245  throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
246 }
247 
248 
249 void
250 MSDevice_Routing::setParameter(const std::string& key, const std::string& value) {
251  double doubleValue;
252  try {
253  doubleValue = StringUtils::toDouble(value);
254  } catch (NumberFormatException&) {
255  throw InvalidArgument("Setting parameter '" + key + "' requires a number for device of type '" + deviceName() + "'");
256  }
257  if (StringUtils::startsWith(key, "edge:")) {
258  const std::string edgeID = key.substr(5);
259  const MSEdge* edge = MSEdge::dictionary(edgeID);
260  if (edge == nullptr) {
261  throw InvalidArgument("Edge '" + edgeID + "' is invalid for parameter setting of '" + deviceName() + "'");
262  }
263  MSRoutingEngine::setEdgeTravelTime(edge, doubleValue);
264  } else if (key == "period") {
265  const SUMOTime oldPeriod = myPeriod;
266  myPeriod = TIME2STEPS(doubleValue);
267  if (myPeriod <= 0) {
269  } else if (oldPeriod <= 0) {
270  // re-schedule routing command
272  }
273  } else {
274  throw InvalidArgument("Setting parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
275  }
276 }
277 
278 
279 void
282  out.writeAttr(SUMO_ATTR_ID, getID());
283  std::vector<std::string> internals;
284  internals.push_back(toString(myPeriod));
285  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
286  out.closeTag();
287 }
288 
289 
290 void
292  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
293  bis >> myPeriod;
294 }
295 
296 
297 /****************************************************************************/
MSRoutingEngine::reroute
static void reroute(SUMOVehicle &vehicle, const SUMOTime currentTime, const bool onInit)
initiate the rerouting, create router / thread pool on first use
Definition: MSRoutingEngine.cpp:225
SUMOTrafficObject
Representation of a vehicle or person.
Definition: SUMOTrafficObject.h:48
OptionsCont::getInt
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
Definition: OptionsCont.cpp:216
SUMOVehicleParameter::wasSet
bool wasSet(int what) const
Returns whether the given parameter was set.
Definition: SUMOVehicleParameter.h:306
MSEventControl::addEvent
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Definition: MSEventControl.cpp:53
MSNet.h
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
Option_Bool
Definition: Option.h:540
SUMOSAXAttributes::getString
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOVehicle::getParameter
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
OutputDevice
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
DELTA_T
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
MSRoutingEngine::getLastAdaptation
static SUMOTime getLastAdaptation()
Information when the last edge weight adaptation occurred.
Definition: MSRoutingEngine.h:78
OptionsCont.h
StringUtils::toDouble
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
Definition: StringUtils.cpp:313
MSNet::getBeginOfTimestepEvents
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:430
SUMOTrafficObject::getID
virtual const std::string & getID() const =0
Get the vehicle's ID.
VEHPARS_FORCE_REROUTE
const int VEHPARS_FORCE_REROUTE
Definition: SUMOVehicleParameter.h:63
WrappingCommand.h
MSDevice_Routing::~MSDevice_Routing
~MSDevice_Routing()
Destructor.
Definition: MSDevice_Routing.cpp:156
OptionsCont::getString
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
Definition: OptionsCont.cpp:202
WrappingCommand::deschedule
void deschedule()
Marks this Command as being descheduled.
Definition: WrappingCommand.h:79
MSDevice_Routing::deviceName
const std::string deviceName() const
return the name for this type of device
Definition: MSDevice_Routing.h:122
MSRoute::getLastEdge
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:88
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:35
SUMOVehicle
Representation of a vehicle.
Definition: SUMOVehicle.h:61
WrappingCommand< MSDevice_Routing >
MSDevice_Routing::myLastRouting
SUMOTime myLastRouting
The last time a routing took place.
Definition: MSDevice_Routing.h:214
MSDevice_Routing::myRerouteCommand
WrappingCommand< MSDevice_Routing > * myRerouteCommand
The (optional) command responsible for rerouting.
Definition: MSDevice_Routing.h:220
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
SUMO_ATTR_ID
Definition: SUMOXMLDefinitions.h:379
MSEdge.h
MSVehicleDevice::myHolder
SUMOVehicle & myHolder
The vehicle that stores the device.
Definition: MSVehicleDevice.h:85
MSRoute
Definition: MSRoute.h:67
MSRoutingEngine::setEdgeTravelTime
static void setEdgeTravelTime(const MSEdge *const edge, const double travelTime)
adapt the known travel time for an edge
Definition: MSRoutingEngine.cpp:318
SUMOVehicleParameter::depart
SUMOTime depart
Definition: SUMOVehicleParameter.h:476
OutputDevice::closeTag
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Definition: OutputDevice.cpp:254
NumberFormatException
Definition: UtilExceptions.h:96
SUMOVehicle::getRoute
virtual const MSRoute & getRoute() const =0
Returns the current route.
OutputDevice::writeAttr
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
MSRoute::size
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:82
MSDevice_Routing::checkOptions
static bool checkOptions(OptionsCont &oc)
checks MSDevice_Routing-options
Definition: MSDevice_Routing.cpp:93
MSRoutingEngine::initEdgeWeights
static void initEdgeWeights()
initialize the edge weights if not done before
Definition: MSRoutingEngine.cpp:100
OptionsCont::addDescription
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
Definition: OptionsCont.cpp:473
MSRoutingEngine::getEffort
static double getEffort(const MSEdge *const e, const SUMOVehicle *const v, double t)
Returns the effort to pass an edge.
Definition: MSRoutingEngine.cpp:130
MSDevice::insertDefaultAssignmentOptions
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
Definition: MSDevice.cpp:126
TIME2STEPS
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
OptionsCont::addSynonyme
void addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
Definition: OptionsCont.cpp:96
MSDevice_Routing::saveState
void saveState(OutputDevice &out) const
Saves the state of the device.
Definition: MSDevice_Routing.cpp:280
MSNet::getCurrentTimeStep
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:284
MSDevice_Routing::setParameter
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this device. Throw exception for unsupported key
Definition: MSDevice_Routing.cpp:250
MSEdge::isTazConnector
bool isTazConnector() const
Definition: MSEdge.h:256
MSEdge::dictionary
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:804
SUMOVehicle::replaceRoute
virtual bool replaceRoute(const MSRoute *route, const std::string &info, bool onInit=false, int offset=0, bool addStops=true, bool removeStops=true)=0
Replaces the current route by the given one.
MSDevice_Routing::wrappedRerouteCommandExecute
SUMOTime wrappedRerouteCommandExecute(SUMOTime currentTime)
Performs rerouting after a period.
Definition: MSDevice_Routing.cpp:215
OptionsCont::doRegister
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
Definition: OptionsCont.cpp:75
ProcessError
Definition: UtilExceptions.h:40
SUMO_TAG_DEVICE
Definition: SUMOXMLDefinitions.h:272
time2string
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
Option_String
Definition: Option.h:401
StaticCommand.h
MSGlobals.h
MSDevice_Routing.h
OptionsCont
A storage for options typed value containers)
Definition: OptionsCont.h:90
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:76
StringUtils::startsWith
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
Definition: StringUtils.cpp:142
MSMoveReminder::NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
Definition: MSMoveReminder.h:91
MSRoutingEngine.h
string2time
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
MSDevice_Routing::loadState
void loadState(const SUMOSAXAttributes &attrs)
Loads the state of the device from the given description.
Definition: MSDevice_Routing.cpp:291
OptionsCont::isDefault
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
Definition: OptionsCont.cpp:164
MSDevice_Routing::notifyEnter
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Computes a new route on vehicle insertion.
Definition: MSDevice_Routing.cpp:165
MSRoutingEngine::initWeightUpdate
static void initWeightUpdate()
intialize period edge weight update
Definition: MSRoutingEngine.cpp:74
MSEdgeControl.h
OptionsCont::getFloat
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
Definition: OptionsCont.cpp:209
OutputDevice::openTag
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
Definition: OutputDevice.cpp:240
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
StringUtils.h
SUMO_ATTR_STATE
The state of a link.
Definition: SUMOXMLDefinitions.h:705
MSRoutingEngine::hasEdgeUpdates
static bool hasEdgeUpdates()
returns whether any routing actions take place
Definition: MSRoutingEngine.h:73
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
MSDevice::equippedByDefaultAssignmentOptions
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
Definition: MSDevice.h:204
MSDevice_Routing::myPreInsertionPeriod
SUMOTime myPreInsertionPeriod
The period with which a vehicle shall be rerouted before insertion.
Definition: MSDevice_Routing.h:211
InvalidArgument
Definition: UtilExceptions.h:57
Option_Float
Definition: Option.h:472
MSNet::getInsertionEvents
MSEventControl * getInsertionEvents()
Returns the event control for insertion events.
Definition: MSNet.h:450
MSDevice_Routing::insertOptions
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_Routing-options.
Definition: MSDevice_Routing.cpp:50
MSDevice_Routing::myPeriod
SUMOTime myPeriod
The period with which a vehicle shall be rerouted.
Definition: MSDevice_Routing.h:208
SUMOSAXAttributes.h
MSRoute::begin
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:70
config.h
Option_FileName
Definition: Option.h:651
MSDevice_Routing::reroute
void reroute(const SUMOTime currentTime, const bool onInit=false)
initiate the rerouting, create router / thread pool on first use
Definition: MSDevice_Routing.cpp:222
MSEventControl.h
MSLane.h
MSDevice_Routing::mySkipRouting
SUMOTime mySkipRouting
The time for which routing may be skipped because we cannot be inserted.
Definition: MSDevice_Routing.h:217
MSDevice_Routing::buildVehicleDevices
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
Definition: MSDevice_Routing.cpp:123
MSRoutingEngine::getCachedRoute
static const MSRoute * getCachedRoute(const std::pair< const MSEdge *, const MSEdge * > &key)
return the cached route or nullptr on miss
Definition: MSRoutingEngine.cpp:215
SUMOSAXAttributes
Encapsulated SAX-Attributes.
Definition: SUMOSAXAttributes.h:57
MSVehicleControl.h
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:77
MSMoveReminder::Notification
Notification
Definition of a vehicle state.
Definition: MSMoveReminder.h:89
Option_Integer
An integer-option.
Definition: Option.h:333
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
MSDevice_Routing::MSDevice_Routing
MSDevice_Routing(SUMOVehicle &holder, const std::string &id, SUMOTime period, SUMOTime preInsertionPeriod)
Constructor.
Definition: MSDevice_Routing.cpp:143
MSDevice_Routing::getParameter
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
Definition: MSDevice_Routing.cpp:234
MSDevice_Routing::preInsertionReroute
SUMOTime preInsertionReroute(const SUMOTime currentTime)
Performs rerouting before insertion into the network.
Definition: MSDevice_Routing.cpp:187
MSVehicleDevice
Abstract in-vehicle device.
Definition: MSVehicleDevice.h:55