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-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>
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());
73
75#ifdef HAVE_FOX
76FXMutex MSRoutingEngine::myRouteCacheMutex;
77#endif
78
79
80// ===========================================================================
81// method definitions
82// ===========================================================================
83void
85 if (myAdaptationInterval == -1) {
87 myEdgeSpeeds.clear();
88 myEdgeTravelTimes.clear();
92 myWithTaz = oc.getBool("device.rerouting.with-taz");
93 myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
94 myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
95 const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
96 if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
99 } else if (period > 0) {
100 WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
101 }
102 OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
103 }
104}
105
106
107void
109 if (myBikeSpeeds && svc == SVC_BICYCLE) {
111 } else {
113 }
114 if (lastAdaption >= 0) {
115 myLastAdaptation = lastAdaption;
116 }
117 if (index >= 0) {
118 assert(index < (int)myPastEdgeSpeeds.size());
120 }
121}
122
123
124void
125MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
126 if (edgeSpeeds.empty()) {
128 if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
129 myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
130 }
131 const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
132 const double currentSecond = SIMTIME;
133 double maxEdgePriority = -std::numeric_limits<double>::max();
134 for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
135 while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
136 edgeSpeeds.push_back(0);
137 if (myAdaptationSteps > 0) {
138 pastEdgeSpeeds.push_back(std::vector<double>());
139 }
140 if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
141 myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
142 }
143 }
144 if (useLoaded) {
145 edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
146 } else {
147 edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
148 }
149 if (myAdaptationSteps > 0) {
150 pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
151 }
152 maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
153 myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
154 }
155 myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
157 myPriorityFactor = oc.getFloat("weights.priority-factor");
158 myDynamicRandomness = oc.getBool("weights.random-factor.dynamic");
159 if (myPriorityFactor < 0) {
160 throw ProcessError(TL("weights.priority-factor cannot be negative."));
161 }
162 if (myPriorityFactor > 0) {
163 if (myEdgePriorityRange == 0) {
164 WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
166 }
167 }
168 }
169}
170
171
172double
173MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
174 const int id = e->getNumericalID();
175 if (id < (int)myEdgeSpeeds.size()) {
176 return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
177 }
178 return e->getMinimumTravelTime(v);
179}
180
181
182double
183MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
184 const int id = e->getNumericalID();
185 if (id < (int)myEdgeBikeSpeeds.size()) {
186 return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
187 }
188 return e->getMinimumTravelTime(v);
189}
190
191
192double
193MSRoutingEngine::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.) {
198 long long int key = v->getRandomSeed() ^ e->getNumericalID();
200 key ^= SIMSTEP;
201 }
202 effort *= (1 + RandHelper::randHash(key) * (gWeightsRandomFactor - 1));
203 }
204 if (myPriorityFactor != 0) {
205 // lower priority should result in higher effort (and the edge with
206 // minimum priority receives a factor of 1 + myPriorityFactor
207 const double relativeInversePrio = 1 - ((e->getPriority() - myMinEdgePriority) / myEdgePriorityRange);
208 effort *= 1 + relativeInversePrio * myPriorityFactor;
209 }
212 }
213 return effort;
214}
215
216
217double
219 return edge->getLength() / myEffortFunc(edge, veh, 0);
220}
221
222
226 if (myBikeSpeeds) {
228 }
229 if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
231 }
232 myCachedRoutes.clear();
234 const double newWeightFactor = (double)(1. - myAdaptationWeight);
235 for (const MSEdge* const e : edges) {
236 if (e->isDelayed()) {
237 const int id = e->getNumericalID();
238 double currSpeed = e->getMeanSpeed();
239 if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
240 currSpeed = patchSpeedForTurns(e, currSpeed);
241 }
242#ifdef DEBUG_SEPARATE_TURNS
243 if (DEBUG_COND(e->getLanes()[0])) {
244 std::cout << SIMTIME << " edge=" << e->getID()
245 << " meanSpeed=" << e->getMeanSpeed()
246 << " currSpeed=" << currSpeed
247 << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
248 << " oldAvg=" << myEdgeSpeeds[id]
249 << "\n";
250 }
251#endif
252 if (myAdaptationSteps > 0) {
253 // moving average
256 if (myBikeSpeeds) {
257 const double currBikeSpeed = e->getMeanSpeedBike();
259 myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
260 }
261 } else {
262 // exponential moving average
263 if (currSpeed != myEdgeSpeeds[id]) {
264 myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
265 }
266 if (myBikeSpeeds) {
267 const double currBikeSpeed = e->getMeanSpeedBike();
268 if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
269 myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
270 }
271 }
272 }
273 }
274 }
275 if (myAdaptationSteps > 0) {
277 }
278 myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
279 if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
280 OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
282 dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
283 dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
285 for (const MSEdge* e : edges) {
287 dev.writeAttr(SUMO_ATTR_ID, e->getID());
288 dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
289 if (myBikeSpeeds) {
290 // @note edge-priority is not included here
291 dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
292 }
293 dev.closeTag();
294 }
295 dev.closeTag();
296 }
298}
299
300
301double
302MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
303 const double length = edge->getLength();
304 double maxSpeed = 0;
305 for (const auto& pair : edge->getViaSuccessors()) {
306 if (pair.second == nullptr) {
307 continue;
308 }
309 TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
310 if (tc.second > 0) {
311 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
312 maxSpeed = MAX2(avgSpeed, maxSpeed);
313 }
314 }
315 if (maxSpeed > 0) {
316 // perform correction
317 const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
318 for (const auto& pair : edge->getViaSuccessors()) {
319 if (pair.second == nullptr) {
320 continue;
321 }
322 const int iid = pair.second->getNumericalID();
324 if (tc.second > 0) {
325 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
326 if (avgSpeed < correctedSpeed) {
327 double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
328 internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
329 const double origInternalSpeed = myEdgeSpeeds[iid];
330 const double newInternalSpeed = pair.second->getLength() / internalTT;
331 const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
332
333 myEdgeSpeeds[iid] = newInternalSpeed;
334 // to ensure myEdgeSpeed reverts to the speed limit
335 // when there are no updates, we also have to patch
336 // myPastEdgeSpeeds with a virtual value that is consistent
337 // with the updated speed
338 // note: internal edges were handled before the normal ones
339 const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
340 myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
341
342#ifdef DEBUG_SEPARATE_TURNS
343 if (DEBUG_COND(pair.second->getLanes()[0])) {
344 std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
345 << " origSpeed=" << currSpeed
346 << " maxSpeed=" << maxSpeed
347 << " correctedSpeed=" << correctedSpeed
348 << " avgSpeed=" << avgSpeed
349 << " internalTT=" << internalTT
350 << " internalSpeed=" << origInternalSpeed
351 << " newInternalSpeed=" << newInternalSpeed
352 << " virtualSpeed=" << virtualSpeed
353 << "\n";
354 }
355#endif
356 }
357 if (myAdaptationStepsIndex == 0) {
358 tc.first = 0;
359 tc.second = 0;
360 }
361 }
362 }
363 return correctedSpeed;
364 }
365 return currSpeed;
366}
367
368
370MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
371 auto routeIt = myCachedRoutes.find(key);
372 if (routeIt != myCachedRoutes.end()) {
373 return routeIt->second;
374 }
375 return nullptr;
376}
377
378
379void
382 const std::string routingAlgorithm = oc.getString("routing-algorithm");
383 const bool hasPermissions = MSNet::getInstance()->hasPermissions();
384 myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
386
388 if (routingAlgorithm == "dijkstra") {
389 router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
390 } else if (routingAlgorithm == "astar") {
392 std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
393 if (oc.isSet("astar.all-distances")) {
394 lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
395 } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
396 const double speedFactor = vehicle->getChosenSpeedFactor();
397 // we need an exemplary vehicle with speedFactor 1
398 vehicle->setChosenSpeedFactor(1);
401 string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
402 lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
403 nullptr, vehicle, "", oc.getInt("device.rerouting.threads"), MSNet::getInstance()->getMapMatcher());
404 vehicle->setChosenSpeedFactor(speedFactor);
405 }
406 router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
407 } else if (routingAlgorithm == "CH" && !hasPermissions) {
410 MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
411 } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
412 // use CHWrapper instead of CH if the net has permissions
416 string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
417 } else {
418 throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
419 }
420
421 RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
422 if (MSNet::getInstance()->hasBidiEdges()) {
423 railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false,
424 oc.getFloat("railway.max-train-length"),
425 oc.getFloat("weights.reversal-penalty"));
426 }
427 const int carWalk = SUMOVehicleParserHelper::parseCarWalkTransfer(oc, MSDevice_Taxi::hasFleet() || MSNet::getInstance()->getInsertionControl().hasTaxiFlow());
428 const double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
429 MSTransportableRouter* transRouter = new MSTransportableRouter(MSNet::adaptIntermodalRouter, carWalk, taxiWait, routingAlgorithm, 0);
430 myRouterProvider = new MSRouterProvider(router, nullptr, transRouter, railRouter);
431#ifndef THREAD_POOL
432#ifdef HAVE_FOX
433 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
434 if (threadPool.size() > 0) {
435 const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
436 if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
437 for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
438 static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
439 }
440 }
441 }
442#endif
443#endif
444}
445
446
447void
448MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
449 const bool onInit, const bool silent, const Prohibitions& prohibited) {
450 if (myRouterProvider == nullptr) {
451 initRouter(&vehicle);
452 }
453 auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
454#ifndef THREAD_POOL
455#ifdef HAVE_FOX
456 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
457 if (threadPool.size() > 0) {
458 threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
459 return;
460 }
461#endif
462#endif
463 if (!prohibited.empty()) {
464 router.prohibit(prohibited);
465 }
466 try {
467 vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
468 } catch (ProcessError&) {
469 if (!silent) {
470 if (!prohibited.empty()) {
471 router.prohibit(Prohibitions());
472 }
473 throw;
474 }
475 }
476 if (!prohibited.empty()) {
477 router.prohibit(Prohibitions());
478 }
479}
480
481
482void
483MSRoutingEngine::reroute(MSTransportable& t, const SUMOTime currentTime, const std::string& info,
484 const bool onInit, const bool silent, const Prohibitions& prohibited) {
486#ifndef THREAD_POOL
487#ifdef HAVE_FOX
488 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
489 if (threadPool.size() > 0) {
490 // threadPool.add(new RoutingTask(t, currentTime, info, onInit, silent, prohibited));
491 return;
492 }
493#endif
494#endif
495 if (!prohibited.empty()) {
496 router.prohibit(prohibited);
497 }
498 try {
499 t.reroute(currentTime, info, router, onInit, myWithTaz, silent);
500 } catch (ProcessError&) {
501 if (!silent) {
502 if (!prohibited.empty()) {
503 router.prohibit(Prohibitions());
504 }
505 throw;
506 }
507 }
508 if (!prohibited.empty()) {
509 router.prohibit(Prohibitions());
510 }
511}
512
513
514void
515MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
516 myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
517}
518
519void
520MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
522 tc.first += travelTime;
523 tc.second += 1;
524}
525
526
528MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const Prohibitions& prohibited) {
529 if (myRouterProvider == nullptr) {
531 initEdgeWeights(svc);
532 initRouter();
533 }
534#ifndef THREAD_POOL
535#ifdef HAVE_FOX
536 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
537 if (threadPool.size() > 0) {
538 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
539 router.prohibit(prohibited);
540 return router;
541 }
542#else
543 UNUSED_PARAMETER(rngIndex);
544#endif
545#endif
546 myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
548}
549
550
552MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const Prohibitions& prohibited) {
553 if (myRouterProvider == nullptr) {
556 initRouter();
557 }
558#ifndef THREAD_POOL
559#ifdef HAVE_FOX
560 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
561 if (threadPool.size() > 0) {
562 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
563 router.prohibit(prohibited);
564 return router;
565 }
566#else
567 UNUSED_PARAMETER(rngIndex);
568#endif
569#endif
570 myRouterProvider->getIntermodalRouter().prohibit(prohibited);
572}
573
574
575void
577 myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
578 myPastEdgeSpeeds.clear();
579 myEdgeSpeeds.clear();
580 myEdgeTravelTimes.clear();
581 myPastEdgeBikeSpeeds.clear();
582 myEdgeBikeSpeeds.clear();
583 // @todo recheck. calling release crashes in parallel routing
584 //for (auto& item : myCachedRoutes) {
585 // item.second->release();
586 //}
587 myCachedRoutes.clear();
589#ifdef HAVE_FOX
590 if (MSGlobals::gNumThreads > 1) {
591 // router deletion is done in thread destructor
592 myRouterProvider = nullptr;
593 return;
594 }
595#endif
596 delete myRouterProvider;
597 myRouterProvider = nullptr;
598}
599
600
601void
603 if (myEdgeSpeeds.size() == 0) {
604 return;
605 }
610 for (const MSEdge* const e : edges) {
611 if (e->isDelayed()) {
612 const int id = e->getNumericalID();
614 out.writeAttr(SUMO_ATTR_ID, e->getID());
616 if (myAdaptationSteps > 0) {
618 }
619 if (myBikeSpeeds) {
621 if (myAdaptationSteps > 0) {
623 }
624 }
625 out.closeTag();
626 }
627 }
628 out.closeTag();
629}
630
631
632void
634 const MSEdge* const e = MSEdge::dictionary(attrs.getString(SUMO_ATTR_ID));
635 e->markDelayed();
636 const int id = e->getNumericalID();
637 bool checkedSteps = false;
638 bool checkedBikeSpeeds = false;
639 bool ok = true;
640 if ((int)myEdgeSpeeds.size() > id) {
641 myEdgeSpeeds[id] = attrs.get<double>(SUMO_ATTR_SPEED, nullptr, ok);
642 if (myBikeSpeeds) {
644 myEdgeBikeSpeeds[id] = attrs.get<double>(SUMO_ATTR_BIKESPEED, nullptr, ok);
645 } else if (!checkedBikeSpeeds) {
646 checkedBikeSpeeds = true;
647 WRITE_WARNING("Bike speeds missing in loaded state");
648 }
649 }
650 if (myAdaptationSteps > 0) {
651 const std::vector<double> speeds = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTSPEED, nullptr, ok);
652 if ((int)speeds.size() == myAdaptationSteps) {
653 myPastEdgeSpeeds[id] = speeds;
655 myPastEdgeBikeSpeeds[id] = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTBIKESPEED, nullptr, ok);
656 }
657 } else if (!checkedSteps) {
658 checkedSteps = true;
659 WRITE_WARNING("Number of adaptation speeds in loaded state doesn't match option --device.rerouting.adaptation-steps");
660 }
661 }
662 }
663}
664
665
666#ifdef HAVE_FOX
667void
668MSRoutingEngine::waitForAll() {
669#ifndef THREAD_POOL
670 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
671 if (threadPool.size() > 0) {
672 threadPool.waitAll();
673 }
674#endif
675}
676
677
678// ---------------------------------------------------------------------------
679// MSRoutingEngine::RoutingTask-methods
680// ---------------------------------------------------------------------------
681void
682MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
683 SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
684 if (!myProhibited.empty()) {
685 router.prohibit(myProhibited);
686 }
687 try {
688 myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
689 } catch (ProcessError&) {
690 if (!mySilent) {
691 if (!myProhibited.empty()) {
692 router.prohibit(Prohibitions());
693 }
694 throw;
695 }
696 }
697 if (!myProhibited.empty()) {
698 router.prohibit(Prohibitions());
699 }
700 const MSEdge* source = *myVehicle.getRoute().begin();
701 const MSEdge* dest = myVehicle.getRoute().getLastEdge();
702 if (source->isTazConnector() && dest->isTazConnector()) {
703 const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
704 FXMutexLock lock(myRouteCacheMutex);
706 MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
707 }
708 }
709}
710
711
712#endif
713
714
715/****************************************************************************/
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 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 SIMSTEP
Definition SUMOTime.h:61
#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_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 std::map< const E *, double > &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:1096
int getPriority() const
Returns the priority of the edge.
Definition MSEdge.h:336
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition MSEdge.cpp:1298
double getLength() const
return the length of the edge
Definition MSEdge.h:693
bool isTazConnector() const
Definition MSEdge.h:291
const std::string & getRoutingType() const
Returns the type of the edge.
Definition MSEdge.h:325
double getMinimumTravelTime(const SUMOVehicle *const veh) const
returns the minimum travel time for the given vehicle
Definition MSEdge.h:484
int getNumericalID() const
Returns the numerical id of the edge.
Definition MSEdge.h:306
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:1057
void markDelayed() const
Definition MSEdge.h:737
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:1760
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:187
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
Definition MSNet.h:495
double getPreference(const std::string &routingType, const SUMOVTypeParameter &pars) const
retriefe edge type specific routing preference
Definition MSNet.cpp:365
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:435
static void adaptIntermodalRouter(MSTransportableRouter &router)
Definition MSNet.cpp:1679
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 void addEdgeTravelTime(const MSEdge &edge, const SUMOTime travelTime)
record actual travel time for an edge
static void initWeightUpdate()
intialize period edge weight update
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.
std::map< const MSEdge *, double > Prohibitions
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 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
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 & 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 randHash(long long int x)
return a value scrambled value from [0, 1]
Definition RandHelper.h:269
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 long long int getRandomSeed() const =0
return an object-specific random constant
virtual const SUMOVTypeParameter & getVTypeParameter() const =0
Returns the object's "vehicle" type parameter.
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)
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