Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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-2025 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>
32#include <microsim/MSGlobals.h>
44
45//#define DEBUG_SEPARATE_TURNS
46#define DEBUG_COND(obj) (obj->isSelected())
47
48// ===========================================================================
49// static member variables
50// ===========================================================================
51std::vector<double> MSRoutingEngine::myEdgeSpeeds;
52std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
53std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
54std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
55std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
65std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
67double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
69std::map<std::thread::id, SumoRNG*> MSRoutingEngine::myThreadRNGs;
71
73#ifdef HAVE_FOX
74FXMutex MSRoutingEngine::myRouteCacheMutex;
75#endif
76
77
78// ===========================================================================
79// method definitions
80// ===========================================================================
81void
83 if (myAdaptationInterval == -1) {
85 myEdgeSpeeds.clear();
86 myEdgeTravelTimes.clear();
90 myWithTaz = oc.getBool("device.rerouting.with-taz");
91 myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
92 myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
93 const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
94 if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
97 } else if (period > 0) {
98 WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
99 }
100 OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
101 }
102}
103
104
105void
113
114
115void
116MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
117 if (edgeSpeeds.empty()) {
119 if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
120 myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
121 }
122 const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
123 const double currentSecond = SIMTIME;
124 double maxEdgePriority = -std::numeric_limits<double>::max();
125 for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
126 while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
127 edgeSpeeds.push_back(0);
128 if (myAdaptationSteps > 0) {
129 pastEdgeSpeeds.push_back(std::vector<double>());
130 }
131 if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
132 myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
133 }
134 }
135 if (useLoaded) {
136 edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
137 } else {
138 edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
139 }
140 if (myAdaptationSteps > 0) {
141 pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
142 }
143 maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
144 myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
145 }
146 myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
148 myPriorityFactor = oc.getFloat("weights.priority-factor");
149 if (myPriorityFactor < 0) {
150 throw ProcessError(TL("weights.priority-factor cannot be negative."));
151 }
152 if (myPriorityFactor > 0) {
153 if (myEdgePriorityRange == 0) {
154 WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
156 }
157 }
158 }
159}
160
161
162double
163MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
164 const int id = e->getNumericalID();
165 if (id < (int)myEdgeSpeeds.size()) {
166 return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
167 }
168 return e->getMinimumTravelTime(v);
169}
170
171
172double
173MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
174 const int id = e->getNumericalID();
175 if (id < (int)myEdgeBikeSpeeds.size()) {
176 return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
177 }
178 return e->getMinimumTravelTime(v);
179}
180
181SumoRNG*
184 auto it = myThreadRNGs.find(std::this_thread::get_id());
185 // created by InitTask
186 assert(it != myThreadRNGs.end());
187 return it->second;
188 }
189 return nullptr;
190}
191
192
193double
194MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
195 double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
196 ? getEffort(e, v, t)
197 : getEffortBike(e, v, t));
198 if (gWeightsRandomFactor != 1.) {
200 }
201 if (myPriorityFactor != 0) {
202 // lower priority should result in higher effort (and the edge with
203 // minimum priority receives a factor of 1 + myPriorityFactor
204 const double relativeInversePrio = 1 - ((e->getPriority() - myMinEdgePriority) / myEdgePriorityRange);
205 effort *= 1 + relativeInversePrio * myPriorityFactor;
206 }
207 return effort;
208}
209
210
211double
213 return edge->getLength() / myEffortFunc(edge, veh, 0);
214}
215
216
220 if (myBikeSpeeds) {
222 }
223 if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
225 }
226 myCachedRoutes.clear();
228 const double newWeightFactor = (double)(1. - myAdaptationWeight);
229 for (const MSEdge* const e : edges) {
230 if (e->isDelayed()) {
231 const int id = e->getNumericalID();
232 double currSpeed = e->getMeanSpeed();
233 if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
234 currSpeed = patchSpeedForTurns(e, currSpeed);
235 }
236#ifdef DEBUG_SEPARATE_TURNS
237 if (DEBUG_COND(e->getLanes()[0])) {
238 std::cout << SIMTIME << " edge=" << e->getID()
239 << " meanSpeed=" << e->getMeanSpeed()
240 << " currSpeed=" << currSpeed
241 << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
242 << " oldAvg=" << myEdgeSpeeds[id]
243 << "\n";
244 }
245#endif
246 if (myAdaptationSteps > 0) {
247 // moving average
250 if (myBikeSpeeds) {
251 const double currBikeSpeed = e->getMeanSpeedBike();
253 myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
254 }
255 } else {
256 // exponential moving average
257 if (currSpeed != myEdgeSpeeds[id]) {
258 myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
259 }
260 if (myBikeSpeeds) {
261 const double currBikeSpeed = e->getMeanSpeedBike();
262 if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
263 myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
264 }
265 }
266 }
267 }
268 }
269 if (myAdaptationSteps > 0) {
271 }
272 myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
273 if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
274 OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
276 dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
277 dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
279 for (const MSEdge* e : edges) {
281 dev.writeAttr(SUMO_ATTR_ID, e->getID());
282 dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
283 if (myBikeSpeeds) {
284 // @note edge-priority is not included here
285 dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
286 }
287 dev.closeTag();
288 }
289 dev.closeTag();
290 }
292}
293
294
295double
296MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
297 const double length = edge->getLength();
298 double maxSpeed = 0;
299 for (const auto& pair : edge->getViaSuccessors()) {
300 if (pair.second == nullptr) {
301 continue;
302 }
303 TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
304 if (tc.second > 0) {
305 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
306 maxSpeed = MAX2(avgSpeed, maxSpeed);
307 }
308 }
309 if (maxSpeed > 0) {
310 // perform correction
311 const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
312 for (const auto& pair : edge->getViaSuccessors()) {
313 if (pair.second == nullptr) {
314 continue;
315 }
316 const int iid = pair.second->getNumericalID();
318 if (tc.second > 0) {
319 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
320 if (avgSpeed < correctedSpeed) {
321 double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
322 internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
323 const double origInternalSpeed = myEdgeSpeeds[iid];
324 const double newInternalSpeed = pair.second->getLength() / internalTT;
325 const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
326
327 myEdgeSpeeds[iid] = newInternalSpeed;
328 // to ensure myEdgeSpeed reverts to the speed limit
329 // when there are no updates, we also have to patch
330 // myPastEdgeSpeeds with a virtual value that is consistent
331 // with the updated speed
332 // note: internal edges were handled before the normal ones
333 const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
334 myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
335
336#ifdef DEBUG_SEPARATE_TURNS
337 if (DEBUG_COND(pair.second->getLanes()[0])) {
338 std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
339 << " origSpeed=" << currSpeed
340 << " maxSpeed=" << maxSpeed
341 << " correctedSpeed=" << correctedSpeed
342 << " avgSpeed=" << avgSpeed
343 << " internalTT=" << internalTT
344 << " internalSpeed=" << origInternalSpeed
345 << " newInternalSpeed=" << newInternalSpeed
346 << " virtualSpeed=" << virtualSpeed
347 << "\n";
348 }
349#endif
350 }
351 if (myAdaptationStepsIndex == 0) {
352 tc.first = 0;
353 tc.second = 0;
354 }
355 }
356 }
357 return correctedSpeed;
358 }
359 return currSpeed;
360}
361
362
364MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
365 auto routeIt = myCachedRoutes.find(key);
366 if (routeIt != myCachedRoutes.end()) {
367 return routeIt->second;
368 }
369 return nullptr;
370}
371
372
373void
376 const std::string routingAlgorithm = oc.getString("routing-algorithm");
377 const bool hasPermissions = MSNet::getInstance()->hasPermissions();
378 myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
380
382 if (routingAlgorithm == "dijkstra") {
383 router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
384 } else if (routingAlgorithm == "astar") {
386 std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
387 if (oc.isSet("astar.all-distances")) {
388 lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
389 } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
390 const double speedFactor = vehicle->getChosenSpeedFactor();
391 // we need an exemplary vehicle with speedFactor 1
392 vehicle->setChosenSpeedFactor(1);
395 string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
396 lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
397 nullptr, vehicle, "", oc.getInt("device.rerouting.threads"), MSNet::getInstance()->getMapMatcher());
398 vehicle->setChosenSpeedFactor(speedFactor);
399 }
400 router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
401 } else if (routingAlgorithm == "CH" && !hasPermissions) {
404 MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
405 } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
406 // use CHWrapper instead of CH if the net has permissions
410 string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
411 } else {
412 throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
413 }
414
415 RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
416 if (MSNet::getInstance()->hasBidiEdges()) {
417 railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false, oc.getFloat("railway.max-train-length"));
418 }
419 const int carWalk = SUMOVehicleParserHelper::parseCarWalkTransfer(oc);
420 const double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
421 MSTransportableRouter* transRouter = new MSTransportableRouter(MSNet::adaptIntermodalRouter, carWalk, taxiWait, routingAlgorithm, 0);
422 myRouterProvider = new MSRouterProvider(router, nullptr, transRouter, railRouter);
423#ifndef THREAD_POOL
424#ifdef HAVE_FOX
425 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
426 if (threadPool.size() > 0) {
427 const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
428 if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
429 for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
430 static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
431 }
432 }
434 for (int i = 0; i < threadPool.size(); i++) {
435 threadPool.add(new InitTask(), i);
436 }
437 threadPool.waitAll();
438 // to use when routing is triggered from the main thread (i.e. by a rerouter)
439 myThreadRNGs[std::this_thread::get_id()] = nullptr;
440 }
441#endif
442#endif
443}
444
445
446void
447MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
448 const bool onInit, const bool silent, const MSEdgeVector& prohibited) {
449 if (myRouterProvider == nullptr) {
450 initRouter(&vehicle);
451 }
452 auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
453#ifndef THREAD_POOL
454#ifdef HAVE_FOX
455 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
456 if (threadPool.size() > 0) {
457 threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
458 return;
459 }
460#endif
461#endif
462 if (!prohibited.empty()) {
463 router.prohibit(prohibited);
464 }
465 try {
466 vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
467 } catch (ProcessError&) {
468 if (!silent) {
469 if (!prohibited.empty()) {
470 router.prohibit(MSEdgeVector());
471 }
472 throw;
473 }
474 }
475 if (!prohibited.empty()) {
476 router.prohibit(MSEdgeVector());
477 }
478}
479
480
481void
482MSRoutingEngine::reroute(MSTransportable& t, const SUMOTime currentTime, const std::string& info,
483 const bool onInit, const bool silent, const MSEdgeVector& prohibited) {
485#ifndef THREAD_POOL
486#ifdef HAVE_FOX
487 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
488 if (threadPool.size() > 0) {
489 // threadPool.add(new RoutingTask(t, currentTime, info, onInit, silent, prohibited));
490 return;
491 }
492#endif
493#endif
494 if (!prohibited.empty()) {
495 router.prohibit(prohibited);
496 }
497 try {
498 t.reroute(currentTime, info, router, onInit, myWithTaz, silent);
499 } catch (ProcessError&) {
500 if (!silent) {
501 if (!prohibited.empty()) {
502 router.prohibit(MSEdgeVector());
503 }
504 throw;
505 }
506 }
507 if (!prohibited.empty()) {
508 router.prohibit(MSEdgeVector());
509 }
510}
511
512
513void
514MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
515 myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
516}
517
518void
519MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
521 tc.first += travelTime;
522 tc.second += 1;
523}
524
525
527MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector& prohibited) {
528 if (myRouterProvider == nullptr) {
530 initEdgeWeights(svc);
531 initRouter();
532 }
533#ifndef THREAD_POOL
534#ifdef HAVE_FOX
535 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
536 if (threadPool.size() > 0) {
537 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
538 router.prohibit(prohibited);
539 return router;
540 }
541#else
542 UNUSED_PARAMETER(rngIndex);
543#endif
544#endif
545 myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
547}
548
549
551MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const MSEdgeVector& prohibited) {
552 if (myRouterProvider == nullptr) {
555 initRouter();
556 }
557#ifndef THREAD_POOL
558#ifdef HAVE_FOX
559 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
560 if (threadPool.size() > 0) {
561 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
562 router.prohibit(prohibited);
563 return router;
564 }
565#else
566 UNUSED_PARAMETER(rngIndex);
567#endif
568#endif
569 myRouterProvider->getIntermodalRouter().prohibit(prohibited);
571}
572
573
574void
576 myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
577 myPastEdgeSpeeds.clear();
578 myEdgeSpeeds.clear();
579 myEdgeTravelTimes.clear();
580 myPastEdgeBikeSpeeds.clear();
581 myEdgeBikeSpeeds.clear();
582 // @todo recheck. calling release crashes in parallel routing
583 //for (auto& item : myCachedRoutes) {
584 // item.second->release();
585 //}
586 myCachedRoutes.clear();
588#ifdef HAVE_FOX
589 if (MSGlobals::gNumThreads > 1) {
590 // router deletion is done in thread destructor
591 myRouterProvider = nullptr;
592 return;
593 }
594#endif
595 delete myRouterProvider;
596 myRouterProvider = nullptr;
597}
598
599
600#ifdef HAVE_FOX
601void
602MSRoutingEngine::waitForAll() {
603#ifndef THREAD_POOL
604 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
605 if (threadPool.size() > 0) {
606 threadPool.waitAll();
607 }
608#endif
609}
610
611
612// ---------------------------------------------------------------------------
613// MSRoutingEngine::RoutingTask-methods
614// ---------------------------------------------------------------------------
615void
616MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
617 SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
618 if (!myProhibited.empty()) {
619 router.prohibit(myProhibited);
620 }
621 try {
622 myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
623 } catch (ProcessError&) {
624 if (!mySilent) {
625 if (!myProhibited.empty()) {
626 router.prohibit(MSEdgeVector());
627 }
628 throw;
629 }
630 }
631 if (!myProhibited.empty()) {
632 router.prohibit(MSEdgeVector());
633 }
634 const MSEdge* source = *myVehicle.getRoute().begin();
635 const MSEdge* dest = myVehicle.getRoute().getLastEdge();
636 if (source->isTazConnector() && dest->isTazConnector()) {
637 const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
638 FXMutexLock lock(myRouteCacheMutex);
640 MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
641 }
642 }
643}
644
645// ---------------------------------------------------------------------------
646// MSRoutingEngine::InitTask-methods
647// ---------------------------------------------------------------------------
648void
649MSRoutingEngine::InitTask::run(MFXWorkerThread* /*context*/) {
650 FXMutexLock lock(myRouteCacheMutex);
651 SumoRNG* rng = new SumoRNG("routing_" + toString(myThreadRNGs.size()));
652 myThreadRNGs[std::this_thread::get_id()] = rng;
653}
654
655#endif
656
657
658/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
RouterProvider< MSEdge, MSLane, MSJunction, SUMOVehicle > MSRouterProvider
IntermodalRouter< MSEdge, MSLane, MSJunction, SUMOVehicle > MSTransportableRouter
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:305
#define TLF(string,...)
Definition MsgHandler.h:307
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition Route.h:32
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:32
T MIN2(T a, T b)
Definition StdDefs.h:76
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
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.
void prohibit(const std::vector< E * > &toProhibit)
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:1086
int getPriority() const
Returns the priority of the edge.
Definition MSEdge.h:328
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition MSEdge.cpp:1288
double getLength() const
return the length of the edge
Definition MSEdge.h:685
bool isTazConnector() const
Definition MSEdge.h:291
double getMinimumTravelTime(const SUMOVehicle *const veh) const
returns the minimum travel time for the given vehicle
Definition MSEdge.h:476
int getNumericalID() const
Returns the numerical id of the edge.
Definition MSEdge.h:306
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:177
static int gNumThreads
how many threads to use
Definition MSGlobals.h:149
MSMapMatcher * getMapMatcher() const
Definition MSNet.cpp:1681
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
Definition MSNet.h:486
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:325
static double getTravelTime(const MSEdge *const e, const SUMOVehicle *const v, double t)
Returns the travel time to pass an edge.
Definition MSNet.cpp:166
bool hasPermissions() const
Returns whether the network has specific vehicle class permissions.
Definition MSNet.h:212
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition MSNet.h:426
static void adaptIntermodalRouter(MSTransportableRouter &router)
Definition MSNet.cpp:1600
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 bool myHaveRoutingThreads
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
int getRNGIndex() const
returns the index of the associated RNG
bool reroute(SUMOTime t, const std::string &info, MSTransportableRouter &router, const bool onInit=false, const bool withTaz=false, const bool silent=false, const MSEdge *sink=nullptr)
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.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
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.
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)
SUMOAbstractRouter< E, V > & getVehicleRouter(SUMOVehicleClass svc) const
RouterProvider * clone()
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:62
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
static int parseCarWalkTransfer(const OptionsCont &oc, const bool hasTaxi=false)
A wrapper for a Command function.
#define UNUSED_PARAMETER(x)
#define DEBUG_COND
@ key
the parser read a key of a value in an object