Eclipse SUMO - Simulation of Urban MObility
MSDevice_Transportable.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 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>
34 #include "MSDevice_Transportable.h"
35 #include "MSDevice_Taxi.h"
36 
37 
38 // ===========================================================================
39 // method definitions
40 // ===========================================================================
41 // ---------------------------------------------------------------------------
42 // static initialisation methods
43 // ---------------------------------------------------------------------------
45 MSDevice_Transportable::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into, const bool isContainer) {
46  MSDevice_Transportable* device = new MSDevice_Transportable(v, isContainer ? "container_" + v.getID() : "person_" + v.getID(), isContainer);
47  into.push_back(device);
48  return device;
49 }
50 
51 
52 // ---------------------------------------------------------------------------
53 // MSDevice_Transportable-methods
54 // ---------------------------------------------------------------------------
55 MSDevice_Transportable::MSDevice_Transportable(SUMOVehicle& holder, const std::string& id, const bool isContainer)
56  : MSVehicleDevice(holder, id), myAmContainer(isContainer), myTransportables(), myStopped(holder.isStopped()) {
57 }
58 
59 
61  // flush any unfortunate riders still remaining
62  for (auto it = myTransportables.begin(); it != myTransportables.end();) {
63  MSTransportable* transportable = *it;
64  WRITE_WARNING((myAmContainer ? "Removing container '" : "Removing person '") + transportable->getID() +
65  "' at removal of vehicle '" + myHolder.getID() + "'");
66  MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(transportable->getCurrentStage());
67  if (stage != nullptr) {
68  stage->setVehicle(nullptr);
69  }
70  if (myAmContainer) {
71  MSNet::getInstance()->getContainerControl().erase(transportable);
72  } else {
73  MSNet::getInstance()->getPersonControl().erase(transportable);
74  }
75  it = myTransportables.erase(it);
76  }
77 }
78 
79 void
81  const double /* frontOnLane */,
82  const double /* timeOnLane*/,
83  const double /* meanSpeedFrontOnLane */,
84  const double /*meanSpeedVehicleOnLane */,
85  const double /* travelledDistanceFrontOnLane */,
86  const double /* travelledDistanceVehicleOnLane */,
87  const double /* meanLengthOnLane */) {
88  notifyMove(const_cast<SUMOTrafficObject&>(veh), -1, -1, -1);
89 }
90 
91 
92 bool
93 MSDevice_Transportable::notifyMove(SUMOTrafficObject& veh, double /*oldPos*/, double /*newPos*/, double /*newSpeed*/) {
94  if (myStopped) {
95  if (!veh.isStopped()) {
96  for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end(); ++i) {
97  (*i)->setDeparted(MSNet::getInstance()->getCurrentTimeStep());
98  }
99  myStopped = false;
100  }
101  } else {
102  if (veh.isStopped()) {
103  for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end();) {
104  MSTransportable* transportable = *i;
105  if (transportable->getDestination() == veh.getEdge()) {
106  MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(transportable->getCurrentStage());
107  // if this is the last stage, we can use the arrivalPos of the person
108  const bool unspecifiedArrivalPos = stage->unspecifiedArrivalPos() && (
109  transportable->getNumRemainingStages() > 1 || !transportable->getParameter().wasSet(VEHPARS_ARRIVALPOS_SET));
110  const double arrivalPos = (stage->unspecifiedArrivalPos()
112  SUMO_ATTR_ARRIVALPOS, transportable->getID(), true)
113  : stage->getArrivalPos());
114  if (unspecifiedArrivalPos ||
116  i = myTransportables.erase(i); // erase first in case proceed throws an exception
117  if (!transportable->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep())) {
118  if (myAmContainer) {
119  MSNet::getInstance()->getContainerControl().erase(transportable);
120  } else {
121  MSNet::getInstance()->getPersonControl().erase(transportable);
122  }
123  }
124  if (MSStopOut::active()) {
125  SUMOVehicle* vehicle = dynamic_cast<SUMOVehicle*>(&veh);
126  if (myAmContainer) {
128  } else {
130  }
131  }
132  MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
133  if (taxiDevice != nullptr) {
134  taxiDevice->customerArrived(transportable);
135  }
136  continue;
137  }
138  }
139  ++i;
140  }
141  myStopped = true;
142  }
143  }
144  return true;
145 }
146 
147 
148 bool
151  for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end(); ++i) {
152  (*i)->setDeparted(MSNet::getInstance()->getCurrentTimeStep());
153  }
154  }
155  return true;
156 }
157 
158 
159 bool
161  MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
162  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
163  for (std::vector<MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end();) {
164  MSTransportable* transportable = *i;
165  if (transportable->getDestination() != veh.getEdge()) {
166  WRITE_WARNING((myAmContainer ? "Teleporting container '" : "Teleporting person '") + transportable->getID() +
167  "' from vehicle destination edge '" + veh.getEdge()->getID() +
168  "' to intended destination edge '" + transportable->getDestination()->getID() + "'");
169  }
170  if (!transportable->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep(), true)) {
171  if (myAmContainer) {
172  MSNet::getInstance()->getContainerControl().erase(transportable);
173  } else {
174  MSNet::getInstance()->getPersonControl().erase(transportable);
175  }
176  }
177  i = myTransportables.erase(i);
178  }
179  }
180  return true;
181 }
182 
183 
184 void
186  myTransportables.push_back(transportable);
187  if (MSStopOut::active()) {
188  if (myAmContainer) {
190  } else {
192  }
193  }
194  MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(myHolder.getDevice(typeid(MSDevice_Taxi)));
195  if (taxiDevice != nullptr) {
196  taxiDevice->customerEntered(transportable);
197  }
198 }
199 
200 
201 void
203  auto it = std::find(myTransportables.begin(), myTransportables.end(), transportable);
204  if (it != myTransportables.end()) {
205  myTransportables.erase(it);
206  if (MSStopOut::active() && myHolder.isStopped()) {
207  if (myAmContainer) {
209  } else {
211  }
212  }
213  }
214 }
215 
216 
217 void
220  out.writeAttr(SUMO_ATTR_ID, getID());
221  std::vector<std::string> internals;
222  internals.push_back(toString(myStopped));
223  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
224  out.closeTag();
225 }
226 
227 
228 void
230  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
231  bis >> myStopped;
232 }
233 
234 
235 std::string
236 MSDevice_Transportable::getParameter(const std::string& key) const {
237  if (key == "IDList") {
238  std::vector<std::string> ids;
239  for (const MSTransportable* t : myTransportables) {
240  ids.push_back(t->getID());
241  }
242  return toString(ids);
243  }
244  throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
245 }
246 
247 
248 /****************************************************************************/
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
const int VEHPARS_ARRIVALPOS_SET
@ SUMO_TAG_DEVICE
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_ID
@ SUMO_ATTR_STATE
The state of a link.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
A device which collects info on the vehicle trip (mainly on departure and arrival)
Definition: MSDevice_Taxi.h:48
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.
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.
static MSDevice_Transportable * buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into, const bool isContainer)
Build devices for the given vehicle, if needed.
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)
Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
bool myStopped
Whether the vehicle is at a stop.
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 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 getLength() const
return the length of the edge
Definition: MSEdge.h:630
static double gStopTolerance
The tolerance to apply when matching waiting persons and vehicles.
Definition: MSGlobals.h:133
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
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:171
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:995
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:986
bool unspecifiedArrivalPos() const
void setVehicle(SUMOVehicle *v)
double getArrivalPos() const
return default value for undefined arrivalPos
void loadedContainers(const SUMOVehicle *veh, int n)
Definition: MSStopOut.cpp:88
static MSStopOut * getInstance()
Definition: MSStopOut.h:60
static bool active()
Definition: MSStopOut.h:54
void unloadedPersons(const SUMOVehicle *veh, int n)
Definition: MSStopOut.cpp:83
void unloadedContainers(const SUMOVehicle *veh, int n)
Definition: MSStopOut.cpp:93
void loadedPersons(const SUMOVehicle *veh, int n)
Definition: MSStopOut.cpp:75
virtual void erase(MSTransportable *transportable)
removes a single transportable
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
virtual bool proceed(MSNet *net, SUMOTime time, const bool vehicleArrived=false)
MSStage * getCurrentStage() const
Return the current stage.
const MSEdge * getDestination() const
Returns the current destination.
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
const std::string & getID() const
Returns the id.
Definition: Named.h:73
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
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) const =0
Returns the string-value of the named (by its enum-value) attribute.
Representation of a vehicle, person, or container.
virtual bool isStopped() const =0
Returns whether the object is at a stop.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
Representation of a vehicle.
Definition: SUMOVehicle.h:58
virtual MSVehicleDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or 0.
virtual double getLength() const =0
Returns the vehicles's length.
virtual bool isStoppedInRange(const double pos, const double tolerance) const =0
Returns whether the vehicle is stopped in the range of the given position.
double arrivalPos
(optional) The position the vehicle shall arrive on
bool wasSet(int what) const
Returns whether the given parameter was set.
static double interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string &id, bool silent=false)
Interprets negative edge positions and fits them onto a given edge.