1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2007-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file MSRoutingEngine.h 11 /// @author Michael Behrisch 12 /// @author Daniel Krajzewicz 13 /// @author Jakob Erdmann 14 /// @date Tue, 04 Dec 2007 15 /// @version $Id$ 16 /// 17 // A device that performs vehicle rerouting based on current edge speeds 18 /****************************************************************************/ 19 #ifndef MSRoutingEngine_h 20 #define MSRoutingEngine_h 21 22 23 // =========================================================================== 24 // included modules 25 // =========================================================================== 26 #include <config.h> 27 28 #include <set> 29 #include <vector> 30 #include <map> 31 #include <utils/common/SUMOTime.h> 32 #include <utils/common/WrappingCommand.h> 33 #include <utils/router/SUMOAbstractRouter.h> 34 #include <utils/router/AStarRouter.h> 35 #include <microsim/MSVehicle.h> 36 #include "MSDevice.h" 37 38 #ifdef HAVE_FOX 39 #include <utils/foxtools/FXWorkerThread.h> 40 #endif 41 42 43 // =========================================================================== 44 // class definitions 45 // =========================================================================== 46 /** 47 * @class MSRoutingEngine 48 * @brief A device that performs vehicle rerouting based on current edge speeds 49 * 50 * The routing-device system consists of in-vehicle devices that perform a routing 51 * and a simulation-wide (static) methods for colecting edge weights. 52 * 53 * The edge weights container "myEdgeSpeeds" is pre-initialised as soon as one 54 * device is built and is kept updated via an event that adapts it to the current 55 * mean speed on the simulated network's edges. 56 * 57 * A device is assigned to a vehicle using the common explicit/probability - procedure. 58 * 59 * A device computes a new route for a vehicle as soon as the vehicle is inserted 60 * (within "enterLaneAtInsertion") - and, if the given period is larger than 0 - each 61 * x time steps where x is the period. This is triggered by an event that executes 62 * "wrappedRerouteCommandExecute". 63 */ 64 class MSRoutingEngine { 65 public: 66 /// @brief intialize period edge weight update 67 static void initWeightUpdate(); 68 69 /// @brief initialize the edge weights if not done before 70 static void initEdgeWeights(); 71 72 /// @brief returns whether any routing actions take place hasEdgeUpdates()73 static bool hasEdgeUpdates() { 74 return myEdgeWeightSettingCommand != nullptr; 75 } 76 77 /// @brief Information when the last edge weight adaptation occurred getLastAdaptation()78 static SUMOTime getLastAdaptation() { 79 return myLastAdaptation; 80 } 81 82 /// @brief return the cached route or nullptr on miss 83 static const MSRoute* getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key); 84 85 /// @brief initiate the rerouting, create router / thread pool on first use 86 static void reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const bool onInit); 87 88 /// @brief adapt the known travel time for an edge 89 static void setEdgeTravelTime(const MSEdge* const edge, const double travelTime); 90 91 /// @brief deletes the router instance 92 static void cleanup(); 93 94 /// @brief returns whether any routing actions take place isEnabled()95 static bool isEnabled() { 96 return !myWithTaz && myAdaptationInterval >= 0; 97 } 98 99 /// @brief return the router instance 100 static SUMOAbstractRouter<MSEdge, SUMOVehicle>& getRouterTT( 101 const MSEdgeVector& prohibited = MSEdgeVector()); 102 103 /** @brief Returns the effort to pass an edge 104 * 105 * This method is given to the used router in order to obtain the efforts 106 * to pass an edge from the internal edge weights container. 107 * 108 * The time is not used, here, as the current simulation state is 109 * used in an aggregated way. 110 * 111 * @param[in] e The edge for which the effort to be passed shall be returned 112 * @param[in] v The vehicle that is rerouted 113 * @param[in] t The time for which the effort shall be returned 114 * @return The effort (time to pass in this case) for an edge 115 * @see DijkstraRouter_ByProxi 116 */ 117 static double getEffort(const MSEdge* const e, const SUMOVehicle* const v, double t); 118 119 /// @brief return current travel speed assumption 120 static double getAssumedSpeed(const MSEdge* edge); 121 122 #ifdef HAVE_FOX 123 static void waitForAll(); lock()124 static void lock() { 125 myThreadPool.lock(); 126 } unlock()127 static void unlock() { 128 myThreadPool.unlock(); 129 } isParallel()130 static bool isParallel() { 131 return myThreadPool.size() > 0; 132 } 133 #endif 134 135 136 private: 137 #ifdef HAVE_FOX 138 /** 139 * @class WorkerThread 140 * @brief the thread which provides the router instance as context 141 */ 142 class WorkerThread : public FXWorkerThread { 143 public: WorkerThread(FXWorkerThread::Pool & pool,SUMOAbstractRouter<MSEdge,SUMOVehicle> * router)144 WorkerThread(FXWorkerThread::Pool& pool, 145 SUMOAbstractRouter<MSEdge, SUMOVehicle>* router) 146 : FXWorkerThread(pool), myRouter(router) {} getRouter()147 SUMOAbstractRouter<MSEdge, SUMOVehicle>& getRouter() const { 148 return *myRouter; 149 } ~WorkerThread()150 virtual ~WorkerThread() { 151 stop(); 152 delete myRouter; 153 } 154 private: 155 SUMOAbstractRouter<MSEdge, SUMOVehicle>* myRouter; 156 }; 157 158 /** 159 * @class RoutingTask 160 * @brief the routing task which mainly calls reroute of the vehicle 161 */ 162 class RoutingTask : public FXWorkerThread::Task { 163 public: RoutingTask(SUMOVehicle & v,const SUMOTime time,const bool onInit)164 RoutingTask(SUMOVehicle& v, const SUMOTime time, const bool onInit) 165 : myVehicle(v), myTime(time), myOnInit(onInit) {} 166 void run(FXWorkerThread* context); 167 private: 168 SUMOVehicle& myVehicle; 169 const SUMOTime myTime; 170 const bool myOnInit; 171 private: 172 /// @brief Invalidated assignment operator. 173 RoutingTask& operator=(const RoutingTask&); 174 }; 175 #endif 176 177 /// @name Network state adaptation 178 /// @{ 179 180 /** @brief Adapt edge efforts by the current edge states 181 * 182 * This method is called by the event handler at the end of a simulation 183 * step. The current edge weights are combined with the previously stored. 184 * 185 * @param[in] currentTime The current simulation time 186 * @return The offset to the next call (always 1 in this case - edge weights are updated each time step) 187 * @todo Describe how the weights are adapted 188 * @see MSEventHandler 189 * @see StaticCommand 190 */ 191 static SUMOTime adaptEdgeEfforts(SUMOTime currentTime); 192 /// @} 193 194 195 private: 196 /// @brief The weights adaptation/overwriting command 197 static Command* myEdgeWeightSettingCommand; 198 199 /// @brief The container of edge speeds 200 static std::vector<double> myEdgeSpeeds; 201 202 /// @brief Information which weight prior edge efforts have 203 static double myAdaptationWeight; 204 205 /// @brief At which time interval the edge weights get updated 206 static SUMOTime myAdaptationInterval; 207 208 /// @brief Information when the last edge weight adaptation occurred 209 static SUMOTime myLastAdaptation; 210 211 /// @brief The number of steps for averaging edge speeds (ring-buffer) 212 static int myAdaptationSteps; 213 214 /// @brief The current index in the pastEdgeSpeed ring-buffer 215 static int myAdaptationStepsIndex; 216 217 /// @brief The container of edge speeds 218 static std::vector<std::vector<double> > myPastEdgeSpeeds; 219 220 /// @brief whether taz shall be used at initial rerouting 221 static bool myWithTaz; 222 223 /// @brief The router to use 224 static SUMOAbstractRouter<MSEdge, SUMOVehicle>* myRouter; 225 226 /// @brief The router to use by rerouter elements 227 static AStarRouter<MSEdge, SUMOVehicle, SUMOAbstractRouterPermissions<MSEdge, SUMOVehicle> >* myRouterWithProhibited; 228 229 /// @brief The container of pre-calculated routes 230 static std::map<std::pair<const MSEdge*, const MSEdge*>, const MSRoute*> myCachedRoutes; 231 232 #ifdef HAVE_FOX 233 static FXWorkerThread::Pool myThreadPool; 234 #endif 235 236 private: 237 /// @brief Invalidated copy constructor. 238 MSRoutingEngine(const MSRoutingEngine&); 239 240 /// @brief Invalidated assignment operator. 241 MSRoutingEngine& operator=(const MSRoutingEngine&); 242 243 244 }; 245 246 247 #endif 248 249 /****************************************************************************/ 250 251