Eclipse SUMO - Simulation of Urban MObility
MSRoutingEngine.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2007-2024 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 /****************************************************************************/
22 // A device that performs vehicle rerouting based on current edge speeds
23 /****************************************************************************/
24 #include <config.h>
25 
26 #include "MSRoutingEngine.h"
27 #include <microsim/MSNet.h>
28 #include <microsim/MSLane.h>
29 #include <microsim/MSEdge.h>
30 #include <microsim/MSEdgeControl.h>
32 #include <microsim/MSGlobals.h>
41 #include <utils/router/CHRouter.h>
43 
44 //#define DEBUG_SEPARATE_TURNS
45 #define DEBUG_COND(obj) (obj->isSelected())
46 
47 // ===========================================================================
48 // static member variables
49 // ===========================================================================
50 std::vector<double> MSRoutingEngine::myEdgeSpeeds;
51 std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
52 std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
53 std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
54 std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
64 std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
66 double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
68 std::map<std::thread::id, SumoRNG*> MSRoutingEngine::myThreadRNGs;
69 
71 #ifdef HAVE_FOX
72 FXMutex MSRoutingEngine::myRouteCacheMutex;
73 #endif
74 
75 
76 // ===========================================================================
77 // method definitions
78 // ===========================================================================
79 void
81  if (myAdaptationInterval == -1) {
83  myEdgeSpeeds.clear();
84  myEdgeTravelTimes.clear();
85  myAdaptationSteps = -1;
86  myLastAdaptation = -1;
88  myWithTaz = oc.getBool("device.rerouting.with-taz");
89  myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
90  myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
91  const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
92  if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
95  } else if (period > 0) {
96  WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
97  }
98  OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
99  }
100 }
101 
102 
103 void
105  if (myBikeSpeeds && svc == SVC_BICYCLE) {
107  } else {
109  }
110 }
111 
112 
113 void
114 MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
115  if (edgeSpeeds.empty()) {
116  const OptionsCont& oc = OptionsCont::getOptions();
117  if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
118  myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
119  }
120  const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
121  const double currentSecond = SIMTIME;
122  double maxEdgePriority = -std::numeric_limits<double>::max();
123  for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
124  while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
125  edgeSpeeds.push_back(0);
126  if (myAdaptationSteps > 0) {
127  pastEdgeSpeeds.push_back(std::vector<double>());
128  }
129  if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
130  myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
131  }
132  }
133  if (useLoaded) {
134  edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
135  } else {
136  edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
137  }
138  if (myAdaptationSteps > 0) {
139  pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
140  }
141  maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
142  myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
143  }
144  myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
146  myPriorityFactor = oc.getFloat("weights.priority-factor");
147  if (myPriorityFactor < 0) {
148  throw ProcessError(TL("weights.priority-factor cannot be negative."));
149  }
150  if (myPriorityFactor > 0) {
151  if (myEdgePriorityRange == 0) {
152  WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
153  myPriorityFactor = 0;
154  }
155  }
156  }
157 }
158 
159 
160 double
161 MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
162  const int id = e->getNumericalID();
163  if (id < (int)myEdgeSpeeds.size()) {
164  return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
165  }
166  return e->getMinimumTravelTime(v);
167 }
168 
169 
170 double
171 MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
172  const int id = e->getNumericalID();
173  if (id < (int)myEdgeBikeSpeeds.size()) {
174  return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
175  }
176  return e->getMinimumTravelTime(v);
177 }
178 
179 SumoRNG*
181  if (myThreadRNGs.size() > 0) {
182  auto it = myThreadRNGs.find(std::this_thread::get_id());
183  if (it != myThreadRNGs.end()) {
184  return it->second;
185  }
186  std::cout << " something bad happended\n";
187  }
188  return nullptr;
189 }
190 
191 
192 double
193 MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
194  double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
195  ? getEffort(e, v, t)
196  : getEffortBike(e, v, t));
197  if (gWeightsRandomFactor != 1.) {
199  }
200  if (myPriorityFactor != 0) {
201  // lower priority should result in higher effort (and the edge with
202  // minimum priority receives a factor of 1 + myPriorityFactor
203  const double relativeInversePrio = 1 - ((e->getPriority() - myMinEdgePriority) / myEdgePriorityRange);
204  effort *= 1 + relativeInversePrio * myPriorityFactor;
205  }
206  return effort;
207 }
208 
209 
210 double
212  return edge->getLength() / myEffortFunc(edge, veh, 0);
213 }
214 
215 
216 SUMOTime
219  if (myBikeSpeeds) {
221  }
222  if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
223  return myAdaptationInterval;
224  }
225  myCachedRoutes.clear();
227  const double newWeightFactor = (double)(1. - myAdaptationWeight);
228  for (const MSEdge* const e : edges) {
229  if (e->isDelayed()) {
230  const int id = e->getNumericalID();
231  double currSpeed = e->getMeanSpeed();
232  if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
233  currSpeed = patchSpeedForTurns(e, currSpeed);
234  }
235 #ifdef DEBUG_SEPARATE_TURNS
236  if (DEBUG_COND(e->getLanes()[0])) {
237  std::cout << SIMTIME << " edge=" << e->getID()
238  << " meanSpeed=" << e->getMeanSpeed()
239  << " currSpeed=" << currSpeed
240  << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
241  << " oldAvg=" << myEdgeSpeeds[id]
242  << "\n";
243  }
244 #endif
245  if (myAdaptationSteps > 0) {
246  // moving average
248  myPastEdgeSpeeds[id][myAdaptationStepsIndex] = currSpeed;
249  if (myBikeSpeeds) {
250  const double currBikeSpeed = e->getMeanSpeedBike();
252  myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
253  }
254  } else {
255  // exponential moving average
256  if (currSpeed != myEdgeSpeeds[id]) {
257  myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
258  }
259  if (myBikeSpeeds) {
260  const double currBikeSpeed = e->getMeanSpeedBike();
261  if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
262  myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
263  }
264  }
265  }
266  }
267  }
268  if (myAdaptationSteps > 0) {
270  }
271  myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
272  if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
273  OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
275  dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
276  dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
278  for (const MSEdge* e : edges) {
279  dev.openTag(SUMO_TAG_EDGE);
280  dev.writeAttr(SUMO_ATTR_ID, e->getID());
281  dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
282  if (myBikeSpeeds) {
283  // @note edge-priority is not included here
284  dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
285  }
286  dev.closeTag();
287  }
288  dev.closeTag();
289  }
290  return myAdaptationInterval;
291 }
292 
293 
294 double
295 MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
296  const double length = edge->getLength();
297  double maxSpeed = 0;
298  for (const auto& pair : edge->getViaSuccessors()) {
299  if (pair.second == nullptr) {
300  continue;
301  }
302  TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
303  if (tc.second > 0) {
304  const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
305  maxSpeed = MAX2(avgSpeed, maxSpeed);
306  }
307  }
308  if (maxSpeed > 0) {
309  // perform correction
310  const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
311  for (const auto& pair : edge->getViaSuccessors()) {
312  if (pair.second == nullptr) {
313  continue;
314  }
315  const int iid = pair.second->getNumericalID();
316  TimeAndCount& tc = myEdgeTravelTimes[iid];
317  if (tc.second > 0) {
318  const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
319  if (avgSpeed < correctedSpeed) {
320  double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
321  internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
322  const double origInternalSpeed = myEdgeSpeeds[iid];
323  const double newInternalSpeed = pair.second->getLength() / internalTT;
324  const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
325 
326  myEdgeSpeeds[iid] = newInternalSpeed;
327  // to ensure myEdgeSpeed reverts to the speed limit
328  // when there are no updates, we also have to patch
329  // myPastEdgeSpeeds with a virtual value that is consistent
330  // with the updated speed
331  // note: internal edges were handled before the normal ones
332  const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
333  myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
334 
335 #ifdef DEBUG_SEPARATE_TURNS
336  if (DEBUG_COND(pair.second->getLanes()[0])) {
337  std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
338  << " origSpeed=" << currSpeed
339  << " maxSpeed=" << maxSpeed
340  << " correctedSpeed=" << correctedSpeed
341  << " avgSpeed=" << avgSpeed
342  << " internalTT=" << internalTT
343  << " internalSpeed=" << origInternalSpeed
344  << " newInternalSpeed=" << newInternalSpeed
345  << " virtualSpeed=" << virtualSpeed
346  << "\n";
347  }
348 #endif
349  }
350  if (myAdaptationStepsIndex == 0) {
351  tc.first = 0;
352  tc.second = 0;
353  }
354  }
355  }
356  return correctedSpeed;
357  }
358  return currSpeed;
359 }
360 
361 
363 MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
364  auto routeIt = myCachedRoutes.find(key);
365  if (routeIt != myCachedRoutes.end()) {
366  return routeIt->second;
367  }
368  return nullptr;
369 }
370 
371 
372 void
375  const std::string routingAlgorithm = oc.getString("routing-algorithm");
376  const bool hasPermissions = MSNet::getInstance()->hasPermissions();
377  myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
379 
380  SUMOAbstractRouter<MSEdge, SUMOVehicle>* router = nullptr;
381  if (routingAlgorithm == "dijkstra") {
382  router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
383  } else if (routingAlgorithm == "astar") {
384  typedef AStarRouter<MSEdge, SUMOVehicle> AStar;
385  std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
386  if (oc.isSet("astar.all-distances")) {
387  lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
388  } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
389  const double speedFactor = vehicle->getChosenSpeedFactor();
390  // we need an exemplary vehicle with speedFactor 1
391  vehicle->setChosenSpeedFactor(1);
394  string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
395  lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
396  nullptr, vehicle, "", oc.getInt("device.rerouting.threads"));
397  vehicle->setChosenSpeedFactor(speedFactor);
398  }
399  router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
400  } else if (routingAlgorithm == "CH" && !hasPermissions) {
401  const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
402  router = new CHRouter<MSEdge, SUMOVehicle>(
403  MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
404  } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
405  // use CHWrapper instead of CH if the net has permissions
406  const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
409  string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
410  } else {
411  throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
412  }
413 
414  RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
415  if (MSNet::getInstance()->hasBidiEdges()) {
416  railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false, oc.getFloat("railway.max-train-length"));
417  }
418  myRouterProvider = new MSRouterProvider(router, nullptr, nullptr, railRouter);
419 #ifndef THREAD_POOL
420 #ifdef HAVE_FOX
421  MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
422  if (threadPool.size() > 0) {
423  const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
424  if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
425  for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
426  static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
427  }
428  }
429 #ifndef WIN32
430  /*
431  int i = 0;
432  for (MFXWorkerThread* t : threads) {
433  myThreadRNGs[(std::thread::id)t->id()] = new SumoRNG("routing_" + toString(i++));
434  }
435  */
436 #endif
437  }
438 #endif
439 #endif
440 }
441 
442 
443 void
444 MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
445  const bool onInit, const bool silent, const MSEdgeVector& prohibited) {
446  if (myRouterProvider == nullptr) {
447  initRouter(&vehicle);
448  }
449  auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
450 #ifndef THREAD_POOL
451 #ifdef HAVE_FOX
452  MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
453  if (threadPool.size() > 0) {
454  threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
455  return;
456  }
457 #endif
458 #endif
459  if (!prohibited.empty()) {
460  router.prohibit(prohibited);
461  }
462  try {
463  vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
464  } catch (ProcessError&) {
465  if (!silent) {
466  if (!prohibited.empty()) {
467  router.prohibit(MSEdgeVector());
468  }
469  throw;
470  }
471  }
472  if (!prohibited.empty()) {
473  router.prohibit(MSEdgeVector());
474  }
475 }
476 
477 
478 void
479 MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
480  myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
481 }
482 
483 void
484 MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
486  tc.first += travelTime;
487  tc.second += 1;
488 }
489 
490 
492 MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector& prohibited) {
493  if (myRouterProvider == nullptr) {
495  initEdgeWeights(svc);
496  initRouter();
497  }
498 #ifndef THREAD_POOL
499 #ifdef HAVE_FOX
500  MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
501  if (threadPool.size() > 0) {
502  auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
503  router.prohibit(prohibited);
504  return router;
505  }
506 #else
507  UNUSED_PARAMETER(rngIndex);
508 #endif
509 #endif
510  myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
511  return myRouterProvider->getVehicleRouter(svc);
512 }
513 
514 
516 MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const MSEdgeVector& prohibited) {
517  if (myRouterProvider == nullptr) {
520  initRouter();
521  }
522 #ifndef THREAD_POOL
523 #ifdef HAVE_FOX
524  MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
525  if (threadPool.size() > 0) {
526  auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
527  router.prohibit(prohibited);
528  return router;
529  }
530 #else
531  UNUSED_PARAMETER(rngIndex);
532 #endif
533 #endif
534  myRouterProvider->getIntermodalRouter().prohibit(prohibited);
536 }
537 
538 
539 void
541  myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
542  myPastEdgeSpeeds.clear();
543  myEdgeSpeeds.clear();
544  myEdgeTravelTimes.clear();
545  myPastEdgeBikeSpeeds.clear();
546  myEdgeBikeSpeeds.clear();
547  // @todo recheck. calling release crashes in parallel routing
548  //for (auto& item : myCachedRoutes) {
549  // item.second->release();
550  //}
551  myCachedRoutes.clear();
553 #ifdef HAVE_FOX
554  if (MSGlobals::gNumThreads > 1) {
555  // router deletion is done in thread destructor
556  myRouterProvider = nullptr;
557  return;
558  }
559 #endif
560  delete myRouterProvider;
561  myRouterProvider = nullptr;
562 }
563 
564 
565 #ifdef HAVE_FOX
566 void
567 MSRoutingEngine::waitForAll() {
568 #ifndef THREAD_POOL
569  MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
570  if (threadPool.size() > 0) {
571  threadPool.waitAll();
572  }
573 #endif
574 }
575 
576 
577 // ---------------------------------------------------------------------------
578 // MSRoutingEngine::RoutingTask-methods
579 // ---------------------------------------------------------------------------
580 void
581 MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
582  SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
583  if (!myProhibited.empty()) {
584  router.prohibit(myProhibited);
585  }
586  try {
587  myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
588  } catch (ProcessError&) {
589  if (!mySilent) {
590  if (!myProhibited.empty()) {
591  router.prohibit(MSEdgeVector());
592  }
593  throw;
594  }
595  }
596  if (!myProhibited.empty()) {
597  router.prohibit(MSEdgeVector());
598  }
599  const MSEdge* source = *myVehicle.getRoute().begin();
600  const MSEdge* dest = myVehicle.getRoute().getLastEdge();
601  if (source->isTazConnector() && dest->isTazConnector()) {
602  const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
603  FXMutexLock lock(myRouteCacheMutex);
605  MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
606  }
607  }
608 }
609 #endif
610 
611 
612 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
RouterProvider< MSEdge, MSLane, MSJunction, SUMOVehicle > MSRouterProvider
Definition: MSRouterDefs.h:39
#define DEBUG_COND(obj)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition: Route.h:31
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SUMOTime_MAX
Definition: SUMOTime.h:34
#define SIMTIME
Definition: SUMOTime.h:62
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
double gWeightsRandomFactor
Definition: StdDefs.cpp:31
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
Computes the shortest path through a network using the A* algorithm.
Definition: AStarRouter.h:76
Computes the shortest path through a contracted network.
Definition: CHRouter.h:59
Computes the shortest path through a contracted network.
Base (microsim) event class.
Definition: Command.h:50
Computes the shortest path through a network using the Dijkstra algorithm.
A pool of worker threads which distributes the tasks and collects the results.
void waitAll(const bool deleteFinished=true)
waits for all tasks to be finished
void add(Task *const t, int index=-1)
Gives a number to the given task and assigns it to the worker with the given index....
const std::vector< MFXWorkerThread * > & getWorkers()
int size() const
Returns the number of threads in the pool.
A thread repeatingly calculating incoming tasks.
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
Definition: MSEdge.h:77
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:1022
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:325
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition: MSEdge.cpp:1224
double getLength() const
return the length of the edge
Definition: MSEdge.h:662
bool isTazConnector() const
Definition: MSEdge.h:288
double getMinimumTravelTime(const SUMOVehicle *const veh) const
returns the minimum travel time for the given vehicle
Definition: MSEdge.h:473
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:303
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static double gWeightsSeparateTurns
Whether turning specific weights are estimated (and how much)
Definition: MSGlobals.h:172
static int gNumThreads
how many threads to use
Definition: MSGlobals.h:146
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:182
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
Definition: MSNet.h:481
static double getTravelTime(const MSEdge *const e, const SUMOVehicle *const v, double t)
Returns the travel time to pass an edge.
Definition: MSNet.cpp:162
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:421
bool hasPermissions() const
Returns whether the network has specific vehicle class permissions.
Definition: MSNet.h:207
static SUMOTime myAdaptationInterval
At which time interval the edge weights get updated.
static double myAdaptationWeight
Information which weight prior edge efforts have.
static int myAdaptationStepsIndex
The current index in the pastEdgeSpeed ring-buffer.
static double myMinEdgePriority
Minimum priority for all edges.
static std::vector< TimeAndCount > myEdgeTravelTimes
Sum of travel times experienced by equipped vehicles for each edge.
static double getEffortBike(const MSEdge *const e, const SUMOVehicle *const v, double t)
static void setEdgeTravelTime(const MSEdge *const edge, const double travelTime)
adapt the known travel time for an edge
static void reroute(SUMOVehicle &vehicle, const SUMOTime currentTime, const std::string &info, const bool onInit=false, const bool silent=false, const MSEdgeVector &prohibited=MSEdgeVector())
initiate the rerouting, create router / thread pool on first use
static double myEdgePriorityRange
the difference between maximum and minimum priority for all edges
static double myPriorityFactor
Coefficient for factoring edge priority into routing weight.
static std::map< std::pair< const MSEdge *, const MSEdge * >, ConstMSRoutePtr > myCachedRoutes
The container of pre-calculated routes.
static SUMOTime adaptEdgeEfforts(SUMOTime currentTime)
Adapt edge efforts by the current edge states.
static bool myBikeSpeeds
whether separate speeds for bicycles shall be tracked
static void _initEdgeWeights(std::vector< double > &edgeSpeeds, std::vector< std::vector< double > > &pastEdgeSpeeds)
initialized edge speed storage into the given containers
static SumoRNG * getThreadRNG()
returns RNG associated with the current thread
static bool myWithTaz
whether taz shall be used at initial rerouting
static std::vector< std::vector< double > > myPastEdgeBikeSpeeds
static std::vector< double > myEdgeSpeeds
The container of edge speeds.
std::pair< SUMOTime, int > TimeAndCount
static std::map< std::thread::id, SumoRNG * > myThreadRNGs
static void addEdgeTravelTime(const MSEdge &edge, const SUMOTime travelTime)
record actual travel time for an edge
static void initWeightUpdate()
intialize period edge weight update
static void initEdgeWeights(SUMOVehicleClass svc)
initialize the edge weights if not done before
static MSVehicleRouter & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector &prohibited=MSEdgeVector())
return the vehicle router instance
static SUMOTime myLastAdaptation
Information when the last edge weight adaptation occurred.
static void cleanup()
deletes the router instance
static void initRouter(SUMOVehicle *vehicle=nullptr)
static SUMOAbstractRouter< MSEdge, SUMOVehicle >::Operation myEffortFunc
static ConstMSRoutePtr getCachedRoute(const std::pair< const MSEdge *, const MSEdge * > &key)
return the cached route or nullptr on miss
static int myAdaptationSteps
The number of steps for averaging edge speeds (ring-buffer)
static MSRouterProvider * myRouterProvider
The router to use.
static Command * myEdgeWeightSettingCommand
The weights adaptation/overwriting command.
static std::vector< std::vector< double > > myPastEdgeSpeeds
The container of past edge speeds (when using a simple moving average)
static double getEffort(const MSEdge *const e, const SUMOVehicle *const v, double t)
Returns the effort to pass an edge.
static double getAssumedSpeed(const MSEdge *edge, const SUMOVehicle *veh)
return current travel speed assumption
static MSTransportableRouter & getIntermodalRouterTT(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector())
return the person router instance
static double patchSpeedForTurns(const MSEdge *edge, double currSpeed)
static double getEffortExtra(const MSEdge *const e, const SUMOVehicle *const v, double t)
static std::vector< double > myEdgeBikeSpeeds
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
RouterProvider * clone()
SUMOAbstractRouter< E, V > & getVehicleRouter(SUMOVehicleClass svc) const
IntermodalRouter< E, L, N, V > & getIntermodalRouter() const
virtual void prohibit(const std::vector< E * > &toProhibit)
virtual double getChosenSpeedFactor() const =0
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
virtual bool reroute(SUMOTime t, const std::string &info, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false, const bool silent=false, const MSEdge *sink=nullptr)=0
Performs a rerouting using the given router.
virtual void setChosenSpeedFactor(const double factor)=0
A wrapper for a Command function.
Definition: StaticCommand.h:38
@ key
the parser read a key of a value in an object