Eclipse SUMO - Simulation of Urban MObility
MSTransportable.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 /****************************************************************************/
20 // The common superclass for modelling transportable objects like persons and containers
21 /****************************************************************************/
22 #include <config.h>
23 
25 #include <utils/geom/GeomHelper.h>
29 #include <microsim/MSEdge.h>
30 #include <microsim/MSLane.h>
31 #include <microsim/MSNet.h>
39 
40 
41 // ===========================================================================
42 // method definitions
43 // ===========================================================================
45  SUMOTrafficObject(pars->id),
46  myParameter(pars), myVType(vtype), myPlan(plan), myAmPerson(isPerson) {
47  myStep = myPlan->begin();
48  // init devices
50 }
51 
52 
54  if (myStep != myPlan->end() && getCurrentStageType() == MSStageType::DRIVING) {
55  MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(*myStep);
56  if (stage->getVehicle() != nullptr) {
57  stage->getVehicle()->removeTransportable(this);
58  }
59  }
60  if (myPlan != nullptr) {
61  for (MSTransportablePlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
62  delete *i;
63  }
64  delete myPlan;
65  myPlan = nullptr;
66  }
67  for (MSTransportableDevice* dev : myDevices) {
68  delete dev;
69  }
70  delete myParameter;
71  if (myVType->isVehicleSpecific()) {
73  }
74 }
75 
76 std::mt19937*
78  return getEdge()->getLanes()[0]->getRNG();
79 }
80 
81 bool
82 MSTransportable::proceed(MSNet* net, SUMOTime time, const bool vehicleArrived) {
83  MSStage* prior = *myStep;
84  const std::string& error = prior->setArrived(net, this, time, vehicleArrived);
85  // must be done before increasing myStep to avoid invalid state for rendering
86  if (myAmPerson) {
87  prior->getEdge()->removePerson(this);
88  } else {
89  prior->getEdge()->removeContainer(this);
90  }
91  myStep++;
92  if (error != "") {
93  throw ProcessError(error);
94  }
95  if (prior->getStageType() == MSStageType::WALKING) {
96  checkAccess(prior);
97  }
98  if (myStep != myPlan->end()) {
99  if ((*myStep)->getStageType() == MSStageType::WALKING && (prior->getStageType() != MSStageType::ACCESS || prior->getDestination() != (*myStep)->getFromEdge())) {
100  checkAccess(prior, false);
101  }
102  (*myStep)->proceed(net, this, time, prior);
103  return true;
104  } else {
105  // cleanup
106  if (prior->getDestinationStop() != nullptr) {
107  prior->getDestinationStop()->removeTransportable(this);
108  }
110  return false;
111  }
112 }
113 
114 
115 void
116 MSTransportable::setID(const std::string& /*newID*/) {
117  throw ProcessError("Changing a transportable ID is not permitted");
118 }
119 
120 SUMOTime
122  return myParameter->depart;
123 }
124 
125 void
127  (*myStep)->setDeparted(now);
128 }
129 
130 double
132  return (*myStep)->getEdgePos(MSNet::getInstance()->getCurrentTimeStep());
133 }
134 
135 Position
137  return (*myStep)->getPosition(MSNet::getInstance()->getCurrentTimeStep());
138 }
139 
140 double
142  return (*myStep)->getAngle(MSNet::getInstance()->getCurrentTimeStep());
143 }
144 
145 double
147  return STEPS2TIME((*myStep)->getWaitingTime(MSNet::getInstance()->getCurrentTimeStep()));
148 }
149 
150 double
152  return (*myStep)->getSpeed();
153 }
154 
155 
156 int
158  return (int)(myPlan->end() - myStep);
159 }
160 
161 
162 int
164  return (int)myPlan->size();
165 }
166 
167 
168 void
170  os.openTag(isPerson() ? "personinfo" : "containerinfo");
171  os.writeAttr("id", getID());
172  os.writeAttr("depart", time2string(getDesiredDepart()));
173  os.writeAttr("type", getVehicleType().getID());
174  for (MSStage* const i : *myPlan) {
175  i->tripInfoOutput(os, this);
176  }
177  os.closeTag();
178 }
179 
180 
181 void
182 MSTransportable::routeOutput(OutputDevice& os, const bool withRouteLength) const {
183  const std::string typeID = (
187  if (hasArrived()) {
188  os.writeAttr("arrival", time2string(MSNet::getInstance()->getCurrentTimeStep()));
189  }
190  const MSStage* previous = nullptr;
191  for (const MSStage* const stage : *myPlan) {
192  stage->routeOutput(myAmPerson, os, withRouteLength, previous);
193  previous = stage;
194  }
195  os.closeTag();
196  os.lf();
197 }
198 
199 
200 void
202  // myStep is invalidated upon modifying myPlan
203  const int stepIndex = (int)(myStep - myPlan->begin());
204  if (next < 0) {
205  myPlan->push_back(stage);
206  } else {
207  if (stepIndex + next > (int)myPlan->size()) {
208  throw ProcessError("invalid index '" + toString(next) + "' for inserting new stage into plan of '" + getID() + "'");
209  }
210  myPlan->insert(myPlan->begin() + stepIndex + next, stage);
211  }
212  myStep = myPlan->begin() + stepIndex;
213 }
214 
215 
216 void
218  assert(myStep + next < myPlan->end());
219  assert(next >= 0);
220  if (next > 0) {
221  // myStep is invalidated upon modifying myPlan
222  int stepIndex = (int)(myStep - myPlan->begin());
223  delete *(myStep + next);
224  myPlan->erase(myStep + next);
225  myStep = myPlan->begin() + stepIndex;
226  } else {
227  if (myStep + 1 == myPlan->end()) {
228  // stay in the simulation until the start of simStep to allow appending new stages (at the correct position)
229  appendStage(new MSStageWaiting(getEdge(), nullptr, 0, 0, getEdgePos(), "last stage removed", false));
230  }
231  (*myStep)->abort(this);
232  proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep());
233  }
234 }
235 
236 
237 void
239  for (MSTransportablePlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
240  (*i)->setSpeed(speed);
241  }
242 }
243 
244 
245 void
247  if (myVType->isVehicleSpecific()) {
249  }
250  myVType = type;
251 }
252 
253 
256  if (myVType->isVehicleSpecific()) {
257  return *myVType;
258  }
259  MSVehicleType* type = myVType->buildSingularType(myVType->getID() + "@" + getID());
260  replaceVehicleType(type);
261  return *type;
262 }
263 
264 
267  PositionVector centerLine;
268  const Position p = getPosition();
269  const double angle = getAngle();
270  const double length = getVehicleType().getLength();
271  const Position back = p + Position(-cos(angle) * length, -sin(angle) * length);
272  centerLine.push_back(p);
273  centerLine.push_back(back);
274  centerLine.move2side(0.5 * getVehicleType().getWidth());
275  PositionVector result = centerLine;
276  centerLine.move2side(-getVehicleType().getWidth());
277  result.append(centerLine.reverse(), POSITION_EPS);
278  //std::cout << " transp=" << getID() << " p=" << p << " angle=" << GeomHelper::naviDegree(angle) << " back=" << back << " result=" << result << "\n";
279  return result;
280 }
281 
282 
283 std::string
284 MSTransportable::getStageSummary(int stageIndex) const {
285  assert(stageIndex < (int)myPlan->size());
286  assert(stageIndex >= 0);
287  return (*myPlan)[stageIndex]->getStageSummary(myAmPerson);
288 }
289 
290 
291 bool
293  return myStep == myPlan->end();
294 }
295 
296 bool
298  return myPlan->size() > 0 && myPlan->front()->getDeparted() >= 0;
299 }
300 
301 
302 void
304  // check whether the transportable was riding to the orignal stop
305  // @note: parkingArea can currently not be set as myDestinationStop so we
306  // check for stops on the edge instead
308  if (!myAmPerson) {
309  WRITE_WARNING("parkingAreaReroute not support for containers");
310  return;
311  }
312  if (getDestination() == &orig->getLane().getEdge()) {
313  MSStageDriving* const stage = dynamic_cast<MSStageDriving*>(*myStep);
314  assert(stage != 0);
315  assert(stage->getVehicle() != 0);
316  // adapt plan
317  stage->setDestination(&replacement->getLane().getEdge(), replacement);
318  if (myStep + 1 == myPlan->end()) {
319  return;
320  }
321  // if the next step is a walk, adapt the route
322  MSStage* nextStage = *(myStep + 1);
323  if (nextStage->getStageType() == MSStageType::TRIP) {
324  dynamic_cast<MSStageTrip*>(nextStage)->setOrigin(stage->getDestination());
325  } else if (nextStage->getStageType() == MSStageType::WALKING) {
326  MSStageTrip* newStage = new MSStageTrip(stage->getDestination(), nullptr, nextStage->getDestination(),
327  nextStage->getDestinationStop(), -1, 0, "", -1, 1, getID(), 0, true, nextStage->getArrivalPos());
328  removeStage(1);
329  appendStage(newStage, 1);
330  }
331  // if the plan contains another ride with the same vehicle from the same
332  // parking area, adapt the preceeding walk to end at the replacement
333  for (auto it = myStep + 2; it != myPlan->end(); it++) {
334  MSStage* const futureStage = *it;
335  MSStage* const prevStage = *(it - 1);
336  if (futureStage->getStageType() == MSStageType::DRIVING) {
337  MSStageDriving* const ds = static_cast<MSStageDriving*>(futureStage);
338  // ride origin is set implicitly from the walk destination
339  ds->setOrigin(nullptr);
340  if (ds->getLines() == stage->getLines()
341  && prevStage->getDestination() == &orig->getLane().getEdge()) {
342  if (prevStage->getStageType() == MSStageType::TRIP) {
343  dynamic_cast<MSStageTrip*>(prevStage)->setDestination(stage->getDestination(), replacement);
344  } else if (prevStage->getStageType() == MSStageType::WALKING) {
345  MSStageTrip* newStage = new MSStageTrip(prevStage->getFromEdge(), nullptr, stage->getDestination(),
346  replacement, -1, 0, "", -1, 1, getID(), 0, true, stage->getArrivalPos());
347  int prevStageRelIndex = (int)(it - 1 - myStep);
348  removeStage(prevStageRelIndex);
349  appendStage(newStage, prevStageRelIndex);
350  }
351  break;
352  }
353  }
354  }
355  }
356 }
357 
359 MSTransportable::getDevice(const std::type_info& type) const {
360  for (MSTransportableDevice* const dev : myDevices) {
361  if (typeid(*dev) == type) {
362  return dev;
363  }
364  }
365  return nullptr;
366 }
367 
368 double
370  const MSEdge* edge = getEdge();
371  const double ep = getEdgePos();
372  const double gp = edge->getLanes()[0]->interpolateLanePosToGeometryPos(ep);
373  return edge->getLanes()[0]->getShape().slopeDegreeAtOffset(gp);
374 }
375 
376 SUMOTime
378  return (*myStep)->getWaitingTime(MSNet::getInstance()->getCurrentTimeStep());
379 }
380 
381 double
384 }
385 
388  return getVehicleType().getVehicleClass();
389 }
390 
391 
392 void
394  // this saves lots of departParameters which are only needed for transportables that did not yet depart
395  // the parameters may hold the name of a vTypeDistribution but we are interested in the actual type
397  std::ostringstream state;
398  int stepIdx = (int)(myStep - myPlan->begin());
399  for (auto it = myPlan->begin(); it != myStep; ++it) {
400  if ((*it)->getStageType() == MSStageType::TRIP) {
401  stepIdx--;
402  }
403  }
404  state << myParameter->parametersSet << " " << stepIdx;
405  (*myStep)->saveState(state);
406  out.writeAttr(SUMO_ATTR_STATE, state.str());
407  const MSStage* previous = nullptr;
408  for (const MSStage* const stage : *myPlan) {
409  stage->routeOutput(myAmPerson, out, false, previous);
410  previous = stage;
411  }
412  out.closeTag();
413 }
414 
415 
416 void
417 MSTransportable::loadState(const std::string& state) {
418  std::istringstream iss(state);
419  int step;
420  iss >> myParameter->parametersSet >> step;
421  myStep = myPlan->begin() + step;
422  (*myStep)->loadState(this, iss);
423 }
424 
425 
426 /****************************************************************************/
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
long long int SUMOTime
Definition: SUMOTime.h:31
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_CONTAINERTYPE_ID
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_PERSON
@ SUMO_ATTR_STATE
The state of a link.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
static void buildTransportableDevices(MSTransportable &p, std::vector< MSTransportableDevice * > &into)
Build devices for the given person, if needed.
Definition: MSDevice.cpp:119
A road/street connecting two junctions.
Definition: MSEdge.h:77
virtual void removeContainer(MSTransportable *container) const
Remove container from myContainers.
Definition: MSEdge.h:667
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:166
virtual void removePerson(MSTransportable *p) const
Definition: MSEdge.cpp:953
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:673
The simulated network and simulation perfomer.
Definition: MSNet.h:89
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:371
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:986
const std::set< std::string > & getLines() const
SUMOVehicle * getVehicle() const
Whether the transportable waits for a vehicle.
double getArrivalPos() const
return default value for undefined arrivalPos
void setOrigin(const MSEdge *origin)
change origin for parking area rerouting
const MSEdge * getDestination() const
returns the destination edge
Definition: MSStage.cpp:70
virtual const MSEdge * getFromEdge() const
Definition: MSStage.cpp:82
virtual double getArrivalPos() const
Definition: MSStage.h:89
virtual const std::string setArrived(MSNet *net, MSTransportable *transportable, SUMOTime now, const bool vehicleArrived)
logs end of the step
Definition: MSStage.cpp:131
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
Definition: MSStage.h:80
MSStageType getStageType() const
Definition: MSStage.h:114
void setDestination(const MSEdge *newDestination, MSStoppingPlace *newDestStop)
Definition: MSStage.cpp:159
virtual void routeOutput(const bool isPerson, OutputDevice &os, const bool withRouteLength, const MSStage *const previous) const =0
Called on writing vehroute output.
virtual const MSEdge * getEdge() const
Returns the current edge.
Definition: MSStage.cpp:76
A lane area vehicles can halt at.
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
Abstract in-person device.
virtual double getEdgePos() const
Return the position on the edge.
bool hasDeparted() const
return whether the transportable has started it's plan
SUMOVehicleClass getVClass() const
Returns the object's access class.
SUMOTime getWaitingTime() const
virtual double getAngle() const
return the current angle of the transportable
void routeOutput(OutputDevice &os, const bool withRouteLength) const
Called on writing vehroute output.
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
virtual double getSpeed() const
the current speed of the transportable
PositionVector getBoundingBox() const
return the bounding box of the person
const bool myAmPerson
std::string getStageSummary(int stageIndex) const
return textual summary for the given stage
MSTransportableDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists or 0.
void setDeparted(SUMOTime now)
logs depart time of the current stage
void setSpeed(double speed)
sets the walking speed (ignored in other stages)
virtual bool proceed(MSNet *net, SUMOTime time, const bool vehicleArrived=false)
MSTransportablePlan::iterator myStep
the iterator over the route
MSTransportablePlan * myPlan
the plan of the transportable
MSVehicleType * myVType
This transportable's type. (mainly used for drawing related information Note sure if it is really nec...
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
bool isPerson() const
Whether it is a person.
virtual Position getPosition() const
Return the Network coordinate of the transportable.
const SUMOVehicleParameter * myParameter
the plan of the transportable
std::mt19937 * getRNG() const
returns the associated RNG
void saveState(OutputDevice &out)
Saves the current state into the given stream.
bool isContainer() const
Whether it is a container.
void removeStage(int next)
removes the nth next stage
virtual ~MSTransportable()
destructor
int getNumStages() const
Return the total number stages in this persons plan.
MSStageType getCurrentStageType() const
the current stage type of the transportable
void rerouteParkingArea(MSStoppingPlace *orig, MSStoppingPlace *replacement)
adapt plan when the vehicle reroutes and now stops at replacement instead of orig
const MSEdge * getEdge() const
Returns the current edge.
void loadState(const std::string &state)
Reconstructs the current state.
std::vector< MSTransportableDevice * > myDevices
The devices this transportable has.
virtual double getWaitingSeconds() const
the time this transportable spent waiting in seconds
MSTransportable(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportablePlan *plan, const bool isPerson)
constructor
bool hasArrived() const
return whether the person has reached the end of its plan
double getSlope() const
Returns the slope of the road at object's position in degrees.
void tripInfoOutput(OutputDevice &os) const
Called on writing tripinfo output.
void appendStage(MSStage *stage, int next=-1)
Appends the given stage to the current plan.
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
virtual void checkAccess(const MSStage *const prior, const bool isDisembark=true)
std::vector< MSStage * > MSTransportablePlan
the structure holding the plan of a transportable
const MSEdge * getDestination() const
Returns the current destination.
void setID(const std::string &newID)
set the id (inherited from Named but forbidden for transportables)
virtual double getSpeedFactor() const
the current speed factor of the transportable (where applicable)
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
SUMOTime getDesiredDepart() const
Returns the desired departure time.
double getMaxSpeed() const
Returns the object's maximum speed.
void removeVType(const MSVehicleType *vehType)
The car-following model and parameter.
Definition: MSVehicleType.h:62
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
bool isVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:90
double getLength() const
Get vehicle's length [m].
MSVehicleType * buildSingularType(const std::string &id) const
Duplicates the microsim vehicle type giving the newly created type the given id, marking it as vehicl...
const std::string & getID() const
Returns the id.
Definition: Named.h:73
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
void lf()
writes a line feed if applicable
Definition: OutputDevice.h:227
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.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
A list of positions.
void append(const PositionVector &v, double sameThreshold=2.0)
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
PositionVector reverse() const
reverse position vector
Representation of a vehicle, person, or container.
virtual void removeTransportable(MSTransportable *t)=0
removes a person or container
Structure representing possible vehicle parameter.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
void write(OutputDevice &dev, const OptionsCont &oc, const SumoXMLTag tag=SUMO_TAG_VEHICLE, const std::string &typeID="") const
Writes the parameters as a beginning element.