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