SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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.dlr.de/
12 // Copyright (C) 2001-2015 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>
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_INTERNAL
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 // static member defintion
66 // ===========================================================================
67 MSEdge MSTriggeredRerouter::mySpecialDest_keepDestination("MSTriggeredRerouter_keepDestination", -1, MSEdge::EDGEFUNCTION_UNKNOWN, "", "", -1);
68 MSEdge MSTriggeredRerouter::mySpecialDest_terminateRoute("MSTriggeredRerouter_terminateRoute", -1, MSEdge::EDGEFUNCTION_UNKNOWN, "", "", -1);
69 
70 // ===========================================================================
71 // method definitions
72 // ===========================================================================
74  const MSEdgeVector& edges,
75  SUMOReal prob, const std::string& file, bool off) :
76  MSTrigger(id),
77  MSMoveReminder(id),
78  SUMOSAXHandler(file),
79  myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
80  // build actors
81  for (MSEdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
82 #ifdef HAVE_INTERNAL
84  MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(**j);
85  s->addDetector(this);
86  continue;
87  }
88 #endif
89  const std::vector<MSLane*>& destLanes = (*j)->getLanes();
90  for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
91  (*i)->addMoveReminder(this);
92  }
93  }
94  if (off) {
95  setUserMode(true);
97  }
98 }
99 
100 
102 }
103 
104 // ------------ loading begin
105 void
107  const SUMOSAXAttributes& attrs) {
108  if (element == SUMO_TAG_INTERVAL) {
109  bool ok = true;
112  }
113  if (element == SUMO_TAG_DEST_PROB_REROUTE) {
114  // by giving probabilities of new destinations
115  // get the destination edge
116  std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
117  if (dest == "") {
118  throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
119  }
120  MSEdge* to = MSEdge::dictionary(dest);
121  if (to == 0) {
122  if (dest == "keepDestination") {
124  } else if (dest == "terminateRoute") {
126  } else {
127  throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
128  }
129  }
130  // get the probability to reroute
131  bool ok = true;
132  SUMOReal prob = attrs.getOpt<SUMOReal>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
133  if (!ok) {
134  throw ProcessError();
135  }
136  if (prob < 0) {
137  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
138  }
139  // add
140  myCurrentEdgeProb.add(prob, to);
141  }
142 
143  if (element == SUMO_TAG_CLOSING_REROUTE) {
144  // by closing
145  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
146  MSEdge* closed = MSEdge::dictionary(closed_id);
147  if (closed == 0) {
148  throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
149  }
150  myCurrentClosed.push_back(closed);
151  bool ok;
152  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
153  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
154  myCurrentPermissions = parseVehicleClasses(allow, disallow);
155  }
156 
157  if (element == SUMO_TAG_ROUTE_PROB_REROUTE) {
158  // by explicit rerouting using routes
159  // check if route exists
160  std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
161  if (routeStr == "") {
162  throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
163  }
164  const MSRoute* route = MSRoute::dictionary(routeStr);
165  if (route == 0) {
166  throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
167  }
168 
169  // get the probability to reroute
170  bool ok = true;
171  SUMOReal prob = attrs.getOpt<SUMOReal>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
172  if (!ok) {
173  throw ProcessError();
174  }
175  if (prob < 0) {
176  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
177  }
178  // add
179  myCurrentRouteProb.add(prob, route);
180  }
181 }
182 
183 
184 void
186  if (element == SUMO_TAG_INTERVAL) {
187  RerouteInterval ri;
190  ri.closed = myCurrentClosed;
194  myCurrentClosed.clear();
197  myIntervals.push_back(ri);
198  if (!ri.closed.empty() && ri.permissions != SVCAll) {
202  }
203  }
204 }
205 
206 
207 // ------------ loading end
208 
209 
210 SUMOTime
212  for (std::vector<RerouteInterval>::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
213  if (i->begin == currentTime && !i->closed.empty() && i->permissions != SVCAll) {
214  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
215  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
216  i->prevPermissions.push_back((*l)->getPermissions());
217  (*l)->setPermissions(i->permissions);
218  }
219  (*e)->rebuildAllowedLanes();
220  }
224  }
225  if (i->end == currentTime && !i->closed.empty() && i->permissions != SVCAll) {
226  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
227  std::vector<SVCPermissions>::const_iterator p = i->prevPermissions.begin();
228  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l, ++p) {
229  (*l)->setPermissions(*p);
230  }
231  (*e)->rebuildAllowedLanes();
232  }
233  }
234  }
235  return 0;
236 }
237 
238 
241  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
242  if (i->begin <= time && i->end > time) {
243  if (
244  // affected by closingReroute, possibly combined with destProbReroute (route prob makes no sense)
245  veh.getRoute().containsAnyOf(i->closed) ||
246  // no closingReroute but destProbReroute or routeProbReroute
247  i->edgeProbs.getOverallProb() > 0 || i->routeProbs.getOverallProb() > 0) {
248  return &*i;
249  }
250  }
251  }
252  return 0;
253 }
254 
255 
258  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
259  if (i->begin <= time && i->end > time) {
260  if (i->edgeProbs.getOverallProb() != 0 || i->routeProbs.getOverallProb() != 0 || !i->closed.empty()) {
261  return &*i;
262  }
263  }
264  }
265  return 0;
266 }
267 
268 
269 
270 bool
273  return false;
274  }
275  // check whether the vehicle shall be rerouted
277  const MSTriggeredRerouter::RerouteInterval* rerouteDef = getCurrentReroute(time, veh);
278  if (rerouteDef == 0) {
279  return false;
280  }
281 
283  if (RandHelper::rand() > prob) {
284  return false;
285  }
286 
287  // get vehicle params
288  const MSRoute& route = veh.getRoute();
289  const MSEdge* lastEdge = route.getLastEdge();
290  // get rerouting params
291  const MSRoute* newRoute = rerouteDef->routeProbs.getOverallProb() > 0 ? rerouteDef->routeProbs.get() : 0;
292  // we will use the route if given rather than calling our own dijsktra...
293  if (newRoute != 0) {
294  veh.replaceRoute(newRoute);
295  return false;
296  }
297  const MSEdge* newEdge = lastEdge;
298  // ok, try using a new destination
299  const bool destUnreachable = std::find(rerouteDef->closed.begin(), rerouteDef->closed.end(), lastEdge) != rerouteDef->closed.end();
300  // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination
301  if (rerouteDef->closed.size() == 0 || destUnreachable) {
302  newEdge = rerouteDef->edgeProbs.getOverallProb() > 0 ? rerouteDef->edgeProbs.get() : route.getLastEdge();
303  if (newEdge == &mySpecialDest_terminateRoute) {
304  newEdge = veh.getEdge();
305  } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) {
306  if (destUnreachable) {
307  WRITE_WARNING("Cannot keep destination for vehicle '" + veh.getID() + "' due to closed edges. Terminating route.");
308  newEdge = veh.getEdge();
309  } else {
310  newEdge = lastEdge;
311  }
312  } else if (newEdge == 0) {
313  assert(false); // this should never happen
314  newEdge = veh.getEdge();
315  }
316  }
317  // we have a new destination, let's replace the vehicle route
318  ConstMSEdgeVector edges;
320  veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
321  veh.replaceRouteEdges(edges);
322  return false;
323 }
324 
325 
326 void
328  myAmInUserMode = val;
329 }
330 
331 
332 void
334  myUserProbability = prob;
335 }
336 
337 
338 bool
340  return myAmInUserMode;
341 }
342 
343 
344 SUMOReal
347 }
348 
349 
350 SUMOReal
352  return myUserProbability;
353 }
354 
355 
356 
357 /****************************************************************************/
358 
MSEdgeVector closed
The list of closed edges.
virtual const MSRoute & getRoute() const =0
Returns the current route.
SUMOTime setPermissions(const SUMOTime currentTime)
Sets the edge permission if there are any defined in the closingEdge.
SVCPermissions myCurrentPermissions
List of permissions for closed edges.
RandomDistributor< MSEdge * > edgeProbs
The distributions of new destinations to use.
bool add(SUMOReal prob, T val, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:93
SUMOTime myCurrentIntervalBegin
The first and the last time steps of the interval.
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
void setUserUsageProbability(SUMOReal prob)
Sets the probability with which a vehicle is rerouted given by the user.
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:531
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
SUMOReal getUserProbability() const
Returns the rerouting probability given by the user.
const SVCPermissions SVCAll
void setUserMode(bool val)
Sets whether the process is currently steered by the user.
SAX-handler base for SUMO-files.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:235
The purpose of the edge is not known.
Definition: MSEdge.h:92
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
SUMOReal myProbability
The probability and the user-given probability.
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:81
virtual void myEndElement(int element)
Called when a closing tag occurs.
The vehicle changes lanes (micro only)
An abstract device that changes the state of the micro simulation.
Definition: MSTrigger.h:48
Representation of a vehicle.
Definition: SUMOVehicle.h:65
Encapsulated SAX-Attributes.
virtual ~MSTriggeredRerouter()
Destructor.
SUMOTime begin
The begin time these definitions are valid.
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:369
T get(MTRand *which=0) const
Draw a sample of the distribution.
A wrapper for a Command function.
RandomDistributor< const MSRoute * > myCurrentRouteProb
new routes with probabilities
static MSEdge mySpecialDest_keepDestination
special destination values
SUMOReal getProbability() const
Returns the rerouting probability.
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason)
Tries to reroute the vehicle.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
Something on a lane to be noticed about vehicle movement.
static MSEdge mySpecialDest_terminateRoute
const RerouteInterval * getCurrentReroute(SUMOTime time, SUMOVehicle &veh) const
Returns the rerouting definition valid for the given time and vehicle, 0 if none. ...
virtual SUMOTime addEvent(Command *operation, SUMOTime execTimeStep, AdaptType type)
Adds an Event.
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:790
RandomDistributor< MSEdge * > myCurrentEdgeProb
new destinations with probabilities
void clear()
Clears the distribution.
SUMOReal getOverallProb() const
Return the sum of the probabilites assigned to the members.
bool inUserMode() const
Returns whether the user is setting the rerouting probability.
SUMOTime end
The end time these definitions are valid.
RandomDistributor< const MSRoute * > routeProbs
The distributions of new routes to use.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
virtual bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)=0
Replaces the current route by the given one.
std::vector< RerouteInterval > myIntervals
List of rerouting definition intervals.
MSEdgeVector myCurrentClosed
List of closed edges.
bool myAmInUserMode
Information whether the current rerouting probability is the user-given.
int SUMOTime
Definition: SUMOTime.h:43
MSTriggeredRerouter(const std::string &id, const MSEdgeVector &edges, SUMOReal prob, const std::string &file, bool off)
Constructor.
Patch the time in a way that it is at least as high as the simulation begin time. ...
#define SUMOReal
Definition: config.h:218
static const bool gUseMesoSim
Definition: MSGlobals.h:102
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:78
SVCPermissions permissions
The permissions to use.
virtual const std::string & getID() const =0
Get the vehicle's ID.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:116
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:220