LCOV - code coverage report
Current view: top level - src/microsim/devices - MSRoutingEngine.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 243 270 90.0 %
Date: 2024-04-30 15:40:33 Functions: 19 20 95.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2007-2024 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 <utils/options/OptionsCont.h>
      35             : #include <utils/common/WrappingCommand.h>
      36             : #include <utils/common/StaticCommand.h>
      37             : #include <utils/common/StringUtils.h>
      38             : #include <utils/xml/SUMOSAXAttributes.h>
      39             : #include <utils/router/DijkstraRouter.h>
      40             : #include <utils/router/AStarRouter.h>
      41             : #include <utils/router/CHRouter.h>
      42             : #include <utils/router/CHRouterWrapper.h>
      43             : 
      44             : //#define DEBUG_SEPARATE_TURNS
      45             : #define DEBUG_COND(obj) (obj->isSelected())
      46             : 
      47             : // ===========================================================================
      48             : // static member variables
      49             : // ===========================================================================
      50             : std::vector<double> MSRoutingEngine::myEdgeSpeeds;
      51             : std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
      52             : std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
      53             : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
      54             : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
      55             : Command* MSRoutingEngine::myEdgeWeightSettingCommand = nullptr;
      56             : double MSRoutingEngine::myAdaptationWeight;
      57             : int MSRoutingEngine::myAdaptationSteps;
      58             : int MSRoutingEngine::myAdaptationStepsIndex = 0;
      59             : SUMOTime MSRoutingEngine::myAdaptationInterval = -1;
      60             : SUMOTime MSRoutingEngine::myLastAdaptation = -1;
      61             : bool MSRoutingEngine::myWithTaz;
      62             : bool MSRoutingEngine::myBikeSpeeds;
      63             : MSRouterProvider* MSRoutingEngine::myRouterProvider = nullptr;
      64             : std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
      65             : double MSRoutingEngine::myPriorityFactor(0);
      66             : double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
      67             : double MSRoutingEngine::myEdgePriorityRange(0);
      68             : std::map<std::thread::id, SumoRNG*> MSRoutingEngine::myThreadRNGs;
      69             : 
      70             : SUMOAbstractRouter<MSEdge, SUMOVehicle>::Operation MSRoutingEngine::myEffortFunc = &MSRoutingEngine::getEffort;
      71             : #ifdef HAVE_FOX
      72             : FXMutex MSRoutingEngine::myRouteCacheMutex;
      73             : #endif
      74             : 
      75             : 
      76             : // ===========================================================================
      77             : // method definitions
      78             : // ===========================================================================
      79             : void
      80     1641864 : MSRoutingEngine::initWeightUpdate() {
      81     1641864 :     if (myAdaptationInterval == -1) {
      82        7411 :         myEdgeWeightSettingCommand = nullptr;
      83             :         myEdgeSpeeds.clear();
      84             :         myEdgeTravelTimes.clear();
      85        7411 :         myAdaptationSteps = -1;
      86        7411 :         myLastAdaptation = -1;
      87        7411 :         const OptionsCont& oc = OptionsCont::getOptions();
      88        7411 :         myWithTaz = oc.getBool("device.rerouting.with-taz");
      89        7411 :         myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
      90        7411 :         myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
      91       14822 :         const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
      92        7411 :         if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
      93        7331 :             myEdgeWeightSettingCommand = new StaticCommand<MSRoutingEngine>(&MSRoutingEngine::adaptEdgeEfforts);
      94        7331 :             MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myEdgeWeightSettingCommand);
      95          80 :         } else if (period > 0) {
      96           0 :             WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
      97             :         }
      98       22233 :         OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
      99             :     }
     100     1641864 : }
     101             : 
     102             : 
     103             : void
     104    10192179 : MSRoutingEngine::initEdgeWeights(SUMOVehicleClass svc) {
     105    10192179 :     if (myBikeSpeeds && svc == SVC_BICYCLE) {
     106         252 :         _initEdgeWeights(myEdgeBikeSpeeds, myPastEdgeBikeSpeeds);
     107             :     } else {
     108    10191927 :         _initEdgeWeights(myEdgeSpeeds, myPastEdgeSpeeds);
     109             :     }
     110    10192179 : }
     111             : 
     112             : 
     113             : void
     114    10192179 : MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
     115    10192179 :     if (edgeSpeeds.empty()) {
     116        7281 :         const OptionsCont& oc = OptionsCont::getOptions();
     117        7369 :         if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
     118       14386 :             myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
     119             :         }
     120        7281 :         const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
     121        7281 :         const double currentSecond = SIMTIME;
     122             :         double maxEdgePriority = -std::numeric_limits<double>::max();
     123      700267 :         for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
     124     1385972 :             while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
     125      692986 :                 edgeSpeeds.push_back(0);
     126      692986 :                 if (myAdaptationSteps > 0) {
     127      692314 :                     pastEdgeSpeeds.push_back(std::vector<double>());
     128             :                 }
     129      692986 :                 if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
     130        1175 :                     myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
     131             :                 }
     132             :             }
     133      692986 :             if (useLoaded) {
     134         114 :                 edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
     135             :             } else {
     136      692872 :                 edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
     137             :             }
     138      692986 :             if (myAdaptationSteps > 0) {
     139     1384628 :                 pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
     140             :             }
     141      692986 :             maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
     142     1346937 :             myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
     143             :         }
     144        7281 :         myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
     145        7281 :         myLastAdaptation = MSNet::getInstance()->getCurrentTimeStep();
     146        7281 :         myPriorityFactor = oc.getFloat("weights.priority-factor");
     147        7281 :         if (myPriorityFactor < 0) {
     148           0 :             throw ProcessError(TL("weights.priority-factor cannot be negative."));
     149             :         }
     150        7281 :         if (myPriorityFactor > 0) {
     151           7 :             if (myEdgePriorityRange == 0) {
     152           0 :                 WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
     153           0 :                 myPriorityFactor = 0;
     154             :             }
     155             :         }
     156             :     }
     157    10192179 : }
     158             : 
     159             : 
     160             : double
     161   118792120 : MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
     162             :     const int id = e->getNumericalID();
     163   118792120 :     if (id < (int)myEdgeSpeeds.size()) {
     164   106244117 :         return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
     165             :     }
     166    12596999 :     return e->getMinimumTravelTime(v);
     167             : }
     168             : 
     169             : 
     170             : double
     171        1924 : MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
     172             :     const int id = e->getNumericalID();
     173        1924 :     if (id < (int)myEdgeBikeSpeeds.size()) {
     174        1924 :         return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
     175             :     }
     176           0 :     return e->getMinimumTravelTime(v);
     177             : }
     178             : 
     179             : SumoRNG*
     180       24825 : MSRoutingEngine::getThreadRNG() {
     181       24825 :     if (myThreadRNGs.size() > 0) {
     182             :         auto it = myThreadRNGs.find(std::this_thread::get_id());
     183           0 :         if (it != myThreadRNGs.end()) {
     184           0 :             return it->second;
     185             :         }
     186           0 :         std::cout << " something bad happended\n";
     187             :     }
     188             :     return nullptr;
     189             : }
     190             : 
     191             : 
     192             : double
     193       30615 : MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
     194        2636 :     double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
     195       32671 :                      ? getEffort(e, v, t)
     196         580 :                      : getEffortBike(e, v, t));
     197       30615 :     if (gWeightsRandomFactor != 1.) {
     198       24825 :         effort *= RandHelper::rand(1., gWeightsRandomFactor, getThreadRNG());
     199             :     }
     200       30615 :     if (myPriorityFactor != 0) {
     201             :         // lower priority should result in higher effort (and the edge with
     202             :         // minimum priority receives a factor of 1 + myPriorityFactor
     203         840 :         const double relativeInversePrio = 1 - ((e->getPriority() - myMinEdgePriority) / myEdgePriorityRange);
     204         840 :         effort *= 1 + relativeInversePrio * myPriorityFactor;
     205             :     }
     206       30615 :     return effort;
     207             : }
     208             : 
     209             : 
     210             : double
     211        5089 : MSRoutingEngine::getAssumedSpeed(const MSEdge* edge, const SUMOVehicle* veh) {
     212        5089 :     return edge->getLength() / myEffortFunc(edge, veh, 0);
     213             : }
     214             : 
     215             : 
     216             : SUMOTime
     217     7856047 : MSRoutingEngine::adaptEdgeEfforts(SUMOTime currentTime) {
     218     7856047 :     initEdgeWeights(SVC_PASSENGER);
     219     7856047 :     if (myBikeSpeeds) {
     220         192 :         initEdgeWeights(SVC_BICYCLE);
     221             :     }
     222     7856047 :     if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
     223      510224 :         return myAdaptationInterval;
     224             :     }
     225             :     myCachedRoutes.clear();
     226     7345823 :     const MSEdgeVector& edges = MSNet::getInstance()->getEdgeControl().getEdges();
     227     7345823 :     const double newWeightFactor = (double)(1. - myAdaptationWeight);
     228   500002497 :     for (const MSEdge* const e : edges) {
     229             :         if (e->isDelayed()) {
     230             :             const int id = e->getNumericalID();
     231   108596774 :             double currSpeed = e->getMeanSpeed();
     232   108596774 :             if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
     233      127595 :                 currSpeed = patchSpeedForTurns(e, currSpeed);
     234             :             }
     235             : #ifdef DEBUG_SEPARATE_TURNS
     236             :             if (DEBUG_COND(e->getLanes()[0])) {
     237             :                 std::cout << SIMTIME << " edge=" << e->getID()
     238             :                           << " meanSpeed=" << e->getMeanSpeed()
     239             :                           << " currSpeed=" << currSpeed
     240             :                           << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
     241             :                           << " oldAvg=" << myEdgeSpeeds[id]
     242             :                           << "\n";
     243             :             }
     244             : #endif
     245   108596774 :             if (myAdaptationSteps > 0) {
     246             :                 // moving average
     247   108533708 :                 myEdgeSpeeds[id] += (currSpeed - myPastEdgeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
     248   108533708 :                 myPastEdgeSpeeds[id][myAdaptationStepsIndex] = currSpeed;
     249   108533708 :                 if (myBikeSpeeds) {
     250           0 :                     const double currBikeSpeed = e->getMeanSpeedBike();
     251           0 :                     myEdgeBikeSpeeds[id] += (currBikeSpeed - myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
     252           0 :                     myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
     253             :                 }
     254             :             } else {
     255             :                 // exponential moving average
     256       63066 :                 if (currSpeed != myEdgeSpeeds[id]) {
     257       25322 :                     myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
     258             :                 }
     259       63066 :                 if (myBikeSpeeds) {
     260        1090 :                     const double currBikeSpeed = e->getMeanSpeedBike();
     261        1090 :                     if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
     262         722 :                         myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
     263             :                     }
     264             :                 }
     265             :             }
     266             :         }
     267             :     }
     268     7345823 :     if (myAdaptationSteps > 0) {
     269     7326309 :         myAdaptationStepsIndex = (myAdaptationStepsIndex + 1) % myAdaptationSteps;
     270             :     }
     271     7345823 :     myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
     272    14691646 :     if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
     273       11539 :         OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
     274       11539 :         dev.openTag(SUMO_TAG_INTERVAL);
     275             :         dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
     276       11539 :         dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
     277       23078 :         dev.writeAttr(SUMO_ATTR_END, STEPS2TIME(currentTime + myAdaptationInterval));
     278      140799 :         for (const MSEdge* e : edges) {
     279      129260 :             dev.openTag(SUMO_TAG_EDGE);
     280             :             dev.writeAttr(SUMO_ATTR_ID, e->getID());
     281      129260 :             dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
     282      129260 :             if (myBikeSpeeds) {
     283             :                 // @note edge-priority is not included here
     284        2688 :                 dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
     285             :             }
     286      258520 :             dev.closeTag();
     287             :         }
     288       23078 :         dev.closeTag();
     289             :     }
     290     7345823 :     return myAdaptationInterval;
     291             : }
     292             : 
     293             : 
     294             : double
     295      127595 : MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
     296             :     const double length = edge->getLength();
     297             :     double maxSpeed = 0;
     298      550565 :     for (const auto& pair : edge->getViaSuccessors()) {
     299      422970 :         if (pair.second == nullptr) {
     300       40005 :             continue;
     301             :         }
     302      382965 :         TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
     303      382965 :         if (tc.second > 0) {
     304       53590 :             const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
     305             :             maxSpeed = MAX2(avgSpeed, maxSpeed);
     306             :         }
     307             :     }
     308      127595 :     if (maxSpeed > 0) {
     309             :         // perform correction
     310       31755 :         const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
     311      141470 :         for (const auto& pair : edge->getViaSuccessors()) {
     312      109715 :             if (pair.second == nullptr) {
     313        9815 :                 continue;
     314             :             }
     315             :             const int iid = pair.second->getNumericalID();
     316       99900 :             TimeAndCount& tc = myEdgeTravelTimes[iid];
     317       99900 :             if (tc.second > 0) {
     318       53590 :                 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
     319       53590 :                 if (avgSpeed < correctedSpeed) {
     320       22330 :                     double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
     321       22330 :                     internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
     322       22330 :                     const double origInternalSpeed = myEdgeSpeeds[iid];
     323       22330 :                     const double newInternalSpeed = pair.second->getLength() / internalTT;
     324       22330 :                     const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
     325             : 
     326       22330 :                     myEdgeSpeeds[iid] = newInternalSpeed;
     327             :                     // to ensure myEdgeSpeed reverts to the speed limit
     328             :                     // when there are no updates, we also have to patch
     329             :                     // myPastEdgeSpeeds with a virtual value that is consistent
     330             :                     // with the updated speed
     331             :                     // note: internal edges were handled before the normal ones
     332       22330 :                     const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
     333       22330 :                     myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
     334             : 
     335             : #ifdef DEBUG_SEPARATE_TURNS
     336             :                     if (DEBUG_COND(pair.second->getLanes()[0])) {
     337             :                         std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
     338             :                                   << " origSpeed=" << currSpeed
     339             :                                   << " maxSpeed=" << maxSpeed
     340             :                                   << " correctedSpeed=" << correctedSpeed
     341             :                                   << " avgSpeed=" << avgSpeed
     342             :                                   << " internalTT=" << internalTT
     343             :                                   << " internalSpeed=" << origInternalSpeed
     344             :                                   << " newInternalSpeed=" << newInternalSpeed
     345             :                                   << " virtualSpeed=" << virtualSpeed
     346             :                                   << "\n";
     347             :                     }
     348             : #endif
     349             :                 }
     350       53590 :                 if (myAdaptationStepsIndex == 0) {
     351         525 :                     tc.first = 0;
     352         525 :                     tc.second = 0;
     353             :                 }
     354             :             }
     355             :         }
     356             :         return correctedSpeed;
     357             :     }
     358             :     return currSpeed;
     359             : }
     360             : 
     361             : 
     362             : ConstMSRoutePtr
     363      675361 : MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
     364             :     auto routeIt = myCachedRoutes.find(key);
     365      675361 :     if (routeIt != myCachedRoutes.end()) {
     366             :         return routeIt->second;
     367             :     }
     368             :     return nullptr;
     369             : }
     370             : 
     371             : 
     372             : void
     373        6064 : MSRoutingEngine::initRouter(SUMOVehicle* vehicle) {
     374        6064 :     OptionsCont& oc = OptionsCont::getOptions();
     375        6064 :     const std::string routingAlgorithm = oc.getString("routing-algorithm");
     376        6064 :     const bool hasPermissions = MSNet::getInstance()->hasPermissions();
     377        6064 :     myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
     378       12095 :     myEffortFunc = ((gWeightsRandomFactor != 1 || myPriorityFactor != 0 || myBikeSpeeds) ? &MSRoutingEngine::getEffortExtra : &MSRoutingEngine::getEffort);
     379             : 
     380             :     SUMOAbstractRouter<MSEdge, SUMOVehicle>* router = nullptr;
     381        6064 :     if (routingAlgorithm == "dijkstra") {
     382        5812 :         router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
     383         252 :     } else if (routingAlgorithm == "astar") {
     384             :         typedef AStarRouter<MSEdge, SUMOVehicle> AStar;
     385             :         std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
     386         468 :         if (oc.isSet("astar.all-distances")) {
     387           0 :             lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
     388         468 :         } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
     389          28 :             const double speedFactor = vehicle->getChosenSpeedFactor();
     390             :             // we need an exemplary vehicle with speedFactor 1
     391          28 :             vehicle->setChosenSpeedFactor(1);
     392             :             CHRouterWrapper<MSEdge, SUMOVehicle> chrouter(
     393          28 :                 MSEdge::getAllEdges(), true, &MSNet::getTravelTime,
     394          84 :                 string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
     395          56 :             lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
     396          56 :                      nullptr, vehicle, "", oc.getInt("device.rerouting.threads"));
     397          28 :             vehicle->setChosenSpeedFactor(speedFactor);
     398          28 :         }
     399         702 :         router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
     400          18 :     } else if (routingAlgorithm == "CH" && !hasPermissions) {
     401           6 :         const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
     402             :         router = new CHRouter<MSEdge, SUMOVehicle>(
     403           6 :             MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
     404          12 :     } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
     405             :         // use CHWrapper instead of CH if the net has permissions
     406          12 :         const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
     407             :         router = new CHRouterWrapper<MSEdge, SUMOVehicle>(
     408          12 :             MSEdge::getAllEdges(), true, myEffortFunc,
     409          24 :             string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
     410             :     } else {
     411           0 :         throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
     412             :     }
     413             : 
     414             :     RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
     415        6064 :     if (MSNet::getInstance()->hasBidiEdges()) {
     416         572 :         railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false, oc.getFloat("railway.max-train-length"));
     417             :     }
     418        6064 :     myRouterProvider = new MSRouterProvider(router, nullptr, nullptr, railRouter);
     419             : #ifndef THREAD_POOL
     420             : #ifdef HAVE_FOX
     421        6064 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     422        6064 :     if (threadPool.size() > 0) {
     423             :         const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
     424         699 :         if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
     425        2704 :             for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
     426        2005 :                 static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
     427             :             }
     428             :         }
     429             : #ifndef WIN32
     430             :         /*
     431             :         int i = 0;
     432             :         for (MFXWorkerThread* t : threads) {
     433             :             myThreadRNGs[(std::thread::id)t->id()] = new SumoRNG("routing_" + toString(i++));
     434             :         }
     435             :         */
     436             : #endif
     437             :     }
     438             : #endif
     439             : #endif
     440        6064 : }
     441             : 
     442             : 
     443             : void
     444     2099851 : MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
     445             :                          const bool onInit, const bool silent, const MSEdgeVector& prohibited) {
     446     2099851 :     if (myRouterProvider == nullptr) {
     447        5983 :         initRouter(&vehicle);
     448             :     }
     449     2099851 :     auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
     450             : #ifndef THREAD_POOL
     451             : #ifdef HAVE_FOX
     452     2099851 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     453     2099851 :     if (threadPool.size() > 0) {
     454      129931 :         threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
     455      129931 :         return;
     456             :     }
     457             : #endif
     458             : #endif
     459     1969920 :     if (!prohibited.empty()) {
     460         127 :         router.prohibit(prohibited);
     461             :     }
     462             :     try {
     463     1969920 :         vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
     464          98 :     } catch (ProcessError&) {
     465          98 :         if (!silent) {
     466          96 :             if (!prohibited.empty()) {
     467           0 :                 router.prohibit(MSEdgeVector());
     468             :             }
     469          96 :             throw;
     470             :         }
     471          98 :     }
     472     1969824 :     if (!prohibited.empty()) {
     473         254 :         router.prohibit(MSEdgeVector());
     474             :     }
     475             : }
     476             : 
     477             : 
     478             : void
     479          10 : MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
     480          10 :     myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
     481          10 : }
     482             : 
     483             : void
     484       10980 : MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
     485       10980 :     TimeAndCount& tc = myEdgeTravelTimes[edge.getNumericalID()];
     486       10980 :     tc.first += travelTime;
     487       10980 :     tc.second += 1;
     488       10980 : }
     489             : 
     490             : 
     491             : MSVehicleRouter&
     492      725017 : MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector& prohibited) {
     493      725017 :     if (myRouterProvider == nullptr) {
     494          81 :         initWeightUpdate();
     495          81 :         initEdgeWeights(svc);
     496          81 :         initRouter();
     497             :     }
     498             : #ifndef THREAD_POOL
     499             : #ifdef HAVE_FOX
     500      725017 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     501      725017 :     if (threadPool.size() > 0) {
     502       35261 :         auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
     503       35261 :         router.prohibit(prohibited);
     504       35261 :         return router;
     505             :     }
     506             : #else
     507             :     UNUSED_PARAMETER(rngIndex);
     508             : #endif
     509             : #endif
     510     1379512 :     myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
     511      689756 :     return myRouterProvider->getVehicleRouter(svc);
     512             : }
     513             : 
     514             : 
     515             : MSTransportableRouter&
     516           0 : MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const MSEdgeVector& prohibited) {
     517           0 :     if (myRouterProvider == nullptr) {
     518           0 :         initWeightUpdate();
     519           0 :         initEdgeWeights(SVC_PEDESTRIAN);
     520           0 :         initRouter();
     521             :     }
     522             : #ifndef THREAD_POOL
     523             : #ifdef HAVE_FOX
     524           0 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     525           0 :     if (threadPool.size() > 0) {
     526           0 :         auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
     527           0 :         router.prohibit(prohibited);
     528           0 :         return router;
     529             :     }
     530             : #else
     531             :     UNUSED_PARAMETER(rngIndex);
     532             : #endif
     533             : #endif
     534           0 :     myRouterProvider->getIntermodalRouter().prohibit(prohibited);
     535           0 :     return myRouterProvider->getIntermodalRouter();
     536             : }
     537             : 
     538             : 
     539             : void
     540       35160 : MSRoutingEngine::cleanup() {
     541       35160 :     myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
     542             :     myPastEdgeSpeeds.clear();
     543             :     myEdgeSpeeds.clear();
     544             :     myEdgeTravelTimes.clear();
     545             :     myPastEdgeBikeSpeeds.clear();
     546             :     myEdgeBikeSpeeds.clear();
     547             :     // @todo recheck. calling release crashes in parallel routing
     548             :     //for (auto& item : myCachedRoutes) {
     549             :     //    item.second->release();
     550             :     //}
     551             :     myCachedRoutes.clear();
     552       35160 :     myAdaptationStepsIndex = 0;
     553             : #ifdef HAVE_FOX
     554       35160 :     if (MSGlobals::gNumThreads > 1) {
     555             :         // router deletion is done in thread destructor
     556        3810 :         myRouterProvider = nullptr;
     557        3810 :         return;
     558             :     }
     559             : #endif
     560       31350 :     delete myRouterProvider;
     561       31350 :     myRouterProvider = nullptr;
     562             : }
     563             : 
     564             : 
     565             : #ifdef HAVE_FOX
     566             : void
     567   151071395 : MSRoutingEngine::waitForAll() {
     568             : #ifndef THREAD_POOL
     569   151071395 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     570   151071395 :     if (threadPool.size() > 0) {
     571     6653712 :         threadPool.waitAll();
     572             :     }
     573             : #endif
     574   151071371 : }
     575             : 
     576             : 
     577             : // ---------------------------------------------------------------------------
     578             : // MSRoutingEngine::RoutingTask-methods
     579             : // ---------------------------------------------------------------------------
     580             : void
     581      129931 : MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
     582      129931 :     SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
     583      129931 :     if (!myProhibited.empty()) {
     584          54 :         router.prohibit(myProhibited);
     585             :     }
     586             :     try {
     587      129931 :         myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
     588          25 :     } catch (ProcessError&) {
     589          25 :         if (!mySilent) {
     590          24 :             if (!myProhibited.empty()) {
     591           0 :                 router.prohibit(MSEdgeVector());
     592             :             }
     593          24 :             throw;
     594             :         }
     595          25 :     }
     596      129907 :     if (!myProhibited.empty()) {
     597         108 :         router.prohibit(MSEdgeVector());
     598             :     }
     599      129907 :     const MSEdge* source = *myVehicle.getRoute().begin();
     600      129907 :     const MSEdge* dest = myVehicle.getRoute().getLastEdge();
     601      129907 :     if (source->isTazConnector() && dest->isTazConnector()) {
     602           4 :         const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
     603             :         FXMutexLock lock(myRouteCacheMutex);
     604           4 :         if (MSRoutingEngine::myCachedRoutes.find(key) == MSRoutingEngine::myCachedRoutes.end()) {
     605           6 :             MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
     606             :         }
     607             :     }
     608      129907 : }
     609             : #endif
     610             : 
     611             : 
     612             : /****************************************************************************/

Generated by: LCOV version 1.14