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