Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 MSTriggeredRerouter.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @author Mirco Sturari
19 : /// @date Mon, 25 July 2005
20 : ///
21 : // Reroutes vehicles passing an edge
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 :
26 : #include <string>
27 : #include <vector>
28 : #include <map>
29 : #include <utils/common/Command.h>
30 : #include <utils/common/Named.h>
31 : #include <utils/xml/SUMOSAXHandler.h>
32 : #include <utils/distribution/RandomDistributor.h>
33 : #include <microsim/MSMoveReminder.h>
34 : #include "MSStoppingPlaceRerouter.h"
35 :
36 :
37 : // ===========================================================================
38 : // class declarations
39 : // ===========================================================================
40 : class MSNet;
41 : class MSLane;
42 : class MSRoute;
43 : class SUMOVehicle;
44 : class MSBaseVehicle;
45 : class MSParkingArea;
46 : class MSRailSignal;
47 :
48 :
49 : // ===========================================================================
50 : // class definitions
51 : // ===========================================================================
52 : /**
53 : * @class MSTriggeredRerouter
54 : * @brief Reroutes traffic objects passing an edge
55 : *
56 : * A rerouter can be positioned on a list of edges and gives traffic objects which
57 : * enters one of these edges a new route.
58 : *
59 : * The new route may be either chosen from a set of routes where each is
60 : * chosen with a certain probability, or newly computed, either by keeping
61 : * the old destination or by choosing a new one from a set of existing ones.
62 : */
63 : class MSTriggeredRerouter :
64 : public Named, public MSMoveReminder,
65 : public SUMOSAXHandler, MSStoppingPlaceRerouter {
66 :
67 : friend class GUIEdge; // dynamic instantiation
68 :
69 : public:
70 : /** @brief Constructor
71 : *
72 : * @param[in] id The id of the rerouter
73 : * @param[in] edges The edges the rerouter is placed at
74 : * @param[in] prob The probability the rerouter reoutes vehicles with
75 : */
76 : MSTriggeredRerouter(const std::string& id, const MSEdgeVector& edges,
77 : double prob, bool off, bool optional, SUMOTime timeThreshold,
78 : const std::string& vTypes, const Position& pos, const double radius);
79 :
80 :
81 : /** @brief Destructor */
82 : virtual ~MSTriggeredRerouter();
83 :
84 : typedef std::map<const MSEdge*, double> Prohibitions;
85 :
86 : /**
87 : * @struct OvertakeLocation
88 : * Groups data for an overtakingReroute
89 : */
90 99 : struct OvertakeLocation {
91 : /// @brief The list of main edges (const and non-const for different usage)
92 : MSEdgeVector main;
93 : ConstMSEdgeVector cMain;
94 : /// @brief The list of siding edges
95 : MSEdgeVector siding;
96 : ConstMSEdgeVector cSiding;
97 : /// @brief The rail signal at the end of the siding
98 : MSRailSignal* sidingExit = nullptr;
99 : /// @brief The usable length of the siding
100 : double sidingLength = 0;
101 : /// @brief The threshold in savings for triggering reroute
102 : double minSaving;
103 : /// @brief whether the decision to use this siding should be deferred
104 : bool defer;
105 : };
106 :
107 : /**
108 : * @struct RerouteInterval
109 : * Describes the rerouting definitions valid for an interval
110 : */
111 : struct RerouteInterval {
112 : /// unique ID for this interval
113 : long long int id;
114 : /// The begin time these definitions are valid
115 : SUMOTime begin;
116 : /// The end time these definitions are valid
117 : SUMOTime end;
118 : /// The map of closed edges to their permissions and expected end of closing
119 : std::map<MSEdge*, std::pair<SVCPermissions, double> > closed;
120 : /// The list of closed lanes to their permissions
121 : std::map<MSLane*, SVCPermissions> closedLanes;
122 : /// The list of edges that are affected by closed lanes
123 : MSEdgeVector closedLanesAffected;
124 : /// The distributions of new destinations or vias to use
125 : RandomDistributor<MSEdge*> edgeProbs;
126 : /// The distributions of new routes to use
127 : RandomDistributor<ConstMSRoutePtr> routeProbs;
128 : /// The distributions of new parking areas to use as destinations
129 : RandomDistributor<MSStoppingPlaceRerouter::StoppingPlaceVisible> parkProbs;
130 : /// The edge probs are vias and not destinations
131 : bool isVia = false;
132 : /// The permissions are all SVCAll
133 : bool permissionsAllowAll = false;
134 :
135 : /// @name overtakingReroute
136 : ///@{
137 : std::vector<OvertakeLocation> overtakeLocations;
138 : //}
139 :
140 : /// @name stationReroute
141 : ///@{
142 : std::vector<MSStoppingPlaceRerouter::StoppingPlaceVisible> stopAlternatives;
143 : //}
144 :
145 106243 : Prohibitions getClosed() const {
146 : Prohibitions v;
147 108354 : for (const auto& settings : closed) {
148 2111 : v[settings.first] = settings.second.second;
149 : }
150 106243 : return v;
151 : }
152 :
153 73323 : MSEdgeVector getClosedEdges() const {
154 : MSEdgeVector v;
155 85074 : for (const auto& settings : closed) {
156 11751 : v.push_back(settings.first);
157 : }
158 73323 : return v;
159 0 : }
160 : };
161 :
162 : /** @brief Tries to reroute the vehicle
163 : *
164 : * It will not try to reroute if it is a
165 : * lane change because there should be another rerouter on the lane
166 : * the vehicle is coming from.
167 : * Returns false - the vehicle will not be rerouted again.
168 : *
169 : * @param[in] veh The entering vehicle.
170 : * @param[in] reason how the vehicle enters the lane
171 : * @return always false (the vehicle will not be rerouted again)
172 : * @see MSMoveReminder
173 : * @see MSMoveReminder::notifyEnter
174 : * @see MSMoveReminder::Notification
175 : */
176 : bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
177 :
178 : /// @name Methods called on vehicle movement / state change, overwriting MSDevice
179 : /// @{
180 :
181 : /** @brief Triggers rerouting (once) for vehicles that are already on the edge when the rerouter activates
182 : *
183 : * @param[in] veh Vehicle that asks this reminder.
184 : * @param[in] oldPos Position before move.
185 : * @param[in] newPos Position after move with newSpeed.
186 : * @param[in] newSpeed Moving speed.
187 : * @return True (always).
188 : */
189 : bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed);
190 :
191 : /** @brief Removes the reminder
192 : *
193 : * @param[in] veh The leaving vehicle.
194 : * @param[in] lastPos Position on the lane when leaving.
195 : * @param[in] isArrival whether the vehicle arrived at its destination
196 : * @param[in] isLaneChange whether the vehicle changed from the lane
197 : * @return false if the vehicle left th edge
198 : */
199 : bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
200 :
201 : bool triggerRouting(SUMOTrafficObject& veh, MSMoveReminder::Notification reason);
202 :
203 : /// Returns the rerouting definition valid for the given time and object, nullptr if none
204 : const RerouteInterval* getCurrentReroute(SUMOTime time, SUMOTrafficObject& obj) const;
205 :
206 : /// Sets the edge permission if there are any defined in the closingEdge
207 : SUMOTime setPermissions(const SUMOTime currentTime);
208 :
209 : /// Returns the rerouting definition valid for the given time, 0 if none
210 : const RerouteInterval* getCurrentReroute(SUMOTime time) const;
211 :
212 : /// Sets whether the process is currently steered by the user
213 : void setUserMode(bool val);
214 :
215 : /// Sets the probability with which a vehicle is rerouted given by the user
216 : void setUserUsageProbability(double prob);
217 :
218 : /// Returns whether the user is setting the rerouting probability
219 : bool inUserMode() const;
220 :
221 : /// Returns the rerouting probability
222 : double getProbability() const;
223 :
224 : /// Returns the rerouting probability given by the user
225 : double getUserProbability() const;
226 :
227 : // @brief return whether this moveReminder triggers parking reroute
228 9290 : bool isParkingRerouter() const {
229 9290 : return myHaveParkProbs;
230 : }
231 :
232 : const Position& getPosition() {
233 : return myPosition;
234 : }
235 :
236 : /// @brief Return the number of occupied places of the stopping place
237 : double getStoppingPlaceOccupancy(MSStoppingPlace* sp);
238 :
239 : /// @brief Return the number of occupied places of the stopping place from the previous time step
240 : double getLastStepStoppingPlaceOccupancy(MSStoppingPlace* sp);
241 :
242 : /// @brief Return the number of places the stopping place provides
243 : double getStoppingPlaceCapacity(MSStoppingPlace* sp);
244 :
245 : /// @brief store the blocked ParkingArea in the vehicle
246 : void rememberBlockedStoppingPlace(SUMOVehicle& veh, const MSStoppingPlace* parkingArea, bool blocked);
247 :
248 : /// @brief store the score of the ParkingArea in the vehicle
249 : void rememberStoppingPlaceScore(SUMOVehicle& veh, MSStoppingPlace* parkingArea, const std::string& score);
250 :
251 : /// @brief reset all stored ParkingArea scores for this vehicle
252 : void resetStoppingPlaceScores(SUMOVehicle& veh);
253 :
254 : /// @brief get the time the ParkingArea was considered full from this vehicle
255 : SUMOTime sawBlockedStoppingPlace(SUMOVehicle& veh, MSStoppingPlace* parkingArea, bool local);
256 :
257 : /// @brief ask how many times already the vehicle has been rerouted to another stopping place
258 : int getNumberStoppingPlaceReroutes(SUMOVehicle& veh);
259 :
260 : /// @brief update the number of reroutes for the vehicle
261 : void setNumberStoppingPlaceReroutes(SUMOVehicle& veh, int value);
262 :
263 : /// @brief search for an alternative ParkingArea
264 : MSParkingArea* rerouteParkingArea(const MSTriggeredRerouter::RerouteInterval* rerouteDef,
265 : SUMOVehicle& veh, bool& newDestination, ConstMSEdgeVector& newRoute);
266 :
267 : /// @brief determine whether veh should switch from main to siding to be overtaken and return the overtaking vehicle or nullptr
268 : std::pair<const SUMOVehicle*, MSRailSignal*> overtakingTrain(
269 : const SUMOVehicle& veh,
270 : ConstMSEdgeVector::const_iterator mainStart,
271 : const OvertakeLocation& oloc,
272 : double& netSaving);
273 :
274 : /// @brief consider switching the location of the upcoming stop
275 : void checkStopSwitch(MSBaseVehicle& veh, const MSTriggeredRerouter::RerouteInterval* def);
276 :
277 : /// @brief find the last downstream signal on the given route
278 : static MSRailSignal* findSignal(ConstMSEdgeVector::const_iterator begin, ConstMSEdgeVector::const_iterator end);
279 :
280 : /// @brief return railsignal at that edge or nullptr
281 : static MSRailSignal* getRailSignal(const MSEdge* edge);
282 :
283 : /// @brief return all rerouter instances
284 : static const std::map<std::string, MSTriggeredRerouter*>& getInstances() {
285 : return myInstances;
286 : }
287 :
288 : /// @brief issues warning for incomplete parkingReroute relationships
289 : static void checkParkingRerouteConsistency();
290 :
291 : /// @brief provide default values for evaluation components
292 : static double getEvalDefaultWeight(std::string& paramName) {
293 : if (paramName == "") {
294 : return 1.;
295 : }
296 : return 0.;
297 : }
298 :
299 : static const double DEFAULT_MAXDELAY;
300 :
301 : protected:
302 : /// @name inherited from GenericSAXHandler
303 : //@{
304 :
305 : /** @brief Called on the opening of a tag;
306 : *
307 : * @param[in] element ID of the currently opened element
308 : * @param[in] attrs Attributes within the currently opened element
309 : * @exception ProcessError If something fails
310 : * @see GenericSAXHandler::myStartElement
311 : */
312 : virtual void myStartElement(int element,
313 : const SUMOSAXAttributes& attrs);
314 :
315 :
316 : /** @brief Called when a closing tag occurs
317 : *
318 : * @param[in] element ID of the currently opened element
319 : * @exception ProcessError If something fails
320 : * @see GenericSAXHandler::myEndElement
321 : */
322 : virtual void myEndElement(int element);
323 : //@}
324 :
325 : /** @brief Checks whether the detector measures objects of the given type.
326 : *
327 : * @param[in] obj the traffic object of which the type is checked.
328 : * @return whether it should be measured
329 : */
330 : bool applies(const SUMOTrafficObject& obj) const;
331 :
332 : /// @brief reset router after closing edges
333 : void resetClosedEdges(bool hasReroutingDevice, const SUMOTrafficObject& o);
334 :
335 : static bool affected(const std::set<SUMOTrafficObject::NumericalID>& edgeIndices, const MSEdgeVector& closed);
336 :
337 : protected:
338 : /// @brief edges where vehicles are notified
339 : const MSEdgeVector myEdges;
340 :
341 : /// List of rerouting definition intervals
342 : std::vector<RerouteInterval> myIntervals;
343 :
344 : /// The probability and the user-given probability
345 : double myProbability, myUserProbability;
346 :
347 : /// Information whether the current rerouting probability is the user-given
348 : bool myAmInUserMode;
349 :
350 : /// Information whether the rerouting will only take place on request
351 : bool myAmOptional;
352 :
353 : /// Where are we located in the network
354 : Position myPosition;
355 :
356 : /// At which distance are we activated
357 : double myRadius;
358 :
359 : // @brief waiting time threshold for activation
360 : SUMOTime myTimeThreshold;
361 :
362 : /// @brief The vehicle types to look for (empty means all)
363 : std::set<std::string> myVehicleTypes;
364 :
365 : /// used during loading
366 : RerouteInterval myParsedRerouteInterval;
367 :
368 : /// whether this rerouter has loaded parkingReroute definitions
369 : bool myHaveParkProbs;
370 :
371 : std::set<const MSStoppingPlace*> myBlockedStoppingPlaces;
372 :
373 : /// @brief special destination values
374 : static MSEdge mySpecialDest_keepDestination;
375 : static MSEdge mySpecialDest_terminateRoute;
376 :
377 : static std::map<std::string, MSTriggeredRerouter*> myInstances;
378 :
379 : private:
380 : /// @brief Invalidated copy constructor.
381 : MSTriggeredRerouter(const MSTriggeredRerouter&);
382 :
383 : /// @brief Invalidated assignment operator.
384 : MSTriggeredRerouter& operator=(const MSTriggeredRerouter&);
385 :
386 :
387 : };
|