LCOV - code coverage report
Current view: top level - src/microsim/devices - MSRoutingEngine.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 90.4 % 332 300
Test Date: 2026-05-24 16:29:35 Functions: 100.0 % 23 23

            Line data    Source code
       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              : /****************************************************************************/
      14              : /// @file    MSRoutingEngine.cpp
      15              : /// @author  Michael Behrisch
      16              : /// @author  Daniel Krajzewicz
      17              : /// @author  Laura Bieker
      18              : /// @author  Christoph Sommer
      19              : /// @author  Jakob Erdmann
      20              : /// @date    Tue, 04 Dec 2007
      21              : ///
      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>
      30              : #include <microsim/MSEdgeControl.h>
      31              : #include <microsim/MSEventControl.h>
      32              : #include <microsim/MSGlobals.h>
      33              : #include <microsim/MSVehicleControl.h>
      34              : #include <microsim/MSInsertionControl.h>
      35              : #include <microsim/transportables/MSTransportable.h>
      36              : #include <microsim/devices/MSDevice_Taxi.h>
      37              : #include <utils/options/OptionsCont.h>
      38              : #include <utils/common/WrappingCommand.h>
      39              : #include <utils/common/StaticCommand.h>
      40              : #include <utils/common/StringUtils.h>
      41              : #include <utils/xml/SUMOSAXAttributes.h>
      42              : #include <utils/router/DijkstraRouter.h>
      43              : #include <utils/router/AStarRouter.h>
      44              : #include <utils/router/CHRouter.h>
      45              : #include <utils/router/CHRouterWrapper.h>
      46              : #include <utils/vehicle/SUMOVehicleParserHelper.h>
      47              : 
      48              : //#define DEBUG_SEPARATE_TURNS
      49              : #define DEBUG_COND(obj) (obj->isSelected())
      50              : 
      51              : // ===========================================================================
      52              : // static member variables
      53              : // ===========================================================================
      54              : std::vector<double> MSRoutingEngine::myEdgeSpeeds;
      55              : std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
      56              : std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
      57              : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
      58              : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
      59              : Command* MSRoutingEngine::myEdgeWeightSettingCommand = nullptr;
      60              : double MSRoutingEngine::myAdaptationWeight(0);
      61              : int MSRoutingEngine::myAdaptationSteps;
      62              : int MSRoutingEngine::myAdaptationStepsIndex = 0;
      63              : SUMOTime MSRoutingEngine::myAdaptationInterval = -1;
      64              : SUMOTime MSRoutingEngine::myLastAdaptation = -1;
      65              : bool MSRoutingEngine::myWithTaz;
      66              : bool MSRoutingEngine::myBikeSpeeds;
      67              : MSRouterProvider* MSRoutingEngine::myRouterProvider = nullptr;
      68              : std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
      69              : double MSRoutingEngine::myPriorityFactor(0);
      70              : double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
      71              : double MSRoutingEngine::myEdgePriorityRange(0);
      72              : bool MSRoutingEngine::myDynamicRandomness(false);
      73              : bool MSRoutingEngine::myHaveExtras(false);
      74              : 
      75              : SUMOAbstractRouter<MSEdge, SUMOVehicle>::Operation MSRoutingEngine::myEffortFunc = &MSRoutingEngine::getEffort;
      76              : #ifdef HAVE_FOX
      77              : FXMutex MSRoutingEngine::myRouteCacheMutex;
      78              : #endif
      79              : 
      80              : 
      81              : // ===========================================================================
      82              : // method definitions
      83              : // ===========================================================================
      84              : void
      85      1389780 : MSRoutingEngine::initWeightUpdate(SUMOTime lastAdaptation) {
      86      1389780 :     if (myAdaptationInterval == -1) {
      87         7891 :         myEdgeWeightSettingCommand = nullptr;
      88         7891 :         myLastAdaptation = lastAdaptation;
      89         7891 :         const OptionsCont& oc = OptionsCont::getOptions();
      90         7891 :         myWithTaz = oc.getBool("device.rerouting.with-taz");
      91         7891 :         myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
      92         7891 :         myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
      93         7891 :         const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
      94         7891 :         if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
      95              :             SUMOTime nextAdaptation = -1;
      96         7823 :             if (lastAdaptation >= 0) {
      97            5 :                 nextAdaptation = lastAdaptation + myAdaptationInterval;
      98              :             }
      99         7823 :             myEdgeWeightSettingCommand = new StaticCommand<MSRoutingEngine>(&MSRoutingEngine::adaptEdgeEfforts);
     100         7823 :             MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myEdgeWeightSettingCommand, nextAdaptation);
     101         7891 :         } else if (period > 0) {
     102            0 :             WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
     103              :         }
     104        15782 :         OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
     105              :     }
     106      1389780 : }
     107              : 
     108              : 
     109              : void
     110     14021265 : MSRoutingEngine::initEdgeWeights(SUMOVehicleClass svc, SUMOTime lastAdaption, int index) {
     111     14021265 :     const OptionsCont& oc = OptionsCont::getOptions();
     112     14041872 :     if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
     113     14000658 :         myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
     114              :     }
     115     14021265 :     if (myBikeSpeeds && svc == SVC_BICYCLE) {
     116          294 :         _initEdgeWeights(myEdgeBikeSpeeds, myPastEdgeBikeSpeeds);
     117              :     } else {
     118     14020971 :         _initEdgeWeights(myEdgeSpeeds, myPastEdgeSpeeds);
     119              :     }
     120     14021265 :     if (lastAdaption >= 0) {
     121          189 :         myLastAdaptation = lastAdaption;
     122              :     }
     123     14021265 :     if (index >= 0 && myAdaptationSteps > 0) {
     124              :         assert(index < myAdaptationSteps);
     125          189 :         myAdaptationStepsIndex = index;
     126              :     }
     127     14021265 : }
     128              : 
     129              : 
     130              : void
     131        41104 : MSRoutingEngine::initWeightConstants(const OptionsCont& oc) {
     132        82208 :     if (oc.getFloat("weights.priority-factor") != 0) {
     133           35 :         myPriorityFactor = oc.getFloat("weights.priority-factor");
     134           35 :         if (myPriorityFactor < 0) {
     135            0 :             throw ProcessError(TL("weights.priority-factor cannot be negative."));
     136              :         }
     137           35 :         myMinEdgePriority = std::numeric_limits<double>::max();
     138              :         double maxEdgePriority = -std::numeric_limits<double>::max();
     139          364 :         for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
     140          329 :             maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
     141          553 :             myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
     142              :         }
     143           35 :         myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
     144           35 :         if (myEdgePriorityRange == 0) {
     145            0 :             WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
     146            0 :             myPriorityFactor = 0;
     147              :         }
     148              :     }
     149        41104 :     myDynamicRandomness = oc.getBool("weights.random-factor.dynamic");
     150        41104 :     myHaveExtras = gRoutingPreferences || myPriorityFactor != 0 || gWeightsRandomFactor != 0;
     151        41104 : }
     152              : 
     153              : 
     154              : void
     155     14021265 : MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
     156     14021265 :     if (edgeSpeeds.empty()) {
     157         7806 :         const OptionsCont& oc = OptionsCont::getOptions();
     158         7806 :         const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
     159         7806 :         const double currentSecond = SIMTIME;
     160       772241 :         for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
     161      1528870 :             while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
     162       764435 :                 edgeSpeeds.push_back(0);
     163       764435 :                 if (myAdaptationSteps > 0) {
     164       763749 :                     pastEdgeSpeeds.push_back(std::vector<double>());
     165              :                 }
     166       766080 :                 if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
     167         1645 :                     myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
     168              :                 }
     169              :             }
     170       764435 :             if (useLoaded) {
     171          114 :                 edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
     172              :             } else {
     173       764321 :                 edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
     174              :             }
     175       764435 :             if (myAdaptationSteps > 0) {
     176       763749 :                 pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
     177              :             }
     178              :         }
     179         7806 :         myLastAdaptation = MSNet::getInstance()->getCurrentTimeStep();
     180              :     }
     181     14021265 : }
     182              : 
     183              : 
     184              : double
     185    211039411 : MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
     186              :     const int id = e->getNumericalID();
     187    211039411 :     if (id < (int)myEdgeSpeeds.size()) {
     188    203340149 :         return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
     189              :     }
     190      7930578 :     return e->getMinimumTravelTime(v);
     191              : }
     192              : 
     193              : 
     194              : double
     195         3088 : MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
     196              :     const int id = e->getNumericalID();
     197         3088 :     if (id < (int)myEdgeBikeSpeeds.size()) {
     198         3088 :         return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
     199              :     }
     200            0 :     return e->getMinimumTravelTime(v);
     201              : }
     202              : 
     203              : 
     204              : double
     205        73079 : MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
     206         5054 :     double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
     207        76613 :                      ? getEffort(e, v, t)
     208         1520 :                      : getEffortBike(e, v, t));
     209        73079 :     applyExtras(e, v, SIMSTEP, effort);
     210        73079 :     return effort;
     211              : }
     212              : 
     213              : 
     214              : double
     215         4240 : MSRoutingEngine::getAssumedSpeed(const MSEdge* edge, const SUMOVehicle* veh) {
     216         4240 :     return edge->getLength() / myEffortFunc(edge, veh, 0);
     217              : }
     218              : 
     219              : 
     220              : SUMOTime
     221     11870742 : MSRoutingEngine::adaptEdgeEfforts(SUMOTime currentTime) {
     222     11870742 :     initEdgeWeights(SVC_PASSENGER);
     223     11870742 :     if (myBikeSpeeds) {
     224          224 :         initEdgeWeights(SVC_BICYCLE);
     225              :     }
     226     11870742 :     if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
     227        37533 :         return myAdaptationInterval;
     228              :     }
     229              :     myCachedRoutes.clear();
     230     11833209 :     const MSEdgeVector& edges = MSNet::getInstance()->getEdgeControl().getEdges();
     231     11833209 :     const double newWeightFactor = (double)(1. - myAdaptationWeight);
     232    767783552 :     for (const MSEdge* const e : edges) {
     233      8709266 :         if (e->isDelayed()) {
     234              :             const int id = e->getNumericalID();
     235    188027495 :             double currSpeed = e->getMeanSpeed();
     236    188027495 :             if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
     237       161049 :                 currSpeed = patchSpeedForTurns(e, currSpeed);
     238              :             }
     239              : #ifdef DEBUG_SEPARATE_TURNS
     240              :             if (DEBUG_COND(e->getLanes()[0])) {
     241              :                 std::cout << SIMTIME << " edge=" << e->getID()
     242              :                           << " meanSpeed=" << e->getMeanSpeed()
     243              :                           << " currSpeed=" << currSpeed
     244              :                           << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
     245              :                           << " oldAvg=" << myEdgeSpeeds[id]
     246              :                           << "\n";
     247              :             }
     248              : #endif
     249    188027495 :             if (myAdaptationSteps > 0) {
     250              :                 // moving average
     251    187964247 :                 myEdgeSpeeds[id] += (currSpeed - myPastEdgeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
     252    187964247 :                 myPastEdgeSpeeds[id][myAdaptationStepsIndex] = currSpeed;
     253    187964247 :                 if (myBikeSpeeds) {
     254            0 :                     const double currBikeSpeed = e->getMeanSpeedBike();
     255            0 :                     myEdgeBikeSpeeds[id] += (currBikeSpeed - myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
     256            0 :                     myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
     257              :                 }
     258              :             } else {
     259              :                 // exponential moving average
     260        63248 :                 if (currSpeed != myEdgeSpeeds[id]) {
     261        25418 :                     myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
     262              :                 }
     263        63248 :                 if (myBikeSpeeds) {
     264         1272 :                     const double currBikeSpeed = e->getMeanSpeedBike();
     265         1272 :                     if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
     266          812 :                         myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
     267              :                     }
     268              :                 }
     269              :             }
     270              :         }
     271              :     }
     272     11833209 :     if (myAdaptationSteps > 0) {
     273     11813663 :         myAdaptationStepsIndex = (myAdaptationStepsIndex + 1) % myAdaptationSteps;
     274              :     }
     275     11833209 :     myLastAdaptation = currentTime;
     276     23666418 :     if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
     277        11867 :         OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
     278        11867 :         dev.openTag(SUMO_TAG_INTERVAL);
     279        11867 :         dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
     280        11867 :         dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
     281        11867 :         dev.writeAttr(SUMO_ATTR_END, STEPS2TIME(currentTime + myAdaptationInterval));
     282       142546 :         for (const MSEdge* e : edges) {
     283       130679 :             dev.openTag(SUMO_TAG_EDGE);
     284       130679 :             dev.writeAttr(SUMO_ATTR_ID, e->getID());
     285       130679 :             dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
     286       130679 :             if (myBikeSpeeds) {
     287              :                 // @note edge-priority is not included here
     288         1568 :                 dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
     289              :             }
     290       261358 :             dev.closeTag();
     291              :         }
     292        23734 :         dev.closeTag();
     293              :     }
     294     11833209 :     return myAdaptationInterval;
     295              : }
     296              : 
     297              : 
     298              : double
     299       161049 : MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
     300              :     const double length = edge->getLength();
     301              :     double maxSpeed = 0;
     302       694173 :     for (const auto& pair : edge->getViaSuccessors()) {
     303       533124 :         if (pair.second == nullptr) {
     304        50119 :             continue;
     305              :         }
     306       483005 :         TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
     307       483005 :         if (tc.second > 0) {
     308        52850 :             const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
     309              :             maxSpeed = MAX2(avgSpeed, maxSpeed);
     310              :         }
     311              :     }
     312       161049 :     if (maxSpeed > 0) {
     313              :         // perform correction
     314        31095 :         const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
     315       138070 :         for (const auto& pair : edge->getViaSuccessors()) {
     316       106975 :             if (pair.second == nullptr) {
     317        10065 :                 continue;
     318              :             }
     319              :             const int iid = pair.second->getNumericalID();
     320        96910 :             TimeAndCount& tc = myEdgeTravelTimes[iid];
     321        96910 :             if (tc.second > 0) {
     322        52850 :                 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
     323        52850 :                 if (avgSpeed < correctedSpeed) {
     324        21530 :                     double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
     325        21530 :                     internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
     326        21530 :                     const double origInternalSpeed = myEdgeSpeeds[iid];
     327        21530 :                     const double newInternalSpeed = pair.second->getLength() / internalTT;
     328        21530 :                     const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
     329              : 
     330        21530 :                     myEdgeSpeeds[iid] = newInternalSpeed;
     331              :                     // to ensure myEdgeSpeed reverts to the speed limit
     332              :                     // when there are no updates, we also have to patch
     333              :                     // myPastEdgeSpeeds with a virtual value that is consistent
     334              :                     // with the updated speed
     335              :                     // note: internal edges were handled before the normal ones
     336        21530 :                     const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
     337        21530 :                     myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
     338              : 
     339              : #ifdef DEBUG_SEPARATE_TURNS
     340              :                     if (DEBUG_COND(pair.second->getLanes()[0])) {
     341              :                         std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
     342              :                                   << " origSpeed=" << currSpeed
     343              :                                   << " maxSpeed=" << maxSpeed
     344              :                                   << " correctedSpeed=" << correctedSpeed
     345              :                                   << " avgSpeed=" << avgSpeed
     346              :                                   << " internalTT=" << internalTT
     347              :                                   << " internalSpeed=" << origInternalSpeed
     348              :                                   << " newInternalSpeed=" << newInternalSpeed
     349              :                                   << " virtualSpeed=" << virtualSpeed
     350              :                                   << "\n";
     351              :                     }
     352              : #endif
     353              :                 }
     354        52850 :                 if (myAdaptationStepsIndex == 0) {
     355          550 :                     tc.first = 0;
     356          550 :                     tc.second = 0;
     357              :                 }
     358              :             }
     359              :         }
     360              :         return correctedSpeed;
     361              :     }
     362              :     return currSpeed;
     363              : }
     364              : 
     365              : 
     366              : ConstMSRoutePtr
     367       465800 : MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
     368              :     auto routeIt = myCachedRoutes.find(key);
     369       465800 :     if (routeIt != myCachedRoutes.end()) {
     370              :         return routeIt->second;
     371              :     }
     372              :     return nullptr;
     373              : }
     374              : 
     375              : 
     376              : void
     377         7655 : MSRoutingEngine::initRouter(SUMOVehicle* vehicle) {
     378         7655 :     OptionsCont& oc = OptionsCont::getOptions();
     379         7655 :     const std::string routingAlgorithm = oc.getString("routing-algorithm");
     380         7655 :     const bool hasPermissions = MSNet::getInstance()->hasPermissions();
     381         7655 :     myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
     382         7655 :     myEffortFunc = ((gWeightsRandomFactor != 1 || myPriorityFactor != 0 || myBikeSpeeds || gRoutingPreferences) ? &MSRoutingEngine::getEffortExtra : &MSRoutingEngine::getEffort);
     383              : 
     384              :     SUMOAbstractRouter<MSEdge, SUMOVehicle>* router = nullptr;
     385         7655 :     if (routingAlgorithm == "dijkstra") {
     386         7359 :         router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
     387          296 :     } else if (routingAlgorithm == "astar") {
     388              :         typedef AStarRouter<MSEdge, SUMOVehicle, MSMapMatcher> AStar;
     389              :         std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
     390          556 :         if (oc.isSet("astar.all-distances")) {
     391            0 :             lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
     392          556 :         } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
     393           35 :             const double speedFactor = vehicle->getChosenSpeedFactor();
     394              :             // we need an exemplary vehicle with speedFactor 1
     395           35 :             vehicle->setChosenSpeedFactor(1);
     396              :             CHRouterWrapper<MSEdge, SUMOVehicle> chrouter(
     397           35 :                 MSEdge::getAllEdges(), true, &MSNet::getTravelTime,
     398          105 :                 string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
     399           35 :             lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
     400           70 :                      nullptr, vehicle, "", oc.getInt("device.rerouting.threads"), MSNet::getInstance()->getMapMatcher());
     401           35 :             vehicle->setChosenSpeedFactor(speedFactor);
     402           35 :         }
     403          834 :         router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
     404           18 :     } else if (routingAlgorithm == "CH" && !hasPermissions) {
     405            6 :         const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
     406              :         router = new CHRouter<MSEdge, SUMOVehicle>(
     407            6 :             MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
     408           12 :     } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
     409              :         // use CHWrapper instead of CH if the net has permissions
     410           12 :         const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
     411              :         router = new CHRouterWrapper<MSEdge, SUMOVehicle>(
     412           12 :             MSEdge::getAllEdges(), true, myEffortFunc,
     413           36 :             string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
     414              :     } else {
     415            0 :         throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
     416              :     }
     417              : 
     418              :     RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
     419         7655 :     if (MSNet::getInstance()->hasBidiEdges()) {
     420          577 :         railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false,
     421              :                 oc.getFloat("railway.max-train-length"),
     422         1154 :                 oc.getFloat("weights.reversal-penalty"));
     423              :     }
     424         8566 :     const int carWalk = SUMOVehicleParserHelper::parseCarWalkTransfer(oc, MSDevice_Taxi::hasFleet() || MSNet::getInstance()->getInsertionControl().hasTaxiFlow());
     425         7655 :     const double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
     426         7655 :     MSTransportableRouter* transRouter = new MSTransportableRouter(MSNet::adaptIntermodalRouter, carWalk, taxiWait, routingAlgorithm, 0);
     427         7655 :     myRouterProvider = new MSRouterProvider(router, nullptr, transRouter, railRouter);
     428              : #ifndef THREAD_POOL
     429              : #ifdef HAVE_FOX
     430         7655 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     431         7655 :     if (threadPool.size() > 0) {
     432              :         const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
     433          955 :         if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
     434         3752 :             for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
     435         2797 :                 static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
     436              :             }
     437              :         }
     438              :     }
     439              : #endif
     440              : #endif
     441         7655 : }
     442              : 
     443              : 
     444              : void
     445      2145467 : MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
     446              :                          const bool onInit, const bool silent, const Prohibitions& prohibited) {
     447      2145467 :     if (myRouterProvider == nullptr) {
     448         7466 :         initRouter(&vehicle);
     449              :     }
     450      2145467 :     auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
     451              : #ifndef THREAD_POOL
     452              : #ifdef HAVE_FOX
     453      2145467 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     454      2145467 :     if (threadPool.size() > 0) {
     455       189576 :         threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
     456       189576 :         return;
     457              :     }
     458              : #endif
     459              : #endif
     460      1955891 :     if (!prohibited.empty()) {
     461            4 :         router.prohibit(prohibited);
     462              :     }
     463              :     try {
     464      1955891 :         vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
     465           95 :     } catch (ProcessError&) {
     466           95 :         if (!silent) {
     467           95 :             if (!prohibited.empty()) {
     468            0 :                 router.prohibit(Prohibitions());
     469              :             }
     470           95 :             throw;
     471              :         }
     472           95 :     }
     473      1955796 :     if (!prohibited.empty()) {
     474            8 :         router.prohibit(Prohibitions());
     475              :     }
     476              : }
     477              : 
     478              : 
     479              : void
     480          118 : MSRoutingEngine::reroute(MSTransportable& t, const SUMOTime currentTime, const std::string& info,
     481              :                          const bool onInit, const bool silent, const Prohibitions& prohibited) {
     482          118 :     MSTransportableRouter& router = getIntermodalRouterTT(t.getRNGIndex(), prohibited);
     483              : #ifndef THREAD_POOL
     484              : #ifdef HAVE_FOX
     485          118 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     486          118 :     if (threadPool.size() > 0) {
     487              :         // threadPool.add(new RoutingTask(t, currentTime, info, onInit, silent, prohibited));
     488              :         return;
     489              :     }
     490              : #endif
     491              : #endif
     492          100 :     if (!prohibited.empty()) {
     493            0 :         router.prohibit(prohibited);
     494              :     }
     495              :     try {
     496          100 :         t.reroute(currentTime, info, router, onInit, myWithTaz, silent);
     497            0 :     } catch (ProcessError&) {
     498            0 :         if (!silent) {
     499            0 :             if (!prohibited.empty()) {
     500            0 :                 router.prohibit(Prohibitions());
     501              :             }
     502            0 :             throw;
     503              :         }
     504            0 :     }
     505          100 :     if (!prohibited.empty()) {
     506            0 :         router.prohibit(Prohibitions());
     507              :     }
     508              : }
     509              : 
     510              : 
     511              : void
     512            9 : MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
     513            9 :     myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
     514            9 : }
     515              : 
     516              : void
     517        11090 : MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
     518        11090 :     TimeAndCount& tc = myEdgeTravelTimes[edge.getNumericalID()];
     519        11090 :     tc.first += travelTime;
     520        11090 :     tc.second += 1;
     521        11090 : }
     522              : 
     523              : 
     524              : MSVehicleRouter&
     525       622906 : MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const Prohibitions& prohibited) {
     526       622906 :     if (myRouterProvider == nullptr) {
     527          189 :         initWeightUpdate();
     528          189 :         initEdgeWeights(svc);
     529          189 :         initRouter();
     530              :     }
     531              : #ifndef THREAD_POOL
     532              : #ifdef HAVE_FOX
     533       622906 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     534       622906 :     if (threadPool.size() > 0) {
     535        34090 :         auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
     536        34090 :         router.prohibit(prohibited);
     537        34090 :         return router;
     538              :     }
     539              : #else
     540              :     UNUSED_PARAMETER(rngIndex);
     541              : #endif
     542              : #endif
     543      1177632 :     myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
     544       588816 :     return myRouterProvider->getVehicleRouter(svc);
     545              : }
     546              : 
     547              : 
     548              : MSTransportableRouter&
     549          118 : MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const Prohibitions& prohibited) {
     550          118 :     if (myRouterProvider == nullptr) {
     551            0 :         initWeightUpdate();
     552            0 :         initEdgeWeights(SVC_PEDESTRIAN);
     553            0 :         initRouter();
     554              :     }
     555              : #ifndef THREAD_POOL
     556              : #ifdef HAVE_FOX
     557          118 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     558          118 :     if (threadPool.size() > 0) {
     559           18 :         auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
     560           18 :         router.prohibit(prohibited);
     561           18 :         return router;
     562              :     }
     563              : #else
     564              :     UNUSED_PARAMETER(rngIndex);
     565              : #endif
     566              : #endif
     567          100 :     myRouterProvider->getIntermodalRouter().prohibit(prohibited);
     568          100 :     return myRouterProvider->getIntermodalRouter();
     569              : }
     570              : 
     571              : 
     572              : void
     573        42031 : MSRoutingEngine::cleanup() {
     574        42031 :     myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
     575              :     myPastEdgeSpeeds.clear();
     576              :     myEdgeSpeeds.clear();
     577              :     myEdgeTravelTimes.clear();
     578              :     myPastEdgeBikeSpeeds.clear();
     579              :     myEdgeBikeSpeeds.clear();
     580              :     // @todo recheck. calling release crashes in parallel routing
     581              :     //for (auto& item : myCachedRoutes) {
     582              :     //    item.second->release();
     583              :     //}
     584              :     myCachedRoutes.clear();
     585        42031 :     myAdaptationStepsIndex = 0;
     586              : #ifdef HAVE_FOX
     587        42031 :     if (MSGlobals::gNumThreads > 1) {
     588              :         // router deletion is done in thread destructor
     589         4499 :         myRouterProvider = nullptr;
     590         4499 :         return;
     591              :     }
     592              : #endif
     593        37532 :     delete myRouterProvider;
     594        37532 :     myRouterProvider = nullptr;
     595              : }
     596              : 
     597              : 
     598              : void
     599          513 : MSRoutingEngine::saveState(OutputDevice& out) {
     600          513 :     if (myEdgeSpeeds.size() == 0) {
     601              :         return;
     602              :     }
     603          119 :     out.openTag(SUMO_TAG_ROUTINGENGINE);
     604          119 :     out.writeAttr(SUMO_ATTR_LAST, myLastAdaptation);
     605          119 :     out.writeAttr(SUMO_ATTR_INDEX, myAdaptationStepsIndex);
     606          119 :     const MSEdgeVector& edges = MSNet::getInstance()->getEdgeControl().getEdges();
     607         9746 :     for (const MSEdge* const e : edges) {
     608            0 :         if (e->isDelayed()) {
     609              :             const int id = e->getNumericalID();
     610         1435 :             out.openTag(SUMO_TAG_EDGE);
     611         1435 :             out.writeAttr(SUMO_ATTR_ID, e->getID());
     612         1435 :             out.writeAttr(SUMO_ATTR_SPEED, myEdgeSpeeds[id]);
     613         1435 :             if (myAdaptationSteps > 0) {
     614         1435 :                 out.writeAttr(SUMO_ATTR_PASTSPEED, myPastEdgeSpeeds[id]);
     615              :             }
     616         1435 :             if (myBikeSpeeds) {
     617            0 :                 out.writeAttr(SUMO_ATTR_BIKESPEED, myEdgeBikeSpeeds[id]);
     618            0 :                 if (myAdaptationSteps > 0) {
     619            0 :                     out.writeAttr(SUMO_ATTR_PASTBIKESPEED, myPastEdgeBikeSpeeds[id]);
     620              :                 }
     621              :             }
     622         2870 :             out.closeTag();
     623              :         }
     624              :     }
     625          238 :     out.closeTag();
     626              : }
     627              : 
     628              : 
     629              : void
     630         1817 : MSRoutingEngine::loadState(const SUMOSAXAttributes& attrs) {
     631         3634 :     const MSEdge* const e = MSEdge::dictionary(attrs.getString(SUMO_ATTR_ID));
     632              :     e->markDelayed();
     633              :     const int id = e->getNumericalID();
     634              :     bool checkedSteps = false;
     635              :     bool checkedBikeSpeeds = false;
     636         1817 :     bool ok = true;
     637         1817 :     if ((int)myEdgeSpeeds.size() > id) {
     638         1817 :         myEdgeSpeeds[id] = attrs.get<double>(SUMO_ATTR_SPEED, nullptr, ok);
     639         1817 :         if (myBikeSpeeds) {
     640            0 :             if (attrs.hasAttribute(SUMO_ATTR_BIKESPEED)) {
     641            0 :                 myEdgeBikeSpeeds[id] = attrs.get<double>(SUMO_ATTR_BIKESPEED, nullptr, ok);
     642              :             } else if (!checkedBikeSpeeds) {
     643              :                 checkedBikeSpeeds = true;
     644            0 :                 WRITE_WARNING("Bike speeds missing in loaded state");
     645              :             }
     646              :         }
     647         1817 :         if (myAdaptationSteps > 0) {
     648         1817 :             const std::vector<double> speeds = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTSPEED, nullptr, ok);
     649         1817 :             if ((int)speeds.size() == myAdaptationSteps) {
     650         1817 :                 myPastEdgeSpeeds[id] = speeds;
     651         1817 :                 if (myBikeSpeeds && attrs.hasAttribute(SUMO_ATTR_PASTBIKESPEED)) {
     652            0 :                     myPastEdgeBikeSpeeds[id] = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PASTBIKESPEED, nullptr, ok);
     653              :                 }
     654              :             } else if (!checkedSteps) {
     655              :                 checkedSteps = true;
     656            0 :                 WRITE_WARNING("Number of adaptation speeds in loaded state doesn't match option --device.rerouting.adaptation-steps");
     657              :             }
     658         1817 :         }
     659              :     }
     660         1817 : }
     661              : 
     662              : 
     663              : #ifdef HAVE_FOX
     664              : void
     665    121888979 : MSRoutingEngine::waitForAll() {
     666              : #ifndef THREAD_POOL
     667    121888979 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     668    121888979 :     if (threadPool.size() > 0) {
     669     13494752 :         threadPool.waitAll();
     670              :     }
     671              : #endif
     672    121888955 : }
     673              : 
     674              : 
     675              : // ---------------------------------------------------------------------------
     676              : // MSRoutingEngine::RoutingTask-methods
     677              : // ---------------------------------------------------------------------------
     678              : void
     679       189576 : MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
     680       189576 :     SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
     681       189576 :     if (!myProhibited.empty()) {
     682            2 :         router.prohibit(myProhibited);
     683              :     }
     684              :     try {
     685       189576 :         myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
     686           24 :     } catch (ProcessError&) {
     687           24 :         if (!mySilent) {
     688           24 :             if (!myProhibited.empty()) {
     689            0 :                 router.prohibit(Prohibitions());
     690              :             }
     691           24 :             throw;
     692              :         }
     693           24 :     }
     694       189552 :     if (!myProhibited.empty()) {
     695            4 :         router.prohibit(Prohibitions());
     696              :     }
     697       189552 :     const MSEdge* source = *myVehicle.getRoute().begin();
     698       189552 :     const MSEdge* dest = myVehicle.getRoute().getLastEdge();
     699       189552 :     if (source->isTazConnector() && dest->isTazConnector()) {
     700            4 :         const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
     701              :         FXMutexLock lock(myRouteCacheMutex);
     702            4 :         if (MSRoutingEngine::myCachedRoutes.find(key) == MSRoutingEngine::myCachedRoutes.end()) {
     703            6 :             MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
     704              :         }
     705              :     }
     706       189552 : }
     707              : 
     708              : 
     709              : #endif
     710              : 
     711              : 
     712              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1