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 5076 : 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 1904 : const std::string deviceName() const {
156 1904 : return "taxi";
157 : }
158 :
159 : /// @brief whether the taxi is empty
160 : bool isEmpty();
161 :
162 : int getState() const {
163 10268 : 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 try to retrieve the given parameter from this device. Throw exception for unsupported key
194 : std::string getParameter(const std::string& key) const;
195 :
196 : /// @brief try to set the given parameter for this device. Throw exception for unsupported key
197 : void setParameter(const std::string& key, const std::string& value);
198 :
199 : /** @brief Called on writing tripinfo output
200 : *
201 : * @param[in] os The stream to write the information into
202 : * @exception IOError not yet implemented
203 : * @see MSDevice::generateOutput
204 : */
205 : void generateOutput(OutputDevice* tripinfoOut) const;
206 :
207 : /// @brief whether the given reservation is compatible with the taxi line
208 : bool compatibleLine(const Reservation* res);
209 :
210 : static bool compatibleLine(const std::string& taxiLine, const std::string& rideLine);
211 :
212 : /// @brief signal the end of the simulation and the removal of all customers
213 : static void allCustomersErased();
214 :
215 : protected:
216 : /** @brief Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
217 : *
218 : */
219 : void notifyMoveInternal(const SUMOTrafficObject& veh,
220 : const double frontOnLane,
221 : const double timeOnLane,
222 : const double meanSpeedFrontOnLane,
223 : const double meanSpeedVehicleOnLane,
224 : const double travelledDistanceFrontOnLane,
225 : const double travelledDistanceVehicleOnLane,
226 : const double meanLengthOnLane);
227 :
228 : private:
229 : /** @brief Constructor
230 : *
231 : * @param[in] holder The vehicle that holds this device
232 : * @param[in] id The ID of the device
233 : */
234 : MSDevice_Taxi(SUMOVehicle& holder, const std::string& id);
235 :
236 : void updateMove(const SUMOTime traveltime, const double travelledDist);
237 :
238 : /// @brief prepare stop for the given action
239 : void prepareStop(ConstMSEdgeVector& edges,
240 : StopParVector& stops,
241 : double& lastPos, const MSEdge* stopEdge, double stopPos,
242 : const MSStoppingPlace* stopPlace,
243 : const std::string& action, const Reservation* res, const bool isPickup);
244 :
245 : /// @brief determine stopping lane for taxi
246 : MSLane* getStopLane(const MSEdge* edge, const std::string& action);
247 :
248 : /// @brief whether the taxi has another pickup scheduled
249 : bool hasFuturePickup();
250 :
251 : /// @brief optionally swap tasks when a taxi becomes idle
252 : void checkTaskSwap();
253 :
254 : /// @brief initialize the dispatch algorithm
255 : static void initDispatch();
256 :
257 : private:
258 :
259 : int myState = EMPTY;
260 : /// @brief number of customers that were served
261 : int myCustomersServed = 0;
262 : /// @brief distance driven with customers
263 : double myOccupiedDistance = 0;
264 : /// @brief time spent driving with customers
265 : SUMOTime myOccupiedTime = 0;
266 : /// @brief the time at which the taxi service ends (end the vehicle may leave the simulation)
267 : SUMOTime myServiceEnd = SUMOTime_MAX;
268 : /// @brief whether the vehicle is currently stopped
269 : bool myIsStopped = false;
270 : /// @brief the customer of the current reservation
271 : std::set<const MSTransportable*> myCustomers;
272 :
273 : /// @brief algorithm for controlling idle behavior
274 : MSIdling* myIdleAlgorithm;
275 :
276 : /// @brief whether the taxi has reached its schedule service end
277 : bool myReachedServiceEnd = false;
278 :
279 : /// @brief reservations currently being served
280 : std::set<const Reservation*> myCurrentReservations;
281 :
282 : /// @brief routing device (if the vehicle has one)
283 : MSDevice_Routing* myRoutingDevice = nullptr;
284 :
285 : /// @brief the time between successive calls to the dispatcher
286 : static SUMOTime myDispatchPeriod;
287 : /// @brief the dispatch algorithm
288 : static MSDispatch* myDispatcher;
289 : /// @brief The repeated call to the dispatcher
290 : static Command* myDispatchCommand;
291 : /// @brief the last dispatch order
292 : std::vector<const Reservation*> myLastDispatch;
293 : // @brief the list of available taxis
294 : static std::vector<MSDevice_Taxi*> myFleet;
295 : // @brief the maximum personCapacity in the fleet
296 : static int myMaxCapacity;
297 : // @brief the maximum container capacity in the fleet
298 : static int myMaxContainerCapacity;
299 :
300 : static std::set<std::string> myVClassWarningVTypes;
301 :
302 : private:
303 : /// @brief Invalidated copy constructor.
304 : MSDevice_Taxi(const MSDevice_Taxi&);
305 :
306 : /// @brief Invalidated assignment operator.
307 : MSDevice_Taxi& operator=(const MSDevice_Taxi&);
308 :
309 :
310 : };
|