SUMO - Simulation of Urban MObility
MSTriggeredRerouter.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
20 // Reroutes vehicles passing an edge
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>
37 #include <utils/common/Command.h>
40 #include <utils/common/ToString.h>
47 #include <microsim/MSLane.h>
48 #include <microsim/MSVehicle.h>
49 #include <microsim/MSRoute.h>
50 #include <microsim/MSEdge.h>
52 #include <microsim/MSNet.h>
53 #include <microsim/MSGlobals.h>
54 #include <microsim/MSParkingArea.h>
56 #include "MSTriggeredRerouter.h"
57 
58 #include <mesosim/MELoop.h>
59 #include <mesosim/MESegment.h>
60 
61 //#define DEBUG_REROUTER
62 //#define DEBUG_PARKING
63 #define DEBUGCOND (veh.isSelected())
64 
65 // ===========================================================================
66 // static member defintion
67 // ===========================================================================
68 MSEdge MSTriggeredRerouter::mySpecialDest_keepDestination("MSTriggeredRerouter_keepDestination", -1, EDGEFUNC_UNKNOWN, "", "", -1);
69 MSEdge MSTriggeredRerouter::mySpecialDest_terminateRoute("MSTriggeredRerouter_terminateRoute", -1, EDGEFUNC_UNKNOWN, "", "", -1);
70 
71 // ===========================================================================
72 // method definitions
73 // ===========================================================================
75  const MSEdgeVector& edges,
76  double prob, const std::string& file, bool off,
77  SUMOTime timeThreshold) :
78  MSTrigger(id),
79  MSMoveReminder(id),
80  SUMOSAXHandler(file),
81  myProbability(prob),
82  myUserProbability(prob),
83  myAmInUserMode(false),
84  myTimeThreshold(timeThreshold) {
85  // build actors
86  for (MSEdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
89  s->addDetector(this);
90  continue;
91  }
92  const std::vector<MSLane*>& destLanes = (*j)->getLanes();
93  for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
94  (*i)->addMoveReminder(this);
95  }
96  }
97  if (off) {
98  setUserMode(true);
100  }
101 }
102 
103 
105 }
106 
107 // ------------ loading begin
108 void
110  const SUMOSAXAttributes& attrs) {
111  if (element == SUMO_TAG_INTERVAL) {
112  bool ok = true;
115  }
116  if (element == SUMO_TAG_DEST_PROB_REROUTE) {
117  // by giving probabilities of new destinations
118  // get the destination edge
119  std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
120  if (dest == "") {
121  throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
122  }
123  MSEdge* to = MSEdge::dictionary(dest);
124  if (to == 0) {
125  if (dest == "keepDestination") {
127  } else if (dest == "terminateRoute") {
129  } else {
130  throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
131  }
132  }
133  // get the probability to reroute
134  bool ok = true;
135  double prob = attrs.getOpt<double>(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(to, prob);
144  }
145 
146 
147  if (element == SUMO_TAG_CLOSING_REROUTE) {
148  // by closing
149  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
150  MSEdge* closed = MSEdge::dictionary(closed_id);
151  if (closed == 0) {
152  throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
153  }
154  myCurrentClosed.push_back(closed);
155  bool ok;
156  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
157  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
158  myCurrentPermissions = parseVehicleClasses(allow, disallow);
159  }
160 
161  if (element == SUMO_TAG_CLOSING_LANE_REROUTE) {
162  // by closing lane
163  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
164  MSLane* closed = MSLane::dictionary(closed_id);
165  if (closed == 0) {
166  throw ProcessError("MSTriggeredRerouter " + getID() + ": Lane '" + closed_id + "' to close is not known.");
167  }
168  myCurrentClosedLanes.push_back(closed);
169  bool ok;
171  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
172  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
173  myCurrentPermissions = parseVehicleClasses(allow, disallow);
174  } else {
175  // lane closing only makes sense if the lane really receives reduced
176  // permissions
178  }
179  }
180 
181  if (element == SUMO_TAG_ROUTE_PROB_REROUTE) {
182  // by explicit rerouting using routes
183  // check if route exists
184  std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
185  if (routeStr == "") {
186  throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
187  }
188  const MSRoute* route = MSRoute::dictionary(routeStr);
189  if (route == 0) {
190  throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
191  }
192 
193  // get the probability to reroute
194  bool ok = true;
195  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
196  if (!ok) {
197  throw ProcessError();
198  }
199  if (prob < 0) {
200  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
201  }
202  // add
203  myCurrentRouteProb.add(route, prob);
204  }
205 
206  if (element == SUMO_TAG_PARKING_ZONE_REROUTE) {
207  // by giving probabilities of new destinations
208  // get the destination edge
209  std::string parkingarea = attrs.getStringSecure(SUMO_ATTR_ID, "");
210  if (parkingarea == "") {
211  throw ProcessError("MSTriggeredRerouter " + getID() + ": No parking area id given.");
212  }
214  if (pa == 0) {
215  throw ProcessError("MSTriggeredRerouter " + getID() + ": Parking area '" + parkingarea + "' is not known.");
216  }
217  // get the probability to reroute
218  bool ok = true;
219  const double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
220  if (!ok) {
221  throw ProcessError();
222  }
223  if (prob < 0) {
224  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + parkingarea + "' is negative (must not).");
225  }
226  // add
227  myCurrentParkProb.add(pa, prob);
228  //MSEdge* to = &(pa->getLane().getEdge());
229  //myCurrentEdgeProb.add(prob, to);
230  }
231 }
232 
233 
234 void
236  if (element == SUMO_TAG_INTERVAL) {
237  RerouteInterval ri;
240  ri.closed = myCurrentClosed;
246  if (ri.closedLanes.size() > 0) {
247  // collect edges that are affect by a closed lane
248  std::set<MSEdge*> affected;
249  for (std::vector<MSLane*>::iterator l = ri.closedLanes.begin(); l != ri.closedLanes.end(); ++l) {
250  affected.insert(&((*l)->getEdge()));
251  }
252  ri.closedLanesAffected.insert(ri.closedLanesAffected.begin(), affected.begin(), affected.end());
253  }
254  myCurrentClosed.clear();
255  myCurrentClosedLanes.clear();
259  myIntervals.push_back(ri);
260  myIntervals.back().id = (long)&myIntervals.back();
261  if (!(ri.closed.empty() && ri.closedLanes.empty()) && ri.permissions != SVCAll) {
264  }
265  }
266 }
267 
268 
269 // ------------ loading end
270 
271 
272 SUMOTime
274  for (std::vector<RerouteInterval>::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
275  if (i->begin == currentTime && !(i->closed.empty() && i->closedLanes.empty()) && i->permissions != SVCAll) {
276  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
277  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
278  //std::cout << SIMTIME << " closing: intervalID=" << i->id << " lane=" << (*l)->getID() << " prevPerm=" << getVehicleClassNames((*l)->getPermissions()) << " new=" << getVehicleClassNames(i->permissions) << "\n";
279  (*l)->setPermissions(i->permissions, i->id);
280  }
281  (*e)->rebuildAllowedLanes();
282  }
283  for (std::vector<MSLane*>::iterator l = i->closedLanes.begin(); l != i->closedLanes.end(); ++l) {
284  (*l)->setPermissions(i->permissions, i->id);
285  (*l)->getEdge().rebuildAllowedLanes();
286  }
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  double /*newPos*/, double /*newSpeed*/) {
347  return notifyEnter(veh, NOTIFICATION_JUNCTION);
348 }
349 
350 
351 bool
352 MSTriggeredRerouter::notifyLeave(SUMOVehicle& /*veh*/, double /*lastPos*/,
353  MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
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  }
371  return true; // waiting time may be reached later
372  }
373  // if we have a closingLaneReroute, only vehicles with a rerouting device can profit from rerouting (otherwise, edge weights will not reflect local jamming)
374  const bool hasReroutingDevice = veh.getDevice(typeid(MSDevice_Routing)) != 0;
375  if (rerouteDef->closedLanes.size() > 0 && !hasReroutingDevice) {
376  return true; // an active interval could appear later
377  }
378  // get vehicle params
379  const MSRoute& route = veh.getRoute();
380  const MSEdge* lastEdge = route.getLastEdge();
381 #ifdef DEBUG_REROUTER
382  if (DEBUGCOND) {
383  std::cout << SIMTIME << " veh=" << veh.getID() << " check rerouter " << getID() << " lane=" << veh.getLane()->getID() << " edge=" << veh.getEdge()->getID() << " finalEdge=" << lastEdge->getID() << " arrivalPos=" << veh.getArrivalPos() << "\n";
384  }
385 #endif
386 
387  if (rerouteDef->parkProbs.getOverallProb() > 0) {
388  bool newDestination = false;
389  MSParkingArea* newParkingArea = rerouteParkingArea(rerouteDef, veh, newDestination);
390  if (newParkingArea != 0) {
391  const MSEdge* newEdge = &(newParkingArea->getLane().getEdge());
392 
393  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
395  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
396 
397  // Compute the route from the current edge to the parking area edge
398  ConstMSEdgeVector edgesToPark;
399  router.compute(veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
400 
401  // Compute the route from the parking area edge to the end of the route
402  ConstMSEdgeVector edgesFromPark;
403  if (!newDestination) {
404  router.compute(newEdge, lastEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
405  }
406 
407  // we have a new destination, let's replace the vehicle route
408  ConstMSEdgeVector edges = edgesToPark;
409  if (edgesFromPark.size() > 0) {
410  edges.insert(edges.end(), edgesFromPark.begin() + 1, edgesFromPark.end());
411  }
412 
413  veh.replaceRouteEdges(edges, false, false, false);
414  std::string errorMsg;
415  if (!veh.replaceParkingArea(newParkingArea, errorMsg)) {
416  WRITE_WARNING("Vehicle '" + veh.getID() + "' at rerouter '" + getID()
417  + "' could not reroute to new parkingArea '" + newParkingArea->getID()
418  + "' reason=" + errorMsg + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
419  }
420  if (newDestination) {
421  veh.setArrivalPos(newParkingArea->getEndLanePosition());
422  }
423  }
424  return false;
425  }
426 
427  // get rerouting params
428  const MSRoute* newRoute = rerouteDef->routeProbs.getOverallProb() > 0 ? rerouteDef->routeProbs.get() : 0;
429  // we will use the route if given rather than calling our own dijsktra...
430  if (newRoute != 0) {
431 #ifdef DEBUG_REROUTER
432  if (DEBUGCOND) {
433  std::cout << " replacedRoute from routeDist " << newRoute->getID() << "\n";
434  }
435 #endif
436  veh.replaceRoute(newRoute);
437  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
438  }
439  const MSEdge* newEdge = lastEdge;
440  // ok, try using a new destination
441  double newArrivalPos = -1;
442  const bool destUnreachable = std::find(rerouteDef->closed.begin(), rerouteDef->closed.end(), lastEdge) != rerouteDef->closed.end();
443  // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination
444  // if we have a closingLaneReroute, no new destinations should be assigned
445  if (rerouteDef->closed.size() == 0 || destUnreachable) {
446  newEdge = rerouteDef->edgeProbs.getOverallProb() > 0 ? rerouteDef->edgeProbs.get() : route.getLastEdge();
447  if (newEdge == &mySpecialDest_terminateRoute) {
448  newEdge = veh.getEdge();
449  newArrivalPos = veh.getPositionOnLane(); // instant arrival
450  } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) {
451  if (destUnreachable && rerouteDef->permissions == SVCAll) {
452  // if permissions aren't set vehicles will simply drive through
453  // the closing unless terminated. If the permissions are specified, assume that the user wants
454  // vehicles to stand and wait until the closing ends
455  WRITE_WARNING("Cannot keep destination edge '" + lastEdge->getID() + "' for vehicle '" + veh.getID() + "' due to closed edges. Terminating route.");
456  newEdge = veh.getEdge();
457  } else {
458  newEdge = lastEdge;
459  }
460  } else if (newEdge == 0) {
461 #ifdef DEBUG_REROUTER
462  if (DEBUGCOND) {
463  std::cout << " could not find new edge!\n";
464  }
465 #endif
466  assert(false); // this should never happen
467  newEdge = veh.getEdge();
468  }
469  }
470  // we have a new destination, let's replace the vehicle route (if it is affected)
471  if (rerouteDef->closed.size() == 0 || destUnreachable || veh.getRoute().containsAnyOf(rerouteDef->closed)) {
472  ConstMSEdgeVector edges;
473  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
475  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
476  router.compute(
477  veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
478  const bool useNewRoute = veh.replaceRouteEdges(edges);
479 #ifdef DEBUG_REROUTER
480  if (DEBUGCOND) std::cout << " rerouting: newEdge=" << newEdge->getID() << " useNewRoute=" << useNewRoute << " newArrivalPos=" << newArrivalPos << " numClosed=" << rerouteDef->closed.size()
481  << " destUnreachable=" << destUnreachable << " containsClosed=" << veh.getRoute().containsAnyOf(rerouteDef->closed) << "\n";
482 #endif
483  if (useNewRoute && newArrivalPos != -1) {
484  // must be called here because replaceRouteEdges may also set the arrivalPos
485  veh.setArrivalPos(newArrivalPos);
486  }
487  }
488  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
489 }
490 
491 
492 void
494  myAmInUserMode = val;
495 }
496 
497 
498 void
500  myUserProbability = prob;
501 }
502 
503 
504 bool
506  return myAmInUserMode;
507 }
508 
509 
510 double
513 }
514 
515 
516 double
518  return myUserProbability;
519 }
520 
521 
522 double
523 MSTriggeredRerouter::getWeight(SUMOVehicle& veh, const std::string param, const double defaultWeight) const {
524  // get custom vehicle parameter
525  if (veh.getParameter().knowsParameter(param)) {
526  try {
527  return TplConvert::_2double(veh.getParameter().getParameter(param, "-1").c_str());
528  } catch (...) {
529  WRITE_WARNING("Invalid value '" + veh.getParameter().getParameter(param, "-1") + "' for vehicle parameter '" + param + "'");
530  }
531  } else {
532  // get custom vType parameter
533  if (veh.getVehicleType().getParameter().knowsParameter(param)) {
534  try {
535  return TplConvert::_2double(veh.getVehicleType().getParameter().getParameter(param, "-1").c_str());
536  } catch (...) {
537  WRITE_WARNING("Invalid value '" + veh.getVehicleType().getParameter().getParameter(param, "-1") + "' for vType parameter '" + param + "'");
538  }
539  }
540  }
541  //WRITE_MESSAGE("Vehicle '" +veh.getID() + "' does not supply vehicle parameter '" + param + "'. Using default of " + toString(defaultWeight) + "\n";
542  return defaultWeight;
543 }
544 
545 
548  SUMOVehicle& veh, bool& newDestination) const {
549 
550  MSParkingArea* nearParkArea = 0;
551 
552  // get vehicle params
553  MSParkingArea* destParkArea = veh.getNextParkingArea();
554  const MSRoute& route = veh.getRoute();
555 
556  // I reroute destination from initial parking area to the near parking area
557  // if the next stop is a parking area and if it is full
558  if (destParkArea != 0 &&
559  destParkArea->getOccupancy() == destParkArea->getCapacity()) {
560 
561  // if the current route ends at the parking area, the new route will
562  // also and at the new area
563  newDestination = (&destParkArea->getLane().getEdge() == route.getLastEdge()
564  && veh.getArrivalPos() >= destParkArea->getBeginLanePosition()
565  && veh.getArrivalPos() <= destParkArea->getEndLanePosition());
566 
567 #ifdef DEBUG_PARKING
568  if (DEBUGCOND) {
569  std::cout << SIMTIME << " veh=" << veh.getID()
570  << " rerouteParkingArea dest=" << destParkArea->getID()
571  << " newDest=" << newDestination
572  << "\n";
573  }
574 #endif
575 
576  typedef std::map<std::string, double> ParkingParamMap_t;
577  typedef std::map<MSParkingArea*, ParkingParamMap_t> MSParkingAreaMap_t;
578 
579  ParkingParamMap_t weights;
580 
581  // The probability of choosing this area inside the zone
582  weights["probability"] = getWeight(veh, "parking.probability.weight", 0.0);
583 
584  // The capacity of this area
585  weights["capacity"] = getWeight(veh, "parking.capacity.weight", 0.0);
586 
587  // The absolute number of free spaces
588  weights["absfreespace"] = getWeight(veh, "parking.absfreespace.weight", 0.0);
589 
590  // The relative number of free spaces
591  weights["relfreespace"] = getWeight(veh, "parking.relfreespace.weight", 0.0);
592 
593  // The distance to the new parking area
594  weights["distanceto"] = getWeight(veh, "parking.distanceto.weight", getWeight(veh, "parking.distance.weight", 1.0));
595 
596  // The time to reach this area
597  weights["timeto"] = getWeight(veh, "parking.timeto.weight", 0.0);
598 
599  // The distance from the new parking area
600  weights["distancefrom"] = getWeight(veh, "parking.distancefrom.weight", 0.0);
601 
602  // The time to reach the end from this area
603  weights["timefrom"] = getWeight(veh, "parking.timefrom.weight", 0.0);
604 
605  // a map stores maximum values to normalize parking values
606  ParkingParamMap_t maxValues;
607 
608  maxValues["probability"] = 0.0;
609  maxValues["capacity"] = 0.0;
610  maxValues["absfreespace"] = 0.0;
611  maxValues["relfreespace"] = 0.0;
612  maxValues["distanceto"] = 0.0;
613  maxValues["timeto"] = 0.0;
614  maxValues["distancefrom"] = 0.0;
615  maxValues["timefrom"] = 0.0;
616 
617  // a map stores elegible parking areas
618  MSParkingAreaMap_t parkAreas;
619 
621 
622  std::vector<MSParkingArea*> parks = rerouteDef->parkProbs.getVals();
623  std::vector<double> probs = rerouteDef->parkProbs.getProbs();
624 
625  for (int i = 0; i < (int)parks.size(); ++i) {
626  MSParkingArea* pa = parks[i];
627  const double prob = probs[i];
628  if (pa->getOccupancy() < pa->getCapacity()) {
629 
630  // a map stores the parking values
631  ParkingParamMap_t parkValues;
632 
633  const RGBColor& c = route.getColor();
634  const MSEdge* parkEdge = &(pa->getLane().getEdge());
635 
636  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
637 
638  // Compute the route from the current edge to the parking area edge
639  ConstMSEdgeVector edgesToPark;
640  router.compute(veh.getEdge(), parkEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
641 
642  if (edgesToPark.size() > 0) {
643  // Compute the route from the parking area edge to the end of the route
644  ConstMSEdgeVector edgesFromPark;
645 
646  if (!newDestination) {
647  router.compute(parkEdge, route.getLastEdge(), &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
648  }
649 
650  if (edgesFromPark.size() > 0 || newDestination) {
651 
652  parkValues["probability"] = prob;
653 
654  if (parkValues["probability"] > maxValues["probability"]) {
655  maxValues["probability"] = parkValues["probability"];
656  }
657 
658  parkValues["capacity"] = (double)(pa->getCapacity());
659  parkValues["absfreespace"] = (double)(pa->getCapacity() - pa->getOccupancy());
660  parkValues["relfreespace"] = parkValues["absfreespace"] / parkValues["capacity"];
661 
662  if (parkValues["capacity"] > maxValues["capacity"]) {
663  maxValues["capacity"] = parkValues["capacity"];
664  }
665 
666  if (parkValues["absfreespace"] > maxValues["absfreespace"]) {
667  maxValues["absfreespace"] = parkValues["absfreespace"];
668  }
669 
670  if (parkValues["relfreespace"] > maxValues["relfreespace"]) {
671  maxValues["relfreespace"] = parkValues["relfreespace"];
672  }
673 
674  MSRoute routeToPark(route.getID() + "!topark#1", edgesToPark, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
675 
676  // The distance from the current edge to the new parking area
677  parkValues["distanceto"] = routeToPark.getDistanceBetween(veh.getPositionOnLane(), pa->getBeginLanePosition(),
678  routeToPark.begin(), routeToPark.end(), includeInternalLengths);
679 
680  // The time to reach the new parking area
681  parkValues["timeto"] = router.recomputeCosts(edgesToPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
682 
683  if (parkValues["distanceto"] > maxValues["distanceto"]) {
684  maxValues["distanceto"] = parkValues["distanceto"];
685  }
686 
687  if (parkValues["timeto"] > maxValues["timeto"]) {
688  maxValues["timeto"] = parkValues["timeto"];
689  }
690 
691  if (newDestination) {
692  parkValues["distancefrom"] = 0;
693  parkValues["timefrom"] = 0;
694  } else {
695  MSRoute routeFromPark(route.getID() + "!frompark#1", edgesFromPark, false,
696  &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
697  // The distance from the new parking area to the end of the route
698  parkValues["distancefrom"] = routeFromPark.getDistanceBetween(pa->getBeginLanePosition(), routeFromPark.getLastEdge()->getLength(),
699  routeFromPark.begin(), routeFromPark.end(), includeInternalLengths);
700  // The time to reach this area
701  parkValues["timefrom"] = router.recomputeCosts(edgesFromPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
702  }
703 
704  if (parkValues["distancefrom"] > maxValues["distancefrom"]) {
705  maxValues["distancefrom"] = parkValues["distancefrom"];
706  }
707 
708  if (parkValues["timefrom"] > maxValues["timefrom"]) {
709  maxValues["timefrom"] = parkValues["timefrom"];
710  }
711 
712  parkAreas[pa] = parkValues;
713 
714 #ifdef DEBUG_PARKING
715  if (DEBUGCOND) {
716  std::cout << " altPA=" << pa->getID()
717  << " vals=" << joinToString(parkValues, " ", ":")
718  << "\n";
719  }
720 #endif
721  }
722  }
723  }
724  }
725 
726 #ifdef DEBUG_PARKING
727  if (DEBUGCOND) {
728  std::cout << " maxValues=" << joinToString(maxValues, " ", ":") << "\n";
729  }
730 #endif
731 
732  // minimum cost to get the parking area
733  double minParkingCost = 0.0;
734 
735  for (MSParkingAreaMap_t::iterator it = parkAreas.begin(); it != parkAreas.end(); ++it) {
736  // get the parking values
737  ParkingParamMap_t parkValues = it->second;
738 
739  // normalizing parking values with maximum values (we want to maximize some parameters then we reverse the value)
740  parkValues["probability"] = maxValues["probability"] > 0.0 ? 1.0 - parkValues["probability"] / maxValues["probability"] : 0.0;
741  parkValues["capacity"] = maxValues["capacity"] > 0.0 ? 1.0 - parkValues["capacity"] / maxValues["capacity"] : 0.0;
742  parkValues["absfreespace"] = maxValues["absfreespace"] > 0.0 ? 1.0 - parkValues["absfreespace"] / maxValues["absfreespace"] : 0.0;
743  parkValues["relfreespace"] = maxValues["relfreespace"] > 0.0 ? 1.0 - parkValues["relfreespace"] / maxValues["relfreespace"] : 0.0;
744 
745  parkValues["distanceto"] = maxValues["distanceto"] > 0.0 ? parkValues["distanceto"] / maxValues["distanceto"] : 0.0;
746  parkValues["timeto"] = maxValues["timeto"] > 0.0 ? parkValues["timeto"] / maxValues["timeto"] : 0.0;
747 
748  parkValues["distancefrom"] = maxValues["distancefrom"] > 0.0 ? parkValues["distancefrom"] / maxValues["distancefrom"] : 0.0;
749  parkValues["timefrom"] = maxValues["timefrom"] > 0.0 ? parkValues["timefrom"] / maxValues["timefrom"] : 0.0;
750 
751  // get the parking area cost
752  double parkingCost = 0.0;
753 
754  // sum every index with its weight
755  for (ParkingParamMap_t::iterator pc = parkValues.begin(); pc != parkValues.end(); ++pc) {
756  parkingCost += weights[pc->first] * pc->second;
757  }
758 
759  // get the parking area with minimum cost
760  if (nearParkArea == 0 || parkingCost < minParkingCost) {
761  minParkingCost = parkingCost;
762  nearParkArea = it->first;
763  }
764 
765 #ifdef DEBUG_PARKING
766  if (DEBUGCOND) {
767  std::cout << " altPA=" << it->first->getID() << " score=" << parkingCost << "\n";
768  }
769 #endif
770  }
771  }
772 
773 #ifdef DEBUG_PARKING
774  if (DEBUGCOND) {
775  std::cout << " parkingResult=" << Named::getIDSecure(nearParkArea) << "\n";
776  }
777 #endif
778 
779  return nearParkArea;
780 }
781 
782 /****************************************************************************/
783 
#define DEBUGCOND
A lane area vehicles can halt at.
Definition: MSParkingArea.h:65
double getProbability() const
Returns the rerouting probability.
MSEdgeVector closed
The list of closed edges.
const RerouteInterval * getCurrentReroute(SUMOTime time, SUMOVehicle &veh) const
Returns the rerouting definition valid for the given time and vehicle, 0 if none. ...
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:607
virtual double getArrivalPos() const =0
Returns this vehicle&#39;s desired arrivalPos for its current route (may change on reroute) ...
double getBeginLanePosition() const
Returns the begin position of this stop.
double getUserProbability() const
Returns the rerouting probability given by the user.
virtual MSParkingArea * getNextParkingArea()=0
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:289
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:863
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.
The vehicle arrived at a junction.
virtual double recomputeCosts(const std::vector< const E *> &edges, const V *const v, SUMOTime msTime) const =0
lane of a reroute of type closing
SUMOTime myCurrentIntervalBegin
The first and the last time steps of the interval.
virtual bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0, bool addStops=true, bool removeStops=true)=0
Replaces the current route by the given one.
std::vector< MSLane * > myCurrentClosedLanes
List of closed lanes.
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:64
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
Notification
Definition of a vehicle state.
double getDistanceBetween(double fromPos, double 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:280
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
A device that performs vehicle rerouting based on current edge speeds.
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...
virtual MSLane * getLane() const =0
Returns the lane the vehicle is on.
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:357
weights: time range begin
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
T MAX2(T a, T b)
Definition: StdDefs.h:73
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:58
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:744
const std::vector< T > & getVals() const
Returns the members of the distribution.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:91
void setUserUsageProbability(double prob)
Sets the probability with which a vehicle is rerouted given by the user.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
const std::string & getID() const
Returns the id.
Definition: Named.h:65
const SVCPermissions SVCAll
all VClasses are allowed
void setUserMode(bool val)
Sets whether the process is currently steered by the user.
SAX-handler base for SUMO-files.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
double myProbability
The probability and the user-given probability.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
#define SIMTIME
Definition: SUMOTime.h:71
authorities vehicles
A road/street connecting two junctions.
Definition: MSEdge.h:80
virtual void myEndElement(int element)
Called when a closing tag occurs.
double getEndLanePosition() const
Returns the end position of this stop.
The vehicle changes lanes (micro only)
MSTriggeredRerouter(const std::string &id, const MSEdgeVector &edges, double prob, const std::string &file, bool off, SUMOTime timeThreshold)
Constructor.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
An abstract device that changes the state of the micro simulation.
Definition: MSTrigger.h:47
const std::vector< double > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
double getWeight(SUMOVehicle &veh, const std::string param, const double defaultWeight) const
Representation of a vehicle.
Definition: SUMOVehicle.h:66
Encapsulated SAX-Attributes.
T get(std::mt19937 *which=0) const
Draw a sample of the distribution.
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:191
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:399
A wrapper for a Command function.
int getCapacity() const
Returns the area capacity.
RandomDistributor< MSParkingArea * > myCurrentParkProb
new destinations with probabilities
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
virtual SUMOTime getAccumulatedWaitingTime() const =0
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
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:204
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:587
MSParkingArea * rerouteParkingArea(const MSTriggeredRerouter::RerouteInterval *rerouteDef, SUMOVehicle &veh, bool &newDestination) const
probability of route of a reroute
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:75
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
const SUMOVTypeParameter & getParameter() const
int getOccupancy() const
Returns the area occupancy.
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Tries to reroute the vehicle.
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Removes the reminder.
RandomDistributor< MSEdge * > myCurrentEdgeProb
new destinations with probabilities
reroute of type closing
void clear()
Clears the distribution.
entry for an alternative parking zone
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1639
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.
RandomDistributor< MSParkingArea * > parkProbs
The distributions of new parking areas to use as destinations.
SUMOTime end
The end time these definitions are valid.
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:242
std::vector< MSLane * > closedLanes
The list of closed lanes.
RandomDistributor< const MSRoute * > routeProbs
The distributions of new routes to use.
virtual double getPositionOnLane() const =0
Get the vehicle&#39;s position along the lane.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
weights: time range end
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.
A single mesoscopic segment (cell)
Definition: MESegment.h:56
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
std::vector< RerouteInterval > myIntervals
List of rerouting definition intervals.
static double _2double(const E *const data)
converts a char-type array into the double value described by it
Definition: TplConvert.h:311
bool inUserMode() const
Returns whether the user is setting the rerouting probability.
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
MSEdgeVector myCurrentClosed
List of closed edges.
bool myAmInUserMode
Information whether the current rerouting probability is the user-given.
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:112
virtual SUMOTime getWaitingTime() const =0
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
an aggreagated-output interval
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
long long int SUMOTime
Definition: TraCIDefs.h:51
virtual MSDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:897
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
bool notifyMove(SUMOVehicle &veh, double oldPos, double newPos, double newSpeed)
Triggers rerouting (once) for vehicles that are already on the edge when the rerouter activates...
const MSLane & getLane() const
Returns the lane this stop is located at.
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
SVCPermissions permissions
The permissions to use.
static bool gUseMesoSim
Definition: MSGlobals.h:97
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:366
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:236
MSEdgeVector closedLanesAffected
The list of edges that are affect by closed lanes.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:117