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-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/****************************************************************************/
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 myOriginalType(&holder.getVehicleType()),
63 myLoadedType(nullptr) {
64 const std::string key = "device." + deviceName() + ".loadedType";
65 const std::string loadedTypeID = holder.getStringParam(key);
66 if (loadedTypeID != "") {
68 if (myLoadedType == nullptr) {
69 throw InvalidArgument(TLF("Vehicle type '%' in parameter '%' of vehicle '%' is not known.", loadedTypeID, key, holder.getID()));
70 }
71 }
72}
73
74
76 // flush any unfortunate riders still remaining
77 for (auto it = myTransportables.begin(); it != myTransportables.end();) {
78 MSTransportable* transportable = *it;
79 WRITE_WARNING((myAmContainer ? "Removing container '" : "Removing person '") + transportable->getID() +
80 "' at removal of vehicle '" + myHolder.getID() + "'");
81 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(transportable->getCurrentStage());
82 if (stage != nullptr) {
83 stage->setVehicle(nullptr);
84 }
85 if (myAmContainer) {
87 } else {
88 MSNet::getInstance()->getPersonControl().erase(transportable);
89 }
90 it = myTransportables.erase(it);
91 }
92}
93
94void
96 const double /* frontOnLane */,
97 const double /* timeOnLane */,
98 const double /* meanSpeedFrontOnLane */,
99 const double /* meanSpeedVehicleOnLane */,
100 const double travelledDistanceFrontOnLane,
101 const double /* travelledDistanceVehicleOnLane */,
102 const double /* meanLengthOnLane */) {
103 notifyMove(const_cast<SUMOTrafficObject&>(veh), -1, travelledDistanceFrontOnLane, veh.getEdge()->getVehicleMaxSpeed(&veh));
104}
105
106bool
108 for (const MSTransportable* t : myTransportables) {
109 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(t->getCurrentStage());
110 if (stage->canLeaveVehicle(t, myHolder, stop)) {
111 return true;
112 }
113 }
114 return false;
115}
116
117
118void
120 const MSStop& stop = myHolder.getNextStop();
121 for (auto it = myTransportables.begin(); it != myTransportables.end();) {
122 MSTransportable* t = *it;
123 if (t->getNumRemainingStages() > 1) {
124 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(t->getCurrentStage());
125 if (stage->canLeaveVehicle(t, myHolder, stop)) {
126 MSStageDriving* const stage2 = dynamic_cast<MSStageDriving*>(t->getNextStage(1));
127 if (stage2 && stage2->isWaitingFor(otherVeh)) {
128 it = myTransportables.erase(it);
129 // proceeding registers t as waiting on edge
131 MSTransportableControl& tc = (t->isPerson() ?
136 otherVeh->addTransportable(t);
137 stage2->setVehicle(otherVeh);
138 continue;
139 }
140 }
141 }
142 it++;
143 }
144}
145
146
147bool
149 if (joinVeh && t->getNumRemainingStages() > 1) {
150 MSStageDriving* const stage2 = dynamic_cast<MSStageDriving*>(t->getNextStage(1));
151 return stage2->isWaitingFor(joinVeh);
152 }
153 return false;
154}
155
156
157bool
158MSDevice_Transportable::notifyMove(SUMOTrafficObject& /*tObject*/, double /*oldPos*/, double newPos, double newSpeed) {
159 SUMOVehicle& veh = myHolder;
160 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
161 if (myStopped) {
162 if (!veh.isStopped()) {
163 const SUMOTime freeFlowTimeCorrection = MSGlobals::gUseMesoSim ? TIME2STEPS(newPos / newSpeed) : 0;
164 for (MSTransportable* const transportable : myTransportables) {
165 transportable->setDeparted(currentTime - freeFlowTimeCorrection);
166 }
167 myStopped = false;
168 }
169 } else {
170 if (veh.isStopped()) {
171 myStopped = true;
172 MSStop& stop = veh.getNextStopMutable();
173 const MSVehicle* joinVeh = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(stop.pars.join));
174 const SUMOTime boardingDuration = veh.getVehicleType().getLoadingDuration(!myAmContainer);
175 int numUnloaded = 0;
176 for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end();) {
177 MSTransportable* transportable = *i;
178 MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(transportable->getCurrentStage());
179 if (stage->canLeaveVehicle(transportable, myHolder, stop) && !willTransferAtJoin(transportable, joinVeh)) {
181 MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
182 if (taxiDevice != nullptr && timeForNext == 0 && !MSGlobals::gUseMesoSim) {
183 // taxi passengers must leave at the end of the stop duration
184 timeForNext = stop.pars.started + stop.pars.duration;
185 }
186 if (timeForNext - DELTA_T > currentTime) {
187 // try deboarding again in the next step
188 myStopped = false;
189 break;
190 }
191 if (stage->getDestinationStop() != nullptr) {
192 stage->getDestinationStop()->addTransportable(transportable);
193 }
194
195 SUMOTime arrivalTime = currentTime;
197 // no boarding / unboarding time in meso
198 arrivalTime += 1;
199 } else {
200 const SUMOTime boardingTime = (SUMOTime)((double)boardingDuration * transportable->getVehicleType().getBoardingFactor());
201 if (timeForNext > currentTime - DELTA_T) {
202 timeForNext += boardingTime;
203 } else {
204 timeForNext = currentTime + boardingTime;
205 }
206 }
207 //ensure that vehicle stops long enough for deboarding
208 stop.duration = MAX2(stop.duration, timeForNext - currentTime);
209
210 veh.removeTransportableMass(transportable);
211 i = myTransportables.erase(i); // erase first in case proceed throws an exception
212 numUnloaded++;
213 if (taxiDevice != nullptr) {
214 taxiDevice->customerArrived(transportable);
215 }
216 if (!transportable->proceed(MSNet::getInstance(), arrivalTime)) {
217 if (myAmContainer) {
218 MSNet::getInstance()->getContainerControl().erase(transportable);
219 } else {
220 MSNet::getInstance()->getPersonControl().erase(transportable);
221 }
222 }
223 if (MSStopOut::active()) {
224 SUMOVehicle* vehicle = dynamic_cast<SUMOVehicle*>(&veh);
225 if (myAmContainer) {
227 } else {
229 }
230 }
231 continue;
232 }
233 ++i;
234 }
235 if (numUnloaded != 0) {
237 }
238 }
239 }
240 return true;
241}
242
243
244bool
247 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
248 for (MSTransportable* const transportable : myTransportables) {
249 transportable->setDeparted(currentTime);
250 }
251 }
253 // to trigger vehicle leaving
254 notifyMove(veh, -1., -1., -1.);
255 }
256 return true;
257}
258
259
260bool
262 MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
264 for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end();) {
266 MSTransportable* transportable = *i;
267 if (transportable->getDestination() != veh.getEdge()) {
268 WRITE_WARNINGF("Teleporting % '%' from vehicle destination edge '%' to intended destination edge '%' time=%",
269 myAmContainer ? "container" : "person", transportable->getID(), veh.getEdge()->getID(),
270 transportable->getDestination()->getID(), time2string(SIMSTEP));
272 }
273 if (!transportable->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep(), true)) {
274 tc.erase(transportable);
275 }
276 i = myTransportables.erase(i);
277 }
278 }
279 return true;
280}
281
282
283void
285 if (myTransportables.empty()) {
287 }
288 myTransportables.push_back(transportable);
289 if (MSStopOut::active()) {
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->customerEntered(transportable);
299 }
301}
302
303
304void
306 auto it = std::find(myTransportables.begin(), myTransportables.end(), transportable);
307 if (it != myTransportables.end()) {
308 myTransportables.erase(it);
310 if (myAmContainer) {
312 } else {
314 }
315 }
316 MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
317 if (taxiDevice != nullptr) {
318 taxiDevice->customerArrived(transportable);
319 }
321 }
322}
323
324
325void
327 if (myLoadedType != nullptr) {
329 if (perAttached > 0) {
330 MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(myHolder);
332 const double numAttached = ceil(myTransportables.size() / perAttached);
333 if (numAttached > 0.) {
334 MSVehicleType* stype = &veh.getSingularType();
337 stype->setLength(myOriginalType->getLength() + numAttached * myLoadedType->getLength());
338 stype->setMass(myOriginalType->getMass() + numAttached * myLoadedType->getMass());
339 SUMOVTypeParameter& sparam = const_cast<SUMOVTypeParameter&>(stype->getParameter());
343 } else {
345 }
346 if (oldVC != myHolder.getVClass()) {
347 veh.reroute(SIMSTEP, "device." + deviceName() + ".loadedType", veh.getRouterTT());
348 }
349 }
350 }
351}
352
353
354void
358 std::vector<std::string> internals;
359 internals.push_back(toString(myStopped));
360 out.writeAttr(SUMO_ATTR_STATE, toString(internals));
361 out.closeTag();
362}
363
364
365void
367 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
368 bis >> myStopped;
369}
370
371
372std::string
373MSDevice_Transportable::getParameter(const std::string& key) const {
374 if (key == "IDList") {
375 std::vector<std::string> ids;
376 for (const MSTransportable* t : myTransportables) {
377 ids.push_back(t->getID());
378 }
379 return toString(ids);
380 }
381 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
382}
383
384
385/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TLF(string,...)
Definition MsgHandler.h:306
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:91
#define SIMSTEP
Definition SUMOTime.h:61
#define TIME2STEPS(x)
Definition SUMOTime.h:57
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SUMO_TAG_DEVICE
@ SUMO_ATTR_ID
@ SUMO_ATTR_STATE
The state of a link.
T MAX2(T a, T b)
Definition StdDefs.h:86
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.
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT() const
bool reroute(SUMOTime t, const std::string &info, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false, const bool silent=false, const MSEdge *sink=nullptr)
Performs a rerouting using the given router.
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
MSVehicleType * myLoadedType
the type to consult if loading/unloading changes vehicle properties
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.
const MSVehicleType * myOriginalType
the original type to set when nothing is being transported
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
void changeAttached()
modifiy vehicle properties when loading/unloading (optional)
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)
static SumoRNG * getEquipmentRNG()
Definition MSDevice.h:92
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition MSEdge.cpp:1180
virtual void removeTransportable(MSTransportable *t) const
Definition MSEdge.cpp:1207
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:186
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition MSNet.cpp:1259
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:392
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1250
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:88
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)
static bool active()
Definition MSStopOut.h:54
void unloadedPersons(const SUMOVehicle *veh, int n)
static MSStopOut * getInstance()
Definition MSStopOut.h:60
void unloadedContainers(const SUMOVehicle *veh, int n)
void loadedPersons(const SUMOVehicle *veh, int n)
Definition MSStopOut.cpp:96
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.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
The car-following model and parameter.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
void setGUIShape(SUMOVehicleShape shape)
Set a new value for this type's gui shape.
int getPersonCapacity() const
Get this vehicle type's person capacity.
SUMOTime getLoadingDuration(const bool isPerson) const
Get this vehicle type's loading duration.
void setLength(const double &length)
Set a new value for this type's length.
void setVClass(SUMOVehicleClass vclass)
Set a new value for this type's vehicle class.
double getLength() const
Get vehicle's length [m].
SUMOVehicleShape getGuiShape() const
Get this vehicle type's shape.
void setMass(double mass)
Set a new value for this type's mass.
double getMass() const
Get this vehicle type's mass.
double getBoardingFactor() const
Get this person type's factor for loading/boarding duration.
const SUMOVTypeParameter & getParameter() const
int getContainerCapacity() const
Get this vehicle type's container capacity.
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.
std::string getStringParam(const std::string &paramName, const bool required=false, const std::string &deflt="") const
Retrieve a string parameter for the traffic object.
virtual void replaceVehicleType(const MSVehicleType *type)=0
Replaces the current vehicle type by the one given.
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 SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
Structure representing possible vehicle parameter.
double locomotiveLength
the length of the locomotive
double carriageLength
the length of train carriages
double carriageGap
the length of the gap between carriages
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 void removeTransportableMass(MSTransportable *t)=0
removes a person or containers mass
virtual const MSStop & getNextStop() const =0
virtual MSStop & getNextStopMutable()=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.