SUMO - Simulation of Urban MObility
MSTriggeredRerouter.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Reroutes vehicles passing an edge
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2017 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 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include <algorithm>
38 #include <utils/common/Command.h>
41 #include <utils/common/ToString.h>
48 #include <microsim/MSLane.h>
49 #include <microsim/MSVehicle.h>
50 #include <microsim/MSRoute.h>
51 #include <microsim/MSEdge.h>
52 #include <microsim/MSNet.h>
53 #include <microsim/MSGlobals.h>
55 #include "MSTriggeredRerouter.h"
56 
57 #include <mesosim/MELoop.h>
58 #include <mesosim/MESegment.h>
59 
60 #ifdef CHECK_MEMORY_LEAKS
61 #include <foreign/nvwa/debug_new.h>
62 #endif // CHECK_MEMORY_LEAKS
63 
64 //#define DEBUG_REROUTER
65 #define DEBUGCOND (veh.getID() == "disabled")
66 
67 // ===========================================================================
68 // static member defintion
69 // ===========================================================================
70 MSEdge MSTriggeredRerouter::mySpecialDest_keepDestination("MSTriggeredRerouter_keepDestination", -1, MSEdge::EDGEFUNCTION_UNKNOWN, "", "", -1);
71 MSEdge MSTriggeredRerouter::mySpecialDest_terminateRoute("MSTriggeredRerouter_terminateRoute", -1, MSEdge::EDGEFUNCTION_UNKNOWN, "", "", -1);
72 
73 // ===========================================================================
74 // method definitions
75 // ===========================================================================
77  const MSEdgeVector& edges,
78  SUMOReal prob, const std::string& file, bool off) :
79  MSTrigger(id),
80  MSMoveReminder(id),
81  SUMOSAXHandler(file),
82  myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
83  // build actors
84  for (MSEdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
87  s->addDetector(this);
88  continue;
89  }
90  const std::vector<MSLane*>& destLanes = (*j)->getLanes();
91  for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
92  (*i)->addMoveReminder(this);
93  }
94  }
95  if (off) {
96  setUserMode(true);
98  }
99 }
100 
101 
103 }
104 
105 // ------------ loading begin
106 void
108  const SUMOSAXAttributes& attrs) {
109  if (element == SUMO_TAG_INTERVAL) {
110  bool ok = true;
113  }
114  if (element == SUMO_TAG_DEST_PROB_REROUTE) {
115  // by giving probabilities of new destinations
116  // get the destination edge
117  std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
118  if (dest == "") {
119  throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
120  }
121  MSEdge* to = MSEdge::dictionary(dest);
122  if (to == 0) {
123  if (dest == "keepDestination") {
125  } else if (dest == "terminateRoute") {
127  } else {
128  throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
129  }
130  }
131  // get the probability to reroute
132  bool ok = true;
133  SUMOReal prob = attrs.getOpt<SUMOReal>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
134  if (!ok) {
135  throw ProcessError();
136  }
137  if (prob < 0) {
138  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
139  }
140  // add
141  myCurrentEdgeProb.add(prob, to);
142  }
143 
144 
145  if (element == SUMO_TAG_CLOSING_REROUTE) {
146  // by closing
147  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
148  MSEdge* closed = MSEdge::dictionary(closed_id);
149  if (closed == 0) {
150  throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
151  }
152  myCurrentClosed.push_back(closed);
153  bool ok;
154  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
155  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
156  myCurrentPermissions = parseVehicleClasses(allow, disallow);
157  }
158 
159  if (element == SUMO_TAG_CLOSING_LANE_REROUTE) {
160  // by closing lane
161  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
162  MSLane* closed = MSLane::dictionary(closed_id);
163  if (closed == 0) {
164  throw ProcessError("MSTriggeredRerouter " + getID() + ": Lane '" + closed_id + "' to close is not known.");
165  }
166  myCurrentClosedLanes.push_back(closed);
167  bool ok;
169  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
170  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
171  myCurrentPermissions = parseVehicleClasses(allow, disallow);
172  } else {
173  // lane closing only makes sense if the lane really receives reduced
174  // permissions
176  }
177  }
178 
179  if (element == SUMO_TAG_ROUTE_PROB_REROUTE) {
180  // by explicit rerouting using routes
181  // check if route exists
182  std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
183  if (routeStr == "") {
184  throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
185  }
186  const MSRoute* route = MSRoute::dictionary(routeStr);
187  if (route == 0) {
188  throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
189  }
190 
191  // get the probability to reroute
192  bool ok = true;
193  SUMOReal prob = attrs.getOpt<SUMOReal>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
194  if (!ok) {
195  throw ProcessError();
196  }
197  if (prob < 0) {
198  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
199  }
200  // add
201  myCurrentRouteProb.add(prob, route);
202  }
203 
204  if (element == SUMO_TAG_PARKING_ZONE_REROUTE) {
205  // by giving probabilities of new destinations
206  // get the destination edge
207  std::string parkingarea = attrs.getStringSecure(SUMO_ATTR_ID, "");
208  if (parkingarea == "") {
209  throw ProcessError("MSTriggeredRerouter " + getID() + ": No parking area id given.");
210  }
211  MSParkingArea* pa = MSNet::getInstance()->getParkingArea(parkingarea);
212  if (pa == 0) {
213  throw ProcessError("MSTriggeredRerouter " + getID() + ": Parking area '" + parkingarea + "' is not known.");
214  }
215  // get the probability to reroute
216  bool ok = true;
217  SUMOReal prob = attrs.getOpt<SUMOReal>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
218  if (!ok) {
219  throw ProcessError();
220  }
221  if (prob < 0) {
222  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + parkingarea + "' is negative (must not).");
223  }
224  // add
225  myCurrentParkProb.add(prob, pa);
226  //MSEdge* to = &(pa->getLane().getEdge());
227  //myCurrentEdgeProb.add(prob, to);
228  }
229 }
230 
231 
232 void
234  if (element == SUMO_TAG_INTERVAL) {
235  RerouteInterval ri;
238  ri.closed = myCurrentClosed;
244  if (ri.closedLanes.size() > 0) {
245  // collect edges that are affect by a closed lane
246  std::set<MSEdge*> affected;
247  for (std::vector<MSLane*>::iterator l = ri.closedLanes.begin(); l != ri.closedLanes.end(); ++l) {
248  affected.insert(&((*l)->getEdge()));
249  }
250  ri.closedLanesAffected.insert(ri.closedLanesAffected.begin(), affected.begin(), affected.end());
251  }
252  myCurrentClosed.clear();
253  myCurrentClosedLanes.clear();
257  myIntervals.push_back(ri);
258  myIntervals.back().id = (long)&myIntervals.back();
259  if (!(ri.closed.empty() && ri.closedLanes.empty()) && ri.permissions != SVCAll) {
263  }
264  }
265 }
266 
267 
268 // ------------ loading end
269 
270 
271 SUMOTime
273  for (std::vector<RerouteInterval>::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
274  if (i->begin == currentTime && !(i->closed.empty() && i->closedLanes.empty()) && i->permissions != SVCAll) {
275  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
276  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
277  //std::cout << SIMTIME << " closing: intervalID=" << i->id << " lane=" << (*l)->getID() << " prevPerm=" << getVehicleClassNames((*l)->getPermissions()) << " new=" << getVehicleClassNames(i->permissions) << "\n";
278  (*l)->setPermissions(i->permissions, i->id);
279  }
280  (*e)->rebuildAllowedLanes();
281  }
282  for (std::vector<MSLane*>::iterator l = i->closedLanes.begin(); l != i->closedLanes.end(); ++l) {
283  (*l)->setPermissions(i->permissions, i->id);
284  (*l)->getEdge().rebuildAllowedLanes();
285  }
289  }
290  if (i->end == currentTime && !(i->closed.empty() && i->closedLanes.empty()) && i->permissions != SVCAll) {
291  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
292  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
293  (*l)->resetPermissions(i->id);
294  //std::cout << SIMTIME << " opening: intervalID=" << i->id << " lane=" << (*l)->getID() << " restore prevPerm=" << getVehicleClassNames((*l)->getPermissions()) << "\n";
295  }
296  (*e)->rebuildAllowedLanes();
297  }
298  for (std::vector<MSLane*>::iterator l = i->closedLanes.begin(); l != i->closedLanes.end(); ++l) {
299  (*l)->resetPermissions(i->id);
300  (*l)->getEdge().rebuildAllowedLanes();
301  }
302  }
303  }
304  return 0;
305 }
306 
307 
310  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
311  if (i->begin <= time && i->end > time) {
312  if (
313  // destProbReroute
314  i->edgeProbs.getOverallProb() > 0 ||
315  // routeProbReroute
316  i->routeProbs.getOverallProb() > 0 ||
317  // parkingZoneReroute
318  i->parkProbs.getOverallProb() > 0 ||
319  // affected by closingReroute
320  veh.getRoute().containsAnyOf(i->closed) ||
321  // affected by closingLaneReroute
322  veh.getRoute().containsAnyOf(i->closedLanesAffected)) {
323  return &*i;
324  }
325  }
326  }
327  return 0;
328 }
329 
330 
333  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
334  if (i->begin <= time && i->end > time) {
335  if (i->parkProbs.getOverallProb() != 0 || i->edgeProbs.getOverallProb() != 0 || i->routeProbs.getOverallProb() != 0 || !i->closed.empty()) {
336  return &*i;
337  }
338  }
339  }
340  return 0;
341 }
342 
343 
344 bool
346  SUMOReal /*newPos*/, SUMOReal /*newSpeed*/) {
347  return notifyEnter(veh, NOTIFICATION_JUNCTION);
348 }
349 
350 
351 bool
354  return reason == NOTIFICATION_LANE_CHANGE;
355 }
356 
357 
358 bool
360  // check whether the vehicle shall be rerouted
362  const MSTriggeredRerouter::RerouteInterval* rerouteDef = getCurrentReroute(time, veh);
363  if (rerouteDef == 0) {
364  return true; // an active interval could appear later
365  }
367  if (RandHelper::rand() > prob) {
368  return false; // XXX another interval could appear later but we would have to track whether the current interval was already tried
369  }
370  // if we have a closingLaneReroute, only vehicles with a rerouting device can profit from rerouting (otherwise, edge weights will not reflect local jamming)
371  const bool hasReroutingDevice = veh.getDevice(typeid(MSDevice_Routing)) != 0;
372  if (rerouteDef->closedLanes.size() > 0 && !hasReroutingDevice) {
373  return true; // an active interval could appear later
374  }
375  // get vehicle params
376  const MSRoute& route = veh.getRoute();
377  const MSEdge* lastEdge = route.getLastEdge();
378 #ifdef DEBUG_REROUTER
379  if (DEBUGCOND) {
380  std::cout << SIMTIME << " veh=" << veh.getID() << " check rerouter " << getID() << " lane=" << veh.getLane()->getID() << " edge=" << veh.getEdge()->getID() << " finalEdge=" << lastEdge->getID() << " arrivalPos=" << veh.getArrivalPos() << "\n";
381  }
382 #endif
383 
384  if (rerouteDef->parkProbs.getOverallProb() > 0) {
385  MSParkingArea* newParkingArea = rerouteParkingZone(rerouteDef, veh);
386  if (newParkingArea != 0) {
387  const MSEdge* newEdge = &(newParkingArea->getLane().getEdge());
388 
389  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
391  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
392 
393  // Compute the route from the current edge to the parking area edge
394  ConstMSEdgeVector edgesToPark;
395  router.compute(veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
396 
397  // Compute the route from the parking area edge to the end of the route
398  ConstMSEdgeVector edgesFromPark;
399  router.compute(newEdge, lastEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
400 
401  // we have a new destination, let's replace the vehicle route
402  ConstMSEdgeVector edges = edgesToPark;
403  if (edgesFromPark.size() > 0) {
404  edges.insert(edges.end(), edgesFromPark.begin() + 1, edgesFromPark.end());
405  }
406 
407  veh.replaceRouteEdges(edges, false, false, false);
408  std::string errorMsg;
409  if (!veh.replaceParkingArea(newParkingArea, errorMsg)) {
410  WRITE_WARNING("Vehicle '" + veh.getID() + "' at rerouter '" + getID()
411  + "' could not reroute to new parkingArea '" + newParkingArea->getID()
412  + "' reason=" + errorMsg + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
413  }
414  }
415  return false;
416  }
417 
418  // get rerouting params
419  const MSRoute* newRoute = rerouteDef->routeProbs.getOverallProb() > 0 ? rerouteDef->routeProbs.get() : 0;
420  // we will use the route if given rather than calling our own dijsktra...
421  if (newRoute != 0) {
422 #ifdef DEBUG_REROUTER
423  if (DEBUGCOND) {
424  std::cout << " replacedRoute from routeDist " << newRoute->getID() << "\n";
425  }
426 #endif
427  veh.replaceRoute(newRoute);
428  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
429  }
430  const MSEdge* newEdge = lastEdge;
431  // ok, try using a new destination
432  SUMOReal newArrivalPos = -1;
433  const bool destUnreachable = std::find(rerouteDef->closed.begin(), rerouteDef->closed.end(), lastEdge) != rerouteDef->closed.end();
434  // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination
435  // if we have a closingLaneReroute, no new destinations should be assigned
436  if (rerouteDef->closed.size() == 0 || destUnreachable) {
437  newEdge = rerouteDef->edgeProbs.getOverallProb() > 0 ? rerouteDef->edgeProbs.get() : route.getLastEdge();
438  if (newEdge == &mySpecialDest_terminateRoute) {
439  newEdge = veh.getEdge();
440  newArrivalPos = veh.getPositionOnLane(); // instant arrival
441  } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) {
442  if (destUnreachable && rerouteDef->permissions == SVCAll) {
443  // if permissions aren't set vehicles will simply drive through
444  // the closing unless terminated. If the permissions are specified, assume that the user wants
445  // vehicles to stand and wait until the closing ends
446  WRITE_WARNING("Cannot keep destination edge '" + lastEdge->getID() + "' for vehicle '" + veh.getID() + "' due to closed edges. Terminating route.");
447  newEdge = veh.getEdge();
448  } else {
449  newEdge = lastEdge;
450  }
451  } else if (newEdge == 0) {
452 #ifdef DEBUG_REROUTER
453  if (DEBUGCOND) {
454  std::cout << " could not find new edge!\n";
455  }
456 #endif
457  assert(false); // this should never happen
458  newEdge = veh.getEdge();
459  }
460  }
461  // we have a new destination, let's replace the vehicle route (if it is affected)
462  if (rerouteDef->closed.size() == 0 || destUnreachable || veh.getRoute().containsAnyOf(rerouteDef->closed)) {
463  ConstMSEdgeVector edges;
464  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
466  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
467  router.compute(
468  veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
469  const bool useNewRoute = veh.replaceRouteEdges(edges);
470 #ifdef DEBUG_REROUTER
471  if (DEBUGCOND) std::cout << " rerouting: newEdge=" << newEdge->getID() << " useNewRoute=" << useNewRoute << " newArrivalPos=" << newArrivalPos << " numClosed=" << rerouteDef->closed.size()
472  << " destUnreachable=" << destUnreachable << " containsClosed=" << veh.getRoute().containsAnyOf(rerouteDef->closed) << "\n";
473 #endif
474  if (useNewRoute && newArrivalPos != -1) {
475  // must be called here because replaceRouteEdges may also set the arrivalPos
476  veh.setArrivalPos(newArrivalPos);
477  }
478  }
479  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
480 }
481 
482 
483 void
485  myAmInUserMode = val;
486 }
487 
488 
489 void
491  myUserProbability = prob;
492 }
493 
494 
495 bool
497  return myAmInUserMode;
498 }
499 
500 
501 SUMOReal
504 }
505 
506 
507 SUMOReal
509  return myUserProbability;
510 }
511 
512 
513 SUMOReal
514 MSTriggeredRerouter::getWeight(SUMOVehicle& veh, const std::string param, const SUMOReal defaultWeight) const {
515  // get custom vehicle parameter
516  if (veh.getParameter().knowsParameter(param)) {
517  try {
518  return TplConvert::_2SUMOReal(veh.getParameter().getParameter(param, "-1").c_str());
519  } catch (...) {
520  WRITE_WARNING("Invalid value '" + veh.getParameter().getParameter(param, "-1") + "' for vehicle parameter '" + param + "'");
521  }
522  } else {
523  // get custom vType parameter
524  if (veh.getVehicleType().getParameter().knowsParameter(param)) {
525  try {
526  return TplConvert::_2SUMOReal(veh.getVehicleType().getParameter().getParameter(param, "-1").c_str());
527  } catch (...) {
528  WRITE_WARNING("Invalid value '" + veh.getVehicleType().getParameter().getParameter(param, "-1") + "' for vType parameter '" + param + "'");
529  }
530  }
531  }
532  //WRITE_MESSAGE("Vehicle '" +veh.getID() + "' does not supply vehicle parameter '" + param + "'. Using default of " + toString(defaultWeight) + "\n";
533  return defaultWeight;
534 }
535 
536 
539 
540  MSParkingArea* nearParkArea = 0;
541 
542  // get vehicle params
543  MSParkingArea* destParkArea = veh.getNextParkingArea();
544  const MSRoute& route = veh.getRoute();
545 
546  // I reroute destination from initial parking area to the near parking area
547  // if the next stop is a parking area and if it is full
548  if (destParkArea != 0 &&
549  destParkArea->getOccupancy() == destParkArea->getCapacity()) {
550 
551  typedef std::map<std::string, SUMOReal> ParkingParamMap_t;
552  typedef std::map<MSParkingArea*, ParkingParamMap_t> MSParkingAreaMap_t;
553 
554  ParkingParamMap_t weights;
555 
556  // The probability of choosing this area inside the zone
557  weights["probability"] = getWeight(veh, "parking.probability.weight", 0.0);
558 
559  // The capacity of this area
560  weights["capacity"] = getWeight(veh, "parking.capacity.weight", 0.0);
561 
562  // The absolute number of free spaces
563  weights["absfreespace"] = getWeight(veh, "parking.absfreespace.weight", 0.0);
564 
565  // The relative number of free spaces
566  weights["relfreespace"] = getWeight(veh, "parking.relfreespace.weight", 0.0);
567 
568  // The distance to the new parking area
569  weights["distanceto"] = getWeight(veh, "parking.distanceto.weight", getWeight(veh, "parking.distance.weight", 1.0));
570 
571  // The time to reach this area
572  weights["timeto"] = getWeight(veh, "parking.timeto.weight", 0.0);
573 
574  // The distance from the new parking area
575  weights["distancefrom"] = getWeight(veh, "parking.distancefrom.weight", 0.0);
576 
577  // The time to reach the end from this area
578  weights["timefrom"] = getWeight(veh, "parking.timefrom.weight", 0.0);
579 
580  // a map stores maximum values to normalize parking values
581  ParkingParamMap_t maxValues;
582 
583  maxValues["probability"] = 0.0;
584  maxValues["capacity"] = 0.0;
585  maxValues["absfreespace"] = 0.0;
586  maxValues["relfreespace"] = 0.0;
587  maxValues["distanceto"] = 0.0;
588  maxValues["timeto"] = 0.0;
589  maxValues["distancefrom"] = 0.0;
590  maxValues["timefrom"] = 0.0;
591 
592  // a map stores elegible parking areas
593  MSParkingAreaMap_t parkAreas;
594 
596 
597  std::vector<MSParkingArea*> parks = rerouteDef->parkProbs.getVals();
598  std::vector<SUMOReal> probs = rerouteDef->parkProbs.getProbs();
599 
600  for (int i = 0; i < (int)parks.size(); ++i) {
601  MSParkingArea* pa = parks[i];
602  const SUMOReal prob = probs[i];
603  if (pa->getOccupancy() < pa->getCapacity()) {
604 
605  // a map stores the parking values
606  ParkingParamMap_t parkValues;
607 
608  const RGBColor& c = route.getColor();
609  const MSEdge* parkEdge = &(pa->getLane().getEdge());
610 
611  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
612 
613  // Compute the route from the current edge to the parking area edge
614  ConstMSEdgeVector edgesToPark;
615  router.compute(veh.getEdge(), parkEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
616 
617  if (edgesToPark.size() > 0) {
618  // Compute the route from the parking area edge to the end of the route
619  ConstMSEdgeVector edgesFromPark;
620  router.compute(parkEdge, route.getLastEdge(), &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
621 
622  if (edgesFromPark.size() > 0) {
623 
624  parkValues["probability"] = prob;
625 
626  if (parkValues["probability"] > maxValues["probability"]) {
627  maxValues["probability"] = parkValues["probability"];
628  }
629 
630  parkValues["capacity"] = (double)(pa->getCapacity());
631  parkValues["absfreespace"] = (double)(pa->getCapacity() - pa->getOccupancy());
632  parkValues["relfreespace"] = parkValues["absfreespace"] / parkValues["capacity"];
633 
634  if (parkValues["capacity"] > maxValues["capacity"]) {
635  maxValues["capacity"] = parkValues["capacity"];
636  }
637 
638  if (parkValues["absfreespace"] > maxValues["absfreespace"]) {
639  maxValues["absfreespace"] = parkValues["absfreespace"];
640  }
641 
642  if (parkValues["relfreespace"] > maxValues["relfreespace"]) {
643  maxValues["relfreespace"] = parkValues["relfreespace"];
644  }
645 
646  MSRoute routeToPark(route.getID() + "!topark#1", edgesToPark, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
647 
648  // The distance from the current edge to the new parking area
649  parkValues["distanceto"] = routeToPark.getDistanceBetween(veh.getPositionOnLane(), pa->getBeginLanePosition(),
650  routeToPark.begin(), routeToPark.end(), includeInternalLengths);
651 
652  // The time to reach the new parking area
653  parkValues["timeto"] = router.recomputeCosts(edgesToPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
654 
655  if (parkValues["distanceto"] > maxValues["distanceto"]) {
656  maxValues["distanceto"] = parkValues["distanceto"];
657  }
658 
659  if (parkValues["timeto"] > maxValues["timeto"]) {
660  maxValues["timeto"] = parkValues["timeto"];
661  }
662 
663  MSRoute routeFromPark(route.getID() + "!frompark#1", edgesFromPark, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
664 
665  // The distance from the new parking area to the end of the route
666  parkValues["distancefrom"] = routeFromPark.getDistanceBetween(pa->getBeginLanePosition(), routeFromPark.getLastEdge()->getLength(),
667  routeFromPark.begin(), routeFromPark.end(), includeInternalLengths);
668 
669  // The time to reach this area
670  parkValues["timefrom"] = router.recomputeCosts(edgesFromPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
671 
672  if (parkValues["distancefrom"] > maxValues["distancefrom"]) {
673  maxValues["distancefrom"] = parkValues["distancefrom"];
674  }
675 
676  if (parkValues["timefrom"] > maxValues["timefrom"]) {
677  maxValues["timefrom"] = parkValues["timefrom"];
678  }
679 
680  parkAreas[pa] = parkValues;
681  }
682  }
683  }
684  }
685 
686  // minimum cost to get the parking area
687  SUMOReal minParkingCost = 0.0;
688 
689  for (MSParkingAreaMap_t::iterator it = parkAreas.begin(); it != parkAreas.end(); ++it) {
690  // get the parking values
691  ParkingParamMap_t parkValues = it->second;
692 
693  // normalizing parking values with maximum values (we want to maximize some parameters then we reverse the value)
694  parkValues["probability"] = maxValues["probability"] > 0.0 ? 1.0 - parkValues["probability"] / maxValues["probability"] : 0.0;
695  parkValues["capacity"] = maxValues["capacity"] > 0.0 ? 1.0 - parkValues["capacity"] / maxValues["capacity"] : 0.0;
696  parkValues["absfreespace"] = maxValues["absfreespace"] > 0.0 ? 1.0 - parkValues["absfreespace"] / maxValues["absfreespace"] : 0.0;
697  parkValues["relfreespace"] = maxValues["relfreespace"] > 0.0 ? 1.0 - parkValues["relfreespace"] / maxValues["relfreespace"] : 0.0;
698 
699  parkValues["distanceto"] = maxValues["distanceto"] > 0.0 ? parkValues["distanceto"] / maxValues["distanceto"] : 0.0;
700  parkValues["timeto"] = maxValues["timeto"] > 0.0 ? parkValues["timeto"] / maxValues["timeto"] : 0.0;
701 
702  parkValues["distancefrom"] = maxValues["distancefrom"] > 0.0 ? parkValues["distancefrom"] / maxValues["distancefrom"] : 0.0;
703  parkValues["timefrom"] = maxValues["timefrom"] > 0.0 ? parkValues["timefrom"] / maxValues["timefrom"] : 0.0;
704 
705  // get the parking area cost
706  SUMOReal parkingCost = 0.0;
707 
708  // sum every index with its weight
709  for (ParkingParamMap_t::iterator pc = parkValues.begin(); pc != parkValues.end(); ++pc) {
710  parkingCost += weights[pc->first] * pc->second;
711  }
712 
713  // get the parking area with minimum cost
714  if (nearParkArea == 0 || parkingCost < minParkingCost) {
715  minParkingCost = parkingCost;
716  nearParkArea = it->first;
717  }
718  }
719  }
720 
721  return nearParkArea;
722 }
723 
724 /****************************************************************************/
725 
virtual MSLane * getLane() const =0
Returns the lane the vehicle is on.
#define DEBUGCOND
A lane area vehicles can halt at.
Definition: MSParkingArea.h:66
int getCapacity() const
Returns the area capacity.
int getOccupancy() const
Returns the area occupancy.
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:571
MSEdgeVector closed
The list of closed edges.
virtual bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0, bool addStops=true)=0
Replaces the current route by the given one.
long long int SUMOTime
Definition: SUMOTime.h:43
bool notifyMove(SUMOVehicle &veh, SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Triggers rerouting (once) for vehicles that are already on the edge when the rerouter activates...
virtual MSParkingArea * getNextParkingArea()=0
const std::vector< SUMOReal > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
MSParkingArea * getParkingArea(const std::string &id) const
Returns the named parking area.
Definition: MSNet.cpp:854
SUMOTime setPermissions(const SUMOTime currentTime)
Sets the edge permission if there are any defined in the closingEdge.
static SUMOReal _2SUMOReal(const E *const data)
converts a char-type array into the SUMOReal value described by it
Definition: TplConvert.h:297
SVCPermissions myCurrentPermissions
List of permissions for closed edges.
RandomDistributor< MSEdge * > edgeProbs
The distributions of new destinations to use.
The vehicle arrived at a junction.
lane of a reroute of type closing
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:96
SUMOTime myCurrentIntervalBegin
The first and the last time steps of the interval.
bool notifyLeave(SUMOVehicle &veh, SUMOReal lastPos, MSMoveReminder::Notification reason)
Removes the reminder.
std::vector< MSLane * > myCurrentClosedLanes
List of closed lanes.
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:670
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
A device that performs vehicle rerouting based on current edge speeds.
virtual SUMOReal recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime) const =0
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
weights: time range begin
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
virtual bool 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...
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&#39;t already in the dictionary...
Definition: MSEdge.cpp:693
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
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.
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:358
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
SAX-handler base for SUMO-files.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
The purpose of the edge is not known.
Definition: MSEdge.h:91
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
#define SIMTIME
Definition: SUMOTime.h:70
const std::vector< T > & getVals() const
Returns the members of the distribution.
authorities vehicles
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.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOReal myProbability
The probability and the user-given probability.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
virtual void myEndElement(int element)
Called when a closing tag occurs.
The vehicle changes lanes (micro only) XXX: What if a vehicle changes lanes and passes a junction sim...
const MSLane & getLane() const
Returns the lane this stop is located at.
const SUMOVTypeParameter & getParameter() const
virtual SUMOReal getPositionOnLane() const =0
Get the vehicle&#39;s position along the lane.
An abstract device that changes the state of the micro simulation.
Definition: MSTrigger.h:48
Representation of a vehicle.
Definition: SUMOVehicle.h:67
Encapsulated SAX-Attributes.
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:285
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:200
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:401
T get(MTRand *which=0) const
Draw a sample of the distribution.
A wrapper for a Command function.
RandomDistributor< MSParkingArea * > myCurrentParkProb
new destinations with probabilities
RandomDistributor< const MSRoute * > myCurrentRouteProb
new routes with probabilities
static MSEdge mySpecialDest_keepDestination
special destination values
void addDetector(MSMoveReminder *data)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:209
SUMOReal getProbability() const
Returns the rerouting probability.
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason)
Tries to reroute the vehicle.
probability of route of a reroute
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:73
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
probability of destiny of a reroute
Something on a lane to be noticed about vehicle movement.
static MSEdge mySpecialDest_terminateRoute
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
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.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:896
RandomDistributor< MSEdge * > myCurrentEdgeProb
new destinations with probabilities
reroute of type closing
void clear()
Clears the distribution.
entry for an alternative parking zone
SUMOReal getOverallProb() const
Return the sum of the probabilites assigned to the members.
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1317
SUMOReal getWeight(SUMOVehicle &veh, const std::string param, const SUMOReal defaultWeight) const
RandomDistributor< MSParkingArea * > parkProbs
The distributions of new parking areas to use as destinations.
virtual const MSRoute & getRoute() const =0
Returns the current route.
bool inUserMode() const
Returns whether the user is setting the rerouting probability.
SUMOTime end
The end time these definitions are valid.
std::vector< MSLane * > closedLanes
The list of closed lanes.
RandomDistributor< const MSRoute * > routeProbs
The distributions of new routes to use.
weights: time range end
A single mesoscopic segment (cell)
Definition: MESegment.h:57
SUMOReal getBeginLanePosition() const
Returns the begin position of this stop.
std::vector< RerouteInterval > myIntervals
List of rerouting definition intervals.
MESegment * getSegmentForEdge(const MSEdge &e, SUMOReal pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:293
MSEdgeVector myCurrentClosed
List of closed edges.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
bool myAmInUserMode
Information whether the current rerouting probability is the user-given.
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:110
MSTriggeredRerouter(const std::string &id, const MSEdgeVector &edges, SUMOReal prob, const std::string &file, bool off)
Constructor.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
an aggreagated-output interval
Patch the time in a way that it is at least as high as the simulation begin time. ...
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:349
#define SUMOReal
Definition: config.h:208
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
MSParkingArea * rerouteParkingZone(const MSTriggeredRerouter::RerouteInterval *rerouteDef, SUMOVehicle &veh) const
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.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
virtual SUMOReal getArrivalPos() const =0
Returns this vehicle&#39;s desired arrivalPos for its current route (may change on reroute) ...
SVCPermissions permissions
The permissions to use.
static bool gUseMesoSim
Definition: MSGlobals.h:95
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
MSEdgeVector closedLanesAffected
The list of edges that are affect by closed lanes.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:122
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:247
virtual MSDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.