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.sourceforge.net/
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 std::set<std::string> MSDevice_Routing::myExplicitIDs;
60 
61 
62 // ===========================================================================
63 // method definitions
64 // ===========================================================================
65 // ---------------------------------------------------------------------------
66 // static initialisation methods
67 // ---------------------------------------------------------------------------
68 void
71  oc.addOptionSubTopic("Routing");
72 
73  oc.doRegister("device.rerouting.probability", new Option_Float(0.));
74  oc.addSynonyme("device.rerouting.probability", "device.routing.probability", true);
75  oc.addDescription("device.rerouting.probability", "Routing", "The probability for a vehicle to have a routing device");
76 
77  oc.doRegister("device.rerouting.explicit", new Option_String());
78  oc.addSynonyme("device.rerouting.explicit", "device.routing.knownveh", true);
79  oc.addDescription("device.rerouting.explicit", "Routing", "Assign a device to named vehicles");
80 
81  oc.doRegister("device.rerouting.deterministic", new Option_Bool(false));
82  oc.addSynonyme("device.rerouting.deterministic", "device.routing.deterministic", true);
83  oc.addDescription("device.rerouting.deterministic", "Routing", "The devices are set deterministic using a fraction of 1000");
84 
85  oc.doRegister("device.rerouting.period", new Option_String("0", "TIME"));
86  oc.addSynonyme("device.rerouting.period", "device.routing.period", true);
87  oc.addDescription("device.rerouting.period", "Routing", "The period with which the vehicle shall be rerouted");
88 
89  oc.doRegister("device.rerouting.pre-period", new Option_String("0", "TIME"));
90  oc.addSynonyme("device.rerouting.pre-period", "device.routing.pre-period", true);
91  oc.addDescription("device.rerouting.pre-period", "Routing", "The rerouting period before depart");
92 
93  oc.doRegister("device.rerouting.adaptation-weight", new Option_Float(.5));
94  oc.addSynonyme("device.rerouting.adaptation-weight", "device.routing.adaptation-weight", true);
95  oc.addDescription("device.rerouting.adaptation-weight", "Routing", "The weight of prior edge weights.");
96 
97  oc.doRegister("device.rerouting.adaptation-interval", new Option_String("1", "TIME"));
98  oc.addSynonyme("device.rerouting.adaptation-interval", "device.routing.adaptation-interval", true);
99  oc.addDescription("device.rerouting.adaptation-interval", "Routing", "The interval for updating the edge weights.");
100 
101  oc.doRegister("device.rerouting.with-taz", new Option_Bool(false));
102  oc.addSynonyme("device.rerouting.with-taz", "device.routing.with-taz", true);
103  oc.addDescription("device.rerouting.with-taz", "Routing", "Use zones (districts) as routing end points");
104 
105  oc.doRegister("device.rerouting.init-with-loaded-weights", new Option_Bool(false));
106  oc.addDescription("device.rerouting.init-with-loaded-weights", "Routing", "Use given weight files for initializing edge weights");
107 
109  myEdgeEfforts.clear();
110 }
111 
112 
113 void
114 MSDevice_Routing::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into) {
116  bool needRerouting = v.getParameter().wasSet(VEHPARS_FORCE_REROUTE);
117  if (!needRerouting && oc.getFloat("device.rerouting.probability") == 0 && !oc.isSet("device.rerouting.explicit")) {
118  // no route computation is modelled
119  return;
120  }
121  // route computation is enabled
122  bool haveByNumber = false;
123  if (oc.getBool("device.rerouting.deterministic")) {
124  haveByNumber = MSNet::getInstance()->getVehicleControl().isInQuota(oc.getFloat("device.rerouting.probability"));
125  } else {
126  haveByNumber = RandHelper::rand() <= oc.getFloat("device.rerouting.probability");
127  }
128  // initialize myExplicitIDs if not done before
129  if (oc.isSet("device.rerouting.explicit") && myExplicitIDs.size() == 0) {
130  const std::vector<std::string> idList = OptionsCont::getOptions().getStringVector("device.rerouting.explicit");
131  myExplicitIDs.insert(idList.begin(), idList.end());
132  }
133  const bool haveByName = myExplicitIDs.count(v.getID()) > 0;
134  myWithTaz = oc.getBool("device.rerouting.with-taz");
135  if (needRerouting || haveByNumber || haveByName) {
136  // build the device
137  MSDevice_Routing* device = new MSDevice_Routing(v, "routing_" + v.getID(),
138  string2time(oc.getString("device.rerouting.period")),
139  string2time(oc.getString("device.rerouting.pre-period")));
140  into.push_back(device);
141  // initialise edge efforts if not done before
142  if (myEdgeEfforts.size() == 0) {
143  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
144  const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
145  const SUMOReal currentSecond = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
146  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
147  if (useLoaded) {
148  myEdgeEfforts[*i] = MSNet::getTravelTime(*i, 0, currentSecond);
149  } else {
150  myEdgeEfforts[*i] = (*i)->getCurrentTravelTime();
151  }
152  }
153  }
154  // make the weights be updated
155  if (myEdgeWeightSettingCommand == 0) {
159  myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
160  myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
161  }
162  if (myWithTaz) {
163  if (MSEdge::dictionary(v.getParameter().fromTaz + "-source") == 0) {
164  WRITE_ERROR("Source district '" + v.getParameter().fromTaz + "' not known when rerouting '" + v.getID() + "'!");
165  return;
166  }
167  if (MSEdge::dictionary(v.getParameter().toTaz + "-sink") == 0) {
168  WRITE_ERROR("Destination district '" + v.getParameter().toTaz + "' not known when rerouting '" + v.getID() + "'!");
169  return;
170  }
171  }
172  }
173 }
174 
175 
176 // ---------------------------------------------------------------------------
177 // MSDevice_Routing-methods
178 // ---------------------------------------------------------------------------
179 MSDevice_Routing::MSDevice_Routing(SUMOVehicle& holder, const std::string& id,
180  SUMOTime period, SUMOTime preInsertionPeriod)
181  : MSDevice(holder, id), myPeriod(period), myPreInsertionPeriod(preInsertionPeriod), myRerouteCommand(0) {
182  if (myWithTaz) {
187  }
188 }
189 
190 
192  // make the rerouting command invalid if there is one
193  if (myRerouteCommand != 0) {
195  }
196 }
197 
198 
199 bool
202  if (myRerouteCommand != 0) { // clean up pre depart rerouting
203  if (myPreInsertionPeriod > 0) {
205  }
206  myRerouteCommand = 0;
207  }
208  if (!myWithTaz) {
209  wrappedRerouteCommandExecute(MSNet::getInstance()->getCurrentTimeStep());
210  }
211  // build repetition trigger if routing shall be done more often
212  if (myPeriod > 0) {
215  myRerouteCommand, myPeriod + MSNet::getInstance()->getCurrentTimeStep(),
217  }
218  }
219  return false;
220 }
221 
222 
223 SUMOTime
225  const MSEdge* source = MSEdge::dictionary(myHolder.getParameter().fromTaz + "-source");
226  const MSEdge* dest = MSEdge::dictionary(myHolder.getParameter().toTaz + "-sink");
227  if (source && dest) {
228  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
229  if (myCachedRoutes.find(key) == myCachedRoutes.end()) {
230  myHolder.reroute(currentTime, getRouter(), true);
231  myCachedRoutes[key] = &myHolder.getRoute();
233  } else {
235  }
236  }
237  return myPreInsertionPeriod;
238 }
239 
240 
241 SUMOTime
243  myHolder.reroute(currentTime, getRouter());
244  return myPeriod;
245 }
246 
247 
248 SUMOReal
249 MSDevice_Routing::getEffort(const MSEdge* const e, const SUMOVehicle* const v, SUMOReal) {
250  if (myEdgeEfforts.find(e) != myEdgeEfforts.end()) {
251  return MAX2(myEdgeEfforts.find(e)->second, e->getMinimumTravelTime(v));
252  }
253  return 0;
254 }
255 
256 
257 SUMOTime
259  std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*>::iterator it = myCachedRoutes.begin();
260  for (; it != myCachedRoutes.end(); ++it) {
261  it->second->release();
262  }
263  myCachedRoutes.clear();
264  SUMOReal newWeight = (SUMOReal)(1. - myAdaptationWeight);
265  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
266  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
267  myEdgeEfforts[*i] = myEdgeEfforts[*i] * myAdaptationWeight + (*i)->getCurrentTravelTime() * newWeight;
268  }
269  return myAdaptationInterval;
270 }
271 
272 
275  if (myRouter == 0) {
276  const std::string routingAlgorithm = OptionsCont::getOptions().getString("routing-algorithm");
277  if (routingAlgorithm == "dijkstra") {
280  } else if (routingAlgorithm == "astar") {
283  } else {
284  throw ProcessError("Unknown routing Algorithm '" + routingAlgorithm + "'!");
285  }
286  }
287  return *myRouter;
288 }
289 
290 
291 void
293  delete myRouter;
294  myRouter = 0;
295 }
296 /****************************************************************************/
297