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

Generated by: LCOV version 2.0-1