Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2026 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>
47
48//#define DEBUG_SEPARATE_TURNS
49#define DEBUG_COND(obj) (obj->isSelected())
50
51// ===========================================================================
52// static member variables
53// ===========================================================================
54std::vector<double> MSRoutingEngine::myEdgeSpeeds;
55std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
56std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
57std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
58std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
68std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
70double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
74
76#ifdef HAVE_FOX
77FXMutex MSRoutingEngine::myRouteCacheMutex;
78#endif
79
80
81// ===========================================================================
82// method definitions
83// ===========================================================================
84void
86 if (myAdaptationInterval == -1) {
88 myLastAdaptation = lastAdaptation;
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) {
95 SUMOTime nextAdaptation = -1;
96 if (lastAdaptation >= 0) {
97 nextAdaptation = lastAdaptation + myAdaptationInterval;
98 }
101 } else if (period > 0) {
102 WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
103 }
104 OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
105 }
106}
107
108
109void
112 if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
113 myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
114 }
115 if (myBikeSpeeds && svc == SVC_BICYCLE) {
117 } else {
119 }
120 if (lastAdaption >= 0) {
121 myLastAdaptation = lastAdaption;
122 }
123 if (index >= 0 && myAdaptationSteps > 0) {
124 assert(index < myAdaptationSteps);
126 }
127}
128
129
130void
132 if (oc.getFloat("weights.priority-factor") != 0) {
133 myPriorityFactor = oc.getFloat("weights.priority-factor");
134 if (myPriorityFactor < 0) {
135 throw ProcessError(TL("weights.priority-factor cannot be negative."));
136 }
137 myMinEdgePriority = std::numeric_limits<double>::max();
138 double maxEdgePriority = -std::numeric_limits<double>::max();
139 for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
140 maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
141 myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
142 }
143 myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
144 if (myEdgePriorityRange == 0) {
145 WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
147 }
148 }
149 myDynamicRandomness = oc.getBool("weights.random-factor.dynamic");
151}
152
153
154void
155MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
156 if (edgeSpeeds.empty()) {
158 const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
159 const double currentSecond = SIMTIME;
160 for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
161 while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
162 edgeSpeeds.push_back(0);
163 if (myAdaptationSteps > 0) {
164 pastEdgeSpeeds.push_back(std::vector<double>());
165 }
166 if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
167 myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
168 }
169 }
170 if (useLoaded) {
171 edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
172 } else {
173 edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
174 }
175 if (myAdaptationSteps > 0) {
176 pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
177 }
178 }
180 }
181}
182
183
184double
185MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
186 const int id = e->getNumericalID();
187 if (id < (int)myEdgeSpeeds.size()) {
188 return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
189 }
190 return e->getMinimumTravelTime(v);
191}
192
193
194double
195MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
196 const int id = e->getNumericalID();
197 if (id < (int)myEdgeBikeSpeeds.size()) {
198 return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
199 }
200 return e->getMinimumTravelTime(v);
201}
202
203
204double
205MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
206 double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
207 ? getEffort(e, v, t)
208 : getEffortBike(e, v, t));
209 applyExtras(e, v, SIMSTEP, effort);
210 return effort;
211}
212
213
214double
216 return edge->getLength() / myEffortFunc(edge, veh, 0);
217}
218
219
223 if (myBikeSpeeds) {
225 }
226 if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
228 }
229 myCachedRoutes.clear();
231 const double newWeightFactor = (double)(1. - myAdaptationWeight);
232 for (const MSEdge* const e : edges) {
233 if (e->isDelayed()) {
234 const int id = e->getNumericalID();
235 double currSpeed = e->getMeanSpeed();
236 if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
237 currSpeed = patchSpeedForTurns(e, currSpeed);
238 }
239#ifdef DEBUG_SEPARATE_TURNS
240 if (DEBUG_COND(e->getLanes()[0])) {
241 std::cout << SIMTIME << " edge=" << e->getID()
242 << " meanSpeed=" << e->getMeanSpeed()
243 << " currSpeed=" << currSpeed
244 << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
245 << " oldAvg=" << myEdgeSpeeds[id]
246 << "\n";
247 }
248#endif
249 if (myAdaptationSteps > 0) {
250 // moving average
253 if (myBikeSpeeds) {
254 const double currBikeSpeed = e->getMeanSpeedBike();
256 myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
257 }
258 } else {
259 // exponential moving average
260 if (currSpeed != myEdgeSpeeds[id]) {
261 myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
262 }
263 if (myBikeSpeeds) {
264 const double currBikeSpeed = e->getMeanSpeedBike();
265 if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
266 myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
267 }
268 }
269 }
270 }
271 }
272 if (myAdaptationSteps > 0) {
274 }
275 myLastAdaptation = currentTime;
276 if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
277 OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
279 dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
280 dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
282 for (const MSEdge* e : edges) {
284 dev.writeAttr(SUMO_ATTR_ID, e->getID());
285 dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
286 if (myBikeSpeeds) {
287 // @note edge-priority is not included here
288 dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
289 }
290 dev.closeTag();
291 }
292 dev.closeTag();
293 }
295}
296
297
298double
299MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
300 const double length = edge->getLength();
301 double maxSpeed = 0;
302 for (const auto& pair : edge->getViaSuccessors()) {
303 if (pair.second == nullptr) {
304 continue;
305 }
306 TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
307 if (tc.second > 0) {
308 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
309 maxSpeed = MAX2(avgSpeed, maxSpeed);
310 }
311 }
312 if (maxSpeed > 0) {
313 // perform correction
314 const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
315 for (const auto& pair : edge->getViaSuccessors()) {
316 if (pair.second == nullptr) {
317 continue;
318 }
319 const int iid = pair.second->getNumericalID();
321 if (tc.second > 0) {
322 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
323 if (avgSpeed < correctedSpeed) {
324 double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
325 internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
326 const double origInternalSpeed = myEdgeSpeeds[iid];
327 const double newInternalSpeed = pair.second->getLength() / internalTT;
328 const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
329
330 myEdgeSpeeds[iid] = newInternalSpeed;
331 // to ensure myEdgeSpeed reverts to the speed limit
332 // when there are no updates, we also have to patch
333 // myPastEdgeSpeeds with a virtual value that is consistent
334 // with the updated speed
335 // note: internal edges were handled before the normal ones
336 const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
337 myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
338
339#ifdef DEBUG_SEPARATE_TURNS
340 if (DEBUG_COND(pair.second->getLanes()[0])) {
341 std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
342 << " origSpeed=" << currSpeed
343 << " maxSpeed=" << maxSpeed
344 << " correctedSpeed=" << correctedSpeed
345 << " avgSpeed=" << avgSpeed
346 << " internalTT=" << internalTT
347 << " internalSpeed=" << origInternalSpeed
348 << " newInternalSpeed=" << newInternalSpeed
349 << " virtualSpeed=" << virtualSpeed
350 << "\n";
351 }
352#endif
353 }
354 if (myAdaptationStepsIndex == 0) {
355 tc.first = 0;
356 tc.second = 0;
357 }
358 }
359 }
360 return correctedSpeed;
361 }
362 return currSpeed;
363}
364
365
367MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
368 auto routeIt = myCachedRoutes.find(key);
369 if (routeIt != myCachedRoutes.end()) {
370 return routeIt->second;
371 }
372 return nullptr;
373}
374
375
376void
379 const std::string routingAlgorithm = oc.getString("routing-algorithm");
380 const bool hasPermissions = MSNet::getInstance()->hasPermissions();
381 myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
383
385 if (routingAlgorithm == "dijkstra") {
386 router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
387 } else if (routingAlgorithm == "astar") {
389 std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
390 if (oc.isSet("astar.all-distances")) {
391 lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
392 } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
393 const double speedFactor = vehicle->getChosenSpeedFactor();
394 // we need an exemplary vehicle with speedFactor 1
395 vehicle->setChosenSpeedFactor(1);
398 string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
399 lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
400 nullptr, vehicle, "", oc.getInt("device.rerouting.threads"), MSNet::getInstance()->getMapMatcher());
401 vehicle->setChosenSpeedFactor(speedFactor);
402 }
403 router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
404 } else if (routingAlgorithm == "CH" && !hasPermissions) {
407 MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
408 } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
409 // use CHWrapper instead of CH if the net has permissions
413 string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
414 } else {
415 throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
416 }
417
418 RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
419 if (MSNet::getInstance()->hasBidiEdges()) {
420 railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false,
421 oc.getFloat("railway.max-train-length"),
422 oc.getFloat("weights.reversal-penalty"));
423 }
424 const int carWalk = SUMOVehicleParserHelper::parseCarWalkTransfer(oc, MSDevice_Taxi::hasFleet() || MSNet::getInstance()->getInsertionControl().hasTaxiFlow());
425 const double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
426 MSTransportableRouter* transRouter = new MSTransportableRouter(MSNet::adaptIntermodalRouter, carWalk, taxiWait, routingAlgorithm, 0);
427 myRouterProvider = new MSRouterProvider(router, nullptr, transRouter, railRouter);
428#ifndef THREAD_POOL
429#ifdef HAVE_FOX
430 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
431 if (threadPool.size() > 0) {
432 const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
433 if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
434 for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
435 static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
436 }
437 }
438 }
439#endif
440#endif
441}
442
443
444void
445MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
446 const bool onInit, const bool silent, const Prohibitions& prohibited) {
447 if (myRouterProvider == nullptr) {
448 initRouter(&vehicle);
449 }
450 auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
451#ifndef THREAD_POOL
452#ifdef HAVE_FOX
453 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
454 if (threadPool.size() > 0) {
455 threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
456 return;
457 }
458#endif
459#endif
460 if (!prohibited.empty()) {
461 router.prohibit(prohibited);
462 }
463 try {
464 vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
465 } catch (ProcessError&) {
466 if (!silent) {
467 if (!prohibited.empty()) {
468 router.prohibit(Prohibitions());
469 }
470 throw;
471 }
472 }
473 if (!prohibited.empty()) {
474 router.prohibit(Prohibitions());
475 }
476}
477
478
479void
480MSRoutingEngine::reroute(MSTransportable& t, const SUMOTime currentTime, const std::string& info,
481 const bool onInit, const bool silent, const Prohibitions& prohibited) {
483#ifndef THREAD_POOL
484#ifdef HAVE_FOX
485 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
486 if (threadPool.size() > 0) {
487 // threadPool.add(new RoutingTask(t, currentTime, info, onInit, silent, prohibited));
488 return;
489 }
490#endif
491#endif
492 if (!prohibited.empty()) {
493 router.prohibit(prohibited);
494 }
495 try {
496 t.reroute(currentTime, info, router, onInit, myWithTaz, silent);
497 } catch (ProcessError&) {
498 if (!silent) {
499 if (!prohibited.empty()) {
500 router.prohibit(Prohibitions());
501 }
502 throw;
503 }
504 }
505 if (!prohibited.empty()) {
506 router.prohibit(Prohibitions());
507 }
508}
509
510
511void
512MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
513 myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
514}
515
516void
517MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
519 tc.first += travelTime;
520 tc.second += 1;
521}
522
523
525MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const Prohibitions& prohibited) {
526 if (myRouterProvider == nullptr) {
528 initEdgeWeights(svc);
529 initRouter();
530 }
531#ifndef THREAD_POOL
532#ifdef HAVE_FOX
533 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
534 if (threadPool.size() > 0) {
535 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
536 router.prohibit(prohibited);
537 return router;
538 }
539#else
540 UNUSED_PARAMETER(rngIndex);
541#endif
542#endif
543 myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
545}
546
547
549MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const Prohibitions& prohibited) {
550 if (myRouterProvider == nullptr) {
553 initRouter();
554 }
555#ifndef THREAD_POOL
556#ifdef HAVE_FOX
557 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
558 if (threadPool.size() > 0) {
559 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
560 router.prohibit(prohibited);
561 return router;
562 }
563#else
564 UNUSED_PARAMETER(rngIndex);
565#endif
566#endif
567 myRouterProvider->getIntermodalRouter().prohibit(prohibited);
569}
570
571
572void
574 myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
575 myPastEdgeSpeeds.clear();
576 myEdgeSpeeds.clear();
577 myEdgeTravelTimes.clear();
578 myPastEdgeBikeSpeeds.clear();
579 myEdgeBikeSpeeds.clear();
580 // @todo recheck. calling release crashes in parallel routing
581 //for (auto& item : myCachedRoutes) {
582 // item.second->release();
583 //}
584 myCachedRoutes.clear();
586#ifdef HAVE_FOX
587 if (MSGlobals::gNumThreads > 1) {
588 // router deletion is done in thread destructor
589 myRouterProvider = nullptr;
590 return;
591 }
592#endif
593 delete myRouterProvider;
594 myRouterProvider = nullptr;
595}
596
597
598void
600 if (myEdgeSpeeds.size() == 0) {
601 return;
602 }
607 for (const MSEdge* const e : edges) {
608 if (e->isDelayed()) {
609 const int id = e->getNumericalID();
611 out.writeAttr(SUMO_ATTR_ID, e->getID());
613 if (myAdaptationSteps > 0) {
615 }
616 if (myBikeSpeeds) {
618 if (myAdaptationSteps > 0) {
620 }
621 }
622 out.closeTag();
623 }
624 }
625 out.closeTag();
626}
627
628
629void
631 const MSEdge* const e = MSEdge::dictionary(attrs.getString(SUMO_ATTR_ID));
632 e->markDelayed();
633 const int id = e->getNumericalID();
634 bool checkedSteps = false;
635 bool checkedBikeSpeeds = false;
636 bool ok = true;
637 if ((int)myEdgeSpeeds.size() > id) {
638 myEdgeSpeeds[id] = attrs.get<double>(SUMO_ATTR_SPEED, nullptr, ok);
639 if (myBikeSpeeds) {
641 myEdgeBikeSpeeds[id] = attrs.get<double>(SUMO_ATTR_BIKESPEED, nullptr, ok);
642 } else if (!checkedBikeSpeeds) {
643 checkedBikeSpeeds = true;
644 WRITE_WARNING("Bike speeds missing in loaded state");
645 }
646 }
647 if (myAdaptationSteps > 0) {
648 const std::vector<double> speeds = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTSPEED, nullptr, ok);
649 if ((int)speeds.size() == myAdaptationSteps) {
650 myPastEdgeSpeeds[id] = speeds;
652 myPastEdgeBikeSpeeds[id] = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTBIKESPEED, nullptr, ok);
653 }
654 } else if (!checkedSteps) {
655 checkedSteps = true;
656 WRITE_WARNING("Number of adaptation speeds in loaded state doesn't match option --device.rerouting.adaptation-steps");
657 }
658 }
659 }
660}
661
662
663#ifdef HAVE_FOX
664void
665MSRoutingEngine::waitForAll() {
666#ifndef THREAD_POOL
667 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
668 if (threadPool.size() > 0) {
669 threadPool.waitAll();
670 }
671#endif
672}
673
674
675// ---------------------------------------------------------------------------
676// MSRoutingEngine::RoutingTask-methods
677// ---------------------------------------------------------------------------
678void
679MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
680 SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
681 if (!myProhibited.empty()) {
682 router.prohibit(myProhibited);
683 }
684 try {
685 myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
686 } catch (ProcessError&) {
687 if (!mySilent) {
688 if (!myProhibited.empty()) {
689 router.prohibit(Prohibitions());
690 }
691 throw;
692 }
693 }
694 if (!myProhibited.empty()) {
695 router.prohibit(Prohibitions());
696 }
697 const MSEdge* source = *myVehicle.getRoute().begin();
698 const MSEdge* dest = myVehicle.getRoute().getLastEdge();
699 if (source->isTazConnector() && dest->isTazConnector()) {
700 const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
701 FXMutexLock lock(myRouteCacheMutex);
703 MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
704 }
705 }
706}
707
708
709#endif
710
711
712/****************************************************************************/
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:286
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition Route.h:32
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SIMSTEP
Definition SUMOTime.h:64
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:65
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_ROUTINGENGINE
the internal state for MSRoutingEngine
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_LAST
@ SUMO_ATTR_PASTSPEED
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_PASTBIKESPEED
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
@ SUMO_ATTR_BIKESPEED
bool gRoutingPreferences
Definition StdDefs.cpp:37
double gWeightsRandomFactor
Definition StdDefs.cpp:35
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
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 _Prohibitions &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.
static bool hasFleet()
returns whether taxis have been loaded
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:1120
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition MSEdge.cpp:1322
double getLength() const
return the length of the edge
Definition MSEdge.h:694
bool isTazConnector() const
Definition MSEdge.h:292
double getMinimumTravelTime(const SUMOVehicle *const veh) const
returns the minimum travel time for the given vehicle
Definition MSEdge.h:485
int getNumericalID() const
Returns the numerical id of the edge.
Definition MSEdge.h:307
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:1081
void markDelayed() const
Definition MSEdge.h:740
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:180
static int gNumThreads
how many threads to use
Definition MSGlobals.h:152
MSMapMatcher * getMapMatcher() const
Definition MSNet.cpp:1787
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:199
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
Definition MSNet.h:505
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
static double getTravelTime(const MSEdge *const e, const SUMOVehicle *const v, double t)
Returns the travel time to pass an edge.
Definition MSNet.cpp:167
bool hasPermissions() const
Returns whether the network has specific vehicle class permissions.
Definition MSNet.h:213
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition MSNet.h:445
static void adaptIntermodalRouter(MSTransportableRouter &router)
Definition MSNet.cpp:1706
static void saveState(OutputDevice &out)
Saves the state (i.e. recorded speeds)
static SUMOTime myAdaptationInterval
At which time interval the edge weights get updated.
static void initEdgeWeights(SUMOVehicleClass svc, SUMOTime lastAdaption=-1, int index=-1)
initialize the edge weights if not done before
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 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 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 bool myHaveExtras
whether extra routing cost modifications are configured
SUMOAbstractRouter< MSEdge, SUMOVehicle >::Prohibitions Prohibitions
static void addEdgeTravelTime(const MSEdge &edge, const SUMOTime travelTime)
record actual travel time for an edge
static void applyExtras(const MSEdge *const e, const SUMOVehicle *const v, SUMOTime step, double &effort)
apply cost modifications from randomness, priorityFactor and preferences
static bool myDynamicRandomness
whether randomness varies over time
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 void initWeightUpdate(SUMOTime lastAdaption=- 1)
intialize period edge weight update
static void reroute(SUMOVehicle &vehicle, const SUMOTime currentTime, const std::string &info, const bool onInit=false, const bool silent=false, const Prohibitions &prohibited={})
initiate the rerouting, create router / thread pool on first use
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 void loadState(const SUMOSAXAttributes &attrs)
Loads the state.
static double patchSpeedForTurns(const MSEdge *edge, double currSpeed)
static MSVehicleRouter & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const Prohibitions &prohibited={})
return the vehicle router instance
static double getEffortExtra(const MSEdge *const e, const SUMOVehicle *const v, double t)
static MSTransportableRouter & getIntermodalRouterTT(const int rngIndex, const Prohibitions &prohibited={})
return the person router instance
static std::vector< double > myEdgeBikeSpeeds
static void initWeightConstants(const OptionsCont &oc)
initialize constants for using myPriorityFactor
int getRNGIndex() const override
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 & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
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 bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="", const int maximumDepth=2)
Creates the device using the output definition stored in the named option.
SUMOAbstractRouter< E, V > & getVehicleRouter(SUMOVehicleClass svc) const
RouterProvider * clone()
IntermodalRouter< E, L, N, V > & getIntermodalRouter() const
virtual void prohibit(const Prohibitions &toProhibit)
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
virtual double getChosenSpeedFactor() const =0
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
Representation of a vehicle.
Definition SUMOVehicle.h:63
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)
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