Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2007-2025 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.h
15 : /// @author Michael Behrisch
16 : /// @author Daniel Krajzewicz
17 : /// @author Jakob Erdmann
18 : /// @date Tue, 04 Dec 2007
19 : ///
20 : // A device that performs vehicle rerouting based on current edge speeds
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <set>
26 : #include <vector>
27 : #include <map>
28 : #include <thread>
29 : #include <utils/common/SUMOTime.h>
30 : #include <utils/common/WrappingCommand.h>
31 : #include <utils/router/AStarRouter.h>
32 : #include <microsim/MSRouterDefs.h>
33 :
34 : #ifdef HAVE_FOX
35 : #include <utils/foxtools/MFXWorkerThread.h>
36 : #endif
37 :
38 :
39 : // ===========================================================================
40 : // class declarations
41 : // ===========================================================================
42 : class MSTransportable;
43 : class SUMOSAXAttributes;
44 :
45 : // ===========================================================================
46 : // class definitions
47 : // ===========================================================================
48 : /**
49 : * @class MSRoutingEngine
50 : * @brief A device that performs vehicle rerouting based on current edge speeds
51 : *
52 : * The routing-device system consists of in-vehicle devices that perform a routing
53 : * and a simulation-wide (static) methods for colecting edge weights.
54 : *
55 : * The edge weights container "myEdgeSpeeds" is pre-initialised as soon as one
56 : * device is built and is kept updated via an event that adapts it to the current
57 : * mean speed on the simulated network's edges.
58 : *
59 : * A device is assigned to a vehicle using the common explicit/probability - procedure.
60 : *
61 : * A device computes a new route for a vehicle as soon as the vehicle is inserted
62 : * (within "enterLaneAtInsertion") - and, if the given period is larger than 0 - each
63 : * x time steps where x is the period. This is triggered by an event that executes
64 : * "wrappedRerouteCommandExecute".
65 : */
66 : class MSRoutingEngine {
67 : public:
68 : typedef std::map<const MSEdge*, double> Prohibitions;
69 :
70 : /// @brief intialize period edge weight update
71 : static void initWeightUpdate();
72 :
73 : /// @brief initialize the edge weights if not done before
74 : static void initEdgeWeights(SUMOVehicleClass svc, SUMOTime lastAdaption = -1, int index = -1);
75 :
76 : /// @brief returns whether any edge weight updates will take place
77 : static bool hasEdgeUpdates() {
78 1575029 : return myEdgeWeightSettingCommand != nullptr;
79 : }
80 :
81 : /// @brief Information when the last edge weight adaptation occurred
82 : static SUMOTime getLastAdaptation() {
83 2327448 : return myLastAdaptation;
84 : }
85 :
86 : /// @brief return the cached route or nullptr on miss
87 : static ConstMSRoutePtr getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key);
88 :
89 : static void initRouter(SUMOVehicle* vehicle = nullptr);
90 :
91 : /// @brief initiate the rerouting, create router / thread pool on first use
92 : static void reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
93 : const bool onInit = false, const bool silent = false, const Prohibitions& prohibited = {});
94 :
95 : /// @brief initiate the person rerouting, create router / thread pool on first use
96 : static void reroute(MSTransportable& t, const SUMOTime currentTime, const std::string& info,
97 : const bool onInit = false, const bool silent = false, const Prohibitions& prohibited = {});
98 :
99 : /// @brief adapt the known travel time for an edge
100 : static void setEdgeTravelTime(const MSEdge* const edge, const double travelTime);
101 :
102 : /// @brief deletes the router instance
103 : static void cleanup();
104 :
105 : /// @brief returns whether any routing actions take place
106 : static bool isEnabled() {
107 142569379 : return !myWithTaz && myAdaptationInterval >= 0;
108 : }
109 :
110 : /// @brief return the vehicle router instance
111 : static MSVehicleRouter& getRouterTT(const int rngIndex,
112 : SUMOVehicleClass svc,
113 : const Prohibitions& prohibited = {});
114 :
115 : /// @brief return the person router instance
116 : static MSTransportableRouter& getIntermodalRouterTT(const int rngIndex,
117 : const Prohibitions& prohibited = {});
118 :
119 : /** @brief Returns the effort to pass an edge
120 : *
121 : * This method is given to the used router in order to obtain the efforts
122 : * to pass an edge from the internal edge weights container.
123 : *
124 : * The time is not used, here, as the current simulation state is
125 : * used in an aggregated way.
126 : *
127 : * @param[in] e The edge for which the effort to be passed shall be returned
128 : * @param[in] v The vehicle that is rerouted
129 : * @param[in] t The time for which the effort shall be returned
130 : * @return The effort (time to pass in this case) for an edge
131 : * @see DijkstraRouter_ByProxi
132 : */
133 : static double getEffort(const MSEdge* const e, const SUMOVehicle* const v, double t);
134 : static double getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double t);
135 : static double getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t);
136 : static SUMOAbstractRouter<MSEdge, SUMOVehicle>::Operation myEffortFunc;
137 :
138 : /// @brief return current travel speed assumption
139 : static double getAssumedSpeed(const MSEdge* edge, const SUMOVehicle* veh);
140 :
141 : /// @brief whether taz-routing is enabled
142 : static bool withTaz() {
143 440358 : return myWithTaz;
144 : }
145 :
146 : /// @brief record actual travel time for an edge
147 : static void addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime);
148 :
149 : /** @brief Saves the state (i.e. recorded speeds)
150 : *
151 : * @param[in] out The OutputDevice to write the information into
152 : */
153 : static void saveState(OutputDevice& out);
154 :
155 : /** @brief Loads the state
156 : *
157 : * @param[in] attrs XML attributes describing the current state
158 : */
159 : static void loadState(const SUMOSAXAttributes& attrs);
160 :
161 : #ifdef HAVE_FOX
162 : static void waitForAll();
163 : #endif
164 :
165 :
166 : private:
167 : #ifdef HAVE_FOX
168 : /**
169 : * @class RoutingTask
170 : * @brief the routing task which mainly calls reroute of the vehicle
171 : */
172 : class RoutingTask : public MFXWorkerThread::Task {
173 : public:
174 188386 : RoutingTask(SUMOVehicle& v, const SUMOTime time, const std::string& info,
175 : const bool onInit, const bool silent, const Prohibitions& prohibited)
176 188386 : : myVehicle(v), myTime(time), myInfo(info), myOnInit(onInit), mySilent(silent), myProhibited(prohibited) {}
177 : void run(MFXWorkerThread* context);
178 : private:
179 : SUMOVehicle& myVehicle;
180 : const SUMOTime myTime;
181 : const std::string myInfo;
182 : const bool myOnInit;
183 : const bool mySilent;
184 : const Prohibitions myProhibited;
185 : private:
186 : /// @brief Invalidated assignment operator.
187 : RoutingTask& operator=(const RoutingTask&) = delete;
188 : };
189 :
190 : #endif
191 :
192 : /// @name Network state adaptation
193 : /// @{
194 :
195 : /** @brief Adapt edge efforts by the current edge states
196 : *
197 : * This method is called by the event handler at the end of a simulation
198 : * step. The current edge weights are combined with the previously stored.
199 : *
200 : * @param[in] currentTime The current simulation time
201 : * @return The offset to the next call (always 1 in this case - edge weights are updated each time step)
202 : * @todo Describe how the weights are adapted
203 : * @see MSEventHandler
204 : * @see StaticCommand
205 : */
206 : static SUMOTime adaptEdgeEfforts(SUMOTime currentTime);
207 :
208 : static double patchSpeedForTurns(const MSEdge* edge, double currSpeed);
209 : /// @}
210 :
211 : /// @brief initialized edge speed storage into the given containers
212 : static void _initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds);
213 :
214 : /// @brief returns RNG associated with the current thread
215 : static SumoRNG* getThreadRNG();
216 :
217 : private:
218 : /// @brief The weights adaptation/overwriting command
219 : static Command* myEdgeWeightSettingCommand;
220 :
221 : /// @brief Information which weight prior edge efforts have
222 : static double myAdaptationWeight;
223 :
224 : /// @brief At which time interval the edge weights get updated
225 : static SUMOTime myAdaptationInterval;
226 :
227 : /// @brief Information when the last edge weight adaptation occurred
228 : static SUMOTime myLastAdaptation;
229 :
230 : /// @brief The number of steps for averaging edge speeds (ring-buffer)
231 : static int myAdaptationSteps;
232 :
233 : /// @brief The current index in the pastEdgeSpeed ring-buffer
234 : static int myAdaptationStepsIndex;
235 :
236 : typedef std::pair<SUMOTime, int> TimeAndCount;
237 :
238 : /// @brief The container of edge speeds
239 : static std::vector<double> myEdgeSpeeds;
240 : static std::vector<double> myEdgeBikeSpeeds;
241 :
242 : /// @brief Sum of travel times experienced by equipped vehicles for each edge
243 : static std::vector<TimeAndCount> myEdgeTravelTimes;
244 :
245 : /// @brief The container of past edge speeds (when using a simple moving average)
246 : static std::vector<std::vector<double> > myPastEdgeSpeeds;
247 : static std::vector<std::vector<double> > myPastEdgeBikeSpeeds;
248 :
249 : /// @brief whether taz shall be used at initial rerouting
250 : static bool myWithTaz;
251 :
252 : /// @brief whether separate speeds for bicycles shall be tracked
253 : static bool myBikeSpeeds;
254 :
255 : /// @brief The router to use
256 : static MSRouterProvider* myRouterProvider;
257 :
258 : /// @brief The container of pre-calculated routes
259 : static std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> myCachedRoutes;
260 :
261 : /// @brief Coefficient for factoring edge priority into routing weight
262 : static double myPriorityFactor;
263 :
264 : /// @brief Minimum priority for all edges
265 : static double myMinEdgePriority;
266 : /// @brief the difference between maximum and minimum priority for all edges
267 : static double myEdgePriorityRange;
268 :
269 : /// @brief whether randomness varies over time
270 : static bool myDynamicRandomness;
271 :
272 : #ifdef HAVE_FOX
273 : /// @brief Mutex for accessing the route cache
274 : static FXMutex myRouteCacheMutex;
275 : #endif
276 :
277 : private:
278 : /// @brief Invalidated copy constructor.
279 : MSRoutingEngine(const MSRoutingEngine&);
280 :
281 : /// @brief Invalidated assignment operator.
282 : MSRoutingEngine& operator=(const MSRoutingEngine&);
283 :
284 :
285 : };
|