LCOV - code coverage report
Current view: top level - src/microsim/devices - MSRoutingEngine.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 92.1 % 291 268
Test Date: 2024-11-22 15:46:21 Functions: 100.0 % 21 21

            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 <microsim/transportables/MSTransportable.h>
      35              : #include <utils/options/OptionsCont.h>
      36              : #include <utils/common/WrappingCommand.h>
      37              : #include <utils/common/StaticCommand.h>
      38              : #include <utils/common/StringUtils.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              : #include <utils/vehicle/SUMOVehicleParserHelper.h>
      44              : 
      45              : //#define DEBUG_SEPARATE_TURNS
      46              : #define DEBUG_COND(obj) (obj->isSelected())
      47              : 
      48              : // ===========================================================================
      49              : // static member variables
      50              : // ===========================================================================
      51              : std::vector<double> MSRoutingEngine::myEdgeSpeeds;
      52              : std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
      53              : std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
      54              : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
      55              : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
      56              : Command* MSRoutingEngine::myEdgeWeightSettingCommand = nullptr;
      57              : double MSRoutingEngine::myAdaptationWeight;
      58              : int MSRoutingEngine::myAdaptationSteps;
      59              : int MSRoutingEngine::myAdaptationStepsIndex = 0;
      60              : SUMOTime MSRoutingEngine::myAdaptationInterval = -1;
      61              : SUMOTime MSRoutingEngine::myLastAdaptation = -1;
      62              : bool MSRoutingEngine::myWithTaz;
      63              : bool MSRoutingEngine::myBikeSpeeds;
      64              : MSRouterProvider* MSRoutingEngine::myRouterProvider = nullptr;
      65              : std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
      66              : double MSRoutingEngine::myPriorityFactor(0);
      67              : double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
      68              : double MSRoutingEngine::myEdgePriorityRange(0);
      69              : std::map<std::thread::id, SumoRNG*> MSRoutingEngine::myThreadRNGs;
      70              : bool MSRoutingEngine::myHaveRoutingThreads(false);
      71              : 
      72              : SUMOAbstractRouter<MSEdge, SUMOVehicle>::Operation MSRoutingEngine::myEffortFunc = &MSRoutingEngine::getEffort;
      73              : #ifdef HAVE_FOX
      74              : FXMutex MSRoutingEngine::myRouteCacheMutex;
      75              : #endif
      76              : 
      77              : 
      78              : // ===========================================================================
      79              : // method definitions
      80              : // ===========================================================================
      81              : void
      82      1514757 : MSRoutingEngine::initWeightUpdate() {
      83      1514757 :     if (myAdaptationInterval == -1) {
      84         8049 :         myEdgeWeightSettingCommand = nullptr;
      85              :         myEdgeSpeeds.clear();
      86              :         myEdgeTravelTimes.clear();
      87         8049 :         myAdaptationSteps = -1;
      88         8049 :         myLastAdaptation = -1;
      89         8049 :         const OptionsCont& oc = OptionsCont::getOptions();
      90         8049 :         myWithTaz = oc.getBool("device.rerouting.with-taz");
      91         8049 :         myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
      92         8049 :         myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
      93         8049 :         const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
      94         8049 :         if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
      95         7986 :             myEdgeWeightSettingCommand = new StaticCommand<MSRoutingEngine>(&MSRoutingEngine::adaptEdgeEfforts);
      96         7986 :             MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myEdgeWeightSettingCommand);
      97           63 :         } else if (period > 0) {
      98            0 :             WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
      99              :         }
     100        16098 :         OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
     101              :     }
     102      1514757 : }
     103              : 
     104              : 
     105              : void
     106     12239715 : MSRoutingEngine::initEdgeWeights(SUMOVehicleClass svc) {
     107     12239715 :     if (myBikeSpeeds && svc == SVC_BICYCLE) {
     108          252 :         _initEdgeWeights(myEdgeBikeSpeeds, myPastEdgeBikeSpeeds);
     109              :     } else {
     110     12239463 :         _initEdgeWeights(myEdgeSpeeds, myPastEdgeSpeeds);
     111              :     }
     112     12239715 : }
     113              : 
     114              : 
     115              : void
     116     12239715 : MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
     117     12239715 :     if (edgeSpeeds.empty()) {
     118         7964 :         const OptionsCont& oc = OptionsCont::getOptions();
     119         8052 :         if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
     120         7876 :             myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
     121              :         }
     122         7964 :         const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
     123         7964 :         const double currentSecond = SIMTIME;
     124              :         double maxEdgePriority = -std::numeric_limits<double>::max();
     125       673782 :         for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
     126      1331636 :             while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
     127       665818 :                 edgeSpeeds.push_back(0);
     128       665818 :                 if (myAdaptationSteps > 0) {
     129       665146 :                     pastEdgeSpeeds.push_back(std::vector<double>());
     130              :                 }
     131       666993 :                 if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
     132         1175 :                     myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
     133              :                 }
     134              :             }
     135       665818 :             if (useLoaded) {
     136          114 :                 edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
     137              :             } else {
     138       665704 :                 edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
     139              :             }
     140       665818 :             if (myAdaptationSteps > 0) {
     141       665146 :                 pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
     142              :             }
     143       665818 :             maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
     144      1290773 :             myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
     145              :         }
     146         7964 :         myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
     147         7964 :         myLastAdaptation = MSNet::getInstance()->getCurrentTimeStep();
     148         7964 :         myPriorityFactor = oc.getFloat("weights.priority-factor");
     149         7964 :         if (myPriorityFactor < 0) {
     150            0 :             throw ProcessError(TL("weights.priority-factor cannot be negative."));
     151              :         }
     152         7964 :         if (myPriorityFactor > 0) {
     153            7 :             if (myEdgePriorityRange == 0) {
     154            0 :                 WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
     155            0 :                 myPriorityFactor = 0;
     156              :             }
     157              :         }
     158              :     }
     159     12239715 : }
     160              : 
     161              : 
     162              : double
     163     99497202 : MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
     164              :     const int id = e->getNumericalID();
     165     99497202 :     if (id < (int)myEdgeSpeeds.size()) {
     166     91008536 :         return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
     167              :     }
     168      8534218 :     return e->getMinimumTravelTime(v);
     169              : }
     170              : 
     171              : 
     172              : double
     173         1924 : MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
     174              :     const int id = e->getNumericalID();
     175         1924 :     if (id < (int)myEdgeBikeSpeeds.size()) {
     176         1924 :         return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
     177              :     }
     178            0 :     return e->getMinimumTravelTime(v);
     179              : }
     180              : 
     181              : SumoRNG*
     182        22677 : MSRoutingEngine::getThreadRNG() {
     183        22677 :     if (myHaveRoutingThreads) {
     184              :         auto it = myThreadRNGs.find(std::this_thread::get_id());
     185         5254 :         if (it != myThreadRNGs.end()) {
     186         5236 :             return it->second;
     187              :         } else {
     188           36 :             SumoRNG* rng = new SumoRNG("routing_" + toString(myThreadRNGs.size()));
     189           18 :             myThreadRNGs[std::this_thread::get_id()] = rng;
     190           18 :             return rng;
     191              :         }
     192              :     }
     193              :     return nullptr;
     194              : }
     195              : 
     196              : 
     197              : double
     198        27908 : MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
     199         2636 :     double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
     200        29964 :                      ? getEffort(e, v, t)
     201          580 :                      : getEffortBike(e, v, t));
     202        27908 :     if (gWeightsRandomFactor != 1.) {
     203        22677 :         effort *= RandHelper::rand(1., gWeightsRandomFactor, getThreadRNG());
     204              :     }
     205        27908 :     if (myPriorityFactor != 0) {
     206              :         // lower priority should result in higher effort (and the edge with
     207              :         // minimum priority receives a factor of 1 + myPriorityFactor
     208          840 :         const double relativeInversePrio = 1 - ((e->getPriority() - myMinEdgePriority) / myEdgePriorityRange);
     209          840 :         effort *= 1 + relativeInversePrio * myPriorityFactor;
     210              :     }
     211        27908 :     return effort;
     212              : }
     213              : 
     214              : 
     215              : double
     216         4240 : MSRoutingEngine::getAssumedSpeed(const MSEdge* edge, const SUMOVehicle* veh) {
     217         4240 :     return edge->getLength() / myEffortFunc(edge, veh, 0);
     218              : }
     219              : 
     220              : 
     221              : SUMOTime
     222     10037052 : MSRoutingEngine::adaptEdgeEfforts(SUMOTime currentTime) {
     223     10037052 :     initEdgeWeights(SVC_PASSENGER);
     224     10037052 :     if (myBikeSpeeds) {
     225          192 :         initEdgeWeights(SVC_BICYCLE);
     226              :     }
     227     10037052 :     if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
     228        94728 :         return myAdaptationInterval;
     229              :     }
     230              :     myCachedRoutes.clear();
     231      9942324 :     const MSEdgeVector& edges = MSNet::getInstance()->getEdgeControl().getEdges();
     232      9942324 :     const double newWeightFactor = (double)(1. - myAdaptationWeight);
     233    573106934 :     for (const MSEdge* const e : edges) {
     234      8152945 :         if (e->isDelayed()) {
     235              :             const int id = e->getNumericalID();
     236    122524470 :             double currSpeed = e->getMeanSpeed();
     237    122524470 :             if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
     238       129475 :                 currSpeed = patchSpeedForTurns(e, currSpeed);
     239              :             }
     240              : #ifdef DEBUG_SEPARATE_TURNS
     241              :             if (DEBUG_COND(e->getLanes()[0])) {
     242              :                 std::cout << SIMTIME << " edge=" << e->getID()
     243              :                           << " meanSpeed=" << e->getMeanSpeed()
     244              :                           << " currSpeed=" << currSpeed
     245              :                           << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
     246              :                           << " oldAvg=" << myEdgeSpeeds[id]
     247              :                           << "\n";
     248              :             }
     249              : #endif
     250    122524470 :             if (myAdaptationSteps > 0) {
     251              :                 // moving average
     252    122461404 :                 myEdgeSpeeds[id] += (currSpeed - myPastEdgeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
     253    122461404 :                 myPastEdgeSpeeds[id][myAdaptationStepsIndex] = currSpeed;
     254    122461404 :                 if (myBikeSpeeds) {
     255            0 :                     const double currBikeSpeed = e->getMeanSpeedBike();
     256            0 :                     myEdgeBikeSpeeds[id] += (currBikeSpeed - myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
     257            0 :                     myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
     258              :                 }
     259              :             } else {
     260              :                 // exponential moving average
     261        63066 :                 if (currSpeed != myEdgeSpeeds[id]) {
     262        25322 :                     myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
     263              :                 }
     264        63066 :                 if (myBikeSpeeds) {
     265         1090 :                     const double currBikeSpeed = e->getMeanSpeedBike();
     266         1090 :                     if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
     267          722 :                         myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
     268              :                     }
     269              :                 }
     270              :             }
     271              :         }
     272              :     }
     273      9942324 :     if (myAdaptationSteps > 0) {
     274      9922810 :         myAdaptationStepsIndex = (myAdaptationStepsIndex + 1) % myAdaptationSteps;
     275              :     }
     276      9942324 :     myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
     277     19884648 :     if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
     278        11807 :         OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
     279        11807 :         dev.openTag(SUMO_TAG_INTERVAL);
     280              :         dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
     281        11807 :         dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
     282        23614 :         dev.writeAttr(SUMO_ATTR_END, STEPS2TIME(currentTime + myAdaptationInterval));
     283       142139 :         for (const MSEdge* e : edges) {
     284       130332 :             dev.openTag(SUMO_TAG_EDGE);
     285              :             dev.writeAttr(SUMO_ATTR_ID, e->getID());
     286       130332 :             dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
     287       130332 :             if (myBikeSpeeds) {
     288              :                 // @note edge-priority is not included here
     289         2688 :                 dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
     290              :             }
     291       260664 :             dev.closeTag();
     292              :         }
     293        23614 :         dev.closeTag();
     294              :     }
     295      9942324 :     return myAdaptationInterval;
     296              : }
     297              : 
     298              : 
     299              : double
     300       129475 : MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
     301              :     const double length = edge->getLength();
     302              :     double maxSpeed = 0;
     303       558215 :     for (const auto& pair : edge->getViaSuccessors()) {
     304       428740 :         if (pair.second == nullptr) {
     305        40545 :             continue;
     306              :         }
     307              :         TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
     308       388195 :         if (tc.second > 0) {
     309        52035 :             const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
     310              :             maxSpeed = MAX2(avgSpeed, maxSpeed);
     311              :         }
     312              :     }
     313       129475 :     if (maxSpeed > 0) {
     314              :         // perform correction
     315        30670 :         const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
     316       135600 :         for (const auto& pair : edge->getViaSuccessors()) {
     317       104930 :             if (pair.second == nullptr) {
     318         9640 :                 continue;
     319              :             }
     320              :             const int iid = pair.second->getNumericalID();
     321        95290 :             TimeAndCount& tc = myEdgeTravelTimes[iid];
     322        95290 :             if (tc.second > 0) {
     323        52035 :                 const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
     324        52035 :                 if (avgSpeed < correctedSpeed) {
     325        21140 :                     double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
     326        21140 :                     internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
     327        21140 :                     const double origInternalSpeed = myEdgeSpeeds[iid];
     328        21140 :                     const double newInternalSpeed = pair.second->getLength() / internalTT;
     329        21140 :                     const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
     330              : 
     331        21140 :                     myEdgeSpeeds[iid] = newInternalSpeed;
     332              :                     // to ensure myEdgeSpeed reverts to the speed limit
     333              :                     // when there are no updates, we also have to patch
     334              :                     // myPastEdgeSpeeds with a virtual value that is consistent
     335              :                     // with the updated speed
     336              :                     // note: internal edges were handled before the normal ones
     337        21140 :                     const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
     338        21140 :                     myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
     339              : 
     340              : #ifdef DEBUG_SEPARATE_TURNS
     341              :                     if (DEBUG_COND(pair.second->getLanes()[0])) {
     342              :                         std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
     343              :                                   << " origSpeed=" << currSpeed
     344              :                                   << " maxSpeed=" << maxSpeed
     345              :                                   << " correctedSpeed=" << correctedSpeed
     346              :                                   << " avgSpeed=" << avgSpeed
     347              :                                   << " internalTT=" << internalTT
     348              :                                   << " internalSpeed=" << origInternalSpeed
     349              :                                   << " newInternalSpeed=" << newInternalSpeed
     350              :                                   << " virtualSpeed=" << virtualSpeed
     351              :                                   << "\n";
     352              :                     }
     353              : #endif
     354              :                 }
     355        52035 :                 if (myAdaptationStepsIndex == 0) {
     356          550 :                     tc.first = 0;
     357          550 :                     tc.second = 0;
     358              :                 }
     359              :             }
     360              :         }
     361              :         return correctedSpeed;
     362              :     }
     363              :     return currSpeed;
     364              : }
     365              : 
     366              : 
     367              : ConstMSRoutePtr
     368       566045 : MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
     369              :     auto routeIt = myCachedRoutes.find(key);
     370       566045 :     if (routeIt != myCachedRoutes.end()) {
     371              :         return routeIt->second;
     372              :     }
     373              :     return nullptr;
     374              : }
     375              : 
     376              : 
     377              : void
     378         7863 : MSRoutingEngine::initRouter(SUMOVehicle* vehicle) {
     379         7863 :     OptionsCont& oc = OptionsCont::getOptions();
     380         7863 :     const std::string routingAlgorithm = oc.getString("routing-algorithm");
     381         7863 :     const bool hasPermissions = MSNet::getInstance()->hasPermissions();
     382         7863 :     myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
     383         7863 :     myEffortFunc = ((gWeightsRandomFactor != 1 || myPriorityFactor != 0 || myBikeSpeeds) ? &MSRoutingEngine::getEffortExtra : &MSRoutingEngine::getEffort);
     384              : 
     385              :     SUMOAbstractRouter<MSEdge, SUMOVehicle>* router = nullptr;
     386         7863 :     if (routingAlgorithm == "dijkstra") {
     387         7605 :         router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
     388          258 :     } else if (routingAlgorithm == "astar") {
     389              :         typedef AStarRouter<MSEdge, SUMOVehicle> AStar;
     390              :         std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
     391          480 :         if (oc.isSet("astar.all-distances")) {
     392            0 :             lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
     393          480 :         } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
     394           28 :             const double speedFactor = vehicle->getChosenSpeedFactor();
     395              :             // we need an exemplary vehicle with speedFactor 1
     396           28 :             vehicle->setChosenSpeedFactor(1);
     397              :             CHRouterWrapper<MSEdge, SUMOVehicle> chrouter(
     398           28 :                 MSEdge::getAllEdges(), true, &MSNet::getTravelTime,
     399           84 :                 string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
     400           28 :             lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
     401           56 :                      nullptr, vehicle, "", oc.getInt("device.rerouting.threads"));
     402           28 :             vehicle->setChosenSpeedFactor(speedFactor);
     403           28 :         }
     404          720 :         router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
     405           18 :     } else if (routingAlgorithm == "CH" && !hasPermissions) {
     406            6 :         const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
     407              :         router = new CHRouter<MSEdge, SUMOVehicle>(
     408            6 :             MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
     409           12 :     } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
     410              :         // use CHWrapper instead of CH if the net has permissions
     411           12 :         const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
     412              :         router = new CHRouterWrapper<MSEdge, SUMOVehicle>(
     413           12 :             MSEdge::getAllEdges(), true, myEffortFunc,
     414           36 :             string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
     415              :     } else {
     416            0 :         throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
     417              :     }
     418              : 
     419              :     RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
     420         7863 :     if (MSNet::getInstance()->hasBidiEdges()) {
     421          894 :         railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false, oc.getFloat("railway.max-train-length"));
     422              :     }
     423         7863 :     const int carWalk = SUMOVehicleParserHelper::parseCarWalkTransfer(oc);
     424         7863 :     const double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
     425         7863 :     MSTransportableRouter* transRouter = new MSTransportableRouter(MSNet::adaptIntermodalRouter, carWalk, taxiWait, routingAlgorithm, 0);
     426         7863 :     myRouterProvider = new MSRouterProvider(router, nullptr, transRouter, railRouter);
     427              : #ifndef THREAD_POOL
     428              : #ifdef HAVE_FOX
     429         7863 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     430         7863 :     if (threadPool.size() > 0) {
     431              :         const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
     432          804 :         if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
     433         3124 :             for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
     434         2320 :                 static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
     435              :             }
     436              :         }
     437          804 :         myHaveRoutingThreads = true;
     438              :     }
     439              : #endif
     440              : #endif
     441         7863 : }
     442              : 
     443              : 
     444              : void
     445      2200639 : MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
     446              :                          const bool onInit, const bool silent, const MSEdgeVector& prohibited) {
     447      2200639 :     if (myRouterProvider == nullptr) {
     448         7766 :         initRouter(&vehicle);
     449              :     }
     450      2200639 :     auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
     451              : #ifndef THREAD_POOL
     452              : #ifdef HAVE_FOX
     453      2200639 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     454      2200639 :     if (threadPool.size() > 0) {
     455       176487 :         threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
     456       176487 :         return;
     457              :     }
     458              : #endif
     459              : #endif
     460      2024152 :     if (!prohibited.empty()) {
     461            4 :         router.prohibit(prohibited);
     462              :     }
     463              :     try {
     464      2024152 :         vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
     465           97 :     } catch (ProcessError&) {
     466           97 :         if (!silent) {
     467           97 :             if (!prohibited.empty()) {
     468            0 :                 router.prohibit(MSEdgeVector());
     469              :             }
     470           97 :             throw;
     471              :         }
     472           97 :     }
     473      2024055 :     if (!prohibited.empty()) {
     474            4 :         router.prohibit(MSEdgeVector());
     475              :     }
     476              : }
     477              : 
     478              : 
     479              : void
     480          111 : MSRoutingEngine::reroute(MSTransportable& t, const SUMOTime currentTime, const std::string& info,
     481              :                          const bool onInit, const bool silent, const MSEdgeVector& prohibited) {
     482          111 :     MSTransportableRouter& router = getIntermodalRouterTT(t.getRNGIndex(), prohibited);
     483              : #ifndef THREAD_POOL
     484              : #ifdef HAVE_FOX
     485          111 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     486          111 :     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(MSEdgeVector());
     501              :             }
     502            0 :             throw;
     503              :         }
     504            0 :     }
     505          100 :     if (!prohibited.empty()) {
     506            0 :         router.prohibit(MSEdgeVector());
     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       465856 : MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector& prohibited) {
     526       465856 :     if (myRouterProvider == nullptr) {
     527           97 :         initWeightUpdate();
     528           97 :         initEdgeWeights(svc);
     529           97 :         initRouter();
     530              :     }
     531              : #ifndef THREAD_POOL
     532              : #ifdef HAVE_FOX
     533       465856 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     534       465856 :     if (threadPool.size() > 0) {
     535        34850 :         auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
     536        34850 :         router.prohibit(prohibited);
     537        34850 :         return router;
     538              :     }
     539              : #else
     540              :     UNUSED_PARAMETER(rngIndex);
     541              : #endif
     542              : #endif
     543       862012 :     myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
     544       431006 :     return myRouterProvider->getVehicleRouter(svc);
     545              : }
     546              : 
     547              : 
     548              : MSTransportableRouter&
     549          111 : MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const MSEdgeVector& prohibited) {
     550          111 :     if (myRouterProvider == nullptr) {
     551            0 :         initWeightUpdate();
     552            0 :         initEdgeWeights(SVC_PEDESTRIAN);
     553            0 :         initRouter();
     554              :     }
     555              : #ifndef THREAD_POOL
     556              : #ifdef HAVE_FOX
     557          111 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     558          111 :     if (threadPool.size() > 0) {
     559           11 :         auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
     560           11 :         router.prohibit(prohibited);
     561           11 :         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        40275 : MSRoutingEngine::cleanup() {
     574        40275 :     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        40275 :     myAdaptationStepsIndex = 0;
     586              : #ifdef HAVE_FOX
     587        40275 :     if (MSGlobals::gNumThreads > 1) {
     588              :         // router deletion is done in thread destructor
     589         4020 :         myRouterProvider = nullptr;
     590         4020 :         return;
     591              :     }
     592              : #endif
     593        36255 :     delete myRouterProvider;
     594        36255 :     myRouterProvider = nullptr;
     595              : }
     596              : 
     597              : 
     598              : #ifdef HAVE_FOX
     599              : void
     600    183543816 : MSRoutingEngine::waitForAll() {
     601              : #ifndef THREAD_POOL
     602    183543816 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     603    183543816 :     if (threadPool.size() > 0) {
     604      7362985 :         threadPool.waitAll();
     605              :     }
     606              : #endif
     607    183543792 : }
     608              : 
     609              : 
     610              : // ---------------------------------------------------------------------------
     611              : // MSRoutingEngine::RoutingTask-methods
     612              : // ---------------------------------------------------------------------------
     613              : void
     614       176487 : MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
     615       176487 :     SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
     616       176487 :     if (!myProhibited.empty()) {
     617            2 :         router.prohibit(myProhibited);
     618              :     }
     619              :     try {
     620       176487 :         myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
     621           24 :     } catch (ProcessError&) {
     622           24 :         if (!mySilent) {
     623           24 :             if (!myProhibited.empty()) {
     624            0 :                 router.prohibit(MSEdgeVector());
     625              :             }
     626           24 :             throw;
     627              :         }
     628           24 :     }
     629       176463 :     if (!myProhibited.empty()) {
     630            2 :         router.prohibit(MSEdgeVector());
     631              :     }
     632       176463 :     const MSEdge* source = *myVehicle.getRoute().begin();
     633       176463 :     const MSEdge* dest = myVehicle.getRoute().getLastEdge();
     634       176463 :     if (source->isTazConnector() && dest->isTazConnector()) {
     635            4 :         const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
     636              :         FXMutexLock lock(myRouteCacheMutex);
     637            4 :         if (MSRoutingEngine::myCachedRoutes.find(key) == MSRoutingEngine::myCachedRoutes.end()) {
     638            6 :             MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
     639              :         }
     640              :     }
     641       176463 : }
     642              : #endif
     643              : 
     644              : 
     645              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1