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*, RouterProhibition> 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 106188 : Prohibitions getClosed() const {
146 : Prohibitions v;
147 108422 : for (const auto& settings : closed) {
148 : // no permissions are changed but edges are forbidden for all during routing
149 3129 : v[settings.first].permissions = settings.second.first == SVCAll ? 0 : settings.second.first;
150 2234 : if (settings.second.second != -1) {
151 : // end time is known
152 3 : v[settings.first].end = STEPS2TIME(settings.second.second);
153 : }
154 : }
155 106188 : return v;
156 : }
157 :
158 79051 : MSEdgeVector getClosedEdges() const {
159 : MSEdgeVector v;
160 91117 : for (const auto& settings : closed) {
161 12066 : v.push_back(settings.first);
162 : }
163 79051 : return v;
164 0 : }
165 : };
166 :
167 : /** @brief Tries to reroute the vehicle
168 : *
169 : * It will not try to reroute if it is a
170 : * lane change because there should be another rerouter on the lane
171 : * the vehicle is coming from.
172 : * Returns false - the vehicle will not be rerouted again.
173 : *
174 : * @param[in] veh The entering vehicle.
175 : * @param[in] reason how the vehicle enters the lane
176 : * @return always false (the vehicle will not be rerouted again)
177 : * @see MSMoveReminder
178 : * @see MSMoveReminder::notifyEnter
179 : * @see MSMoveReminder::Notification
180 : */
181 : bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
182 :
183 : /// @name Methods called on vehicle movement / state change, overwriting MSDevice
184 : /// @{
185 :
186 : /** @brief Triggers rerouting (once) for vehicles that are already on the edge when the rerouter activates
187 : *
188 : * @param[in] veh Vehicle that asks this reminder.
189 : * @param[in] oldPos Position before move.
190 : * @param[in] newPos Position after move with newSpeed.
191 : * @param[in] newSpeed Moving speed.
192 : * @return True (always).
193 : */
194 : bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed);
195 :
196 : /** @brief Removes the reminder
197 : *
198 : * @param[in] veh The leaving vehicle.
199 : * @param[in] lastPos Position on the lane when leaving.
200 : * @param[in] isArrival whether the vehicle arrived at its destination
201 : * @param[in] isLaneChange whether the vehicle changed from the lane
202 : * @return false if the vehicle left th edge
203 : */
204 : bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
205 :
206 : bool triggerRouting(SUMOTrafficObject& veh, MSMoveReminder::Notification reason);
207 :
208 : /// Returns the rerouting definition valid for the given time and object, nullptr if none
209 : const RerouteInterval* getCurrentReroute(SUMOTime time, SUMOTrafficObject& obj) const;
210 :
211 : /// Sets the edge permission if there are any defined in the closingEdge
212 : SUMOTime setPermissions(const SUMOTime currentTime);
213 :
214 : /// Returns the rerouting definition valid for the given time, 0 if none
215 : const RerouteInterval* getCurrentReroute(SUMOTime time) const;
216 :
217 : /// Sets whether the process is currently steered by the user
218 : void setUserMode(bool val);
219 :
220 : /// Sets the probability with which a vehicle is rerouted given by the user
221 : void setUserUsageProbability(double prob);
222 :
223 : /// Returns whether the user is setting the rerouting probability
224 : bool inUserMode() const;
225 :
226 : /// Returns the rerouting probability
227 : double getProbability() const;
228 :
229 : /// Returns the rerouting probability given by the user
230 : double getUserProbability() const;
231 :
232 : // @brief return whether this moveReminder triggers parking reroute
233 9351 : bool isParkingRerouter() const {
234 9351 : return myHaveParkProbs;
235 : }
236 :
237 : const Position& getPosition() {
238 : return myPosition;
239 : }
240 :
241 : /// @brief Return the number of occupied places of the stopping place
242 : double getStoppingPlaceOccupancy(MSStoppingPlace* sp);
243 :
244 : /// @brief Return the number of occupied places of the stopping place from the previous time step
245 : double getLastStepStoppingPlaceOccupancy(MSStoppingPlace* sp);
246 :
247 : /// @brief Return the number of places the stopping place provides
248 : double getStoppingPlaceCapacity(MSStoppingPlace* sp);
249 :
250 : /// @brief store the blocked ParkingArea in the vehicle
251 : void rememberBlockedStoppingPlace(SUMOVehicle& veh, const MSStoppingPlace* parkingArea, bool blocked);
252 :
253 : /// @brief store the score of the ParkingArea in the vehicle
254 : void rememberStoppingPlaceScore(SUMOVehicle& veh, MSStoppingPlace* parkingArea, const std::string& score);
255 :
256 : /// @brief reset all stored ParkingArea scores for this vehicle
257 : void resetStoppingPlaceScores(SUMOVehicle& veh);
258 :
259 : /// @brief get the time the ParkingArea was considered full from this vehicle
260 : SUMOTime sawBlockedStoppingPlace(SUMOVehicle& veh, MSStoppingPlace* parkingArea, bool local);
261 :
262 : /// @brief ask how many times already the vehicle has been rerouted to another stopping place
263 : int getNumberStoppingPlaceReroutes(SUMOVehicle& veh);
264 :
265 : /// @brief update the number of reroutes for the vehicle
266 : void setNumberStoppingPlaceReroutes(SUMOVehicle& veh, int value);
267 :
268 : /// @brief search for an alternative ParkingArea
269 : MSParkingArea* rerouteParkingArea(const MSTriggeredRerouter::RerouteInterval* rerouteDef,
270 : SUMOVehicle& veh, bool& newDestination, ConstMSEdgeVector& newRoute);
271 :
272 : /// @brief determine whether veh should switch from main to siding to be overtaken and return the overtaking vehicle or nullptr
273 : std::pair<const SUMOVehicle*, MSRailSignal*> overtakingTrain(
274 : const SUMOVehicle& veh,
275 : ConstMSEdgeVector::const_iterator mainStart,
276 : const OvertakeLocation& oloc,
277 : double& netSaving);
278 :
279 : /// @brief consider switching the location of the upcoming stop
280 : void checkStopSwitch(MSBaseVehicle& veh, const MSTriggeredRerouter::RerouteInterval* def);
281 :
282 : /// @brief find the last downstream signal on the given route
283 : static MSRailSignal* findSignal(ConstMSEdgeVector::const_iterator begin, ConstMSEdgeVector::const_iterator end);
284 :
285 : /// @brief return railsignal at that edge or nullptr
286 : static MSRailSignal* getRailSignal(const MSEdge* edge);
287 :
288 : /// @brief return all rerouter instances
289 : static const std::map<std::string, MSTriggeredRerouter*>& getInstances() {
290 : return myInstances;
291 : }
292 :
293 : /// @brief issues warning for incomplete parkingReroute relationships
294 : static void checkParkingRerouteConsistency();
295 :
296 : /// @brief provide default values for evaluation components
297 : static double getEvalDefaultWeight(std::string& paramName) {
298 : if (paramName == "") {
299 : return 1.;
300 : }
301 : return 0.;
302 : }
303 :
304 : static const double DEFAULT_MAXDELAY;
305 :
306 : protected:
307 : /// @name inherited from GenericSAXHandler
308 : //@{
309 :
310 : /** @brief Called on the opening of a tag;
311 : *
312 : * @param[in] element ID of the currently opened element
313 : * @param[in] attrs Attributes within the currently opened element
314 : * @exception ProcessError If something fails
315 : * @see GenericSAXHandler::myStartElement
316 : */
317 : virtual void myStartElement(int element,
318 : const SUMOSAXAttributes& attrs);
319 :
320 :
321 : /** @brief Called when a closing tag occurs
322 : *
323 : * @param[in] element ID of the currently opened element
324 : * @exception ProcessError If something fails
325 : * @see GenericSAXHandler::myEndElement
326 : */
327 : virtual void myEndElement(int element);
328 : //@}
329 :
330 : /** @brief Checks whether the detector measures objects of the given type.
331 : *
332 : * @param[in] obj the traffic object of which the type is checked.
333 : * @return whether it should be measured
334 : */
335 : bool applies(const SUMOTrafficObject& obj) const;
336 :
337 : /// @brief reset router after closing edges
338 : void resetClosedEdges(bool hasReroutingDevice, const SUMOTrafficObject& o);
339 :
340 : static bool affected(const std::set<SUMOTrafficObject::NumericalID>& edgeIndices, const MSEdgeVector& closed);
341 :
342 : protected:
343 : /// @brief edges where vehicles are notified
344 : const MSEdgeVector myEdges;
345 :
346 : /// List of rerouting definition intervals
347 : std::vector<RerouteInterval> myIntervals;
348 :
349 : /// The probability and the user-given probability
350 : double myProbability, myUserProbability;
351 :
352 : /// Information whether the current rerouting probability is the user-given
353 : bool myAmInUserMode;
354 :
355 : /// Information whether the rerouting will only take place on request
356 : bool myAmOptional;
357 :
358 : /// Where are we located in the network
359 : Position myPosition;
360 :
361 : /// At which distance are we activated
362 : double myRadius;
363 :
364 : // @brief waiting time threshold for activation
365 : SUMOTime myTimeThreshold;
366 :
367 : /// @brief The vehicle types to look for (empty means all)
368 : std::set<std::string> myVehicleTypes;
369 :
370 : /// used during loading
371 : RerouteInterval myParsedRerouteInterval;
372 :
373 : /// whether this rerouter has loaded parkingReroute definitions
374 : bool myHaveParkProbs;
375 :
376 : std::set<const MSStoppingPlace*> myBlockedStoppingPlaces;
377 :
378 : /// @brief special destination values
379 : static MSEdge mySpecialDest_keepDestination;
380 : static MSEdge mySpecialDest_terminateRoute;
381 :
382 : static std::map<std::string, MSTriggeredRerouter*> myInstances;
383 :
384 : private:
385 : /// @brief Invalidated copy constructor.
386 : MSTriggeredRerouter(const MSTriggeredRerouter&);
387 :
388 : /// @brief Invalidated assignment operator.
389 : MSTriggeredRerouter& operator=(const MSTriggeredRerouter&);
390 :
391 :
392 : };
|