Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 MSStoppingPlaceRerouter.h
15 : /// @author Mirko Barthauer
16 : /// @date Mon, 17 June 2024
17 : ///
18 : // The MSStoppingPlaceRerouter provides an interface to structure the rerouting
19 : // to the best StoppingPlace according to the evaluation components and
20 : // associated weights.
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 : #include <map>
25 : #include <functional>
26 : #include <utils/common/MsgHandler.h>
27 : #include <utils/common/Named.h>
28 : #include <utils/common/SUMOTime.h>
29 : #include <utils/router/SUMOAbstractRouter.h>
30 : #include <utils/xml/SUMOXMLDefinitions.h>
31 : #include <microsim/MSNet.h>
32 : #include <microsim/MSStoppingPlace.h>
33 :
34 : class MSEdge;
35 :
36 : /// @brief store information for a single stopping place
37 12895 : struct StoppingPlaceMemoryEntry {
38 12895 : StoppingPlaceMemoryEntry() : blockedAtTime(-1), blockedAtTimeLocal(-1), score("") {}
39 :
40 : SUMOTime blockedAtTime;
41 : SUMOTime blockedAtTimeLocal;
42 : std::string score;
43 : };
44 :
45 :
46 : class StoppingPlaceMemory {
47 : public:
48 : /// @brief Definition of the map containing all visited stopping places
49 : typedef std::map<const MSStoppingPlace*, StoppingPlaceMemoryEntry, ComparatorIdLess> StoppingPlaceMap;
50 :
51 : ///@brief Constructor
52 2069 : StoppingPlaceMemory() {}
53 :
54 : // Destructor
55 2069 : virtual ~StoppingPlaceMemory() {}
56 :
57 : /** @brief Removes an item
58 : * @param[in] id The id of the item to remove
59 : * @return If the item could be removed (an item with the id was within the container before)
60 : */
61 : bool remove(MSStoppingPlace* id) {
62 : auto it = myMap.find(id);
63 : if (it == myMap.end()) {
64 : return false;
65 : } else {
66 : myMap.erase(it);
67 : return true;
68 : }
69 : }
70 :
71 : /// @brief Removes all data about evaluated StoppingPlace items
72 : void clear() {
73 : myMap.clear();
74 : }
75 :
76 : /// @brief Returns the number of stored items within the container
77 : int size() const {
78 : return (int)myMap.size();
79 : }
80 :
81 : /// @brief Store the time the StoppingPlace was confirmed to be blocked
82 30884 : void rememberBlockedStoppingPlace(const MSStoppingPlace* stoppingPlace, bool local) {
83 30884 : myMap[stoppingPlace].blockedAtTime = SIMSTEP;
84 30884 : if (local) {
85 28179 : myMap[stoppingPlace].blockedAtTimeLocal = SIMSTEP;
86 : }
87 30884 : }
88 :
89 : /// @brief Get the time the StoppingPlace was confirmed to be blocked
90 : SUMOTime sawBlockedStoppingPlace(const MSStoppingPlace* stoppingPlace, bool local) const {
91 : auto it = myMap.find(stoppingPlace);
92 37884 : if (it == myMap.end()) {
93 : return -1;
94 : } else {
95 31531 : return local ? it->second.blockedAtTimeLocal : it->second.blockedAtTime;
96 : }
97 : }
98 :
99 : /// @brief score only needed when running with gui
100 : void rememberStoppingPlaceScore(const MSStoppingPlace* stoppingPlace, const std::string& score) {
101 54667 : myMap[stoppingPlace].score = score;
102 : }
103 :
104 10643 : void resetStoppingPlaceScores() {
105 82625 : for (auto& item : myMap) {
106 71982 : item.second.score = "";
107 : }
108 10643 : }
109 :
110 : /// @brief Returns a reference to the begin iterator for the internal map
111 : typename StoppingPlaceMap::const_iterator begin() const {
112 : return myMap.begin();
113 : }
114 :
115 : /// @brief Returns a reference to the end iterator for the internal map
116 : typename StoppingPlaceMap::const_iterator end() const {
117 : return myMap.end();
118 : }
119 :
120 : private:
121 : /// @brief The map from StoppingPlace to single evaluation
122 : StoppingPlaceMap myMap;
123 :
124 : };
125 :
126 :
127 : class MSStoppingPlaceRerouter {
128 : public:
129 : typedef std::map<std::string, double> StoppingPlaceParamMap_t;
130 : typedef std::map<std::string, bool> StoppingPlaceParamSwitchMap_t;
131 : typedef std::map<MSStoppingPlace*, StoppingPlaceParamMap_t, ComparatorIdLess> StoppingPlaceMap_t;
132 : typedef std::pair<MSStoppingPlace*, bool> StoppingPlaceVisible;
133 :
134 : ///@brief Constructor
135 : MSStoppingPlaceRerouter(SumoXMLTag stoppingType, std::string paramPrefix = "", bool checkValidity = false, bool checkVisibility = true, StoppingPlaceParamMap_t addEvalParams = {}, StoppingPlaceParamSwitchMap_t addInvertParams = {});
136 :
137 : // Destructor
138 6900 : virtual ~MSStoppingPlaceRerouter() {}
139 :
140 : /** @brief main method to trigger the rerouting to the "best" StoppingPlace according to the custom evaluation function
141 : *
142 : * @param[in] veh the concerned vehicle
143 : * @param[in] stoppingPlaceCandidates stopping places to choose from and whether they are visible for the vehicle
144 : * @param[in] probs probabilities of all candidate stopping places
145 : * @param[in] newDestination whether the destination changed
146 : * @param[out] newRoute the route to/from the chosen stopping place is stored here
147 : * @param[in,out] scores input score values from external source and get scores of all components of the "best" StoppingPlace
148 : * @param[in] closedEdges edges to avoid during routing
149 : * @return the best stopping place according to the target function or nullptr
150 : */
151 : MSStoppingPlace* reroute(std::vector<StoppingPlaceVisible>& stoppingPlaceCandidates, const std::vector<double>& probs, SUMOVehicle& veh,
152 : bool& newDestination, ConstMSEdgeVector& newRoute, StoppingPlaceParamMap_t& scores, const MSEdgeVector& closedEdges = {});
153 : /** @brief compute the target function for a single alternative
154 : *
155 : * @param[in] veh the concerned vehicle
156 : * @param[in] brakeGap the distance before which the vehicle cannot stop
157 : * @param[in] newDestination whether the destination changed
158 : * @param[in] alternative the stopping place to evaluate
159 : * @param[in] occupancy occupancy of the stopping place
160 : * @param[in] prob the predefined probability of this stopping place
161 : * @param[in] router the router to use for evaluation if needed
162 : * @param[in,out] stoppingPlaces the data structure to write the evaluation values to
163 : * @param[in,out] newRoutes the data structure to write the chosen route to/from the stopping place to
164 : * @param[in,out] stoppingPlaceApproaches the data structure to write the chosen route to the stopping place to
165 : * @param[in,out] maxValues maximum values for all evaluation components
166 : * @param[in] addInput external input data
167 : * @return false if the stopping place cannot be used
168 : */
169 : virtual bool evaluateDestination(SUMOVehicle& veh, double brakeGap, bool newDestination,
170 : MSStoppingPlace* alternative, double occupancy, double prob,
171 : SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, StoppingPlaceMap_t& stoppingPlaces,
172 : std::map<MSStoppingPlace*, ConstMSEdgeVector>& newRoutes,
173 : std::map<MSStoppingPlace*, ConstMSEdgeVector>& stoppingPlaceApproaches,
174 : StoppingPlaceParamMap_t& maxValues,
175 : StoppingPlaceParamMap_t& addInput);
176 :
177 : /** @brief Compute some custom target function components
178 : *
179 : * @param[in] veh the concerned vehicle
180 : * @param[in] brakeGap the distance before which the vehicle cannot stop
181 : * @param[in] newDestination whether the destination changed
182 : * @param[in] alternative the stopping place to evaluate
183 : * @param[in] occupancy occupancy of the stopping place
184 : * @param[in] router the router to use for evaluation if needed
185 : * @param[in,out] stoppingPlaceValues the data structure to write the evaluation values to
186 : * @param[in] newRoute the complete route to the destination passing by the stopping place
187 : * @param[in] stoppingPlaceApproach the route to the stopping place
188 : * @param[in] maxValues the maximum values of the components
189 : * @param[in] addInput external input data
190 : * @return false if the stopping place cannot be used according to the custom evaluation components
191 : */
192 : virtual bool evaluateCustomComponents(SUMOVehicle& veh, double brakeGap, bool newDestination,
193 : MSStoppingPlace* alternative, double occupancy, double prob,
194 : SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, StoppingPlaceParamMap_t& stoppingPlaceValues,
195 : ConstMSEdgeVector& newRoute,
196 : ConstMSEdgeVector& stoppingPlaceApproach,
197 : StoppingPlaceParamMap_t& maxValues,
198 : StoppingPlaceParamMap_t& addInput);
199 :
200 : /// @brief Whether the stopping place should be discarded due to its results from the component evaluation (allows to check for min/max thresholds and other non-linear relations)
201 : virtual bool validComponentValues(StoppingPlaceParamMap_t& stoppingPlaceValues);
202 :
203 : /// @brief Whether the stopping place should be included in the search (can be used to add an additional filter)
204 : virtual bool useStoppingPlace(MSStoppingPlace* stoppingPlace);
205 :
206 : /// @brief Provide the router to use (MSNet::getRouterTT or MSRoutingEngine)
207 : virtual SUMOAbstractRouter<MSEdge, SUMOVehicle>& getRouter(SUMOVehicle& veh, const MSEdgeVector& prohibited = {});
208 :
209 : /// @brief Return the number of occupied places of the StoppingPlace
210 : virtual double getStoppingPlaceOccupancy(MSStoppingPlace* stoppingPlace) = 0;
211 :
212 : /// @brief Return the number of occupied places of the StoppingPlace from the previous time step
213 : virtual double getLastStepStoppingPlaceOccupancy(MSStoppingPlace* stoppingPlace) = 0;
214 :
215 : /// @brief Return the number of places the StoppingPlace provides
216 : virtual double getStoppingPlaceCapacity(MSStoppingPlace* stoppingPlace) = 0;
217 :
218 : /// @brief store the blocked stopping place in the vehicle
219 : virtual void rememberBlockedStoppingPlace(SUMOVehicle& veh, const MSStoppingPlace* stoppingPlace, bool blocked) = 0;
220 :
221 : /// @brief store the stopping place score in the vehicle
222 : virtual void rememberStoppingPlaceScore(SUMOVehicle& veh, MSStoppingPlace* place, const std::string& score) = 0;
223 :
224 : /// @brief forget all stopping place score for this vehicle
225 : virtual void resetStoppingPlaceScores(SUMOVehicle& veh) = 0;
226 :
227 : /// @brief ask the vehicle when it has seen the stopping place
228 : virtual SUMOTime sawBlockedStoppingPlace(SUMOVehicle& veh, MSStoppingPlace* place, bool local) = 0;
229 :
230 : /// @brief ask how many times already the vehicle has been rerouted to another stopping place
231 : virtual int getNumberStoppingPlaceReroutes(SUMOVehicle& veh) = 0;
232 :
233 : /// @brief update the number of reroutes for the vehicle
234 : virtual void setNumberStoppingPlaceReroutes(SUMOVehicle& veh, int value) = 0;
235 :
236 : /// @brief read target function weights for this vehicle
237 : virtual StoppingPlaceParamMap_t collectWeights(SUMOVehicle& veh);
238 :
239 : /** @brief read the value of a stopping place search param, e.g. a component weight factor
240 : *
241 : * @param[in] veh the concerned vehicle
242 : * @param[in] param the name of the stopping place search param, excluding the param prefix (e.g. "parking.")
243 : * @param[in] defaultWeight value to return in case the param hasn't been defined for the vehicle
244 : * @param[in] warn whether a warning message shall be issued if the param is not defined for the vehicle
245 : * @return param value
246 : */
247 : double getWeight(SUMOVehicle& veh, const std::string param, const double defaultWeight, const bool warn = false);
248 :
249 : /** @brief keep track of the maximum values of each component
250 : *
251 : * @param[in] stoppingPlaceValues the target function component values of a vehicle
252 : * @param[in,out] maxValues stores the maximum values of the given stoppingPlaceValues and previously given maxValues
253 : */
254 : static void updateMaxValues(StoppingPlaceParamMap_t& stoppingPlaceValues, StoppingPlaceParamMap_t& maxValues);
255 :
256 : /** @brief compute the scalar target function value by means of a linear combination of all components/weights after normalising and optionally inverting the values
257 : *
258 : * @param[in] absValues the component values
259 : * @param[in] maxValues max values for all components
260 : * @param[in] weights weight factors for all components
261 : * @param[in] norm which component should be normalised
262 : * @param[in] invert which component should be inverted
263 : * @return target function value for a single stopping place and vehicle
264 : */
265 : static double getTargetValue(const StoppingPlaceParamMap_t& absValues, const StoppingPlaceParamMap_t& maxValues, const StoppingPlaceParamMap_t& weights, const StoppingPlaceParamSwitchMap_t& norm, const StoppingPlaceParamSwitchMap_t& invert);
266 :
267 : protected:
268 : /// @brief Ask the vehicle about the relevant rerouting parameters and initiate the maximum value data structure
269 : void readEvaluationWeights(SUMOVehicle& veh, StoppingPlaceParamMap_t& stoppingPlaceParams, StoppingPlaceParamMap_t& stoppingPlaceDefaults, StoppingPlaceParamMap_t& maxValues) {
270 : for (StoppingPlaceParamMap_t::iterator it = stoppingPlaceParams.begin(); it != stoppingPlaceParams.end(); ++it) {
271 : double value = getWeight(veh, it->first, stoppingPlaceDefaults[it->first]);
272 : it->second = value;
273 : if (value > maxValues[it->first]) {
274 : maxValues[it->first] = value;
275 : }
276 : }
277 : }
278 :
279 : private:
280 :
281 : ///@brief Constructor
282 : MSStoppingPlaceRerouter() = delete;
283 :
284 : protected:
285 : const SumoXMLTag myStoppingType;
286 : const std::string myParamPrefix;
287 : bool myCheckValidity;
288 : const bool myConsiderDestVisibility;
289 : StoppingPlaceParamMap_t myEvalParams;
290 : StoppingPlaceParamSwitchMap_t myNormParams;
291 : StoppingPlaceParamSwitchMap_t myInvertParams;
292 : };
|