SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSDevice_Routing.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A device that performs vehicle rerouting based on current edge speeds
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include "MSDevice_Routing.h"
34 #include <microsim/MSNet.h>
35 #include <microsim/MSLane.h>
36 #include <microsim/MSEdge.h>
37 #include <microsim/MSEdgeControl.h>
43 
44 #ifdef CHECK_MEMORY_LEAKS
45 #include <foreign/nvwa/debug_new.h>
46 #endif // CHECK_MEMORY_LEAKS
47 
48 
49 // ===========================================================================
50 // static member variables
51 // ===========================================================================
52 std::map<const MSEdge*, SUMOReal> MSDevice_Routing::myEdgeEfforts;
57 std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*> MSDevice_Routing::myCachedRoutes;
59 
60 
61 // ===========================================================================
62 // method definitions
63 // ===========================================================================
64 // ---------------------------------------------------------------------------
65 // static initialisation methods
66 // ---------------------------------------------------------------------------
67 void
69  oc.addOptionSubTopic("Routing");
70  insertDefaultAssignmentOptions("rerouting", "Routing", oc);
71 
72  oc.doRegister("device.rerouting.period", new Option_String("0", "TIME"));
73  oc.addSynonyme("device.rerouting.period", "device.routing.period", true);
74  oc.addDescription("device.rerouting.period", "Routing", "The period with which the vehicle shall be rerouted");
75 
76  oc.doRegister("device.rerouting.pre-period", new Option_String("0", "TIME"));
77  oc.addSynonyme("device.rerouting.pre-period", "device.routing.pre-period", true);
78  oc.addDescription("device.rerouting.pre-period", "Routing", "The rerouting period before depart");
79 
80  oc.doRegister("device.rerouting.adaptation-weight", new Option_Float(.5));
81  oc.addSynonyme("device.rerouting.adaptation-weight", "device.routing.adaptation-weight", true);
82  oc.addDescription("device.rerouting.adaptation-weight", "Routing", "The weight of prior edge weights.");
83 
84  oc.doRegister("device.rerouting.adaptation-interval", new Option_String("1", "TIME"));
85  oc.addSynonyme("device.rerouting.adaptation-interval", "device.routing.adaptation-interval", true);
86  oc.addDescription("device.rerouting.adaptation-interval", "Routing", "The interval for updating the edge weights.");
87 
88  oc.doRegister("device.rerouting.with-taz", new Option_Bool(false));
89  oc.addSynonyme("device.rerouting.with-taz", "device.routing.with-taz", true);
90  oc.addDescription("device.rerouting.with-taz", "Routing", "Use zones (districts) as routing end points");
91 
92  oc.doRegister("device.rerouting.init-with-loaded-weights", new Option_Bool(false));
93  oc.addDescription("device.rerouting.init-with-loaded-weights", "Routing", "Use given weight files for initializing edge weights");
94 
96  myEdgeEfforts.clear();
97 }
98 
99 
100 void
101 MSDevice_Routing::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into) {
102  bool needRerouting = v.getParameter().wasSet(VEHPARS_FORCE_REROUTE);
104  if(!needRerouting && oc.getFloat("device.rerouting.probability") == 0 && !oc.isSet("device.rerouting.explicit")) {
105  // no route computation is modelled
106  return;
107  }
108  needRerouting |= equippedByDefaultAssignmentOptions(OptionsCont::getOptions(), "rerouting", v);
109  if(needRerouting) {
110  // route computation is enabled
111  myWithTaz = oc.getBool("device.rerouting.with-taz");
112  // build the device
113  MSDevice_Routing* device = new MSDevice_Routing(v, "routing_" + v.getID(),
114  string2time(oc.getString("device.rerouting.period")),
115  string2time(oc.getString("device.rerouting.pre-period")));
116  into.push_back(device);
117  // initialise edge efforts if not done before
118  if (myEdgeEfforts.size() == 0) {
119  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
120  const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
121  const SUMOReal currentSecond = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
122  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
123  if (useLoaded) {
124  myEdgeEfforts[*i] = MSNet::getTravelTime(*i, 0, currentSecond);
125  } else {
126  myEdgeEfforts[*i] = (*i)->getCurrentTravelTime();
127  }
128  }
129  }
130  // make the weights be updated
131  if (myEdgeWeightSettingCommand == 0) {
135  myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
136  myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
137  }
138  if (myWithTaz) {
139  if (MSEdge::dictionary(v.getParameter().fromTaz + "-source") == 0) {
140  WRITE_ERROR("Source district '" + v.getParameter().fromTaz + "' not known when rerouting '" + v.getID() + "'!");
141  return;
142  }
143  if (MSEdge::dictionary(v.getParameter().toTaz + "-sink") == 0) {
144  WRITE_ERROR("Destination district '" + v.getParameter().toTaz + "' not known when rerouting '" + v.getID() + "'!");
145  return;
146  }
147  }
148  }
149 }
150 
151 
152 // ---------------------------------------------------------------------------
153 // MSDevice_Routing-methods
154 // ---------------------------------------------------------------------------
155 MSDevice_Routing::MSDevice_Routing(SUMOVehicle& holder, const std::string& id,
156  SUMOTime period, SUMOTime preInsertionPeriod)
157  : MSDevice(holder, id), myPeriod(period), myPreInsertionPeriod(preInsertionPeriod), myRerouteCommand(0) {
158  if (myWithTaz) {
163  }
164 }
165 
166 
168  // make the rerouting command invalid if there is one
169  if (myRerouteCommand != 0) {
171  }
172 }
173 
174 
175 bool
178  if (myRerouteCommand != 0) { // clean up pre depart rerouting
179  if (myPreInsertionPeriod > 0) {
181  }
182  myRerouteCommand = 0;
183  }
184  if (!myWithTaz) {
185  wrappedRerouteCommandExecute(MSNet::getInstance()->getCurrentTimeStep());
186  }
187  // build repetition trigger if routing shall be done more often
188  if (myPeriod > 0) {
191  myRerouteCommand, myPeriod + MSNet::getInstance()->getCurrentTimeStep(),
193  }
194  }
195  return false;
196 }
197 
198 
199 SUMOTime
201  const MSEdge* source = MSEdge::dictionary(myHolder.getParameter().fromTaz + "-source");
202  const MSEdge* dest = MSEdge::dictionary(myHolder.getParameter().toTaz + "-sink");
203  if (source && dest) {
204  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
205  if (myCachedRoutes.find(key) == myCachedRoutes.end()) {
206  myHolder.reroute(currentTime, getRouter(), true);
207  myCachedRoutes[key] = &myHolder.getRoute();
209  } else {
211  }
212  }
213  return myPreInsertionPeriod;
214 }
215 
216 
217 SUMOTime
219  myHolder.reroute(currentTime, getRouter());
220  return myPeriod;
221 }
222 
223 
224 SUMOReal
225 MSDevice_Routing::getEffort(const MSEdge* const e, const SUMOVehicle* const v, SUMOReal) {
226  if (myEdgeEfforts.find(e) != myEdgeEfforts.end()) {
227  return MAX2(myEdgeEfforts.find(e)->second, e->getMinimumTravelTime(v));
228  }
229  return 0;
230 }
231 
232 
233 SUMOTime
235  std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*>::iterator it = myCachedRoutes.begin();
236  for (; it != myCachedRoutes.end(); ++it) {
237  it->second->release();
238  }
239  myCachedRoutes.clear();
240  SUMOReal newWeight = (SUMOReal)(1. - myAdaptationWeight);
241  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
242  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
243  myEdgeEfforts[*i] = myEdgeEfforts[*i] * myAdaptationWeight + (*i)->getCurrentTravelTime() * newWeight;
244  }
245  return myAdaptationInterval;
246 }
247 
248 
251  if (myRouter == 0) {
252  const std::string routingAlgorithm = OptionsCont::getOptions().getString("routing-algorithm");
253  if (routingAlgorithm == "dijkstra") {
256  } else if (routingAlgorithm == "astar") {
259  } else {
260  throw ProcessError("Unknown routing Algorithm '" + routingAlgorithm + "'!");
261  }
262  }
263  return *myRouter;
264 }
265 
266 
267 void
269  delete myRouter;
270  myRouter = 0;
271 }
272 
273 
274 /****************************************************************************/
275