Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSDevice_Transportable.cpp
Go to the documentation of this file.
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/****************************************************************************/
23// A device which is used to keep track of persons and containers riding with a vehicle
24/****************************************************************************/
25#include <config.h>
26
29#include <microsim/MSNet.h>
30#include <microsim/MSEdge.h>
31#include <microsim/MSStop.h>
37#include "MSDevice_Taxi.h"
38
39
40// ===========================================================================
41// method definitions
42// ===========================================================================
43// ---------------------------------------------------------------------------
44// static initialisation methods
45// ---------------------------------------------------------------------------
47MSDevice_Transportable::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into, const bool isContainer) {
48 MSDevice_Transportable* device = new MSDevice_Transportable(v, isContainer ? "container_" + v.getID() : "person_" + v.getID(), isContainer);
49 into.push_back(device);
50 return device;
51}
52
53
54// ---------------------------------------------------------------------------
55// MSDevice_Transportable-methods
56// ---------------------------------------------------------------------------
57MSDevice_Transportable::MSDevice_Transportable(SUMOVehicle& holder, const std::string& id, const bool isContainer) :
58 MSVehicleDevice(holder, id),
59 myAmContainer(isContainer),
60 myTransportables(),
61 myStopped(holder.isStopped())
62{ }
63
64
66 // flush any unfortunate riders still remaining
67 for (auto it = myTransportables.begin(); it != myTransportables.end();) {
68 MSTransportable* transportable = *it;
69 WRITE_WARNING((myAmContainer ? "Removing container '" : "Removing person '") + transportable->getID() +
70 "' at removal of vehicle '" + myHolder.getID() + "'");
71 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(transportable->getCurrentStage());
72 if (stage != nullptr) {
73 stage->setVehicle(nullptr);
74 }
75 if (myAmContainer) {
77 } else {
78 MSNet::getInstance()->getPersonControl().erase(transportable);
79 }
80 it = myTransportables.erase(it);
81 }
82}
83
84void
86 const double /* frontOnLane */,
87 const double /* timeOnLane */,
88 const double /* meanSpeedFrontOnLane */,
89 const double /* meanSpeedVehicleOnLane */,
90 const double travelledDistanceFrontOnLane,
91 const double /* travelledDistanceVehicleOnLane */,
92 const double /* meanLengthOnLane */) {
93 notifyMove(const_cast<SUMOTrafficObject&>(veh), -1, travelledDistanceFrontOnLane, veh.getEdge()->getVehicleMaxSpeed(&veh));
94}
95
96bool
98 for (const MSTransportable* t : myTransportables) {
99 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(t->getCurrentStage());
100 if (stage->canLeaveVehicle(t, myHolder, stop)) {
101 return true;
102 }
103 }
104 return false;
105}
106
107
108void
110 const MSStop& stop = myHolder.getNextStop();
111 for (auto it = myTransportables.begin(); it != myTransportables.end();) {
112 MSTransportable* t = *it;
113 if (t->getNumRemainingStages() > 1) {
114 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(t->getCurrentStage());
115 if (stage->canLeaveVehicle(t, myHolder, stop)) {
116 MSStageDriving* const stage2 = dynamic_cast<MSStageDriving*>(t->getNextStage(1));
117 if (stage2 && stage2->isWaitingFor(otherVeh)) {
118 it = myTransportables.erase(it);
119 // proceeding registers t as waiting on edge
121 MSTransportableControl& tc = (t->isPerson() ?
126 otherVeh->addTransportable(t);
127 stage2->setVehicle(otherVeh);
128 continue;
129 }
130 }
131 }
132 it++;
133 }
134}
135
136
137bool
139 if (joinVeh && t->getNumRemainingStages() > 1) {
140 MSStageDriving* const stage2 = dynamic_cast<MSStageDriving*>(t->getNextStage(1));
141 return stage2->isWaitingFor(joinVeh);
142 }
143 return false;
144}
145
146
147bool
148MSDevice_Transportable::notifyMove(SUMOTrafficObject& /*tObject*/, double /*oldPos*/, double newPos, double newSpeed) {
149 SUMOVehicle& veh = myHolder;
150 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
151 if (myStopped) {
152 if (!veh.isStopped()) {
153 const SUMOTime freeFlowTimeCorrection = MSGlobals::gUseMesoSim ? TIME2STEPS(newPos / newSpeed) : 0;
154 for (MSTransportable* const transportable : myTransportables) {
155 transportable->setDeparted(currentTime - freeFlowTimeCorrection);
156 }
157 myStopped = false;
158 }
159 } else {
160 if (veh.isStopped()) {
161 myStopped = true;
162 MSStop& stop = veh.getNextStop();
163 const MSVehicle* joinVeh = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(stop.pars.join));
164 const SUMOTime boardingDuration = veh.getVehicleType().getLoadingDuration(!myAmContainer);
165 for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end();) {
166 MSTransportable* transportable = *i;
167 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(transportable->getCurrentStage());
168 if (stage->canLeaveVehicle(transportable, myHolder, stop) && !willTransferAtJoin(transportable, joinVeh)) {
170 MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
171 if (taxiDevice != nullptr && timeForNext == 0 && !MSGlobals::gUseMesoSim) {
172 // taxi passengers must leave at the end of the stop duration
173 timeForNext = stop.pars.started + stop.pars.duration;
174 }
175 if (timeForNext - DELTA_T > currentTime) {
176 // try deboarding again in the next step
177 myStopped = false;
178 break;
179 }
180 if (stage->getDestinationStop() != nullptr) {
181 stage->getDestinationStop()->addTransportable(transportable);
182 }
183
184 SUMOTime arrivalTime = currentTime;
186 // no boarding / unboarding time in meso
187 arrivalTime += 1;
188 } else {
189 const SUMOTime boardingTime = (SUMOTime)((double)boardingDuration * transportable->getVehicleType().getBoardingFactor());
190 if (timeForNext > currentTime - DELTA_T) {
191 timeForNext += boardingTime;
192 } else {
193 timeForNext = currentTime + boardingTime;
194 }
195 }
196 //ensure that vehicle stops long enough for deboarding
197 stop.duration = MAX2(stop.duration, timeForNext - currentTime);
198
199 i = myTransportables.erase(i); // erase first in case proceed throws an exception
200 if (taxiDevice != nullptr) {
201 taxiDevice->customerArrived(transportable);
202 }
203 if (!transportable->proceed(MSNet::getInstance(), arrivalTime)) {
204 if (myAmContainer) {
205 MSNet::getInstance()->getContainerControl().erase(transportable);
206 } else {
207 MSNet::getInstance()->getPersonControl().erase(transportable);
208 }
209 }
210 if (MSStopOut::active()) {
211 SUMOVehicle* vehicle = dynamic_cast<SUMOVehicle*>(&veh);
212 if (myAmContainer) {
214 } else {
216 }
217 }
218 continue;
219 }
220 ++i;
221 }
222 }
223 }
224 return true;
225}
226
227
228bool
231 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
232 for (MSTransportable* const transportable : myTransportables) {
233 transportable->setDeparted(currentTime);
234 }
235 }
237 // to trigger vehicle leaving
238 notifyMove(veh, -1., -1., -1.);
239 }
240 return true;
241}
242
243
244bool
246 MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
248 for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end();) {
250 MSTransportable* transportable = *i;
251 if (transportable->getDestination() != veh.getEdge()) {
252 WRITE_WARNING((myAmContainer ? "Teleporting container '" : "Teleporting person '") + transportable->getID() +
253 "' from vehicle destination edge '" + veh.getEdge()->getID() +
254 "' to intended destination edge '" + transportable->getDestination()->getID() + "' time=" + time2string(SIMSTEP));
256 }
257 if (!transportable->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep(), true)) {
258 tc.erase(transportable);
259 }
260 i = myTransportables.erase(i);
261 }
262 }
263 return true;
264}
265
266
267void
269 myTransportables.push_back(transportable);
270 if (MSStopOut::active()) {
271 if (myAmContainer) {
273 } else {
275 }
276 }
277 MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
278 if (taxiDevice != nullptr) {
279 taxiDevice->customerEntered(transportable);
280 }
281}
282
283
284void
286 auto it = std::find(myTransportables.begin(), myTransportables.end(), transportable);
287 if (it != myTransportables.end()) {
288 myTransportables.erase(it);
290 if (myAmContainer) {
292 } else {
294 }
295 }
296 MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
297 if (taxiDevice != nullptr) {
298 taxiDevice->customerArrived(transportable);
299 }
300 }
301}
302
303
304void
308 std::vector<std::string> internals;
309 internals.push_back(toString(myStopped));
310 out.writeAttr(SUMO_ATTR_STATE, toString(internals));
311 out.closeTag();
312}
313
314
315void
317 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
318 bis >> myStopped;
319}
320
321
322std::string
323MSDevice_Transportable::getParameter(const std::string& key) const {
324 if (key == "IDList") {
325 std::vector<std::string> ids;
326 for (const MSTransportable* t : myTransportables) {
327 ids.push_back(t->getID());
328 }
329 return toString(ids);
330 }
331 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
332}
333
334
335/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_WARNING(msg)
Definition MsgHandler.h:295
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
#define SIMSTEP
Definition SUMOTime.h:61
#define TIME2STEPS(x)
Definition SUMOTime.h:57
@ SUMO_TAG_DEVICE
@ SUMO_ATTR_ID
@ SUMO_ATTR_STATE
The state of a link.
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
The base class for microscopic and mesoscopic vehicles.
virtual void addTransportable(MSTransportable *transportable)
Adds a person or container to this vehicle.
A device which collects info on the vehicle trip (mainly on departure and arrival)
void customerArrived(const MSTransportable *person)
called by MSDevice_Transportable upon unloading a person
void customerEntered(const MSTransportable *t)
called by MSDevice_Transportable upon loading a person
void saveState(OutputDevice &out) const
Saves the state of the device.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks whether the vehicle is at a stop and transportable action is needed.
static bool willTransferAtJoin(const MSTransportable *t, const MSBaseVehicle *joinVeh)
check if boardingDuration should be applied
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Passengers leaving on arrival.
bool anyLeavingAtStop(const MSStop &stop) const
static MSDevice_Transportable * buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into, const bool isContainer)
Build devices for the given vehicle, if needed.
void transferAtSplitOrJoin(MSBaseVehicle *otherVeh)
transfers transportables that want to continue in the other train part (without boarding/loading dela...
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Adds passengers on vehicle insertion.
MSDevice_Transportable(SUMOVehicle &holder, const std::string &id, const bool isContainer)
Constructor.
std::vector< MSTransportable * > myTransportables
The passengers of the vehicle.
void notifyMoveInternal(const SUMOTrafficObject &veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane)
Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
void addTransportable(MSTransportable *transportable)
Add a passenger.
const bool myAmContainer
Whether it is a container device.
const std::string deviceName() const
return the name for this type of device
void loadState(const SUMOSAXAttributes &attrs)
Loads the state of the device from the given description.
void removeTransportable(MSTransportable *transportable)
Remove a passenger (TraCI)
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition MSEdge.cpp:1170
virtual void removeTransportable(MSTransportable *t) const
Definition MSEdge.cpp:1197
static bool gUseMesoSim
Definition MSGlobals.h:106
Representation of a lane in the micro simulation.
Definition MSLane.h:84
Notification
Definition of a vehicle state.
@ NOTIFICATION_ARRIVED
The vehicle arrived at its destination (is deleted)
@ NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:185
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition MSNet.cpp:1198
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:320
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:378
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1189
bool canLeaveVehicle(const MSTransportable *t, const SUMOVehicle &veh, const MSStop &stop)
checks whether the person may exit at the current vehicle position
bool isWaitingFor(const SUMOVehicle *vehicle) const
Whether the person waits for the given vehicle.
void setVehicle(SUMOVehicle *v)
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
Definition MSStage.h:85
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition MSStop.h:83
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition MSStop.h:81
SUMOTime duration
The stopping duration.
Definition MSStop.h:67
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition MSStop.h:65
void loadedContainers(const SUMOVehicle *veh, int n)
Definition MSStopOut.cpp:99
static bool active()
Definition MSStopOut.h:54
void unloadedPersons(const SUMOVehicle *veh, int n)
Definition MSStopOut.cpp:89
static MSStopOut * getInstance()
Definition MSStopOut.h:60
void unloadedContainers(const SUMOVehicle *veh, int n)
void loadedPersons(const SUMOVehicle *veh, int n)
Definition MSStopOut.cpp:76
bool addTransportable(const MSTransportable *p)
adds a transportable to this stop
void abortWaitingForVehicle(MSTransportable *t)
let the given transportable abort waiting for a vehicle (when removing stage via TraCI)
void registerTeleportWrongDest()
register a teleport to the final destination
virtual void erase(MSTransportable *transportable)
removes a single transportable
const MSEdge * getDestination() const
Returns the current destination.
MSStage * getNextStage(int offset) const
Return the next (or previous) stage denoted by the offset.
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
MSStage * getCurrentStage() const
Return the current stage.
virtual bool proceed(MSNet *net, SUMOTime time, const bool vehicleArrived=false)
bool isPerson() const
Whether it is a person.
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
const MSEdge * getEdge() const
Returns the current edge.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
SUMOTime getLoadingDuration(const bool isPerson) const
Get this vehicle type's loading duration.
double getBoardingFactor() const
Get this person type's factor for loading/boarding duration.
const std::string & getID() const
Returns the id.
Definition Named.h:74
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
Representation of a vehicle, person, or container.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual MSDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or nullptr if not.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
Representation of a vehicle.
Definition SUMOVehicle.h:62
virtual bool isStopped() const =0
Returns whether the vehicle is at a stop and waiting for a person or container to continue.
virtual MSStop & getNextStop()=0
SUMOTime started
the time at which this stop was reached
std::string join
the id of the vehicle (train portion) to which this vehicle shall be joined
SUMOTime duration
The stopping duration.