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/MSJunction.h>
30#include <microsim/MSEdge.h>
33#include <microsim/MSGlobals.h>
36#include <microsim/MSVehicle.h>
37#include <microsim/MSRoute.h>
39#include <mesosim/MEVehicle.h>
42#include <set>
59
60//#define DEBUG_SEPARATE_TURNS
61#define DEBUG_COND(obj) (obj->isSelected())
62
63// ===========================================================================
64// static member variables
65// ===========================================================================
66std::vector<double> MSRoutingEngine::myEdgeSpeeds;
67std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
68std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
69std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
70std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
80std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
82double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
86
88#ifdef HAVE_FOX
89FXMutex MSRoutingEngine::myRouteCacheMutex;
90#endif
94
95
96// ===========================================================================
97// method definitions
98// ===========================================================================
99void
101 if (myAdaptationInterval == -1) {
103 myLastAdaptation = lastAdaptation;
105 myWithTaz = oc.getBool("device.rerouting.with-taz");
106 myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
107 myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
108 const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
109 if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
110 SUMOTime nextAdaptation = -1;
111 if (lastAdaptation >= 0) {
112 nextAdaptation = lastAdaptation + myAdaptationInterval;
113 }
116 } else if (period > 0) {
117 WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
118 }
119 OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
120 }
121}
122
123
124void
127 if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
128 myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
129 }
130 if (myBikeSpeeds && svc == SVC_BICYCLE) {
132 } else {
134 }
135 if (lastAdaption >= 0) {
136 myLastAdaptation = lastAdaption;
137 }
138 if (index >= 0 && myAdaptationSteps > 0) {
139 assert(index < myAdaptationSteps);
141 }
142}
143
144
145void
147 if (oc.getFloat("weights.priority-factor") != 0) {
148 myPriorityFactor = oc.getFloat("weights.priority-factor");
149 if (myPriorityFactor < 0) {
150 throw ProcessError(TL("weights.priority-factor cannot be negative."));
151 }
152 myMinEdgePriority = std::numeric_limits<double>::max();
153 double maxEdgePriority = -std::numeric_limits<double>::max();
154 for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
155 maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
156 myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
157 }
158 myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
159 if (myEdgePriorityRange == 0) {
160 WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
162 }
163 }
164 myDynamicRandomness = oc.getBool("weights.random-factor.dynamic");
166}
167
168
169void
170MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
171 if (edgeSpeeds.empty()) {
173 const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
174 const double currentSecond = SIMTIME;
175 for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
176 while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
177 edgeSpeeds.push_back(0);
178 if (myAdaptationSteps > 0) {
179 pastEdgeSpeeds.push_back(std::vector<double>());
180 }
181 if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
182 myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
183 }
184 }
185 if (useLoaded) {
186 edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
187 } else {
188 edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
189 }
190 if (myAdaptationSteps > 0) {
191 pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
192 }
193 }
195 }
196}
197
198
199double
200MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
201 const int id = e->getNumericalID();
202 if (id < (int)myEdgeSpeeds.size()) {
203 return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
204 }
205 return e->getMinimumTravelTime(v);
206}
207
208
209double
210MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
211 const int id = e->getNumericalID();
212 if (id < (int)myEdgeBikeSpeeds.size()) {
213 return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
214 }
215 return e->getMinimumTravelTime(v);
216}
217
218
219double
220MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
221 double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
222 ? getEffort(e, v, t)
223 : getEffortBike(e, v, t));
224 applyExtras(e, v, SIMSTEP, effort);
225 return effort;
226}
227
228
229double
231 return edge->getLength() / myEffortFunc(edge, veh, 0);
232}
233
234
238 if (myBikeSpeeds) {
240 }
241 if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
243 }
244 {
245#ifdef HAVE_FOX
246 FXMutexLock lock(myRouteCacheMutex);
247#endif
248 myCachedRoutes.clear();
249 }
251 const double newWeightFactor = (double)(1. - myAdaptationWeight);
252 bool cchEdgeMoved = false;
253 for (const MSEdge* const e : edges) {
254 if (e->isDelayed()) {
255 const int id = e->getNumericalID();
256 double currSpeed = e->getMeanSpeed();
257 if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
258 currSpeed = patchSpeedForTurns(e, currSpeed);
259 }
260#ifdef DEBUG_SEPARATE_TURNS
261 if (DEBUG_COND(e->getLanes()[0])) {
262 std::cout << SIMTIME << " edge=" << e->getID()
263 << " meanSpeed=" << e->getMeanSpeed()
264 << " currSpeed=" << currSpeed
265 << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
266 << " oldAvg=" << myEdgeSpeeds[id]
267 << "\n";
268 }
269#endif
270 const double oldSmoothedSpeed = myEdgeSpeeds[id];
271 if (myAdaptationSteps > 0) {
272 // moving average
275 if (myBikeSpeeds) {
276 const double currBikeSpeed = e->getMeanSpeedBike();
278 myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
279 }
280 } else {
281 // exponential moving average
282 if (currSpeed != myEdgeSpeeds[id]) {
283 myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
284 }
285 if (myBikeSpeeds) {
286 const double currBikeSpeed = e->getMeanSpeedBike();
287 if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
288 myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
289 }
290 }
291 }
292 // sparse CCH re-customization: remember which edges actually
293 // moved; the update deadband is applied at the customize barrier
294 if (myCCHLive != nullptr && myEdgeSpeeds[id] != oldSmoothedSpeed) {
296 cchEdgeMoved = true;
297 }
298 }
299 }
300 if (myAdaptationSteps > 0) {
302 }
303 myLastAdaptation = currentTime;
304 // The device's CCH customization barrier: re-customize the metrics from
305 // the freshly updated speed tables and publish (double-buffered). Runs
306 // on the main thread after the speed update; no worker query is in
307 // flight at this point. The family skips quiet barriers and runs that
308 // never route (see CCHMetricFamily::atBarrier: measured on Lausanne, the
309 // unconditional per-tick customize was 80% of meso wall time at
310 // adaptation-interval 2, and ran even with rerouting probability 0).
311 if (myCCHLive != nullptr) {
312 myCCHLive->atBarrier(STEPS2TIME(currentTime), cchEdgeMoved);
313 }
314 if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
315 OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
317 dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
318 dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
320 for (const MSEdge* e : edges) {
322 dev.writeAttr(SUMO_ATTR_ID, e->getID());
323 dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
324 if (myBikeSpeeds) {
325 // @note edge-priority is not included here
326 dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
327 }
328 dev.closeTag();
329 }
330 dev.closeTag();
331 }
333}
334
335
338 if (myCCHGraph == nullptr) {
339 myCCHGraph = new MSCCHGraph(MSEdge::getAllEdges()); // union topology; class masks prime at first fill
340 }
341 return myCCHGraph;
342}
343
344
345void
347 if (myCCHLive != nullptr) {
348 return; // device-side state built once (the graph alone may already
349 // exist for MSNet's free-flow router)
350 }
351 // One LIVE metric per vehicle TYPE known when routing starts (see
352 // utils/router/CCHMetricFamily.h for the keying and buffer semantics).
353 // All types share ONE CCH topology (the union); route files stream, so
354 // types appearing later register through the family's wanted list and
355 // get their metric at the next customization barrier.
360 oc.getFloat("device.rerouting.cch-update-threshold.factor"),
361 STEPS2TIME(string2time(oc.getString("device.rerouting.cch-update-threshold.constant"))),
363 oc.getInt("device.rerouting.cch-ensemble"));
364 std::vector<std::string> vtypeIDs;
366 for (const std::string& id : vtypeIDs) {
367 const MSVehicleType* vt = MSNet::getInstance()->getVehicleControl().getVType(id, nullptr, true);
368 if (vt != nullptr && !vt->isVehicleSpecific()) {
369 myCCHLive->seedKey(vt);
370 }
371 }
372 // publish initial metrics so the first queries succeed
373 myCCHLive->customize(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()));
374}
375
376
379 // The effort-reference vehicle: constructed DIRECTLY (what buildVehicle
380 // does minus initVehicle), so it is never counted in the vehicle
381 // statistics, never given devices and never inserted -- it exists only
382 // so every metric fill evaluates the same reference. The mean speed
383 // factor makes it deterministic (the findRoute precedent) and the fixed
384 // id makes the frozen weights.random-factor realization reproducible
385 // (the random seed is a hash of the id).
387 // slot 0 keeps the historical id (and with it the frozen random-factor
388 // realization); ensemble slots differ only in the id, which seeds their
389 // own realization -- see CCHMetricFamily::RefVehicleFactory
390 pars->id = "cchRef:" + type->getID() + (slot == 0 ? "" : ":" + toString(slot));
391 const MSEdge* refEdge = nullptr;
392 for (const MSEdge* e : MSEdge::getAllEdges()) {
393 if (!e->isInternal() && !e->isTazConnector()) {
394 refEdge = e;
395 break;
396 }
397 }
398 ConstMSRoutePtr route = std::make_shared<MSRoute>(pars->id, ConstMSEdgeVector({refEdge}), false, nullptr, StopParVector());
400 return new MEVehicle(pars, route, const_cast<MSVehicleType*>(type),
401 type->getSpeedFactor().getParameter(0));
402 }
403 return new MSVehicle(pars, route, const_cast<MSVehicleType*>(type),
404 type->getSpeedFactor().getParameter(0));
405}
406
407
408void
410 if (myCCHGraph == nullptr) {
411 return;
412 }
413 // the primed connection masks reflect the OLD successor lists; the next
414 // fill of either family re-primes from the live ones. Safe to do right
415 // here: masks are only read at fill time, and every fill runs on the
416 // main thread (the device barrier, the free-flow repair) -- never on a
417 // query thread.
419 if (myCCHFreeflow != nullptr) {
421 }
422 if (myCCHLive != nullptr) {
424 }
425}
426
427
430 // the published metrics always track the live speeds; the query time
431 // only matters for duarouter's per-weight-period metrics. Lookup is by
432 // vehicle TYPE (the metric's exactness key); a vehicle-specific type
433 // (TraCI-modified singular copy) routes on the exact fallback rather
434 // than on another type's metric.
435 if (veh == nullptr || myCCHLive == nullptr) {
436 return nullptr;
437 }
438 const MSVehicleType* type = &veh->getVehicleType();
439 if (type->isVehicleSpecific()) {
440 return nullptr;
441 }
442 return myCCHLive->published(type, veh->getID());
443}
444
445
448 // MAIN-THREAD ONLY (see header): MSNet's routers serve TraCI, triggers
449 // and the GUI, never the rerouting worker threads, so the family's lazy
450 // creation and stale repair may run synchronously right here.
451 if (veh == nullptr) {
452 return nullptr;
453 }
454 // Everything MSNet::getTravelTime reads ahead of the free-flow layer is
455 // per-vehicle and cannot live in a shared metric -> exact fallback:
456 // individual TraCI edge weights, global TraCI edge weights, a routing
457 // mode other than DEFAULT (the AGGREGATED modes belong to the device
458 // metrics; the transient-permission modes already fall back inside
459 // CCHRouter::compute).
462 return nullptr;
463 }
464 const MSVehicle* const msVeh = dynamic_cast<const MSVehicle*>(veh);
465 if (msVeh != nullptr && !msVeh->getWeightsStorage().empty()) {
466 return nullptr;
467 }
468 const MSVehicleType* type = &veh->getVehicleType();
469 if (type->isVehicleSpecific()) {
470 return nullptr;
471 }
472 if (myCCHFreeflow == nullptr) {
473 // free-flow efforts are static: a STATIC family with a single weight
474 // period, lazily customized per type on first query
478 }
479 return myCCHFreeflow->get(type, type->getVehicleClass(),
481}
482
483
484double
485MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
486 const double length = edge->getLength();
487 double maxSpeed = 0;
488 for (const auto& pair : edge->getViaSuccessors()) {
489 if (pair.second == nullptr) {
490 continue;
491 }
492 TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
493 if (tc.second > 0) {
494 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
495 maxSpeed = MAX2(avgSpeed, maxSpeed);
496 }
497 }
498 if (maxSpeed > 0) {
499 // perform correction
500 const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
501 for (const auto& pair : edge->getViaSuccessors()) {
502 if (pair.second == nullptr) {
503 continue;
504 }
505 const int iid = pair.second->getNumericalID();
507 if (tc.second > 0) {
508 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
509 if (avgSpeed < correctedSpeed) {
510 double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
511 internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
512 const double origInternalSpeed = myEdgeSpeeds[iid];
513 const double newInternalSpeed = pair.second->getLength() / internalTT;
514 const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
515
516 myEdgeSpeeds[iid] = newInternalSpeed;
517 // to ensure myEdgeSpeed reverts to the speed limit
518 // when there are no updates, we also have to patch
519 // myPastEdgeSpeeds with a virtual value that is consistent
520 // with the updated speed
521 // note: internal edges were handled before the normal ones
522 const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
523 myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
524
525#ifdef DEBUG_SEPARATE_TURNS
526 if (DEBUG_COND(pair.second->getLanes()[0])) {
527 std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
528 << " origSpeed=" << currSpeed
529 << " maxSpeed=" << maxSpeed
530 << " correctedSpeed=" << correctedSpeed
531 << " avgSpeed=" << avgSpeed
532 << " internalTT=" << internalTT
533 << " internalSpeed=" << origInternalSpeed
534 << " newInternalSpeed=" << newInternalSpeed
535 << " virtualSpeed=" << virtualSpeed
536 << "\n";
537 }
538#endif
539 }
540 if (myAdaptationStepsIndex == 0) {
541 tc.first = 0;
542 tc.second = 0;
543 }
544 }
545 }
546 return correctedSpeed;
547 }
548 return currSpeed;
549}
550
551
553MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
554#ifdef HAVE_FOX
555 // worker threads insert into the cache concurrently (RoutingTask::run)
556 FXMutexLock lock(myRouteCacheMutex);
557#endif
558 auto routeIt = myCachedRoutes.find(key);
559 if (routeIt != myCachedRoutes.end()) {
560 return routeIt->second;
561 }
562 return nullptr;
563}
564
565
566void
569 const std::string routingAlgorithm = oc.getString("routing-algorithm");
570 const bool hasPermissions = MSNet::getInstance()->hasPermissions();
571 myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
573
575 if (routingAlgorithm == "dijkstra") {
576 router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
577 } else if (routingAlgorithm == "astar") {
579 std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
580 if (oc.isSet("astar.all-distances")) {
581 lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
582 } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
583 const double speedFactor = vehicle->getChosenSpeedFactor();
584 // we need an exemplary vehicle with speedFactor 1
585 vehicle->setChosenSpeedFactor(1);
588 string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
589 lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
590 nullptr, vehicle, "", oc.getInt("device.rerouting.threads"), MSNet::getInstance()->getMapMatcher());
591 vehicle->setChosenSpeedFactor(speedFactor);
592 }
593 router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
594 } else if (routingAlgorithm == "CH" && !hasPermissions) {
597 MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
598 } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
599 // use CHWrapper instead of CH if the net has permissions
603 string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
604 } else if (routingAlgorithm == "CCH") {
605 // CCH metrics are keyed by vehicle TYPE and filled with a reference
606 // vehicle of the type (customizeCCH), mirroring duarouter's
607 // RODUACCHMetrics: type/class-specific routing preferences, the
608 // bicycle speed table, the type's maximum speed and the static
609 // priority multiplier are captured exactly per metric.
610 // weights.random-factor freezes one realization per metric -- the
611 // same approximation CHRouterWrapper makes when building its
612 // hierarchies; exact per-vehicle randomization remains the domain of
613 // dijkstra and astar.
614 initCCH(); // build the immutable topology + publish an initial metric (once)
615 // embedded fallback for non-passenger / prohibited / unreachable queries
620 } else {
621 throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
622 }
623
624 RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
625 if (MSNet::getInstance()->hasBidiEdges()) {
626 railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false,
627 oc.getFloat("railway.max-train-length"),
628 oc.getFloat("weights.reversal-penalty"));
629 }
630 const int carWalk = SUMOVehicleParserHelper::parseCarWalkTransfer(oc, MSDevice_Taxi::hasFleet() || MSNet::getInstance()->getInsertionControl().hasTaxiFlow());
631 const double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
632 MSTransportableRouter* transRouter = new MSTransportableRouter(MSNet::adaptIntermodalRouter, carWalk, taxiWait, routingAlgorithm, 0);
633 myRouterProvider = new MSRouterProvider(router, nullptr, transRouter, railRouter);
634#ifndef THREAD_POOL
635#ifdef HAVE_FOX
636 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
637 if (threadPool.size() > 0) {
638 const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
639 if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
640 for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
641 static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
642 }
643 }
644 }
645#endif
646#endif
647}
648
649
650void
651MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
652 const bool onInit, const bool silent, const Prohibitions& prohibited) {
653 if (myRouterProvider == nullptr) {
654 initRouter(&vehicle);
655 }
656 auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
657#ifndef THREAD_POOL
658#ifdef HAVE_FOX
659 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
660 if (threadPool.size() > 0) {
661 threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
662 return;
663 }
664#endif
665#endif
666 if (!prohibited.empty()) {
667 router.prohibit(prohibited);
668 }
669 try {
670 vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
671 } catch (ProcessError&) {
672 if (!silent) {
673 if (!prohibited.empty()) {
674 router.prohibit(Prohibitions());
675 }
676 throw;
677 }
678 }
679 if (!prohibited.empty()) {
680 router.prohibit(Prohibitions());
681 }
682}
683
684
685void
686MSRoutingEngine::reroute(MSTransportable& t, const SUMOTime currentTime, const std::string& info,
687 const bool onInit, const bool silent, const Prohibitions& prohibited) {
689#ifndef THREAD_POOL
690#ifdef HAVE_FOX
691 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
692 if (threadPool.size() > 0) {
693 // threadPool.add(new RoutingTask(t, currentTime, info, onInit, silent, prohibited));
694 return;
695 }
696#endif
697#endif
698 if (!prohibited.empty()) {
699 router.prohibit(prohibited);
700 }
701 try {
702 t.reroute(currentTime, info, router, onInit, myWithTaz, silent);
703 } catch (ProcessError&) {
704 if (!silent) {
705 if (!prohibited.empty()) {
706 router.prohibit(Prohibitions());
707 }
708 throw;
709 }
710 }
711 if (!prohibited.empty()) {
712 router.prohibit(Prohibitions());
713 }
714}
715
716
717void
718MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
719 myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
720}
721
722void
723MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
725 tc.first += travelTime;
726 tc.second += 1;
727}
728
729
731MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const Prohibitions& prohibited) {
732 if (myRouterProvider == nullptr) {
734 initEdgeWeights(svc);
735 initRouter();
736 }
737#ifndef THREAD_POOL
738#ifdef HAVE_FOX
739 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
740 if (threadPool.size() > 0) {
741 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
742 router.prohibit(prohibited);
743 return router;
744 }
745#else
746 UNUSED_PARAMETER(rngIndex);
747#endif
748#endif
749 myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
751}
752
753
755MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const Prohibitions& prohibited) {
756 if (myRouterProvider == nullptr) {
759 initRouter();
760 }
761#ifndef THREAD_POOL
762#ifdef HAVE_FOX
763 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
764 if (threadPool.size() > 0) {
765 auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
766 router.prohibit(prohibited);
767 return router;
768 }
769#else
770 UNUSED_PARAMETER(rngIndex);
771#endif
772#endif
773 myRouterProvider->getIntermodalRouter().prohibit(prohibited);
775}
776
777
778void
780 // free the CCH state so a subsequent load (libsumo / GUI reload) rebuilds
781 // it against the new network; the router clones referencing it were
782 // deleted together with the worker threads / router provider.
783 // Deleting the metric families' owned ref vehicles dereferences their
784 // MSVehicleType*, so this must run BEFORE MSNet deletes its
785 // MSVehicleControl (see the call in ~MSNet); the nullptr checks below
786 // make a second call from cleanup() a safe no-op.
787 delete myCCHLive;
788 myCCHLive = nullptr;
789 delete myCCHFreeflow;
790 myCCHFreeflow = nullptr;
791 delete myCCHGraph;
792 myCCHGraph = nullptr;
793}
794
795
796void
798 myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
799 myPastEdgeSpeeds.clear();
800 myEdgeSpeeds.clear();
801 myEdgeTravelTimes.clear();
802 myPastEdgeBikeSpeeds.clear();
803 myEdgeBikeSpeeds.clear();
804 // @todo recheck. calling release crashes in parallel routing
805 //for (auto& item : myCachedRoutes) {
806 // item.second->release();
807 //}
808 {
809#ifdef HAVE_FOX
810 FXMutexLock lock(myRouteCacheMutex);
811#endif
812 myCachedRoutes.clear();
813 }
815 cleanupCCH();
816#ifdef HAVE_FOX
817 if (MSGlobals::gNumThreads > 1) {
818 // router deletion is done in thread destructor
819 myRouterProvider = nullptr;
820 return;
821 }
822#endif
823 delete myRouterProvider;
824 myRouterProvider = nullptr;
825}
826
827
828void
830 if (myEdgeSpeeds.size() == 0) {
831 return;
832 }
837 for (const MSEdge* const e : edges) {
838 if (e->isDelayed()) {
839 const int id = e->getNumericalID();
841 out.writeAttr(SUMO_ATTR_ID, e->getID());
843 if (myAdaptationSteps > 0) {
845 }
846 if (myBikeSpeeds) {
848 if (myAdaptationSteps > 0) {
850 }
851 }
852 out.closeTag();
853 }
854 }
855 out.closeTag();
856}
857
858
859void
861 const MSEdge* const e = MSEdge::dictionary(attrs.getString(SUMO_ATTR_ID));
862 e->markDelayed();
863 const int id = e->getNumericalID();
864 bool checkedSteps = false;
865 bool checkedBikeSpeeds = false;
866 bool ok = true;
867 if ((int)myEdgeSpeeds.size() > id) {
868 myEdgeSpeeds[id] = attrs.get<double>(SUMO_ATTR_SPEED, nullptr, ok);
869 if (myBikeSpeeds) {
871 myEdgeBikeSpeeds[id] = attrs.get<double>(SUMO_ATTR_BIKESPEED, nullptr, ok);
872 } else if (!checkedBikeSpeeds) {
873 checkedBikeSpeeds = true;
874 WRITE_WARNING("Bike speeds missing in loaded state");
875 }
876 }
877 if (myAdaptationSteps > 0) {
878 const std::vector<double> speeds = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTSPEED, nullptr, ok);
879 if ((int)speeds.size() == myAdaptationSteps) {
880 myPastEdgeSpeeds[id] = speeds;
882 myPastEdgeBikeSpeeds[id] = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTBIKESPEED, nullptr, ok);
883 }
884 } else if (!checkedSteps) {
885 checkedSteps = true;
886 WRITE_WARNING("Number of adaptation speeds in loaded state doesn't match option --device.rerouting.adaptation-steps");
887 }
888 }
889 }
890}
891
892
893#ifdef HAVE_FOX
894void
895MSRoutingEngine::waitForAll() {
896#ifndef THREAD_POOL
897 MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
898 if (threadPool.size() > 0) {
899 threadPool.waitAll();
900 }
901#endif
902}
903
904
905// ---------------------------------------------------------------------------
906// MSRoutingEngine::RoutingTask-methods
907// ---------------------------------------------------------------------------
908void
909MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
910 SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
911 if (!myProhibited.empty()) {
912 router.prohibit(myProhibited);
913 }
914 try {
915 myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
916 } catch (ProcessError&) {
917 if (!mySilent) {
918 if (!myProhibited.empty()) {
919 router.prohibit(Prohibitions());
920 }
921 throw;
922 }
923 }
924 if (!myProhibited.empty()) {
925 router.prohibit(Prohibitions());
926 }
927 const MSEdge* source = *myVehicle.getRoute().begin();
928 const MSEdge* dest = myVehicle.getRoute().getLastEdge();
929 if (source->isTazConnector() && dest->isTazConnector()) {
930 const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
931 FXMutexLock lock(myRouteCacheMutex);
933 MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
934 }
935 }
936}
937
938
939#endif
940
941
942/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
CCHMetricFamily< MSEdge, SUMOVehicle, MSVehicleType > MSCCHMetricFamily
the per-vehicle-type CCH metric store (utils/router/CCHMetricFamily.h)
RouterProvider< MSEdge, MSLane, MSJunction, SUMOVehicle > MSRouterProvider
IntermodalRouter< MSEdge, MSLane, MSJunction, SUMOVehicle > MSTransportableRouter
CCHGraph< MSEdge, SUMOVehicle > MSCCHGraph
the MSEdge instantiation of the CCH graph mapping (utils/router/CCHGraph.h)
#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:69
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:70
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
std::vector< SUMOVehicleParameter::Stop > StopParVector
@ 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
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
Computes the shortest path through a network using the A* algorithm.
Definition AStarRouter.h:76
Metric-independent RoutingKit CCH topology over the PURE road graph.
Definition CCHGraph.h:97
void invalidateClassMasks() const
Drop every primed connection mask so the next fill re-primes from the CURRENT successor lists.
Definition CCHGraph.h:365
per-vehicle-type CCH metric store over a shared CCHGraph
MetricPtr get(const K *key, SUMOVehicleClass vClass, SUMOTime time, const V *veh)
the metric for (type key, period of time), built on the first query of the pair; nullptr before init....
void seedKey(const K *key)
allocate the metric state (all ensemble slots) for one type; call only while no query is in flight (s...
void atBarrier(double now, bool effortsMoved)
the owner's customization barrier: bump the speed epoch when an effort moved and re-customize when it...
void customize(double now)
refill + customize + publish every type's metric from the live efforts and permissions....
void invalidateEdge(const E *e)
a runtime permission change (closure / re-opening) hit this edge: queue it bypassing the deadband and...
MetricPtr published(const K *key, const std::string &vehID)
the published metric for a type key and querying vehicle id (the id picks the ensemble slot – see the...
void flagPermissionsStale()
flagStale() under the simulation's name for the permission case
void markDirty(const E *e)
queue an edge whose gate effort changed (both buffers; the deadband applies later,...
Contraction-hierarchy router over the edge graph mapped by GRAPH.
Definition CCHRouter.h:83
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.
double getParameter(const int index) const
Returns the nth parameter of this distribution.
void prohibit(const _Prohibitions &toProhibit)
A vehicle from the mesoscopic point of view.
Definition MEVehicle.h:42
A pool of worker threads which distributes the tasks and collects the results.
void waitAll(const bool deleteFinished=true)
waits for all tasks to be finished
void add(Task *const t, int index=-1)
Gives a number to the given task and assigns it to the worker with the given index....
const std::vector< MFXWorkerThread * > & getWorkers()
int size() const
Returns the number of threads in the pool.
A thread repeatingly calculating incoming tasks.
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle's internal edge travel times/efforts container.
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:1144
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition MSEdge.cpp:1353
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:1105
void markDelayed() const
Definition MSEdge.h:750
bool empty() const
Returns whether neither travel times nor efforts are stored.
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUseMesoSim
Definition MSGlobals.h:106
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:1822
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:201
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:169
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition MSNet.cpp:1334
bool hasPermissions() const
Returns whether the network has specific vehicle class permissions.
Definition MSNet.h:213
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:402
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition MSNet.h:445
static void adaptIntermodalRouter(MSTransportableRouter &router)
Definition MSNet.cpp:1741
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 SUMOVehicle * buildCCHRefVehicle(const MSVehicleType *type, int slot)
construct the unregistered effort-reference vehicle for a type: never counted, inserted or given devi...
static MSCCHGraph * myCCHGraph
the immutable shared CCH topology (built once), or nullptr if inactive
static MSCCHGraph * ensureCCHGraph()
the shared CCH topology, built on first demand (used by MSNet::getRouterTT to construct its CCH route...
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 void cleanupCCH()
tears down the CCH state (myCCHLive/myCCHFreeflow/myCCHGraph) only – the ref vehicles owned by the CC...
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 MSCCHMetricFamily * myCCHLive
the rerouting device's LIVE metric family over the adaptive speed tables (see utils/router/CCHMetricF...
static void _initEdgeWeights(std::vector< double > &edgeSpeeds, std::vector< std::vector< double > > &pastEdgeSpeeds)
initialized edge speed storage into the given containers
static void initCCH()
build the shared CCH + the live family with one metric per loaded type, publish initial metrics
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 const RoutingKit::CustomizableContractionHierarchyMetric * getPublishedCCHMetric(SUMOVehicleClass vClass, SUMOTime time, const SUMOVehicle *veh)
the currently published (customized) CCH metric FOR A GIVEN vehicle class, or nullptr if that class h...
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 MSCCHMetricFamily * myCCHFreeflow
the STATIC free-flow metric family behind MSNet's routers (TraCI / triggers / GUI,...
static void initRouter(SUMOVehicle *vehicle=nullptr)
static SUMOAbstractRouter< MSEdge, SUMOVehicle >::Operation myEffortFunc
static void invalidateCCHEdge(const MSEdge *e)
a runtime permission change (closure / re-opening) hit this edge: invalidate the graph's primed conne...
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 const RoutingKit::CustomizableContractionHierarchyMetric * getFreeflowCCHMetric(SUMOVehicleClass vClass, SUMOTime time, const SUMOVehicle *veh)
the free-flow CCH metric for MSNet's routers (TraCI / triggers / GUI), keyed by vehicle type and fill...
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)
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
void insertVTypeIDs(std::vector< std::string > &into) const
Inserts ids of all known vehicle types and vehicle type distributions to the given vector.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
The car-following model and parameter.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
const std::string & getID() const
Returns the name of the vehicle type.
const Distribution_Parameterized & getSpeedFactor() const
Returns this type's speed factor.
bool isVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
const std::string & getID() const
Returns the id.
Definition Named.h:73
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, const bool escape=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 const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual double getChosenSpeedFactor() const =0
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual int getRoutingMode() const =0
return routing mode (configures router choice but also handling of transient permission changes)
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
Structure representing possible vehicle parameter.
std::string id
The vehicle's id.
static int parseCarWalkTransfer(const OptionsCont &oc, const bool hasTaxi)
A wrapper for a Command function.
#define UNUSED_PARAMETER(x)
#define DEBUG_COND
TRACI_CONST int ROUTING_MODE_DEFAULT
@ key
the parser read a key of a value in an object