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 i = myTransportables.erase(i); // erase first in case proceed throws an exception
211 numUnloaded++;
212 if (taxiDevice != nullptr) {
213 taxiDevice->customerArrived(transportable);
214 }
215 if (!transportable->proceed(MSNet::getInstance(), arrivalTime)) {
216 if (myAmContainer) {
217 MSNet::getInstance()->getContainerControl().erase(transportable);
218 } else {
219 MSNet::getInstance()->getPersonControl().erase(transportable);
220 }
221 }
222 if (MSStopOut::active()) {
223 SUMOVehicle* vehicle = dynamic_cast<SUMOVehicle*>(&veh);
224 if (myAmContainer) {
226 } else {
228 }
229 }
230 continue;
231 }
232 ++i;
233 }
234 if (numUnloaded != 0) {
236 }
237 }
238 }
239 return true;
240}
241
242
243bool
246 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
247 for (MSTransportable* const transportable : myTransportables) {
248 transportable->setDeparted(currentTime);
249 }
250 }
252 // to trigger vehicle leaving
253 notifyMove(veh, -1., -1., -1.);
254 }
255 return true;
256}
257
258
259bool
261 MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
263 for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end();) {
265 MSTransportable* transportable = *i;
266 if (transportable->getDestination() != veh.getEdge()) {
267 WRITE_WARNINGF("Teleporting % '%' from vehicle destination edge '%' to intended destination edge '%' time=%",
268 myAmContainer ? "container" : "person", transportable->getID(), veh.getEdge()->getID(),
269 transportable->getDestination()->getID(), time2string(SIMSTEP));
271 }
272 if (!transportable->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep(), true)) {
273 tc.erase(transportable);
274 }
275 i = myTransportables.erase(i);
276 }
277 }
278 return true;
279}
280
281
282void
284 if (myTransportables.empty()) {
286 }
287 myTransportables.push_back(transportable);
288 if (MSStopOut::active()) {
289 if (myAmContainer) {
291 } else {
293 }
294 }
295 MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
296 if (taxiDevice != nullptr) {
297 taxiDevice->customerEntered(transportable);
298 }
300}
301
302
303void
305 auto it = std::find(myTransportables.begin(), myTransportables.end(), transportable);
306 if (it != myTransportables.end()) {
307 myTransportables.erase(it);
309 if (myAmContainer) {
311 } else {
313 }
314 }
315 MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
316 if (taxiDevice != nullptr) {
317 taxiDevice->customerArrived(transportable);
318 }
320 }
321}
322
323
324void
326 if (myLoadedType != nullptr) {
328 if (perAttached > 0) {
329 MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(myHolder);
331 const double numAttached = ceil(myTransportables.size() / perAttached);
332 if (numAttached > 0.) {
333 MSVehicleType* stype = &veh.getSingularType();
336 stype->setLength(myOriginalType->getLength() + numAttached * myLoadedType->getLength());
337 stype->setMass(myOriginalType->getMass() + numAttached * myLoadedType->getMass());
338 SUMOVTypeParameter& sparam = const_cast<SUMOVTypeParameter&>(stype->getParameter());
342 } else {
344 }
345 if (oldVC != myHolder.getVClass()) {
346 veh.reroute(SIMSTEP, "device." + deviceName() + ".loadedType", veh.getRouterTT());
347 }
348 }
349 }
350}
351
352
353void
357 std::vector<std::string> internals;
358 internals.push_back(toString(myStopped));
359 out.writeAttr(SUMO_ATTR_STATE, toString(internals));
360 out.closeTag();
361}
362
363
364void
366 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
367 bis >> myStopped;
368}
369
370
371std::string
372MSDevice_Transportable::getParameter(const std::string& key) const {
373 if (key == "IDList") {
374 std::vector<std::string> ids;
375 for (const MSTransportable* t : myTransportables) {
376 ids.push_back(t->getID());
377 }
378 return toString(ids);
379 }
380 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
381}
382
383
384/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TLF(string,...)
Definition MsgHandler.h:307
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:1176
virtual void removeTransportable(MSTransportable *t) const
Definition MSEdge.cpp:1203
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:1209
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:326
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:384
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1200
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 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.