Eclipse 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-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
21 // Reroutes vehicles passing an edge
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <string>
26 #include <algorithm>
29 #include <utils/common/Command.h>
32 #include <utils/common/ToString.h>
39 #include <microsim/MSLane.h>
40 #include <microsim/MSVehicle.h>
41 #include <microsim/MSRoute.h>
42 #include <microsim/MSEdge.h>
44 #include <microsim/MSNet.h>
46 #include <microsim/MSGlobals.h>
47 #include <microsim/MSParkingArea.h>
51 #include "MSTriggeredRerouter.h"
52 
53 #include <mesosim/MELoop.h>
54 #include <mesosim/MESegment.h>
55 
56 //#define DEBUG_REROUTER
57 //#define DEBUG_PARKING
58 #define DEBUGCOND (veh.isSelected())
59 //#define DEBUGCOND (veh.getID() == "")
60 
61 // ===========================================================================
62 // static member defintion
63 // ===========================================================================
64 MSEdge MSTriggeredRerouter::mySpecialDest_keepDestination("MSTriggeredRerouter_keepDestination", -1, SumoXMLEdgeFunc::UNKNOWN, "", "", -1, 0);
65 MSEdge MSTriggeredRerouter::mySpecialDest_terminateRoute("MSTriggeredRerouter_terminateRoute", -1, SumoXMLEdgeFunc::UNKNOWN, "", "", -1, 0);
66 std::map<std::string, MSTriggeredRerouter*> MSTriggeredRerouter::myInstances;
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
72  const MSEdgeVector& edges,
73  double prob, const std::string& file, bool off,
74  SUMOTime timeThreshold,
75  const std::string& vTypes) :
76  MSTrigger(id),
77  MSMoveReminder(id),
78  SUMOSAXHandler(file),
79  myProbability(prob),
80  myUserProbability(prob),
81  myAmInUserMode(false),
82  myTimeThreshold(timeThreshold) {
83  myInstances[id] = this;
84  // build actors
85  for (MSEdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
88  s->addDetector(this);
89  continue;
90  }
91  const std::vector<MSLane*>& destLanes = (*j)->getLanes();
92  for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
93  (*i)->addMoveReminder(this);
94  }
95  }
96  if (off) {
97  setUserMode(true);
99  }
100  const std::vector<std::string> vt = StringTokenizer(vTypes).getVector();
101  myVehicleTypes.insert(vt.begin(), vt.end());
102 }
103 
104 
106  myInstances.erase(getID());
107 }
108 
109 // ------------ loading begin
110 void
112  const SUMOSAXAttributes& attrs) {
113  if (element == SUMO_TAG_INTERVAL) {
114  bool ok = true;
117  }
118  if (element == SUMO_TAG_DEST_PROB_REROUTE) {
119  // by giving probabilities of new destinations
120  // get the destination edge
121  std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
122  if (dest == "") {
123  throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
124  }
125  MSEdge* to = MSEdge::dictionary(dest);
126  if (to == nullptr) {
127  if (dest == "keepDestination") {
129  } else if (dest == "terminateRoute") {
131  } else {
132  throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
133  }
134  }
135  // get the probability to reroute
136  bool ok = true;
137  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
138  if (!ok) {
139  throw ProcessError();
140  }
141  if (prob < 0) {
142  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
143  }
144  // add
145  myCurrentEdgeProb.add(to, prob);
146  }
147 
148 
149  if (element == SUMO_TAG_CLOSING_REROUTE) {
150  // by closing
151  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
152  MSEdge* closed = MSEdge::dictionary(closed_id);
153  if (closed == nullptr) {
154  throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
155  }
156  myCurrentClosed.push_back(closed);
157  bool ok;
158  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
159  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
160  myCurrentPermissions = parseVehicleClasses(allow, disallow);
161  }
162 
163  if (element == SUMO_TAG_CLOSING_LANE_REROUTE) {
164  // by closing lane
165  std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
166  MSLane* closed = MSLane::dictionary(closed_id);
167  if (closed == nullptr) {
168  throw ProcessError("MSTriggeredRerouter " + getID() + ": Lane '" + closed_id + "' to close is not known.");
169  }
170  myCurrentClosedLanes.push_back(closed);
171  bool ok;
173  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, getID().c_str(), ok, "", false);
174  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, getID().c_str(), ok, "");
175  myCurrentPermissions = parseVehicleClasses(allow, disallow);
176  } else {
177  // lane closing only makes sense if the lane really receives reduced
178  // permissions
180  }
181  }
182 
183  if (element == SUMO_TAG_ROUTE_PROB_REROUTE) {
184  // by explicit rerouting using routes
185  // check if route exists
186  std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
187  if (routeStr == "") {
188  throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
189  }
190  const MSRoute* route = MSRoute::dictionary(routeStr);
191  if (route == nullptr) {
192  throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
193  }
194 
195  // get the probability to reroute
196  bool ok = true;
197  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
198  if (!ok) {
199  throw ProcessError();
200  }
201  if (prob < 0) {
202  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
203  }
204  // add
205  myCurrentRouteProb.add(route, prob);
206  }
207 
208  if (element == SUMO_TAG_PARKING_ZONE_REROUTE) {
209  // by giving probabilities of new destinations
210  // get the destination edge
211  std::string parkingarea = attrs.getStringSecure(SUMO_ATTR_ID, "");
212  if (parkingarea == "") {
213  throw ProcessError("MSTriggeredRerouter " + getID() + ": No parking area id given.");
214  }
216  if (pa == nullptr) {
217  throw ProcessError("MSTriggeredRerouter " + getID() + ": Parking area '" + parkingarea + "' is not known.");
218  }
219  // get the probability to reroute
220  bool ok = true;
221  const double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
222  if (!ok) {
223  throw ProcessError();
224  }
225  if (prob < 0) {
226  throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + parkingarea + "' is negative (must not).");
227  }
228  const bool visible = attrs.getOpt<bool>(SUMO_ATTR_VISIBLE, getID().c_str(), ok, false);
229  // add
230  myCurrentParkProb.add(std::make_pair(pa, visible), prob);
231  //MSEdge* to = &(pa->getLane().getEdge());
232  //myCurrentEdgeProb.add(prob, to);
233  }
234 }
235 
236 
237 void
239  if (element == SUMO_TAG_INTERVAL) {
240  RerouteInterval ri;
243  ri.closed = myCurrentClosed;
249  for (auto paVi : ri.parkProbs.getVals()) {
250  paVi.first->setNumAlternatives((int)ri.parkProbs.getVals().size() - 1);
251  }
252  if (ri.closedLanes.size() > 0) {
253  // collect edges that are affect by a closed lane
254  std::set<MSEdge*> affected;
255  for (const MSLane* const l : ri.closedLanes) {
256  affected.insert(&l->getEdge());
257  }
258  ri.closedLanesAffected.insert(ri.closedLanesAffected.begin(), affected.begin(), affected.end());
259  }
260  SUMOTime closingBegin = ri.begin;
261  SUMOTime simBegin = string2time(OptionsCont::getOptions().getString("begin"));
262  if (closingBegin < simBegin && ri.end > simBegin) {
263  // interval started before simulation begin but is still active at
264  // the start of the simulation
265  ri.begin = simBegin;
266  }
267  myCurrentClosed.clear();
268  myCurrentClosedLanes.clear();
272  myIntervals.push_back(ri);
273  myIntervals.back().id = (long long)&myIntervals.back();
274  if (!(ri.closed.empty() && ri.closedLanes.empty()) && ri.permissions != SVCAll) {
277  }
278  }
279 }
280 
281 
282 // ------------ loading end
283 
284 
285 SUMOTime
287  for (std::vector<RerouteInterval>::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
288  if (i->begin == currentTime && !(i->closed.empty() && i->closedLanes.empty()) && i->permissions != SVCAll) {
289  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
290  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
291  //std::cout << SIMTIME << " closing: intervalID=" << i->id << " lane=" << (*l)->getID() << " prevPerm=" << getVehicleClassNames((*l)->getPermissions()) << " new=" << getVehicleClassNames(i->permissions) << "\n";
292  (*l)->setPermissions(i->permissions, i->id);
293  }
294  (*e)->rebuildAllowedLanes();
295  }
296  for (std::vector<MSLane*>::iterator l = i->closedLanes.begin(); l != i->closedLanes.end(); ++l) {
297  (*l)->setPermissions(i->permissions, i->id);
298  (*l)->getEdge().rebuildAllowedLanes();
299  }
302  }
303  if (i->end == currentTime && !(i->closed.empty() && i->closedLanes.empty()) && i->permissions != SVCAll) {
304  for (MSEdgeVector::iterator e = i->closed.begin(); e != i->closed.end(); ++e) {
305  for (std::vector<MSLane*>::const_iterator l = (*e)->getLanes().begin(); l != (*e)->getLanes().end(); ++l) {
306  (*l)->resetPermissions(i->id);
307  //std::cout << SIMTIME << " opening: intervalID=" << i->id << " lane=" << (*l)->getID() << " restore prevPerm=" << getVehicleClassNames((*l)->getPermissions()) << "\n";
308  }
309  (*e)->rebuildAllowedLanes();
310  }
311  for (std::vector<MSLane*>::iterator l = i->closedLanes.begin(); l != i->closedLanes.end(); ++l) {
312  (*l)->resetPermissions(i->id);
313  (*l)->getEdge().rebuildAllowedLanes();
314  }
315  }
316  }
317  return 0;
318 }
319 
320 
323  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
324  if (i->begin <= time && i->end > time) {
325  if (
326  // destProbReroute
327  i->edgeProbs.getOverallProb() > 0 ||
328  // routeProbReroute
329  i->routeProbs.getOverallProb() > 0 ||
330  // parkingZoneReroute
331  i->parkProbs.getOverallProb() > 0 ||
332  // affected by closingReroute
333  veh.getRoute().containsAnyOf(i->closed) ||
334  // affected by closingLaneReroute
335  veh.getRoute().containsAnyOf(i->closedLanesAffected)) {
336  return &*i;
337  }
338  }
339  }
340  return nullptr;
341 }
342 
343 
346  for (std::vector<RerouteInterval>::const_iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
347  if (i->begin <= time && i->end > time) {
348  if (i->parkProbs.getOverallProb() != 0 || i->edgeProbs.getOverallProb() != 0 || i->routeProbs.getOverallProb() != 0 || !i->closed.empty()) {
349  return &*i;
350  }
351  }
352  }
353  return nullptr;
354 }
355 
356 
357 bool
359  double /*newPos*/, double /*newSpeed*/) {
360  return notifyEnter(veh, NOTIFICATION_JUNCTION);
361 }
362 
363 
364 bool
366  MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
367  return reason == NOTIFICATION_LANE_CHANGE;
368 }
369 
370 
371 bool
373  if (!tObject.isVehicle()) {
374  return false;
375  }
376  SUMOVehicle& veh = static_cast<SUMOVehicle&>(tObject);
377  if (!vehicleApplies(veh)) {
378  return false;
379  }
380  // check whether the vehicle shall be rerouted
382  const MSTriggeredRerouter::RerouteInterval* rerouteDef = getCurrentReroute(time, veh);
383  if (rerouteDef == nullptr) {
384  return true; // an active interval could appear later
385  }
386  const double prob = myAmInUserMode ? myUserProbability : myProbability;
387  if (prob < 1 && RandHelper::rand(veh.getRNG()) > prob) {
388  return false; // XXX another interval could appear later but we would have to track whether the current interval was already tried
389  }
391  return true; // waiting time may be reached later
392  }
393  // if we have a closingLaneReroute, only vehicles with a rerouting device can profit from rerouting (otherwise, edge weights will not reflect local jamming)
394  const bool hasReroutingDevice = veh.getDevice(typeid(MSDevice_Routing)) != nullptr;
395  if (rerouteDef->closedLanes.size() > 0 && !hasReroutingDevice) {
396  return true; // an active interval could appear later
397  }
398  // get vehicle params
399  const MSRoute& route = veh.getRoute();
400  const MSEdge* lastEdge = route.getLastEdge();
401 #ifdef DEBUG_REROUTER
402  if (DEBUGCOND) {
403  std::cout << SIMTIME << " veh=" << veh.getID() << " check rerouter " << getID() << " lane=" << veh.getLane()->getID() << " edge=" << veh.getEdge()->getID() << " finalEdge=" << lastEdge->getID() << " arrivalPos=" << veh.getArrivalPos() << "\n";
404  }
405 #endif
406 
407  if (rerouteDef->parkProbs.getOverallProb() > 0) {
408 #ifdef HAVE_FOX
409  FXConditionalLock lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
410 #endif
411  bool newDestination = false;
412  ConstMSEdgeVector newRoute;
413  MSParkingArea* newParkingArea = rerouteParkingArea(rerouteDef, veh, newDestination, newRoute);
414  if (newParkingArea != nullptr) {
415  // adapt plans of any riders
416  for (MSTransportable* p : veh.getPersons()) {
417  p->rerouteParkingArea(veh.getNextParkingArea(), newParkingArea);
418  }
419 
420  if (newDestination) {
421  // update arrival parameters
422  SUMOVehicleParameter* newParameter = new SUMOVehicleParameter();
423  *newParameter = veh.getParameter();
425  newParameter->arrivalPos = newParkingArea->getEndLanePosition();
426  veh.replaceParameter(newParameter);
427  }
428 
429  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
430  ? MSRoutingEngine::getRouterTT(veh.getRNGIndex(), veh.getVClass(), rerouteDef->closed)
431  : MSNet::getInstance()->getRouterTT(veh.getRNGIndex(), rerouteDef->closed);
432  const double routeCost = router.recomputeCosts(newRoute, &veh, MSNet::getInstance()->getCurrentTimeStep());
433  ConstMSEdgeVector prevEdges(veh.getCurrentRouteEdge(), veh.getRoute().end());
434  const double previousCost = router.recomputeCosts(prevEdges, &veh, MSNet::getInstance()->getCurrentTimeStep());
435  const double savings = previousCost - routeCost;
436  hasReroutingDevice
438  : MSNet::getInstance()->getRouterTT(veh.getRNGIndex()); // reset closed edges
439  //if (getID() == "ego") std::cout << SIMTIME << " pCost=" << previousCost << " cost=" << routeCost
440  // << " prevEdges=" << toString(prevEdges)
441  // << " newEdges=" << toString(edges)
442  // << "\n";
443 
444  std::string errorMsg;
445  if (veh.replaceParkingArea(newParkingArea, errorMsg)) {
446  veh.replaceRouteEdges(newRoute, routeCost, savings, getID() + ":" + toString(SUMO_TAG_PARKING_ZONE_REROUTE), false, false, false);
447  } else {
448  WRITE_WARNING("Vehicle '" + veh.getID() + "' at rerouter '" + getID()
449  + "' could not reroute to new parkingArea '" + newParkingArea->getID()
450  + "' reason=" + errorMsg + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
451  }
452  }
453  return false;
454  }
455 
456  // get rerouting params
457  const MSRoute* newRoute = rerouteDef->routeProbs.getOverallProb() > 0 ? rerouteDef->routeProbs.get() : 0;
458  // we will use the route if given rather than calling our own dijsktra...
459  if (newRoute != nullptr) {
460 #ifdef DEBUG_REROUTER
461  if (DEBUGCOND) {
462  std::cout << " replacedRoute from routeDist " << newRoute->getID() << "\n";
463  }
464 #endif
465  veh.replaceRoute(newRoute, getID());
466  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
467  }
468  const MSEdge* newEdge = lastEdge;
469  // ok, try using a new destination
470  double newArrivalPos = -1;
471  const bool destUnreachable = std::find(rerouteDef->closed.begin(), rerouteDef->closed.end(), lastEdge) != rerouteDef->closed.end();
472  bool keepDestination = false;
473  // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination
474  // if we have a closingLaneReroute, no new destinations should be assigned
475  if (rerouteDef->closed.size() == 0 || destUnreachable) {
476  newEdge = rerouteDef->edgeProbs.getOverallProb() > 0 ? rerouteDef->edgeProbs.get() : route.getLastEdge();
477  if (newEdge == &mySpecialDest_terminateRoute) {
478  keepDestination = true;
479  newEdge = veh.getEdge();
480  newArrivalPos = veh.getPositionOnLane(); // instant arrival
481  } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) {
482  if (destUnreachable && rerouteDef->permissions == SVCAll) {
483  // if permissions aren't set vehicles will simply drive through
484  // the closing unless terminated. If the permissions are specified, assume that the user wants
485  // vehicles to stand and wait until the closing ends
486  WRITE_WARNING("Cannot keep destination edge '" + lastEdge->getID() + "' for vehicle '" + veh.getID() + "' due to closed edges. Terminating route.");
487  newEdge = veh.getEdge();
488  } else {
489  newEdge = lastEdge;
490  }
491  } else if (newEdge == nullptr) {
492 #ifdef DEBUG_REROUTER
493  if (DEBUGCOND) {
494  std::cout << " could not find new edge!\n";
495  }
496 #endif
497  assert(false); // this should never happen
498  newEdge = veh.getEdge();
499  }
500  }
501  // we have a new destination, let's replace the vehicle route (if it is affected)
502  if (rerouteDef->closed.size() == 0 || destUnreachable || veh.getRoute().containsAnyOf(rerouteDef->closed)) {
503  ConstMSEdgeVector edges;
504  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = hasReroutingDevice
505  ? MSRoutingEngine::getRouterTT(veh.getRNGIndex(), veh.getVClass(), rerouteDef->closed)
506  : MSNet::getInstance()->getRouterTT(veh.getRNGIndex(), rerouteDef->closed);
507  router.compute(veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
508  if (edges.size() == 0 && !keepDestination && rerouteDef->edgeProbs.getOverallProb() > 0) {
509  // destination unreachable due to closed intermediate edges. pick among alternative targets
510  RandomDistributor<MSEdge*> edgeProbs2 = rerouteDef->edgeProbs;
511  edgeProbs2.remove(const_cast<MSEdge*>(newEdge));
512  while (edges.size() == 0 && edgeProbs2.getVals().size() > 0) {
513  newEdge = edgeProbs2.get();
514  edgeProbs2.remove(const_cast<MSEdge*>(newEdge));
515  if (newEdge == &mySpecialDest_terminateRoute) {
516  newEdge = veh.getEdge();
517  newArrivalPos = veh.getPositionOnLane(); // instant arrival
518  }
519  if (newEdge == &mySpecialDest_keepDestination && rerouteDef->permissions != SVCAll) {
520  newEdge = lastEdge;
521  break;
522  }
523  router.compute(
524  veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
525  }
526 
527  }
528  const double routeCost = router.recomputeCosts(edges, &veh, MSNet::getInstance()->getCurrentTimeStep());
529  hasReroutingDevice
531  : MSNet::getInstance()->getRouterTT(veh.getRNGIndex()); // reset closed edges
532  const bool useNewRoute = veh.replaceRouteEdges(edges, routeCost, 0, getID());
533 #ifdef DEBUG_REROUTER
534  if (DEBUGCOND) std::cout << " rerouting: newDest=" << newEdge->getID()
535  << " newEdges=" << toString(edges)
536  << " useNewRoute=" << useNewRoute << " newArrivalPos=" << newArrivalPos << " numClosed=" << rerouteDef->closed.size()
537  << " destUnreachable=" << destUnreachable << " containsClosed=" << veh.getRoute().containsAnyOf(rerouteDef->closed) << "\n";
538 #endif
539  if (useNewRoute && newArrivalPos != -1) {
540  // must be called here because replaceRouteEdges may also set the arrivalPos
541  veh.setArrivalPos(newArrivalPos);
542  }
543  }
544  return false; // XXX another interval could appear later but we would have to track whether the currenty interval was already used
545 }
546 
547 
548 void
550  myAmInUserMode = val;
551 }
552 
553 
554 void
556  myUserProbability = prob;
557 }
558 
559 
560 bool
562  return myAmInUserMode;
563 }
564 
565 
566 double
569 }
570 
571 
572 double
574  return myUserProbability;
575 }
576 
577 
578 double
579 MSTriggeredRerouter::getWeight(SUMOVehicle& veh, const std::string param, const double defaultWeight) const {
580  // get custom vehicle parameter
581  if (veh.getParameter().knowsParameter(param)) {
582  try {
583  return StringUtils::toDouble(veh.getParameter().getParameter(param, "-1"));
584  } catch (...) {
585  WRITE_WARNING("Invalid value '" + veh.getParameter().getParameter(param, "-1") + "' for vehicle parameter '" + param + "'");
586  }
587  } else {
588  // get custom vType parameter
589  if (veh.getVehicleType().getParameter().knowsParameter(param)) {
590  try {
591  return StringUtils::toDouble(veh.getVehicleType().getParameter().getParameter(param, "-1"));
592  } catch (...) {
593  WRITE_WARNING("Invalid value '" + veh.getVehicleType().getParameter().getParameter(param, "-1") + "' for vType parameter '" + param + "'");
594  }
595  }
596  }
597  //WRITE_MESSAGE("Vehicle '" +veh.getID() + "' does not supply vehicle parameter '" + param + "'. Using default of " + toString(defaultWeight) + "\n";
598  return defaultWeight;
599 }
600 
601 
604  SUMOVehicle& veh, bool& newDestination, ConstMSEdgeVector& newRoute) const {
605  // reroute destination from initial parking area to the near parking area
606  // if the next stop is a parking area, it is included in the current
607  // alternative set and if it can be observed to be full
608 
609  MSParkingArea* nearParkArea = nullptr;
610  std::vector<ParkingAreaVisible> parks = rerouteDef->parkProbs.getVals();
611 
612  // get vehicle params
613  MSParkingArea* destParkArea = veh.getNextParkingArea();
614  const MSRoute& route = veh.getRoute();
615 
616  if (destParkArea == nullptr) {
617  // not driving towards a parkingArea
618  return nullptr;
619  }
620 
621  bool destVisible = false;
622  for (auto paVis : parks) {
623  if (paVis.first == destParkArea
624  && (paVis.second
625  // if the vehicle is on the destParkArea edge it is always visible
626  || &(destParkArea->getLane().getEdge()) == veh.getEdge())) {
627  destVisible = true;
628  break;
629  }
630  }
631  if (!destVisible) {
632  // cannot determine destination occupancy
633  return nullptr;
634  }
635  if (destParkArea->getLastStepOccupancy() == destParkArea->getCapacity()) {
636  // if the current route ends at the parking area, the new route will
637  // also and at the new area
638  newDestination = (&destParkArea->getLane().getEdge() == route.getLastEdge()
639  && veh.getArrivalPos() >= destParkArea->getBeginLanePosition()
640  && veh.getArrivalPos() <= destParkArea->getEndLanePosition());
641 
642 #ifdef DEBUG_PARKING
643  if (DEBUGCOND) {
644  std::cout << SIMTIME << " veh=" << veh.getID()
645  << " rerouteParkingArea dest=" << destParkArea->getID()
646  << " onDestEdge=" << (&(destParkArea->getLane().getEdge()) == veh.getEdge())
647  << " newDest=" << newDestination
648  << "\n";
649  }
650 #endif
651 
652  typedef std::map<std::string, double> ParkingParamMap_t;
653  typedef std::map<MSParkingArea*, ParkingParamMap_t> MSParkingAreaMap_t;
654 
655  ParkingParamMap_t weights;
656  std::map<MSParkingArea*, ConstMSEdgeVector> newRoutes;
657 
658  // The probability of choosing this area inside the zone
659  weights["probability"] = getWeight(veh, "parking.probability.weight", 0.0);
660 
661  // The capacity of this area
662  weights["capacity"] = getWeight(veh, "parking.capacity.weight", 0.0);
663 
664  // The absolute number of free spaces
665  weights["absfreespace"] = getWeight(veh, "parking.absfreespace.weight", 0.0);
666 
667  // The relative number of free spaces
668  weights["relfreespace"] = getWeight(veh, "parking.relfreespace.weight", 0.0);
669 
670  // The distance to the new parking area
671  weights["distanceto"] = getWeight(veh, "parking.distanceto.weight", getWeight(veh, "parking.distance.weight", 1.0));
672 
673  // The time to reach this area
674  weights["timeto"] = getWeight(veh, "parking.timeto.weight", 0.0);
675 
676  // The distance from the new parking area
677  weights["distancefrom"] = getWeight(veh, "parking.distancefrom.weight", 0.0);
678 
679  // The time to reach the end from this area
680  weights["timefrom"] = getWeight(veh, "parking.timefrom.weight", 0.0);
681 
682  // a map stores maximum values to normalize parking values
683  ParkingParamMap_t maxValues;
684 
685  maxValues["probability"] = 0.0;
686  maxValues["capacity"] = 0.0;
687  maxValues["absfreespace"] = 0.0;
688  maxValues["relfreespace"] = 0.0;
689  maxValues["distanceto"] = 0.0;
690  maxValues["timeto"] = 0.0;
691  maxValues["distancefrom"] = 0.0;
692  maxValues["timefrom"] = 0.0;
693 
694  // a map stores elegible parking areas
695  MSParkingAreaMap_t parkAreas;
696 
698 
699  const std::vector<double>& probs = rerouteDef->parkProbs.getProbs();
700 
701  const double brakeGap = veh.getBrakeGap();
702 
703  for (int i = 0; i < (int)parks.size(); ++i) {
704  MSParkingArea* pa = parks[i].first;
705  const double prob = probs[i];
706  // alternative occupancy is randomized (but never full) if invisible
707  // current destination must be visible at this point
708  int paOccupancy = parks[i].second || pa == destParkArea ? pa->getOccupancy() : RandHelper::rand(pa->getCapacity());
709  if (paOccupancy < pa->getCapacity()) {
710 
711  // a map stores the parking values
712  ParkingParamMap_t parkValues;
713 
714  const RGBColor& c = route.getColor();
715  const MSEdge* parkEdge = &(pa->getLane().getEdge());
716 
717  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
718 
719  // Compute the route from the current edge to the parking area edge
720  ConstMSEdgeVector edgesToPark;
721  if (veh.getEdge() == parkEdge && pa->getLastFreePos(veh) < veh.getPositionOnLane()) {
722  router.computeLooped(veh.getEdge(), parkEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark, true);
723  } else {
724  router.compute(veh.getEdge(), parkEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark, true);
725  }
726 
727  if (edgesToPark.size() > 0) {
728  // Compute the route from the parking area edge to the end of the route
729  ConstMSEdgeVector edgesFromPark;
730 
731  const MSEdge* nextDestination = route.getLastEdge();
732  double nextPos = veh.getArrivalPos();
733  int nextDestinationIndex = route.size() - 1;
734  if (!newDestination) {
735  std::vector<std::pair<int, double> > stopIndices = veh.getStopIndices();
736  if (stopIndices.size() > 1) {
737  nextDestinationIndex = stopIndices[1].first;
738  nextDestination = route.getEdges()[nextDestinationIndex];
739  nextPos = stopIndices[1].second;
740 
741  }
742  if (parkEdge == nextDestination && nextPos < pa->getLastFreePos(veh)) {
743  router.computeLooped(parkEdge, nextDestination, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark, true);
744  } else {
745  router.compute(parkEdge, nextDestination, &veh, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark, true);
746  }
747  }
748 
749  if (edgesFromPark.size() > 0 || newDestination) {
750 
751  parkValues["probability"] = prob;
752 
753  if (parkValues["probability"] > maxValues["probability"]) {
754  maxValues["probability"] = parkValues["probability"];
755  }
756 
757  parkValues["capacity"] = (double)(pa->getCapacity());
758  parkValues["absfreespace"] = (double)(pa->getCapacity() - paOccupancy);
759  parkValues["relfreespace"] = parkValues["absfreespace"] / parkValues["capacity"];
760 
761  if (parkValues["capacity"] > maxValues["capacity"]) {
762  maxValues["capacity"] = parkValues["capacity"];
763  }
764 
765  if (parkValues["absfreespace"] > maxValues["absfreespace"]) {
766  maxValues["absfreespace"] = parkValues["absfreespace"];
767  }
768 
769  if (parkValues["relfreespace"] > maxValues["relfreespace"]) {
770  maxValues["relfreespace"] = parkValues["relfreespace"];
771  }
772 
773  MSRoute routeToPark(route.getID() + "!topark#1", edgesToPark, false, &c == &RGBColor::DEFAULT_COLOR ? nullptr : new RGBColor(c), route.getStops());
774 
775  // The distance from the current edge to the new parking area
776  parkValues["distanceto"] = routeToPark.getDistanceBetween(veh.getPositionOnLane(), pa->getBeginLanePosition(),
777  routeToPark.begin(), routeToPark.end() - 1, includeInternalLengths);
778 
779  //std::cout << SIMTIME << " veh=" << veh.getID() << " candidate=" << pa->getID()
780  // << " distanceTo=" << parkValues["distanceto"]
781  // << " brakeGap=" << brakeGap
782  // << " routeToPark=" << toString(edgesToPark)
783  // << " fromPos=" << veh.getPositionOnLane()
784  // << " tPos=" << pa->getBeginLanePosition()
785  // << "\n";
786  if (parkValues["distanceto"] < brakeGap) {
787  //std::cout << " removed: pa too close\n";
788  // to close to stop for this parkingArea
789  continue;
790  }
791 
792  // The time to reach the new parking area
793  parkValues["timeto"] = router.recomputeCosts(edgesToPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
794 
795  if (parkValues["distanceto"] > maxValues["distanceto"]) {
796  maxValues["distanceto"] = parkValues["distanceto"];
797  }
798 
799  if (parkValues["timeto"] > maxValues["timeto"]) {
800  maxValues["timeto"] = parkValues["timeto"];
801  }
802 
803  ConstMSEdgeVector newEdges = edgesToPark;
804 
805  if (newDestination) {
806  parkValues["distancefrom"] = 0;
807  parkValues["timefrom"] = 0;
808  } else {
809  MSRoute routeFromPark(route.getID() + "!frompark#1", edgesFromPark, false,
810  &c == &RGBColor::DEFAULT_COLOR ? nullptr : new RGBColor(c), route.getStops());
811  // The distance from the new parking area to the end of the route
812  parkValues["distancefrom"] = routeFromPark.getDistanceBetween(pa->getBeginLanePosition(), routeFromPark.getLastEdge()->getLength(),
813  routeFromPark.begin(), routeFromPark.end() - 1, includeInternalLengths);
814  // The time to reach this area
815  parkValues["timefrom"] = router.recomputeCosts(edgesFromPark, &veh, MSNet::getInstance()->getCurrentTimeStep());
816  newEdges.insert(newEdges.end(), edgesFromPark.begin() + 1, edgesFromPark.end());
817  newEdges.insert(newEdges.end(), route.begin() + nextDestinationIndex + 1, route.end());
818  }
819 
820  if (parkValues["distancefrom"] > maxValues["distancefrom"]) {
821  maxValues["distancefrom"] = parkValues["distancefrom"];
822  }
823 
824  if (parkValues["timefrom"] > maxValues["timefrom"]) {
825  maxValues["timefrom"] = parkValues["timefrom"];
826  }
827 
828  parkAreas[pa] = parkValues;
829  newRoutes[pa] = newEdges;
830 
831 #ifdef DEBUG_PARKING
832  if (DEBUGCOND) {
833  std::cout << " altPA=" << pa->getID()
834  << " vals=" << joinToString(parkValues, " ", ":")
835  << "\n";
836  }
837 #endif
838  }
839  }
840  }
841  }
842  MSNet::getInstance()->getRouterTT(veh.getRNGIndex()); // reset closed edges
843 
844 #ifdef DEBUG_PARKING
845  if (DEBUGCOND) {
846  std::cout << " maxValues=" << joinToString(maxValues, " ", ":") << "\n";
847  }
848 #endif
849 
850  // minimum cost to get the parking area
851  double minParkingCost = 0.0;
852 
853  for (MSParkingAreaMap_t::iterator it = parkAreas.begin(); it != parkAreas.end(); ++it) {
854  // get the parking values
855  ParkingParamMap_t parkValues = it->second;
856 
857  // normalizing parking values with maximum values (we want to maximize some parameters then we reverse the value)
858  parkValues["probability"] = maxValues["probability"] > 0.0 ? 1.0 - parkValues["probability"] / maxValues["probability"] : 0.0;
859  parkValues["capacity"] = maxValues["capacity"] > 0.0 ? 1.0 - parkValues["capacity"] / maxValues["capacity"] : 0.0;
860  parkValues["absfreespace"] = maxValues["absfreespace"] > 0.0 ? 1.0 - parkValues["absfreespace"] / maxValues["absfreespace"] : 0.0;
861  parkValues["relfreespace"] = maxValues["relfreespace"] > 0.0 ? 1.0 - parkValues["relfreespace"] / maxValues["relfreespace"] : 0.0;
862 
863  parkValues["distanceto"] = maxValues["distanceto"] > 0.0 ? parkValues["distanceto"] / maxValues["distanceto"] : 0.0;
864  parkValues["timeto"] = maxValues["timeto"] > 0.0 ? parkValues["timeto"] / maxValues["timeto"] : 0.0;
865 
866  parkValues["distancefrom"] = maxValues["distancefrom"] > 0.0 ? parkValues["distancefrom"] / maxValues["distancefrom"] : 0.0;
867  parkValues["timefrom"] = maxValues["timefrom"] > 0.0 ? parkValues["timefrom"] / maxValues["timefrom"] : 0.0;
868 
869  // get the parking area cost
870  double parkingCost = 0.0;
871 
872  // sum every index with its weight
873  for (ParkingParamMap_t::iterator pc = parkValues.begin(); pc != parkValues.end(); ++pc) {
874  parkingCost += weights[pc->first] * pc->second;
875  }
876 
877  // get the parking area with minimum cost
878  if (nearParkArea == nullptr || parkingCost < minParkingCost) {
879  minParkingCost = parkingCost;
880  nearParkArea = it->first;
881  newRoute = newRoutes[nearParkArea];
882  }
883 
884 #ifdef DEBUG_PARKING
885  if (DEBUGCOND) {
886  std::cout << " altPA=" << it->first->getID() << " score=" << parkingCost << "\n";
887  }
888 #endif
889  }
890  }
891 
892 #ifdef DEBUG_PARKING
893  if (DEBUGCOND) {
894  std::cout << " parkingResult=" << Named::getIDSecure(nearParkArea) << "\n";
895  }
896 #endif
897 
898  return nearParkArea;
899 }
900 
901 
902 bool
904  if (myVehicleTypes.empty() || myVehicleTypes.count(veh.getVehicleType().getOriginalID()) > 0) {
905  return true;
906  } else {
908  for (auto vTypeDist : vTypeDists) {
909  if (myVehicleTypes.count(vTypeDist) > 0) {
910  return true;
911  }
912  }
913  return false;
914  }
915 }
916 
917 
918 /****************************************************************************/
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
#define DEBUGCOND
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define SUMOTime_MAX
Definition: SUMOTime.h:32
#define SIMTIME
Definition: SUMOTime.h:60
long long int SUMOTime
Definition: SUMOTime.h:31
const SVCPermissions SVCAll
all VClasses are allowed
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
@ SVC_AUTHORITY
authorities vehicles
@ GIVEN
The arrival position is given.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_CLOSING_REROUTE
reroute of type closing
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_PARKING_ZONE_REROUTE
entry for an alternative parking zone
@ SUMO_TAG_ROUTE_PROB_REROUTE
probability of route of a reroute
@ SUMO_TAG_DEST_PROB_REROUTE
probability of destiny of a reroute
@ SUMO_TAG_CLOSING_LANE_REROUTE
lane of a reroute of type closing
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_PROB
@ SUMO_ATTR_ID
@ SUMO_ATTR_VISIBLE
T MAX2(T a, T b)
Definition: StdDefs.h:79
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:250
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
A scoped lock which only triggers on condition.
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:302
A single mesoscopic segment (cell)
Definition: MESegment.h:47
void addDetector(MSMoveReminder *data)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:244
A device that performs vehicle rerouting based on current edge speeds.
A road/street connecting two junctions.
Definition: MSEdge.h:77
double getLength() const
return the length of the edge
Definition: MSEdge.h:630
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:814
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUseMesoSim
Definition: MSGlobals.h:88
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:94
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:115
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:66
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1908
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:673
Something on a lane to be noticed about vehicle movement.
Notification
Definition of a vehicle state.
@ NOTIFICATION_LANE_CHANGE
The vehicle changes lanes (micro only)
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:1199
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:371
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:1098
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:464
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:695
A lane area vehicles can halt at.
Definition: MSParkingArea.h:57
int getCapacity() const
Returns the area capacity.
double getLastFreePos(const SUMOVehicle &forVehicle) const
Returns the last free position on this stop.
int getLastStepOccupancy() const
Returns the area occupancy at the end of the last simulation step.
int getOccupancy() const
Returns the area occupancy.
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:81
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:397
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:75
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:113
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:87
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true, int routePosition=0) const
Compute the distance between 2 given edges on this route, including the length of internal lanes....
Definition: MSRoute.cpp:299
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition: MSRoute.cpp:247
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:388
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:120
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
double getBeginLanePosition() const
Returns the begin position of this stop.
double getEndLanePosition() const
Returns the end position of this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
An abstract device that changes the state of the micro simulation.
Definition: MSTrigger.h:38
SUMOTime setPermissions(const SUMOTime currentTime)
Sets the edge permission if there are any defined in the closingEdge.
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Tries to reroute the vehicle.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Triggers rerouting (once) for vehicles that are already on the edge when the rerouter activates.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Removes the reminder.
RandomDistributor< ParkingAreaVisible > myCurrentParkProb
new destinations with probabilities
double getUserProbability() const
Returns the rerouting probability given by the user.
std::vector< MSLane * > myCurrentClosedLanes
List of closed lanes.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void setUserUsageProbability(double prob)
Sets the probability with which a vehicle is rerouted given by the user.
SVCPermissions myCurrentPermissions
List of permissions for closed edges.
MSParkingArea * rerouteParkingArea(const MSTriggeredRerouter::RerouteInterval *rerouteDef, SUMOVehicle &veh, bool &newDestination, ConstMSEdgeVector &newRoute) const
static MSEdge mySpecialDest_terminateRoute
virtual void myEndElement(int element)
Called when a closing tag occurs.
const RerouteInterval * getCurrentReroute(SUMOTime time, SUMOVehicle &veh) const
Returns the rerouting definition valid for the given time and vehicle, 0 if none.
double myProbability
The probability and the user-given probability.
virtual ~MSTriggeredRerouter()
Destructor.
bool inUserMode() const
Returns whether the user is setting the rerouting probability.
std::set< std::string > myVehicleTypes
The vehicle types to look for (empty means all)
MSEdgeVector myCurrentClosed
List of closed edges.
RandomDistributor< MSEdge * > myCurrentEdgeProb
new destinations with probabilities
static std::map< std::string, MSTriggeredRerouter * > myInstances
bool vehicleApplies(const SUMOVehicle &veh) const
Checks whether the detector measures vehicles of the given type.
double getWeight(SUMOVehicle &veh, const std::string param, const double defaultWeight) const
SUMOTime myCurrentIntervalBegin
The first and the last time steps of the interval.
MSTriggeredRerouter(const std::string &id, const MSEdgeVector &edges, double prob, const std::string &file, bool off, SUMOTime timeThreshold, const std::string &vTypes)
Constructor.
bool myAmInUserMode
Information whether the current rerouting probability is the user-given.
RandomDistributor< const MSRoute * > myCurrentRouteProb
new routes with probabilities
static MSEdge mySpecialDest_keepDestination
special destination values
double getProbability() const
Returns the rerouting probability.
std::vector< RerouteInterval > myIntervals
List of rerouting definition intervals.
void setUserMode(bool val)
Sets whether the process is currently steered by the user.
const std::set< std::string > getVTypeDistributionMembership(const std::string &id) const
Return the distribution IDs the vehicle type is a member of.
const std::string & getOriginalID() const
Returns the id of the original vehicle type if this is a vehicle specific type, the id otherwise.
const SUMOVTypeParameter & getParameter() const
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:66
const std::string & getID() const
Returns the id.
Definition: Named.h:73
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:194
static double rand(std::mt19937 *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.h:51
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
const std::vector< double > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
const std::vector< T > & getVals() const
Returns the members of the distribution.
T get(std::mt19937 *which=0) const
Draw a sample of the distribution.
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
bool remove(T val)
Removes a value with an assigned probability from the distribution.
void clear()
Clears the distribution.
bool computeLooped(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)
Builds the route between the given edges using the minimum effort at the given time if from == to,...
double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
Encapsulated SAX-Attributes.
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.
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.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SAX-handler base for SUMO-files.
Representation of a vehicle, person, or container.
virtual SUMOTime getWaitingTime() const =0
virtual bool isVehicle() const
Whether it is a vehicle.
virtual std::mt19937 * getRNG() const =0
Returns the associated RNG for this object.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition: SUMOVehicle.h:58
virtual std::vector< std::pair< int, double > > getStopIndices() const =0
return list of route indices and stop positions for the remaining stops
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual MSParkingArea * getNextParkingArea()=0
virtual bool replaceParkingArea(MSParkingArea *parkingArea, std::string &errorMsg)=0
Replaces a stop.
virtual MSVehicleDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.
virtual SUMOTime getAccumulatedWaitingTime() const =0
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.
virtual int getRNGIndex() const =0
virtual const std::vector< MSTransportable * > & getPersons() const =0
retrieve riding persons
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual double getArrivalPos() const =0
Returns this vehicle's desired arrivalPos for its current route (may change on reroute)
virtual void replaceParameter(const SUMOVehicleParameter *newParameter)=0
Replaces the vehicle's parameter.
virtual bool replaceRouteEdges(ConstMSEdgeVector &edges, double cost, double savings, const std::string &info, bool onInit=false, bool check=false, bool removeStops=true)=0
Replaces the current route by the given edges.
virtual double getBrakeGap() const =0
get distance for coming to a stop (used for rerouting checks)
virtual void setArrivalPos(double arrivalPos)=0
Sets this vehicle's desired arrivalPos for its current route.
Structure representing possible vehicle parameter.
double arrivalPos
(optional) The position the vehicle shall arrive on
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
std::vector< std::string > getVector()
return vector of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
A wrapper for a Command function.
SUMOTime begin
The begin time these definitions are valid.
SUMOTime end
The end time these definitions are valid.
RandomDistributor< MSEdge * > edgeProbs
The distributions of new destinations to use.
RandomDistributor< const MSRoute * > routeProbs
The distributions of new routes to use.
MSEdgeVector closedLanesAffected
The list of edges that are affect by closed lanes.
RandomDistributor< ParkingAreaVisible > parkProbs
The distributions of new parking areas to use as destinations.
SVCPermissions permissions
The permissions to use.
MSEdgeVector closed
The list of closed edges.
std::vector< MSLane * > closedLanes
The list of closed lanes.