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 /****************************************************************************/
11 // A device that performs vehicle rerouting based on current edge speeds
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
14 // Copyright (C) 2007-2014 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>
44 
45 #ifdef CHECK_MEMORY_LEAKS
46 #include <foreign/nvwa/debug_new.h>
47 #endif // CHECK_MEMORY_LEAKS
48 
49 
50 // ===========================================================================
51 // static member variables
52 // ===========================================================================
53 std::vector<SUMOReal> MSDevice_Routing::myEdgeEfforts;
58 std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*> MSDevice_Routing::myCachedRoutes;
60 
61 
62 // ===========================================================================
63 // method definitions
64 // ===========================================================================
65 // ---------------------------------------------------------------------------
66 // static initialisation methods
67 // ---------------------------------------------------------------------------
68 void
70  oc.addOptionSubTopic("Routing");
71  insertDefaultAssignmentOptions("rerouting", "Routing", oc);
72 
73  oc.doRegister("device.rerouting.period", new Option_String("0", "TIME"));
74  oc.addSynonyme("device.rerouting.period", "device.routing.period", true);
75  oc.addDescription("device.rerouting.period", "Routing", "The period with which the vehicle shall be rerouted");
76 
77  oc.doRegister("device.rerouting.pre-period", new Option_String("0", "TIME"));
78  oc.addSynonyme("device.rerouting.pre-period", "device.routing.pre-period", true);
79  oc.addDescription("device.rerouting.pre-period", "Routing", "The rerouting period before depart");
80 
81  oc.doRegister("device.rerouting.adaptation-weight", new Option_Float(.5));
82  oc.addSynonyme("device.rerouting.adaptation-weight", "device.routing.adaptation-weight", true);
83  oc.addDescription("device.rerouting.adaptation-weight", "Routing", "The weight of prior edge weights");
84 
85  oc.doRegister("device.rerouting.adaptation-interval", new Option_String("1", "TIME"));
86  oc.addSynonyme("device.rerouting.adaptation-interval", "device.routing.adaptation-interval", true);
87  oc.addDescription("device.rerouting.adaptation-interval", "Routing", "The interval for updating the edge weights");
88 
89  oc.doRegister("device.rerouting.with-taz", new Option_Bool(false));
90  oc.addSynonyme("device.rerouting.with-taz", "device.routing.with-taz", true);
91  oc.addDescription("device.rerouting.with-taz", "Routing", "Use zones (districts) as routing end points");
92 
93  oc.doRegister("device.rerouting.init-with-loaded-weights", new Option_Bool(false));
94  oc.addDescription("device.rerouting.init-with-loaded-weights", "Routing", "Use given weight files for initializing edge weights");
95 
97  myEdgeEfforts.clear();
98 }
99 
100 
101 void
102 MSDevice_Routing::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into) {
103  bool needRerouting = v.getParameter().wasSet(VEHPARS_FORCE_REROUTE);
105  if (!needRerouting && oc.getFloat("device.rerouting.probability") == 0 && !oc.isSet("device.rerouting.explicit")) {
106  // no route computation is modelled
107  return;
108  }
109  needRerouting |= equippedByDefaultAssignmentOptions(OptionsCont::getOptions(), "rerouting", v);
110  if (needRerouting) {
111  // route computation is enabled
112  myWithTaz = oc.getBool("device.rerouting.with-taz");
113  // build the device
114  MSDevice_Routing* device = new MSDevice_Routing(v, "routing_" + v.getID(),
115  string2time(oc.getString("device.rerouting.period")),
116  string2time(oc.getString("device.rerouting.pre-period")));
117  into.push_back(device);
118  // initialise edge efforts if not done before
119  if (myEdgeEfforts.size() == 0) {
120  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
121  const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
122  const SUMOReal currentSecond = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
123  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
124  while ((*i)->getNumericalID() >= (int)myEdgeEfforts.size()) {
125  myEdgeEfforts.push_back(0);
126  }
127  if (useLoaded) {
128  myEdgeEfforts[(*i)->getNumericalID()] = MSNet::getTravelTime(*i, 0, currentSecond);
129  } else {
130  myEdgeEfforts[(*i)->getNumericalID()] = (*i)->getCurrentTravelTime();
131  }
132  }
133  }
134  // make the weights be updated
135  if (myEdgeWeightSettingCommand == 0) {
139  myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
140  myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
141  }
142  if (myWithTaz) {
143  if (MSEdge::dictionary(v.getParameter().fromTaz + "-source") == 0) {
144  WRITE_ERROR("Source district '" + v.getParameter().fromTaz + "' not known when rerouting '" + v.getID() + "'!");
145  return;
146  }
147  if (MSEdge::dictionary(v.getParameter().toTaz + "-sink") == 0) {
148  WRITE_ERROR("Destination district '" + v.getParameter().toTaz + "' not known when rerouting '" + v.getID() + "'!");
149  return;
150  }
151  }
152  }
153 }
154 
155 
156 // ---------------------------------------------------------------------------
157 // MSDevice_Routing-methods
158 // ---------------------------------------------------------------------------
159 MSDevice_Routing::MSDevice_Routing(SUMOVehicle& holder, const std::string& id,
160  SUMOTime period, SUMOTime preInsertionPeriod)
161  : MSDevice(holder, id), myPeriod(period), myPreInsertionPeriod(preInsertionPeriod), myRerouteCommand(0) {
162  if (myWithTaz) {
167  }
168 }
169 
170 
172  // make the rerouting command invalid if there is one
173  if (myRerouteCommand != 0) {
175  }
176 }
177 
178 
179 bool
182  if (myRerouteCommand != 0) { // clean up pre depart rerouting
183  if (myPreInsertionPeriod > 0) {
185  }
186  myRerouteCommand = 0;
187  }
188  if (!myWithTaz) {
189  wrappedRerouteCommandExecute(MSNet::getInstance()->getCurrentTimeStep());
190  }
191  // build repetition trigger if routing shall be done more often
192  if (myPeriod > 0) {
195  myRerouteCommand, myPeriod + MSNet::getInstance()->getCurrentTimeStep(),
197  }
198  }
199  return false;
200 }
201 
202 
203 SUMOTime
205  const MSEdge* source = MSEdge::dictionary(myHolder.getParameter().fromTaz + "-source");
206  const MSEdge* dest = MSEdge::dictionary(myHolder.getParameter().toTaz + "-sink");
207  if (source && dest) {
208  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
209  if (myCachedRoutes.find(key) == myCachedRoutes.end()) {
210  myHolder.reroute(currentTime, getRouter(), true);
211  myCachedRoutes[key] = &myHolder.getRoute();
213  } else {
215  }
216  }
217  return myPreInsertionPeriod;
218 }
219 
220 
221 SUMOTime
223  myHolder.reroute(currentTime, getRouter());
224  return myPeriod;
225 }
226 
227 
228 SUMOReal
229 MSDevice_Routing::getEffort(const MSEdge* const e, const SUMOVehicle* const v, SUMOReal) {
230  const int id = e->getNumericalID();
231  if (id < (int)myEdgeEfforts.size()) {
232  return MAX2(myEdgeEfforts[id], e->getMinimumTravelTime(v));
233  }
234  return 0;
235 }
236 
237 
238 SUMOTime
240  std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*>::iterator it = myCachedRoutes.begin();
241  for (; it != myCachedRoutes.end(); ++it) {
242  it->second->release();
243  }
244  myCachedRoutes.clear();
245  const SUMOReal newWeightFactor = (SUMOReal)(1. - myAdaptationWeight);
246  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
247  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
248  const int id = (*i)->getNumericalID();
249  myEdgeEfforts[id] = myEdgeEfforts[id] * myAdaptationWeight + (*i)->getCurrentTravelTime() * newWeightFactor;
250  }
251  return myAdaptationInterval;
252 }
253 
254 
257  if (myRouter == 0) {
258  const std::string routingAlgorithm = OptionsCont::getOptions().getString("routing-algorithm");
259  if (routingAlgorithm == "dijkstra") {
262  } else if (routingAlgorithm == "astar") {
265  } else {
266  throw ProcessError("Unknown routing Algorithm '" + routingAlgorithm + "'!");
267  }
268  }
269  return *myRouter;
270 }
271 
272 
273 void
275  delete myRouter;
276  myRouter = 0;
277 }
278 
279 
280 /****************************************************************************/
281