Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2013-2026 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 MSDevice_Taxi.h
15 : /// @author Jakob Erdmann
16 : /// @date 16.12.2019
17 : ///
18 : // A device which controls a taxi
19 : /****************************************************************************/
20 : #pragma once
21 : #include <config.h>
22 :
23 : #include <utils/common/SUMOTime.h>
24 : #include <utils/common/WrappingCommand.h>
25 : #include "MSVehicleDevice.h"
26 :
27 :
28 : // ===========================================================================
29 : // class declarations
30 : // ===========================================================================
31 : class SUMOTrafficObject;
32 : class MSDispatch;
33 : class MSIdling;
34 : class MSDevice_Routing;
35 : struct Reservation;
36 :
37 :
38 : // ===========================================================================
39 : // class definitions
40 : // ===========================================================================
41 : /**
42 : * @class MSDevice_Taxi
43 : * @brief A device which collects info on the vehicle trip (mainly on departure and arrival)
44 : *
45 : * Each device collects departure time, lane and speed and the same for arrival.
46 : *
47 : * @see MSDevice
48 : */
49 : class MSDevice_Taxi : public MSVehicleDevice {
50 : public:
51 :
52 : enum TaxiState {
53 : EMPTY = 0, // empty (available for servicing customers)
54 : PICKUP = 1, // driving to pick up customer
55 : OCCUPIED = 2 // occupied with customer
56 : };
57 :
58 : /** @brief Inserts MSDevice_Taxi-options
59 : * @param[filled] oc The options container to add the options to
60 : */
61 : static void insertOptions(OptionsCont& oc);
62 :
63 :
64 : /** @brief Build devices for the given vehicle, if needed
65 : *
66 : * The options are read and evaluated whether a Taxi-device shall be built
67 : * for the given vehicle.
68 : *
69 : * The built device is stored in the given vector.
70 : *
71 : * @param[in] v The vehicle for which a device may be built
72 : * @param[filled] into The vector to store the built device in
73 : */
74 : static void buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into);
75 :
76 : /// @brief whether the given lines description is a taxi call
77 : static bool isReservation(const std::set<std::string>& lines);
78 :
79 : /// add new reservation
80 : static void addReservation(MSTransportable* person,
81 : const std::set<std::string>& lines,
82 : SUMOTime reservationTime,
83 : SUMOTime pickupTime,
84 : SUMOTime earliestPickupTime,
85 : const MSEdge* from, double fromPos,
86 : const MSStoppingPlace* fromStop,
87 : const MSEdge* to, double toPos,
88 : const MSStoppingPlace* toStop,
89 : const std::string& group);
90 :
91 : /// @brief retract reservation
92 : static void removeReservation(MSTransportable* person,
93 : const std::set<std::string>& lines,
94 : const MSEdge* from, double fromPos,
95 : const MSEdge* to, double toPos,
96 : const std::string& group);
97 :
98 : /// @brief update reservation's fromPos due to pre-booking
99 : static void updateReservationFromPos(MSTransportable* person,
100 : const std::set<std::string>& lines,
101 : const MSEdge* from, double fromPos,
102 : const MSEdge* to, double toPos,
103 : const std::string& group, double newFromPos);
104 :
105 : /// @brief period command to trigger the dispatch algorithm
106 : static SUMOTime triggerDispatch(SUMOTime currentTime);
107 :
108 : /// @brief check whether there are still (servable) reservations in the system
109 : static bool hasServableReservations();
110 :
111 : /// @brief resets counters
112 : static void cleanup();
113 :
114 : static MSDispatch* getDispatchAlgorithm() {
115 5598 : return myDispatcher;
116 : }
117 :
118 : static const std::vector<MSDevice_Taxi*>& getFleet() {
119 : return myFleet;
120 : }
121 :
122 : public:
123 : /// @brief Destructor.
124 : ~MSDevice_Taxi();
125 :
126 : /// @name Methods called on vehicle movement / state change, overwriting MSDevice
127 : /// @{
128 :
129 : /** @brief Checks for waiting steps when the vehicle moves
130 : *
131 : * @param[in] veh Vehicle that asks this reminder.
132 : * @param[in] oldPos Position before move.
133 : * @param[in] newPos Position after move with newSpeed.
134 : * @param[in] newSpeed Moving speed.
135 : *
136 : * @return True (always).
137 : */
138 : bool notifyMove(SUMOTrafficObject& veh, double oldPos,
139 : double newPos, double newSpeed);
140 :
141 :
142 : /** @brief Saves departure info on insertion
143 : *
144 : * @param[in] veh The entering vehicle.
145 : * @param[in] reason how the vehicle enters the lane
146 : * @return Always true
147 : * @see MSMoveReminder::notifyEnter
148 : * @see MSMoveReminder::Notification
149 : */
150 : bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
151 : /// @}
152 :
153 :
154 : /// @brief return the name for this type of device
155 1918 : const std::string deviceName() const {
156 1918 : return "taxi";
157 : }
158 :
159 : /// @brief whether the taxi is empty
160 : bool isEmpty();
161 :
162 : int getState() const {
163 9261 : return myState;
164 : }
165 :
166 : /// @brief returns whether taxis have been loaded
167 : static bool hasFleet();
168 :
169 : /// @brief service the given reservation
170 : void dispatch(const Reservation& res);
171 :
172 : /// @brief service the given reservations
173 : void dispatchShared(std::vector<const Reservation*> reservations);
174 :
175 : /// @brief remove the persons the taxi is currently waiting for from reservations
176 : void cancelCurrentCustomers();
177 :
178 : /// @brief remove person from reservations
179 : bool cancelCustomer(const MSTransportable* t);
180 :
181 : /// @brief add person after extending reservation
182 : void addCustomer(const MSTransportable* t, const Reservation* res);
183 :
184 : /// @brief whether the given person is allowed to board this taxi
185 : bool allowsBoarding(const MSTransportable* t) const;
186 :
187 : /// @brief called by MSDevice_Transportable upon loading a person
188 : void customerEntered(const MSTransportable* t);
189 :
190 : /// @brief called by MSDevice_Transportable upon unloading a person
191 : void customerArrived(const MSTransportable* person);
192 :
193 : /** @brief Saves the state of the device
194 : */
195 : void saveState(OutputDevice& out) const;
196 :
197 : /** @brief Loads the state of the device from the given description
198 : * @param[in] attrs XML attributes describing the current state
199 : */
200 : void loadState(const SUMOSAXAttributes& attrs);
201 :
202 : /// @brief call during state loading after all transportables are loaded
203 : static void finalizeLoadState();
204 :
205 : /// @brief try to retrieve the given parameter from this device. Throw exception for unsupported key
206 : std::string getParameter(const std::string& key) const;
207 :
208 : /// @brief try to set the given parameter for this device. Throw exception for unsupported key
209 : void setParameter(const std::string& key, const std::string& value);
210 :
211 : /** @brief Called on writing tripinfo output
212 : *
213 : * @param[in] os The stream to write the information into
214 : * @exception IOError not yet implemented
215 : * @see MSDevice::generateOutput
216 : */
217 : void generateOutput(OutputDevice* tripinfoOut) const;
218 :
219 : /// @brief whether the given reservation is compatible with the taxi line
220 : bool compatibleLine(const Reservation* res);
221 :
222 : static bool compatibleLine(const std::string& taxiLine, const std::string& rideLine);
223 :
224 : /// @brief signal the end of the simulation and the removal of all customers
225 : static void allCustomersErased();
226 :
227 : /// @brief return all types that are known to carry a taxi device (or the default type if no devices are initialized)
228 : static const std::map<SUMOVehicleClass, std::string>& getTaxiTypes();
229 :
230 : static SUMOTime getNextDispatchTime();
231 :
232 : /// @brief initialize the dispatch algorithm
233 : static void initDispatch(SUMOTime next = -1);
234 :
235 : protected:
236 : /** @brief Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
237 : *
238 : */
239 : void notifyMoveInternal(const SUMOTrafficObject& veh,
240 : const double frontOnLane,
241 : const double timeOnLane,
242 : const double meanSpeedFrontOnLane,
243 : const double meanSpeedVehicleOnLane,
244 : const double travelledDistanceFrontOnLane,
245 : const double travelledDistanceVehicleOnLane,
246 : const double meanLengthOnLane);
247 :
248 : private:
249 : /** @brief Constructor
250 : *
251 : * @param[in] holder The vehicle that holds this device
252 : * @param[in] id The ID of the device
253 : */
254 : MSDevice_Taxi(SUMOVehicle& holder, const std::string& id);
255 :
256 : void updateMove(const SUMOTime traveltime, const double travelledDist);
257 :
258 : /// @brief prepare stop for the given action
259 : void prepareStop(ConstMSEdgeVector& edges,
260 : StopParVector& stops,
261 : double& lastPos, const MSEdge* stopEdge, double stopPos,
262 : const MSStoppingPlace* stopPlace,
263 : const std::string& action, const Reservation* res, const bool isPickup);
264 :
265 : /// @brief determine stopping lane for taxi
266 : MSLane* getStopLane(const MSEdge* edge, const std::string& action);
267 :
268 : /// @brief whether the taxi has another pickup scheduled
269 : bool hasFuturePickup();
270 :
271 : /// @brief optionally swap tasks when a taxi becomes idle
272 : void checkTaskSwap();
273 :
274 : private:
275 :
276 : int myState = EMPTY;
277 : /// @brief number of customers that were served
278 : int myCustomersServed = 0;
279 : /// @brief distance driven with customers
280 : double myOccupiedDistance = 0;
281 : /// @brief time spent driving with customers
282 : SUMOTime myOccupiedTime = 0;
283 : /// @brief the time at which the taxi service ends (end the vehicle may leave the simulation)
284 : SUMOTime myServiceEnd = SUMOTime_MAX;
285 : /// @brief whether the vehicle is currently stopped
286 : bool myIsStopped = false;
287 : /// @brief the customer of the current reservation
288 : std::set<const MSTransportable*> myCustomers;
289 :
290 : /// @brief algorithm for controlling idle behavior
291 : MSIdling* myIdleAlgorithm;
292 :
293 : /// @brief whether the taxi has reached its schedule service end
294 : bool myReachedServiceEnd = false;
295 :
296 : /// @brief reservations currently being served
297 : std::set<const Reservation*> myCurrentReservations;
298 :
299 : /// @brief routing device (if the vehicle has one)
300 : MSDevice_Routing* myRoutingDevice = nullptr;
301 :
302 : /// @brief the time between successive calls to the dispatcher
303 : static SUMOTime myDispatchPeriod;
304 : /// @brief the dispatch algorithm
305 : static MSDispatch* myDispatcher;
306 : /// @brief The repeated call to the dispatcher
307 : static Command* myDispatchCommand;
308 : /// @brief the last dispatch order
309 : std::vector<const Reservation*> myLastDispatch;
310 : // @brief the list of available taxis
311 : static std::vector<MSDevice_Taxi*> myFleet;
312 : // @brief the maximum personCapacity in the fleet
313 : static int myMaxCapacity;
314 : // @brief the maximum container capacity in the fleet
315 : static int myMaxContainerCapacity;
316 :
317 : /// @brief storing only one type per vClass
318 : static std::map<SUMOVehicleClass, std::string> myTaxiTypes;
319 :
320 : static SUMOTime myNextDispatchTime;
321 :
322 : /// @brief ids of customers loaded from state
323 : static std::map<std::string, MSDevice_Taxi*> myStateLoadedCustomers;
324 : /// @brief ids of reservations loaded from state
325 : static std::map<std::string, MSDevice_Taxi*> myStateLoadedReservations;
326 : private:
327 : /// @brief Invalidated copy constructor.
328 : MSDevice_Taxi(const MSDevice_Taxi&);
329 :
330 : /// @brief Invalidated assignment operator.
331 : MSDevice_Taxi& operator=(const MSDevice_Taxi&);
332 :
333 :
334 : };
|