SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSTriggeredRerouter.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Reroutes vehicles passing an edge
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
12 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
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 <string>
34 #include <algorithm>
36 #include <utils/common/Command.h>
39 #include <utils/common/ToString.h>
40 #include <utils/xml/XMLSubSys.h>
46 #include <microsim/MSLane.h>
47 #include <microsim/MSVehicle.h>
48 #include <microsim/MSRoute.h>
49 #include <microsim/MSEdge.h>
50 #include <microsim/MSNet.h>
51 #include <microsim/MSGlobals.h>
52 #include "MSTriggeredRerouter.h"
53 
54 #ifdef HAVE_MESOSIM
55 #include <mesosim/MELoop.h>
56 #include <mesosim/MESegment.h>
57 #endif
58 
59 #ifdef CHECK_MEMORY_LEAKS
60 #include <foreign/nvwa/debug_new.h>
61 #endif // CHECK_MEMORY_LEAKS
62 
63 
64 // ===========================================================================
65 // method definitions
66 // ===========================================================================
70 
71 
72 // ===========================================================================
73 // method definitions
74 // ===========================================================================
76  const std::vector<MSEdge*> &edges,
77  SUMOReal prob, const std::string& file, bool off)
78  : MSTrigger(id), MSMoveReminder(), SUMOSAXHandler(file),
79  myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
80  // read in the trigger description
81  if (file != "" && !XMLSubSys::runParser(*this, file)) {
82  throw ProcessError();
83  }
84  // build actors
85  for (std::vector<MSEdge*>::const_iterator j = edges.begin(); j != edges.end(); ++j) {
86 #ifdef HAVE_MESOSIM
88  MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(**j);
89  s->addDetector(this);
90  continue;
91  }
92 #endif
93  const std::vector<MSLane*> &destLanes = (*j)->getLanes();
94  for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
95  (*i)->addMoveReminder(this);
96  }
97  }
98  if (off) {
99  setUserMode(true);
101  }
102 }
103 
104 
106 }
107 
108 // ------------ loading begin
109 void
111  const SUMOSAXAttributes& attrs) {
112  if (element == SUMO_TAG_INTERVAL) {
113  bool ok = true;
116  }
117 
120  WRITE_WARNING("'" + toString(SUMO_TAG_DEST_PROB_REROUTE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_DEST_PROB_REROUTE) + "'.");
121  }
123  // by giving probabilities of new destinations
124  // get the destination edge
125  std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
126  if (dest == "") {
127  throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
128  }
129  MSEdge* to = MSEdge::dictionary(dest);
130  if (to == 0) {
131  throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
132  }
133  // get the probability to reroute
134  bool ok = true;
135  SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
136  if (!ok) {
137  throw ProcessError();
138  }
139  if (prob < 0) {
140  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
141  }
142  // add
143  myCurrentEdgeProb.add(prob, to);
144  }
145 
148  WRITE_WARNING("'" + toString(SUMO_TAG_CLOSING_REROUTE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_CLOSING_REROUTE) + "'.");
149  }
150  if (element == SUMO_TAG_CLOSING_REROUTE || element == SUMO_TAG_CLOSING_REROUTE) {
151  // by closing
152  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
153  if (closed_id == "") {
154  throw ProcessError("MSTriggeredRerouter " + getID() + ": closed edge id given.");
155  }
156  MSEdge* closed = MSEdge::dictionary(closed_id);
157  if (closed == 0) {
158  throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
159  }
160  myCurrentClosed.push_back(closed);
161  }
162 
165  WRITE_WARNING("'" + toString(SUMO_TAG_ROUTE_PROB_REROUTE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_ROUTE_PROB_REROUTE) + "'.");
166  }
168  // by explicit rerouting using routes
169  // check if route exists
170  std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
171  if (routeStr == "") {
172  throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
173  }
174  const MSRoute* route = MSRoute::dictionary(routeStr);
175  if (route == 0) {
176  throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
177  }
178 
179  // get the probability to reroute
180  bool ok = true;
181  SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
182  if (!ok) {
183  throw ProcessError();
184  }
185  if (prob < 0) {
186  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
187  }
188  // add
189  myCurrentRouteProb.add(prob, route);
190  }
191 }
192 
193 
194 void
196  if (element == SUMO_TAG_INTERVAL) {
197  RerouteInterval ri;
200  ri.closed = myCurrentClosed;
203  myCurrentClosed.clear();
206  myIntervals.push_back(ri);
207  }
208 }
209 
210 
211 // ------------ loading end
212 
213 
214 bool
216  std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
217  const MSRoute& route = veh.getRoute();
218  while (i != myIntervals.end()) {
219  if ((*i).begin <= time && (*i).end >= time) {
220  if ((*i).edgeProbs.getOverallProb() != 0 || (*i).routeProbs.getOverallProb() != 0 || route.containsAnyOf((*i).closed)) {
221  return true;
222  }
223  }
224  i++;
225  }
226  return false;
227 }
228 
229 
230 bool
232  std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
233  while (i != myIntervals.end()) {
234  if ((*i).begin <= time && (*i).end >= time) {
235  if ((*i).edgeProbs.getOverallProb() != 0 || (*i).routeProbs.getOverallProb() != 0 || (*i).closed.size() != 0) {
236  return true;
237  }
238  }
239  i++;
240  }
241  return false;
242 }
243 
244 
247  std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
248  const MSRoute& route = veh.getRoute();
249  while (i != myIntervals.end()) {
250  if ((*i).begin <= time && (*i).end >= time) {
251  if ((*i).edgeProbs.getOverallProb() != 0 || (*i).routeProbs.getOverallProb() != 0 || route.containsAnyOf((*i).closed)) {
252  return *i;
253  }
254  }
255  i++;
256  }
257  throw 1;
258 }
259 
260 
263  std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
264  while (i != myIntervals.end()) {
265  if ((*i).edgeProbs.getOverallProb() != 0 || (*i).routeProbs.getOverallProb() != 0 || (*i).closed.size() != 0) {
266  return *i;
267  }
268  i++;
269  }
270  throw 1;
271 }
272 
273 
274 
275 bool
278  return false;
279  }
280  // check whether the vehicle shall be rerouted
282  if (!hasCurrentReroute(time, veh)) {
283  return false;
284  }
285 
287  if (RandHelper::rand() > prob) {
288  return false;
289  }
290 
291  // get vehicle params
292  const MSRoute& route = veh.getRoute();
293  const MSEdge* lastEdge = route.getLastEdge();
294  // get rerouting params
295  const MSTriggeredRerouter::RerouteInterval& rerouteDef = getCurrentReroute(time, veh);
296  const MSRoute* newRoute = rerouteDef.routeProbs.getOverallProb() > 0 ? rerouteDef.routeProbs.get() : 0;
297  // we will use the route if given rather than calling our own dijsktra...
298  if (newRoute != 0) {
299  veh.replaceRoute(newRoute);
300  return false;
301  }
302  // ok, try using a new destination
303  const MSEdge* newEdge = rerouteDef.edgeProbs.getOverallProb() > 0 ? rerouteDef.edgeProbs.get() : route.getLastEdge();
304  if (newEdge == 0) {
305  newEdge = lastEdge;
306  }
307 
308  // we have a new destination, let's replace the vehicle route
309  MSEdgeWeightsStorage empty;
310  MSNet::EdgeWeightsProxi proxi(empty, MSNet::getInstance()->getWeightsStorage());
312  router.prohibit(rerouteDef.closed);
313  std::vector<const MSEdge*> edges;
314  router.compute(veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
315  veh.replaceRouteEdges(edges);
316  return false;
317 }
318 
319 
320 void
322  myAmInUserMode = val;
323 }
324 
325 
326 void
328  myUserProbability = prob;
329 }
330 
331 
332 bool
334  return myAmInUserMode;
335 }
336 
337 
338 SUMOReal
341 }
342 
343 
344 SUMOReal
346  return myUserProbability;
347 }
348 
349 
350 
351 /****************************************************************************/
352