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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // Reroutes vehicles passing an edge
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <string>
28 #include <algorithm>
31 #include <utils/common/Command.h>
34 #include <utils/common/ToString.h>
41 #include <microsim/MSLane.h>
42 #include <microsim/MSVehicle.h>
43 #include <microsim/MSRoute.h>
44 #include <microsim/MSEdge.h>
46 #include <microsim/MSNet.h>
48 #include <microsim/MSGlobals.h>
49 #include <microsim/MSParkingArea.h>
52 #include "MSTriggeredRerouter.h"
53 
54 #include <mesosim/MELoop.h>
55 #include <mesosim/MESegment.h>
56 
57 //#define DEBUG_REROUTER
58 #define DEBUG_PARKING
59 #define DEBUGCOND (veh.isSelected())
60 
61 // ===========================================================================
62 // static member defintion
63 // ===========================================================================
64 MSEdge MSTriggeredRerouter::mySpecialDest_keepDestination("MSTriggeredRerouter_keepDestination", -1, EDGEFUNC_UNKNOWN, "", "", -1);
65 MSEdge MSTriggeredRerouter::mySpecialDest_terminateRoute("MSTriggeredRerouter_terminateRoute", -1, EDGEFUNC_UNKNOWN, "", "", -1);
66 
67 // ===========================================================================
68 // method definitions
69 // ===========================================================================
71  const MSEdgeVector& edges,
72  double prob, const std::string& file, bool off,
73  SUMOTime timeThreshold,
74  const std::string& vTypes) :
75  MSTrigger(id),
76  MSMoveReminder(id),
77  SUMOSAXHandler(file),
78  myProbability(prob),
79  myUserProbability(prob),
80  myAmInUserMode(false),
81  myTimeThreshold(timeThreshold) {
82  // build actors
83  for (MSEdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
86  s->addDetector(this);
87  continue;
88  }
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  const std::vector<std::string> vt = StringTokenizer(vTypes).getVector();
99  myVehicleTypes.insert(vt.begin(), vt.end());
100 }
101 
102 
104 }
105 
106 // ------------ loading begin
107 void
109  const SUMOSAXAttributes& attrs) {
110  if (element == SUMO_TAG_INTERVAL) {
111  bool ok = true;
114  }
115  if (element == SUMO_TAG_DEST_PROB_REROUTE) {
116  // by giving probabilities of new destinations
117  // get the destination edge
118  std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
119  if (dest == "") {
120  throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
121  }
122  MSEdge* to = MSEdge::dictionary(dest);
123  if (to == 0) {
124  if (dest == "keepDestination") {
126  } else if (dest == "terminateRoute") {
128  } else {
129  throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
130  }
131  }
132  // get the probability to reroute
133  bool ok = true;
134  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
135  if (!ok) {
136  throw ProcessError();
137  }
138  if (prob < 0) {
139  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
140  }
141  // add
142  myCurrentEdgeProb.add(to, prob);
143  }
144 
145 
146  if (element == SUMO_TAG_CLOSING_REROUTE) {
147  // by closing
148  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
149  MSEdge* closed = MSEdge::dictionary(closed_id);
150  if (closed == 0) {
151  throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
152  }
153  myCurrentClosed.push_back(closed);
154  bool ok;
155  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
156  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
157  myCurrentPermissions = parseVehicleClasses(allow, disallow);
158  }
159 
160  if (element == SUMO_TAG_CLOSING_LANE_REROUTE) {
161  // by closing lane
162  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
163  MSLane* closed = MSLane::dictionary(closed_id);
164  if (closed == 0) {
165  throw ProcessError("MSTriggeredRerouter " + getID() + ": Lane '" + closed_id + "' to close is not known.");
166  }
167  myCurrentClosedLanes.push_back(closed);
168  bool ok;
170  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
171  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
172  myCurrentPermissions = parseVehicleClasses(allow, disallow);
173  } else {
174  // lane closing only makes sense if the lane really receives reduced
175  // permissions
177  }
178  }
179 
180  if (element == SUMO_TAG_ROUTE_PROB_REROUTE) {
181  // by explicit rerouting using routes
182  // check if route exists
183  std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
184  if (routeStr == "") {
185  throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
186  }
187  const MSRoute* route = MSRoute::dictionary(routeStr);
188  if (route == 0) {
189  throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
190  }
191 
192  // get the probability to reroute
193  bool ok = true;
194  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
195  if (!ok) {
196  throw ProcessError();
197  }
198  if (prob < 0) {
199  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
200  }
201  // add
202  myCurrentRouteProb.add(route, prob);
203  }
204 
205  if (element == SUMO_TAG_PARKING_ZONE_REROUTE) {
206  // by giving probabilities of new destinations
207  // get the destination edge
208  std::string parkingarea = attrs.getStringSecure(SUMO_ATTR_ID, "");
209  if (parkingarea == "") {
210  throw ProcessError("MSTriggeredRerouter " + getID() + ": No parking area id given.");
211  }
213  if (pa == 0) {
214  throw ProcessError("MSTriggeredRerouter " + getID() + ": Parking area '" + parkingarea + "' is not known.");
215  }
216  // get the probability to reroute
217  bool ok = true;
218  const double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
219  if (!ok) {
220  throw ProcessError();
221  }
222  if (prob < 0) {
223  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + parkingarea + "' is negative (must not).");
224  }
225  const bool visible = attrs.getOpt<bool>(SUMO_ATTR_VISIBLE, getID().c_str(), ok, false);
226  // add
227  myCurrentParkProb.add(std::make_pair(pa, visible), 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 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  if (!vehicleApplies(veh)) {
361  return false;
362  }
363  // check whether the vehicle shall be rerouted
365  const MSTriggeredRerouter::RerouteInterval* rerouteDef = getCurrentReroute(time, veh);
366  if (rerouteDef == 0) {
367  return true; // an active interval could appear later
368  }
370  if (RandHelper::rand() > prob) {
371  return false; // XXX another interval could appear later but we would have to track whether the current interval was already tried
372  }
374  return true; // waiting time may be reached later
375  }
376  // if we have a closingLaneReroute, only vehicles with a rerouting device can profit from rerouting (otherwise, edge weights will not reflect local jamming)
377  const bool hasReroutingDevice = veh.getDevice(typeid(MSDevice_Routing)) != 0;
378  if (rerouteDef->closedLanes.size() > 0 && !hasReroutingDevice) {
379  return true; // an active interval could appear later
380  }
381  // get vehicle params
382  const MSRoute& route = veh.getRoute();
383  const MSEdge* lastEdge = route.getLastEdge();
384 #ifdef DEBUG_REROUTER
385  if (DEBUGCOND) {
386  std::cout << SIMTIME << " veh=" << veh.getID() << " check rerouter " << getID() << " lane=" << veh.getLane()->getID() << " edge=" << veh.getEdge()->getID() << " finalEdge=" << lastEdge->getID() << " arrivalPos=" << veh.getArrivalPos() << "\n";
387  }
388 #endif
389 
390  if (rerouteDef->parkProbs.getOverallProb() > 0) {
391  bool newDestination = false;
392  MSParkingArea* newParkingArea = rerouteParkingArea(rerouteDef, veh, newDestination);
393  if (newParkingArea != 0) {
394  const MSEdge* newEdge = &(newParkingArea->getLane().getEdge());
395 
396  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
398  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
399 
400  // Compute the route from the current edge to the parking area edge
401  ConstMSEdgeVector edgesToPark;
402  router.compute(veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
403 
404  // Compute the route from the parking area edge to the end of the route
405  ConstMSEdgeVector edgesFromPark;
406  if (!newDestination) {
407  router.compute(newEdge, lastEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
408  } else {
409  // adapt plans of any riders
410  for (MSTransportable* p : veh.getPersons()) {
411  p->rerouteParkingArea(veh.getNextParkingArea(), newParkingArea);
412  }
413  }
414 
415  // we have a new destination, let's replace the vehicle route
416  ConstMSEdgeVector edges = edgesToPark;
417  if (edgesFromPark.size() > 0) {
418  edges.insert(edges.end(), edgesFromPark.begin() + 1, edgesFromPark.end());
419  }
420 
421  if (newDestination) {
422  SUMOVehicleParameter* newParameter = new SUMOVehicleParameter();
423  *newParameter = veh.getParameter();
424  newParameter->arrivalPosProcedure = ARRIVAL_POS_GIVEN;
425  newParameter->arrivalPos = newParkingArea->getEndLanePosition();
426  veh.replaceParameter(newParameter);
427  }
428  veh.replaceRouteEdges(edges, getID(), false, false, false);
429  std::string errorMsg;
430  if (!veh.replaceParkingArea(newParkingArea, errorMsg)) {
431  WRITE_WARNING("Vehicle '" + veh.getID() + "' at rerouter '" + getID()
432  + "' could not reroute to new parkingArea '" + newParkingArea->getID()
433  + "' reason=" + errorMsg + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
434  }
435  }
436  return false;
437  }
438 
439  // get rerouting params
440  const MSRoute* newRoute = rerouteDef->routeProbs.getOverallProb() > 0 ? rerouteDef->routeProbs.get() : 0;
441  // we will use the route if given rather than calling our own dijsktra...
442  if (newRoute != 0) {
443 #ifdef DEBUG_REROUTER
444  if (DEBUGCOND) {
445  std::cout << " replacedRoute from routeDist " << newRoute->getID() << "\n";
446  }
447 #endif
448  veh.replaceRoute(newRoute, getID());
449  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
450  }
451  const MSEdge* newEdge = lastEdge;
452  // ok, try using a new destination
453  double newArrivalPos = -1;
454  const bool destUnreachable = std::find(rerouteDef->closed.begin(), rerouteDef->closed.end(), lastEdge) != rerouteDef->closed.end();
455  // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination
456  // if we have a closingLaneReroute, no new destinations should be assigned
457  if (rerouteDef->closed.size() == 0 || destUnreachable) {
458  newEdge = rerouteDef->edgeProbs.getOverallProb() > 0 ? rerouteDef->edgeProbs.get() : route.getLastEdge();
459  if (newEdge == &mySpecialDest_terminateRoute) {
460  newEdge = veh.getEdge();
461  newArrivalPos = veh.getPositionOnLane(); // instant arrival
462  } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) {
463  if (destUnreachable && rerouteDef->permissions == SVCAll) {
464  // if permissions aren't set vehicles will simply drive through
465  // the closing unless terminated. If the permissions are specified, assume that the user wants
466  // vehicles to stand and wait until the closing ends
467  WRITE_WARNING("Cannot keep destination edge '" + lastEdge->getID() + "' for vehicle '" + veh.getID() + "' due to closed edges. Terminating route.");
468  newEdge = veh.getEdge();
469  } else {
470  newEdge = lastEdge;
471  }
472  } else if (newEdge == 0) {
473 #ifdef DEBUG_REROUTER
474  if (DEBUGCOND) {
475  std::cout << " could not find new edge!\n";
476  }
477 #endif
478  assert(false); // this should never happen
479  newEdge = veh.getEdge();
480  }
481  }
482  // we have a new destination, let's replace the vehicle route (if it is affected)
483  if (rerouteDef->closed.size() == 0 || destUnreachable || veh.getRoute().containsAnyOf(rerouteDef->closed)) {
484  ConstMSEdgeVector edges;
485  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
487  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
488  router.compute(
489  veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
490  const bool useNewRoute = veh.replaceRouteEdges(edges, getID());
491 #ifdef DEBUG_REROUTER
492  if (DEBUGCOND) std::cout << " rerouting: newEdge=" << newEdge->getID() << " useNewRoute=" << useNewRoute << " newArrivalPos=" << newArrivalPos << " numClosed=" << rerouteDef->closed.size()
493  << " destUnreachable=" << destUnreachable << " containsClosed=" << veh.getRoute().containsAnyOf(rerouteDef->closed) << "\n";
494 #endif
495  if (useNewRoute && newArrivalPos != -1) {
496  // must be called here because replaceRouteEdges may also set the arrivalPos
497  veh.setArrivalPos(newArrivalPos);
498  }
499  }
500  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
501 }
502 
503 
504 void
506  myAmInUserMode = val;
507 }
508 
509 
510 void
512  myUserProbability = prob;
513 }
514 
515 
516 bool
518  return myAmInUserMode;
519 }
520 
521 
522 double
525 }
526 
527 
528 double
530  return myUserProbability;
531 }
532 
533 
534 double
535 MSTriggeredRerouter::getWeight(SUMOVehicle& veh, const std::string param, const double defaultWeight) const {
536  // get custom vehicle parameter
537  if (veh.getParameter().knowsParameter(param)) {
538  try {
539  return TplConvert::_2double(veh.getParameter().getParameter(param, "-1").c_str());
540  } catch (...) {
541  WRITE_WARNING("Invalid value '" + veh.getParameter().getParameter(param, "-1") + "' for vehicle parameter '" + param + "'");
542  }
543  } else {
544  // get custom vType parameter
545  if (veh.getVehicleType().getParameter().knowsParameter(param)) {
546  try {
547  return TplConvert::_2double(veh.getVehicleType().getParameter().getParameter(param, "-1").c_str());
548  } catch (...) {
549  WRITE_WARNING("Invalid value '" + veh.getVehicleType().getParameter().getParameter(param, "-1") + "' for vType parameter '" + param + "'");
550  }
551  }
552  }
553  //WRITE_MESSAGE("Vehicle '" +veh.getID() + "' does not supply vehicle parameter '" + param + "'. Using default of " + toString(defaultWeight) + "\n";
554  return defaultWeight;
555 }
556 
557 
560  SUMOVehicle& veh, bool& newDestination) const {
561  // reroute destination from initial parking area to the near parking area
562  // if the next stop is a parking area, it is included in the current
563  // alternative set and if it can be observed to be full
564 
565  MSParkingArea* nearParkArea = nullptr;
566  std::vector<ParkingAreaVisible> parks = rerouteDef->parkProbs.getVals();
567 
568  // get vehicle params
569  MSParkingArea* destParkArea = veh.getNextParkingArea();
570  const MSRoute& route = veh.getRoute();
571 
572  if (destParkArea == nullptr) {
573  // not driving towards a parkingArea
574  return nullptr;
575  }
576 
577  bool destVisible = false;
578  for (auto paVis : parks) {
579  if (paVis.first == destParkArea
580  && (paVis.second
581  // if the vehicle is on the destParkArea edge it is always visible
582  || &(destParkArea->getLane().getEdge()) == veh.getEdge())) {
583  destVisible = true;
584  break;
585  }
586  }
587  if (!destVisible) {
588  // cannot determine destination occupancy
589  return nullptr;
590  }
591  if (destParkArea->getOccupancy() == destParkArea->getCapacity()) {
592  // if the current route ends at the parking area, the new route will
593  // also and at the new area
594  newDestination = (&destParkArea->getLane().getEdge() == route.getLastEdge()
595  && veh.getArrivalPos() >= destParkArea->getBeginLanePosition()
596  && veh.getArrivalPos() <= destParkArea->getEndLanePosition());
597 
598 #ifdef DEBUG_PARKING
599  if (DEBUGCOND) {
600  std::cout << SIMTIME << " veh=" << veh.getID()
601  << " rerouteParkingArea dest=" << destParkArea->getID()
602  << " onDestEdge=" << (&(destParkArea->getLane().getEdge()) == veh.getEdge())
603  << " newDest=" << newDestination
604  << "\n";
605  }
606 #endif
607 
608  typedef std::map<std::string, double> ParkingParamMap_t;
609  typedef std::map<MSParkingArea*, ParkingParamMap_t> MSParkingAreaMap_t;
610 
611  ParkingParamMap_t weights;
612 
613  // The probability of choosing this area inside the zone
614  weights["probability"] = getWeight(veh, "parking.probability.weight", 0.0);
615 
616  // The capacity of this area
617  weights["capacity"] = getWeight(veh, "parking.capacity.weight", 0.0);
618 
619  // The absolute number of free spaces
620  weights["absfreespace"] = getWeight(veh, "parking.absfreespace.weight", 0.0);
621 
622  // The relative number of free spaces
623  weights["relfreespace"] = getWeight(veh, "parking.relfreespace.weight", 0.0);
624 
625  // The distance to the new parking area
626  weights["distanceto"] = getWeight(veh, "parking.distanceto.weight", getWeight(veh, "parking.distance.weight", 1.0));
627 
628  // The time to reach this area
629  weights["timeto"] = getWeight(veh, "parking.timeto.weight", 0.0);
630 
631  // The distance from the new parking area
632  weights["distancefrom"] = getWeight(veh, "parking.distancefrom.weight", 0.0);
633 
634  // The time to reach the end from this area
635  weights["timefrom"] = getWeight(veh, "parking.timefrom.weight", 0.0);
636 
637  // a map stores maximum values to normalize parking values
638  ParkingParamMap_t maxValues;
639 
640  maxValues["probability"] = 0.0;
641  maxValues["capacity"] = 0.0;
642  maxValues["absfreespace"] = 0.0;
643  maxValues["relfreespace"] = 0.0;
644  maxValues["distanceto"] = 0.0;
645  maxValues["timeto"] = 0.0;
646  maxValues["distancefrom"] = 0.0;
647  maxValues["timefrom"] = 0.0;
648 
649  // a map stores elegible parking areas
650  MSParkingAreaMap_t parkAreas;
651 
653 
654  std::vector<double> probs = rerouteDef->parkProbs.getProbs();
655 
656  for (int i = 0; i < (int)parks.size(); ++i) {
657  MSParkingArea* pa = parks[i].first;
658  const double prob = probs[i];
659  // alternative occupancy is randomized (but never full) if invisible
660  // current destination must be visible at this point
661  int paOccupancy = parks[i].second || pa == destParkArea ? pa->getOccupancy() : RandHelper::rand(pa->getCapacity());
662  if (paOccupancy < pa->getCapacity()) {
663 
664  // a map stores the parking values
665  ParkingParamMap_t parkValues;
666 
667  const RGBColor& c = route.getColor();
668  const MSEdge* parkEdge = &(pa->getLane().getEdge());
669 
670  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
671 
672  // Compute the route from the current edge to the parking area edge
673  ConstMSEdgeVector edgesToPark;
674  router.compute(veh.getEdge(), parkEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
675 
676  if (edgesToPark.size() > 0) {
677  // Compute the route from the parking area edge to the end of the route
678  ConstMSEdgeVector edgesFromPark;
679 
680  if (!newDestination) {
681  router.compute(parkEdge, route.getLastEdge(), &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
682  }
683 
684  if (edgesFromPark.size() > 0 || newDestination) {
685 
686  parkValues["probability"] = prob;
687 
688  if (parkValues["probability"] > maxValues["probability"]) {
689  maxValues["probability"] = parkValues["probability"];
690  }
691 
692  parkValues["capacity"] = (double)(pa->getCapacity());
693  parkValues["absfreespace"] = (double)(pa->getCapacity() - paOccupancy);
694  parkValues["relfreespace"] = parkValues["absfreespace"] / parkValues["capacity"];
695 
696  if (parkValues["capacity"] > maxValues["capacity"]) {
697  maxValues["capacity"] = parkValues["capacity"];
698  }
699 
700  if (parkValues["absfreespace"] > maxValues["absfreespace"]) {
701  maxValues["absfreespace"] = parkValues["absfreespace"];
702  }
703 
704  if (parkValues["relfreespace"] > maxValues["relfreespace"]) {
705  maxValues["relfreespace"] = parkValues["relfreespace"];
706  }
707 
708  MSRoute routeToPark(route.getID() + "!topark#1", edgesToPark, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
709 
710  // The distance from the current edge to the new parking area
711  parkValues["distanceto"] = routeToPark.getDistanceBetween(veh.getPositionOnLane(), pa->getBeginLanePosition(),
712  routeToPark.begin(), routeToPark.end(), includeInternalLengths);
713 
714  // The time to reach the new parking area
715  parkValues["timeto"] = router.recomputeCosts(edgesToPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
716 
717  if (parkValues["distanceto"] > maxValues["distanceto"]) {
718  maxValues["distanceto"] = parkValues["distanceto"];
719  }
720 
721  if (parkValues["timeto"] > maxValues["timeto"]) {
722  maxValues["timeto"] = parkValues["timeto"];
723  }
724 
725  if (newDestination) {
726  parkValues["distancefrom"] = 0;
727  parkValues["timefrom"] = 0;
728  } else {
729  MSRoute routeFromPark(route.getID() + "!frompark#1", edgesFromPark, false,
730  &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
731  // The distance from the new parking area to the end of the route
732  parkValues["distancefrom"] = routeFromPark.getDistanceBetween(pa->getBeginLanePosition(), routeFromPark.getLastEdge()->getLength(),
733  routeFromPark.begin(), routeFromPark.end(), includeInternalLengths);
734  // The time to reach this area
735  parkValues["timefrom"] = router.recomputeCosts(edgesFromPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
736  }
737 
738  if (parkValues["distancefrom"] > maxValues["distancefrom"]) {
739  maxValues["distancefrom"] = parkValues["distancefrom"];
740  }
741 
742  if (parkValues["timefrom"] > maxValues["timefrom"]) {
743  maxValues["timefrom"] = parkValues["timefrom"];
744  }
745 
746  parkAreas[pa] = parkValues;
747 
748 #ifdef DEBUG_PARKING
749  if (DEBUGCOND) {
750  std::cout << " altPA=" << pa->getID()
751  << " vals=" << joinToString(parkValues, " ", ":")
752  << "\n";
753  }
754 #endif
755  }
756  }
757  }
758  }
759 
760 #ifdef DEBUG_PARKING
761  if (DEBUGCOND) {
762  std::cout << " maxValues=" << joinToString(maxValues, " ", ":") << "\n";
763  }
764 #endif
765 
766  // minimum cost to get the parking area
767  double minParkingCost = 0.0;
768 
769  for (MSParkingAreaMap_t::iterator it = parkAreas.begin(); it != parkAreas.end(); ++it) {
770  // get the parking values
771  ParkingParamMap_t parkValues = it->second;
772 
773  // normalizing parking values with maximum values (we want to maximize some parameters then we reverse the value)
774  parkValues["probability"] = maxValues["probability"] > 0.0 ? 1.0 - parkValues["probability"] / maxValues["probability"] : 0.0;
775  parkValues["capacity"] = maxValues["capacity"] > 0.0 ? 1.0 - parkValues["capacity"] / maxValues["capacity"] : 0.0;
776  parkValues["absfreespace"] = maxValues["absfreespace"] > 0.0 ? 1.0 - parkValues["absfreespace"] / maxValues["absfreespace"] : 0.0;
777  parkValues["relfreespace"] = maxValues["relfreespace"] > 0.0 ? 1.0 - parkValues["relfreespace"] / maxValues["relfreespace"] : 0.0;
778 
779  parkValues["distanceto"] = maxValues["distanceto"] > 0.0 ? parkValues["distanceto"] / maxValues["distanceto"] : 0.0;
780  parkValues["timeto"] = maxValues["timeto"] > 0.0 ? parkValues["timeto"] / maxValues["timeto"] : 0.0;
781 
782  parkValues["distancefrom"] = maxValues["distancefrom"] > 0.0 ? parkValues["distancefrom"] / maxValues["distancefrom"] : 0.0;
783  parkValues["timefrom"] = maxValues["timefrom"] > 0.0 ? parkValues["timefrom"] / maxValues["timefrom"] : 0.0;
784 
785  // get the parking area cost
786  double parkingCost = 0.0;
787 
788  // sum every index with its weight
789  for (ParkingParamMap_t::iterator pc = parkValues.begin(); pc != parkValues.end(); ++pc) {
790  parkingCost += weights[pc->first] * pc->second;
791  }
792 
793  // get the parking area with minimum cost
794  if (nearParkArea == 0 || parkingCost < minParkingCost) {
795  minParkingCost = parkingCost;
796  nearParkArea = it->first;
797  }
798 
799 #ifdef DEBUG_PARKING
800  if (DEBUGCOND) {
801  std::cout << " altPA=" << it->first->getID() << " score=" << parkingCost << "\n";
802  }
803 #endif
804  }
805  }
806 
807 #ifdef DEBUG_PARKING
808  if (DEBUGCOND) {
809  std::cout << " parkingResult=" << Named::getIDSecure(nearParkArea) << "\n";
810  }
811 #endif
812 
813  return nearParkArea;
814 }
815 
816 
817 bool
819  if (myVehicleTypes.empty() || myVehicleTypes.count(veh.getVehicleType().getID()) > 0) {
820  return true;
821  } else {
822  std::set<std::string> vTypeDists = MSNet::getInstance()->getVehicleControl().getVTypeDistributionMembership(veh.getVehicleType().getID());
823  for (auto vTypeDist : vTypeDists) {
824  if (myVehicleTypes.count(vTypeDist) > 0) {
825  return true;
826  }
827  }
828  return false;
829  }
830 }
831 /****************************************************************************/
832 
#define DEBUGCOND
A lane area vehicles can halt at.
Definition: MSParkingArea.h:59
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:617
long long int SUMOTime
Definition: SUMOTime.h:36
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:283
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:841
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.
lane of a reroute of type closing
SUMOTime myCurrentIntervalBegin
The first and the last time steps of the interval.
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:61
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:274
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:67
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:351
weights: time range begin
virtual bool replaceRoute(const MSRoute *route, const std::string &info, bool onInit=false, int offset=0, bool addStops=true, bool removeStops=true)=0
Replaces the current route by the given one.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:160
T MAX2(T a, T b)
Definition: StdDefs.h:68
MSTriggeredRerouter(const std::string &id, const MSEdgeVector &edges, double prob, const std::string &file, bool off, SUMOTime timeThreshold, const std::string &vTypes)
Constructor.
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:62
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:740
const std::vector< T > & getVals() const
Returns the members of the distribution.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:85
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:72
const std::string & getID() const
Returns the id.
Definition: Named.h:69
The arrival position is given.
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.
std::set< std::string > myVehicleTypes
The vehicle types to look for (empty means all)
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:242
#define SIMTIME
Definition: SUMOTime.h:65
authorities vehicles
RandomDistributor< ParkingAreaVisible > myCurrentParkProb
new destinations with probabilities
A road/street connecting two junctions.
Definition: MSEdge.h:75
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)
std::set< std::string > getVTypeDistributionMembership(const std::string &id) const
Return the distribution IDs the vehicle type is a member of.
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:41
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:60
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:185
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:309
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:402
A wrapper for a Command function.
int getCapacity() const
Returns the area capacity.
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:256
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:211
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:598
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:69
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.
double arrivalPos
(optional) The position the vehicle shall arrive on
RandomDistributor< MSEdge * > myCurrentEdgeProb
new destinations with probabilities
std::vector< std::string > getVector()
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:1696
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.
Structure representing possible vehicle parameter.
SUMOTime end
The end time these definitions are valid.
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:236
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:50
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:94
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:305
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:106
virtual SUMOTime getWaitingTime() const =0
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
an aggreagated-output interval
double recomputeCosts(const std::vector< const E *> &edges, const V *const v, SUMOTime msTime) const
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
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:875
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:71
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 vehicleApplies(const SUMOVehicle &veh) const
Checks whether the detector measures vehicles of the given type.
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.
RandomDistributor< ParkingAreaVisible > parkProbs
The distributions of new parking areas to use as destinations.
static bool gUseMesoSim
Definition: MSGlobals.h:91
Representation of a lane in the micro simulation.
Definition: MSLane.h:71
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:360
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:230
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
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:111