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 //#define DEBUG_REROUTER
61 #define DEBUGCOND (veh.getID() == "disabled")
62 
63 // ===========================================================================
64 // static member defintion
65 // ===========================================================================
66 MSEdge MSTriggeredRerouter::mySpecialDest_keepDestination("MSTriggeredRerouter_keepDestination", -1, MSEdge::EDGEFUNCTION_UNKNOWN, "", "", -1);
67 MSEdge MSTriggeredRerouter::mySpecialDest_terminateRoute("MSTriggeredRerouter_terminateRoute", -1, MSEdge::EDGEFUNCTION_UNKNOWN, "", "", -1);
68 
69 // ===========================================================================
70 // method definitions
71 // ===========================================================================
73  const MSEdgeVector& edges,
74  double prob, const std::string& file, bool off) :
75  MSTrigger(id),
76  MSMoveReminder(id),
77  SUMOSAXHandler(file),
78  myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
79  // build actors
80  for (MSEdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
83  s->addDetector(this);
84  continue;
85  }
86  const std::vector<MSLane*>& destLanes = (*j)->getLanes();
87  for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
88  (*i)->addMoveReminder(this);
89  }
90  }
91  if (off) {
92  setUserMode(true);
94  }
95 }
96 
97 
99 }
100 
101 // ------------ loading begin
102 void
104  const SUMOSAXAttributes& attrs) {
105  if (element == SUMO_TAG_INTERVAL) {
106  bool ok = true;
109  }
110  if (element == SUMO_TAG_DEST_PROB_REROUTE) {
111  // by giving probabilities of new destinations
112  // get the destination edge
113  std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
114  if (dest == "") {
115  throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
116  }
117  MSEdge* to = MSEdge::dictionary(dest);
118  if (to == 0) {
119  if (dest == "keepDestination") {
121  } else if (dest == "terminateRoute") {
123  } else {
124  throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
125  }
126  }
127  // get the probability to reroute
128  bool ok = true;
129  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
130  if (!ok) {
131  throw ProcessError();
132  }
133  if (prob < 0) {
134  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
135  }
136  // add
137  myCurrentEdgeProb.add(to, prob);
138  }
139 
140 
141  if (element == SUMO_TAG_CLOSING_REROUTE) {
142  // by closing
143  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
144  MSEdge* closed = MSEdge::dictionary(closed_id);
145  if (closed == 0) {
146  throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
147  }
148  myCurrentClosed.push_back(closed);
149  bool ok;
150  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
151  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
152  myCurrentPermissions = parseVehicleClasses(allow, disallow);
153  }
154 
155  if (element == SUMO_TAG_CLOSING_LANE_REROUTE) {
156  // by closing lane
157  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
158  MSLane* closed = MSLane::dictionary(closed_id);
159  if (closed == 0) {
160  throw ProcessError("MSTriggeredRerouter " + getID() + ": Lane '" + closed_id + "' to close is not known.");
161  }
162  myCurrentClosedLanes.push_back(closed);
163  bool ok;
165  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
166  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
167  myCurrentPermissions = parseVehicleClasses(allow, disallow);
168  } else {
169  // lane closing only makes sense if the lane really receives reduced
170  // permissions
172  }
173  }
174 
175  if (element == SUMO_TAG_ROUTE_PROB_REROUTE) {
176  // by explicit rerouting using routes
177  // check if route exists
178  std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
179  if (routeStr == "") {
180  throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
181  }
182  const MSRoute* route = MSRoute::dictionary(routeStr);
183  if (route == 0) {
184  throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
185  }
186 
187  // get the probability to reroute
188  bool ok = true;
189  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
190  if (!ok) {
191  throw ProcessError();
192  }
193  if (prob < 0) {
194  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
195  }
196  // add
197  myCurrentRouteProb.add(route, prob);
198  }
199 
200  if (element == SUMO_TAG_PARKING_ZONE_REROUTE) {
201  // by giving probabilities of new destinations
202  // get the destination edge
203  std::string parkingarea = attrs.getStringSecure(SUMO_ATTR_ID, "");
204  if (parkingarea == "") {
205  throw ProcessError("MSTriggeredRerouter " + getID() + ": No parking area id given.");
206  }
207  MSParkingArea* pa = MSNet::getInstance()->getParkingArea(parkingarea);
208  if (pa == 0) {
209  throw ProcessError("MSTriggeredRerouter " + getID() + ": Parking area '" + parkingarea + "' is not known.");
210  }
211  // get the probability to reroute
212  bool ok = true;
213  const double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
214  if (!ok) {
215  throw ProcessError();
216  }
217  if (prob < 0) {
218  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + parkingarea + "' is negative (must not).");
219  }
220  // add
221  myCurrentParkProb.add(pa, prob);
222  //MSEdge* to = &(pa->getLane().getEdge());
223  //myCurrentEdgeProb.add(prob, to);
224  }
225 }
226 
227 
228 void
230  if (element == SUMO_TAG_INTERVAL) {
231  RerouteInterval ri;
234  ri.closed = myCurrentClosed;
240  if (ri.closedLanes.size() > 0) {
241  // collect edges that are affect by a closed lane
242  std::set<MSEdge*> affected;
243  for (std::vector<MSLane*>::iterator l = ri.closedLanes.begin(); l != ri.closedLanes.end(); ++l) {
244  affected.insert(&((*l)->getEdge()));
245  }
246  ri.closedLanesAffected.insert(ri.closedLanesAffected.begin(), affected.begin(), affected.end());
247  }
248  myCurrentClosed.clear();
249  myCurrentClosedLanes.clear();
253  myIntervals.push_back(ri);
254  myIntervals.back().id = (long)&myIntervals.back();
255  if (!(ri.closed.empty() && ri.closedLanes.empty()) && ri.permissions != SVCAll) {
258  }
259  }
260 }
261 
262 
263 // ------------ loading end
264 
265 
266 SUMOTime
268  for (std::vector<RerouteInterval>::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
269  if (i->begin == currentTime && !(i->closed.empty() && i->closedLanes.empty()) && i->permissions != SVCAll) {
270  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
271  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
272  //std::cout << SIMTIME << " closing: intervalID=" << i->id << " lane=" << (*l)->getID() << " prevPerm=" << getVehicleClassNames((*l)->getPermissions()) << " new=" << getVehicleClassNames(i->permissions) << "\n";
273  (*l)->setPermissions(i->permissions, i->id);
274  }
275  (*e)->rebuildAllowedLanes();
276  }
277  for (std::vector<MSLane*>::iterator l = i->closedLanes.begin(); l != i->closedLanes.end(); ++l) {
278  (*l)->setPermissions(i->permissions, i->id);
279  (*l)->getEdge().rebuildAllowedLanes();
280  }
283  }
284  if (i->end == currentTime && !(i->closed.empty() && i->closedLanes.empty()) && i->permissions != SVCAll) {
285  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
286  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
287  (*l)->resetPermissions(i->id);
288  //std::cout << SIMTIME << " opening: intervalID=" << i->id << " lane=" << (*l)->getID() << " restore prevPerm=" << getVehicleClassNames((*l)->getPermissions()) << "\n";
289  }
290  (*e)->rebuildAllowedLanes();
291  }
292  for (std::vector<MSLane*>::iterator l = i->closedLanes.begin(); l != i->closedLanes.end(); ++l) {
293  (*l)->resetPermissions(i->id);
294  (*l)->getEdge().rebuildAllowedLanes();
295  }
296  }
297  }
298  return 0;
299 }
300 
301 
304  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
305  if (i->begin <= time && i->end > time) {
306  if (
307  // destProbReroute
308  i->edgeProbs.getOverallProb() > 0 ||
309  // routeProbReroute
310  i->routeProbs.getOverallProb() > 0 ||
311  // parkingZoneReroute
312  i->parkProbs.getOverallProb() > 0 ||
313  // affected by closingReroute
314  veh.getRoute().containsAnyOf(i->closed) ||
315  // affected by closingLaneReroute
316  veh.getRoute().containsAnyOf(i->closedLanesAffected)) {
317  return &*i;
318  }
319  }
320  }
321  return 0;
322 }
323 
324 
327  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
328  if (i->begin <= time && i->end > time) {
329  if (i->parkProbs.getOverallProb() != 0 || i->edgeProbs.getOverallProb() != 0 || i->routeProbs.getOverallProb() != 0 || !i->closed.empty()) {
330  return &*i;
331  }
332  }
333  }
334  return 0;
335 }
336 
337 
338 bool
340  double /*newPos*/, double /*newSpeed*/) {
341  return notifyEnter(veh, NOTIFICATION_JUNCTION);
342 }
343 
344 
345 bool
346 MSTriggeredRerouter::notifyLeave(SUMOVehicle& /*veh*/, double /*lastPos*/,
347  MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
348  return reason == NOTIFICATION_LANE_CHANGE;
349 }
350 
351 
352 bool
354  // check whether the vehicle shall be rerouted
356  const MSTriggeredRerouter::RerouteInterval* rerouteDef = getCurrentReroute(time, veh);
357  if (rerouteDef == 0) {
358  return true; // an active interval could appear later
359  }
361  if (RandHelper::rand() > prob) {
362  return false; // XXX another interval could appear later but we would have to track whether the current interval was already tried
363  }
364  // if we have a closingLaneReroute, only vehicles with a rerouting device can profit from rerouting (otherwise, edge weights will not reflect local jamming)
365  const bool hasReroutingDevice = veh.getDevice(typeid(MSDevice_Routing)) != 0;
366  if (rerouteDef->closedLanes.size() > 0 && !hasReroutingDevice) {
367  return true; // an active interval could appear later
368  }
369  // get vehicle params
370  const MSRoute& route = veh.getRoute();
371  const MSEdge* lastEdge = route.getLastEdge();
372 #ifdef DEBUG_REROUTER
373  if (DEBUGCOND) {
374  std::cout << SIMTIME << " veh=" << veh.getID() << " check rerouter " << getID() << " lane=" << veh.getLane()->getID() << " edge=" << veh.getEdge()->getID() << " finalEdge=" << lastEdge->getID() << " arrivalPos=" << veh.getArrivalPos() << "\n";
375  }
376 #endif
377 
378  if (rerouteDef->parkProbs.getOverallProb() > 0) {
379  MSParkingArea* newParkingArea = rerouteParkingZone(rerouteDef, veh);
380  if (newParkingArea != 0) {
381  const MSEdge* newEdge = &(newParkingArea->getLane().getEdge());
382 
383  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
385  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
386 
387  // Compute the route from the current edge to the parking area edge
388  ConstMSEdgeVector edgesToPark;
389  router.compute(veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
390 
391  // Compute the route from the parking area edge to the end of the route
392  ConstMSEdgeVector edgesFromPark;
393  router.compute(newEdge, lastEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
394 
395  // we have a new destination, let's replace the vehicle route
396  ConstMSEdgeVector edges = edgesToPark;
397  if (edgesFromPark.size() > 0) {
398  edges.insert(edges.end(), edgesFromPark.begin() + 1, edgesFromPark.end());
399  }
400 
401  veh.replaceRouteEdges(edges, false, false, false);
402  std::string errorMsg;
403  if (!veh.replaceParkingArea(newParkingArea, errorMsg)) {
404  WRITE_WARNING("Vehicle '" + veh.getID() + "' at rerouter '" + getID()
405  + "' could not reroute to new parkingArea '" + newParkingArea->getID()
406  + "' reason=" + errorMsg + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
407  }
408  }
409  return false;
410  }
411 
412  // get rerouting params
413  const MSRoute* newRoute = rerouteDef->routeProbs.getOverallProb() > 0 ? rerouteDef->routeProbs.get() : 0;
414  // we will use the route if given rather than calling our own dijsktra...
415  if (newRoute != 0) {
416 #ifdef DEBUG_REROUTER
417  if (DEBUGCOND) {
418  std::cout << " replacedRoute from routeDist " << newRoute->getID() << "\n";
419  }
420 #endif
421  veh.replaceRoute(newRoute);
422  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
423  }
424  const MSEdge* newEdge = lastEdge;
425  // ok, try using a new destination
426  double newArrivalPos = -1;
427  const bool destUnreachable = std::find(rerouteDef->closed.begin(), rerouteDef->closed.end(), lastEdge) != rerouteDef->closed.end();
428  // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination
429  // if we have a closingLaneReroute, no new destinations should be assigned
430  if (rerouteDef->closed.size() == 0 || destUnreachable) {
431  newEdge = rerouteDef->edgeProbs.getOverallProb() > 0 ? rerouteDef->edgeProbs.get() : route.getLastEdge();
432  if (newEdge == &mySpecialDest_terminateRoute) {
433  newEdge = veh.getEdge();
434  newArrivalPos = veh.getPositionOnLane(); // instant arrival
435  } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) {
436  if (destUnreachable && rerouteDef->permissions == SVCAll) {
437  // if permissions aren't set vehicles will simply drive through
438  // the closing unless terminated. If the permissions are specified, assume that the user wants
439  // vehicles to stand and wait until the closing ends
440  WRITE_WARNING("Cannot keep destination edge '" + lastEdge->getID() + "' for vehicle '" + veh.getID() + "' due to closed edges. Terminating route.");
441  newEdge = veh.getEdge();
442  } else {
443  newEdge = lastEdge;
444  }
445  } else if (newEdge == 0) {
446 #ifdef DEBUG_REROUTER
447  if (DEBUGCOND) {
448  std::cout << " could not find new edge!\n";
449  }
450 #endif
451  assert(false); // this should never happen
452  newEdge = veh.getEdge();
453  }
454  }
455  // we have a new destination, let's replace the vehicle route (if it is affected)
456  if (rerouteDef->closed.size() == 0 || destUnreachable || veh.getRoute().containsAnyOf(rerouteDef->closed)) {
457  ConstMSEdgeVector edges;
458  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
460  : MSNet::getInstance()->getRouterTT(rerouteDef->closed);
461  router.compute(
462  veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
463  const bool useNewRoute = veh.replaceRouteEdges(edges);
464 #ifdef DEBUG_REROUTER
465  if (DEBUGCOND) std::cout << " rerouting: newEdge=" << newEdge->getID() << " useNewRoute=" << useNewRoute << " newArrivalPos=" << newArrivalPos << " numClosed=" << rerouteDef->closed.size()
466  << " destUnreachable=" << destUnreachable << " containsClosed=" << veh.getRoute().containsAnyOf(rerouteDef->closed) << "\n";
467 #endif
468  if (useNewRoute && newArrivalPos != -1) {
469  // must be called here because replaceRouteEdges may also set the arrivalPos
470  veh.setArrivalPos(newArrivalPos);
471  }
472  }
473  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
474 }
475 
476 
477 void
479  myAmInUserMode = val;
480 }
481 
482 
483 void
485  myUserProbability = prob;
486 }
487 
488 
489 bool
491  return myAmInUserMode;
492 }
493 
494 
495 double
498 }
499 
500 
501 double
503  return myUserProbability;
504 }
505 
506 
507 double
508 MSTriggeredRerouter::getWeight(SUMOVehicle& veh, const std::string param, const double defaultWeight) const {
509  // get custom vehicle parameter
510  if (veh.getParameter().knowsParameter(param)) {
511  try {
512  return TplConvert::_2double(veh.getParameter().getParameter(param, "-1").c_str());
513  } catch (...) {
514  WRITE_WARNING("Invalid value '" + veh.getParameter().getParameter(param, "-1") + "' for vehicle parameter '" + param + "'");
515  }
516  } else {
517  // get custom vType parameter
518  if (veh.getVehicleType().getParameter().knowsParameter(param)) {
519  try {
520  return TplConvert::_2double(veh.getVehicleType().getParameter().getParameter(param, "-1").c_str());
521  } catch (...) {
522  WRITE_WARNING("Invalid value '" + veh.getVehicleType().getParameter().getParameter(param, "-1") + "' for vType parameter '" + param + "'");
523  }
524  }
525  }
526  //WRITE_MESSAGE("Vehicle '" +veh.getID() + "' does not supply vehicle parameter '" + param + "'. Using default of " + toString(defaultWeight) + "\n";
527  return defaultWeight;
528 }
529 
530 
533 
534  MSParkingArea* nearParkArea = 0;
535 
536  // get vehicle params
537  MSParkingArea* destParkArea = veh.getNextParkingArea();
538  const MSRoute& route = veh.getRoute();
539 
540  // I reroute destination from initial parking area to the near parking area
541  // if the next stop is a parking area and if it is full
542  if (destParkArea != 0 &&
543  destParkArea->getOccupancy() == destParkArea->getCapacity()) {
544 
545  typedef std::map<std::string, double> ParkingParamMap_t;
546  typedef std::map<MSParkingArea*, ParkingParamMap_t> MSParkingAreaMap_t;
547 
548  ParkingParamMap_t weights;
549 
550  // The probability of choosing this area inside the zone
551  weights["probability"] = getWeight(veh, "parking.probability.weight", 0.0);
552 
553  // The capacity of this area
554  weights["capacity"] = getWeight(veh, "parking.capacity.weight", 0.0);
555 
556  // The absolute number of free spaces
557  weights["absfreespace"] = getWeight(veh, "parking.absfreespace.weight", 0.0);
558 
559  // The relative number of free spaces
560  weights["relfreespace"] = getWeight(veh, "parking.relfreespace.weight", 0.0);
561 
562  // The distance to the new parking area
563  weights["distanceto"] = getWeight(veh, "parking.distanceto.weight", getWeight(veh, "parking.distance.weight", 1.0));
564 
565  // The time to reach this area
566  weights["timeto"] = getWeight(veh, "parking.timeto.weight", 0.0);
567 
568  // The distance from the new parking area
569  weights["distancefrom"] = getWeight(veh, "parking.distancefrom.weight", 0.0);
570 
571  // The time to reach the end from this area
572  weights["timefrom"] = getWeight(veh, "parking.timefrom.weight", 0.0);
573 
574  // a map stores maximum values to normalize parking values
575  ParkingParamMap_t maxValues;
576 
577  maxValues["probability"] = 0.0;
578  maxValues["capacity"] = 0.0;
579  maxValues["absfreespace"] = 0.0;
580  maxValues["relfreespace"] = 0.0;
581  maxValues["distanceto"] = 0.0;
582  maxValues["timeto"] = 0.0;
583  maxValues["distancefrom"] = 0.0;
584  maxValues["timefrom"] = 0.0;
585 
586  // a map stores elegible parking areas
587  MSParkingAreaMap_t parkAreas;
588 
590 
591  std::vector<MSParkingArea*> parks = rerouteDef->parkProbs.getVals();
592  std::vector<double> probs = rerouteDef->parkProbs.getProbs();
593 
594  for (int i = 0; i < (int)parks.size(); ++i) {
595  MSParkingArea* pa = parks[i];
596  const double prob = probs[i];
597  if (pa->getOccupancy() < pa->getCapacity()) {
598 
599  // a map stores the parking values
600  ParkingParamMap_t parkValues;
601 
602  const RGBColor& c = route.getColor();
603  const MSEdge* parkEdge = &(pa->getLane().getEdge());
604 
605  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
606 
607  // Compute the route from the current edge to the parking area edge
608  ConstMSEdgeVector edgesToPark;
609  router.compute(veh.getEdge(), parkEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
610 
611  if (edgesToPark.size() > 0) {
612  // Compute the route from the parking area edge to the end of the route
613  ConstMSEdgeVector edgesFromPark;
614  router.compute(parkEdge, route.getLastEdge(), &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
615 
616  if (edgesFromPark.size() > 0) {
617 
618  parkValues["probability"] = prob;
619 
620  if (parkValues["probability"] > maxValues["probability"]) {
621  maxValues["probability"] = parkValues["probability"];
622  }
623 
624  parkValues["capacity"] = (double)(pa->getCapacity());
625  parkValues["absfreespace"] = (double)(pa->getCapacity() - pa->getOccupancy());
626  parkValues["relfreespace"] = parkValues["absfreespace"] / parkValues["capacity"];
627 
628  if (parkValues["capacity"] > maxValues["capacity"]) {
629  maxValues["capacity"] = parkValues["capacity"];
630  }
631 
632  if (parkValues["absfreespace"] > maxValues["absfreespace"]) {
633  maxValues["absfreespace"] = parkValues["absfreespace"];
634  }
635 
636  if (parkValues["relfreespace"] > maxValues["relfreespace"]) {
637  maxValues["relfreespace"] = parkValues["relfreespace"];
638  }
639 
640  MSRoute routeToPark(route.getID() + "!topark#1", edgesToPark, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
641 
642  // The distance from the current edge to the new parking area
643  parkValues["distanceto"] = routeToPark.getDistanceBetween(veh.getPositionOnLane(), pa->getBeginLanePosition(),
644  routeToPark.begin(), routeToPark.end(), includeInternalLengths);
645 
646  // The time to reach the new parking area
647  parkValues["timeto"] = router.recomputeCosts(edgesToPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
648 
649  if (parkValues["distanceto"] > maxValues["distanceto"]) {
650  maxValues["distanceto"] = parkValues["distanceto"];
651  }
652 
653  if (parkValues["timeto"] > maxValues["timeto"]) {
654  maxValues["timeto"] = parkValues["timeto"];
655  }
656 
657  MSRoute routeFromPark(route.getID() + "!frompark#1", edgesFromPark, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), route.getStops());
658 
659  // The distance from the new parking area to the end of the route
660  parkValues["distancefrom"] = routeFromPark.getDistanceBetween(pa->getBeginLanePosition(), routeFromPark.getLastEdge()->getLength(),
661  routeFromPark.begin(), routeFromPark.end(), includeInternalLengths);
662 
663  // The time to reach this area
664  parkValues["timefrom"] = router.recomputeCosts(edgesFromPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
665 
666  if (parkValues["distancefrom"] > maxValues["distancefrom"]) {
667  maxValues["distancefrom"] = parkValues["distancefrom"];
668  }
669 
670  if (parkValues["timefrom"] > maxValues["timefrom"]) {
671  maxValues["timefrom"] = parkValues["timefrom"];
672  }
673 
674  parkAreas[pa] = parkValues;
675  }
676  }
677  }
678  }
679 
680  // minimum cost to get the parking area
681  double minParkingCost = 0.0;
682 
683  for (MSParkingAreaMap_t::iterator it = parkAreas.begin(); it != parkAreas.end(); ++it) {
684  // get the parking values
685  ParkingParamMap_t parkValues = it->second;
686 
687  // normalizing parking values with maximum values (we want to maximize some parameters then we reverse the value)
688  parkValues["probability"] = maxValues["probability"] > 0.0 ? 1.0 - parkValues["probability"] / maxValues["probability"] : 0.0;
689  parkValues["capacity"] = maxValues["capacity"] > 0.0 ? 1.0 - parkValues["capacity"] / maxValues["capacity"] : 0.0;
690  parkValues["absfreespace"] = maxValues["absfreespace"] > 0.0 ? 1.0 - parkValues["absfreespace"] / maxValues["absfreespace"] : 0.0;
691  parkValues["relfreespace"] = maxValues["relfreespace"] > 0.0 ? 1.0 - parkValues["relfreespace"] / maxValues["relfreespace"] : 0.0;
692 
693  parkValues["distanceto"] = maxValues["distanceto"] > 0.0 ? parkValues["distanceto"] / maxValues["distanceto"] : 0.0;
694  parkValues["timeto"] = maxValues["timeto"] > 0.0 ? parkValues["timeto"] / maxValues["timeto"] : 0.0;
695 
696  parkValues["distancefrom"] = maxValues["distancefrom"] > 0.0 ? parkValues["distancefrom"] / maxValues["distancefrom"] : 0.0;
697  parkValues["timefrom"] = maxValues["timefrom"] > 0.0 ? parkValues["timefrom"] / maxValues["timefrom"] : 0.0;
698 
699  // get the parking area cost
700  double parkingCost = 0.0;
701 
702  // sum every index with its weight
703  for (ParkingParamMap_t::iterator pc = parkValues.begin(); pc != parkValues.end(); ++pc) {
704  parkingCost += weights[pc->first] * pc->second;
705  }
706 
707  // get the parking area with minimum cost
708  if (nearParkArea == 0 || parkingCost < minParkingCost) {
709  minParkingCost = parkingCost;
710  nearParkArea = it->first;
711  }
712  }
713  }
714 
715  return nearParkArea;
716 }
717 
718 /****************************************************************************/
719 
#define DEBUGCOND
A lane area vehicles can halt at.
Definition: MSParkingArea.h:66
double getProbability() const
Returns the rerouting probability.
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.
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:582
MSParkingArea * rerouteParkingZone(const MSTriggeredRerouter::RerouteInterval *rerouteDef, SUMOVehicle &veh) const
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
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.
std::vector< MSLane * > myCurrentClosedLanes
List of closed lanes.
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:281
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
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:341
weights: time range begin
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:158
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:728
const std::vector< T > & getVals() const
Returns the members of the distribution.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:92
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:66
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.
MSTriggeredRerouter(const std::string &id, const MSEdgeVector &edges, double prob, const std::string &file, bool off)
Constructor.
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.
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
authorities vehicles
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)
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:48
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:67
Encapsulated SAX-Attributes.
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:403
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.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:257
RandomDistributor< const MSRoute * > myCurrentRouteProb
new routes with probabilities
static double rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
static MSEdge mySpecialDest_keepDestination
special destination values
void addDetector(MSMoveReminder *data)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:205
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:678
probability of route of a reroute
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:76
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.
T get(MTRand *which=0) const
Draw a sample of the distribution.
RandomDistributor< MSEdge * > myCurrentEdgeProb
new destinations with probabilities
reroute of type closing
void clear()
Clears the distribution.
entry for an alternative parking zone
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1371
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:243
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:57
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:297
bool inUserMode() const
Returns whether the user is setting the rerouting probability.
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:113
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:52
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:925
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:98
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:350
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
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:118
MSParkingArea * getParkingArea(const std::string &id) const
Returns the named parking area.
Definition: MSNet.cpp:874