Eclipse SUMO - Simulation of Urban MObility
MSTransportableControl.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 /****************************************************************************/
21 // Stores all persons in the net and handles their waiting for cars.
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <vector>
26 #include <algorithm>
30 #include <microsim/MSNet.h>
31 #include <microsim/MSEdge.h>
34 #include <microsim/MSVehicle.h>
39 
40 
41 // ===========================================================================
42 // method definitions
43 // ===========================================================================
45  myLoadedNumber(0),
46  myDiscardedNumber(0),
47  myRunningNumber(0),
48  myJammedNumber(0),
49  myWaitingForDepartureNumber(0),
50  myWaitingForVehicleNumber(0),
51  myWaitingUntilNumber(0),
52  myEndedNumber(0),
53  myArrivedNumber(0),
54  myHaveNewWaiting(false) {
56  MSNet* const net = MSNet::getInstance();
57  if (isPerson) {
58  const std::string model = oc.getString("pedestrian.model");
60  if (model == "striping") {
61  myMovementModel = new MSPModel_Striping(oc, net);
62  } else if (model == "nonInteracting") {
64  } else {
65  throw ProcessError("Unknown pedestrian model '" + model + "'");
66  }
67  } else {
69  }
70 }
71 
72 
74  for (std::map<std::string, MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end(); ++i) {
75  delete (*i).second;
76  }
77  myTransportables.clear();
78  myWaiting4Vehicle.clear();
80  delete myMovementModel;
81  }
82  delete myNonInteractingModel;
83 }
84 
85 
86 bool
88  const SUMOVehicleParameter& param = transportable->getParameter();
89  if (myTransportables.find(param.id) == myTransportables.end()) {
90  myTransportables[param.id] = transportable;
91  const SUMOTime step = param.depart % DELTA_T == 0 ? param.depart : (param.depart / DELTA_T + 1) * DELTA_T;
92  myWaiting4Departure[step].push_back(transportable);
95  return true;
96  }
97  return false;
98 }
99 
100 
102 MSTransportableControl::get(const std::string& id) const {
103  std::map<std::string, MSTransportable*>::const_iterator i = myTransportables.find(id);
104  if (i == myTransportables.end()) {
105  return nullptr;
106  }
107  return (*i).second;
108 }
109 
110 
111 void
113  if (OptionsCont::getOptions().isSet("tripinfo-output")) {
114  transportable->tripInfoOutput(OutputDevice::getDeviceByOption("tripinfo-output"));
115  } else if (OptionsCont::getOptions().getBool("duration-log.statistics")) {
116  // collecting statistics is a sideffect
118  transportable->tripInfoOutput(dev);
119  }
120  if (OptionsCont::getOptions().isSet("vehroute-output")) {
121  transportable->routeOutput(OutputDevice::getDeviceByOption("vehroute-output"), OptionsCont::getOptions().getBool("vehroute-output.route-length"));
122  }
123  const std::map<std::string, MSTransportable*>::iterator i = myTransportables.find(transportable->getID());
124  if (i != myTransportables.end()) {
125  myRunningNumber--;
126  myEndedNumber++;
127  delete i->second;
128  myTransportables.erase(i);
129  }
130 }
131 
132 
133 void
135  const SUMOTime step = time % DELTA_T == 0 ? time : (time / DELTA_T + 1) * DELTA_T;
136  // avoid double registration
137  const TransportableVector& transportables = myWaiting4Departure[step];
138  if (std::find(transportables.begin(), transportables.end(), transportable) == transportables.end()) {
139  myWaitingUntil[step].push_back(transportable);
141  }
142 }
143 
144 
145 void
147  myHaveNewWaiting = false;
148  while (myWaiting4Departure.find(time) != myWaiting4Departure.end()) {
149  const TransportableVector& transportables = myWaiting4Departure[time];
150  // we cannot use an iterator here because there might be additions to the vector while proceeding
151  for (int i = 0; i < (int)transportables.size(); ++i) {
153  if (transportables[i]->proceed(net, time)) {
154  myRunningNumber++;
155  } else {
156  erase(transportables[i]);
157  }
158  }
159  myWaiting4Departure.erase(time);
160  }
161  while (myWaitingUntil.find(time) != myWaitingUntil.end()) {
162  const TransportableVector& transportables = myWaitingUntil[time];
163  // we cannot use an iterator here because there might be additions to the vector while proceeding
164  for (int i = 0; i < (int)transportables.size(); ++i) {
166  if (!transportables[i]->proceed(net, time)) {
167  erase(transportables[i]);
168  }
169  }
170  myWaitingUntil.erase(time);
171  }
172 }
173 
174 void
176  myRunningNumber++;
177 }
178 
179 void
180 MSTransportableControl::addWaiting(const MSEdge* const edge, MSTransportable* transportable) {
181  myWaiting4Vehicle[edge].push_back(transportable);
183  myHaveNewWaiting = true;
184 }
185 
186 
187 bool
188 MSTransportableControl::boardAnyWaiting(MSEdge* edge, SUMOVehicle* vehicle, const SUMOVehicleParameter::Stop& stop, SUMOTime& timeToBoardNextPerson, SUMOTime& stopDuration) {
189  UNUSED_PARAMETER(stop);
190  bool ret = false;
191  if (myWaiting4Vehicle.find(edge) != myWaiting4Vehicle.end()) {
194  for (TransportableVector::iterator i = wait.begin(); i != wait.end();) {
195  if ((*i)->isWaitingFor(vehicle)
196  && vehicle->allowsBoarding(*i)
197  && timeToBoardNextPerson - DELTA_T <= currentTime
198  && vehicle->isStoppedInRange((*i)->getEdgePos(), MSGlobals::gStopTolerance)) {
199  edge->removePerson(*i);
200  vehicle->addTransportable(*i);
201  if (timeToBoardNextPerson >= 0) { // meso does not have boarding times
202  const SUMOTime boardingDuration = vehicle->getVehicleType().getBoardingDuration();
203  //update the time point at which the next person can board the vehicle
204  if (timeToBoardNextPerson > currentTime - DELTA_T) {
205  timeToBoardNextPerson += boardingDuration;
206  } else {
207  timeToBoardNextPerson = currentTime + boardingDuration;
208  }
209  }
210 
211  static_cast<MSStageDriving*>((*i)->getCurrentStage())->setVehicle(vehicle);
212  if ((*i)->getCurrentStage()->getOriginStop() != nullptr) {
213  (*i)->getCurrentStage()->getOriginStop()->removeTransportable(*i);
214  }
215  i = wait.erase(i);
217  ret = true;
218  } else {
219  ++i;
220  }
221  }
222  if (wait.size() == 0) {
223  myWaiting4Vehicle.erase(myWaiting4Vehicle.find(edge));
224  }
225  if (ret && timeToBoardNextPerson >= 0) {
226  //if the time a person needs to enter the vehicle extends the duration of the stop of the vehicle extend
227  //the duration by setting it to the boarding duration of the person
228  stopDuration = MAX2(stopDuration, timeToBoardNextPerson - currentTime);
229  timeToBoardNextPerson -= DELTA_T;
230  }
231  }
232  return ret;
233 }
234 
235 
236 bool
237 MSTransportableControl::loadAnyWaiting(MSEdge* edge, SUMOVehicle* vehicle, const SUMOVehicleParameter::Stop& stop, SUMOTime& timeToLoadNextContainer, SUMOTime& stopDuration) {
238  bool ret = false;
239  if (myWaiting4Vehicle.find(edge) != myWaiting4Vehicle.end()) {
241  TransportableVector& waitContainers = myWaiting4Vehicle[edge];
242  for (TransportableVector::iterator i = waitContainers.begin(); i != waitContainers.end();) {
243  if ((*i)->isWaitingFor(vehicle)
244  && vehicle->getVehicleType().getContainerCapacity() > vehicle->getContainerNumber()
245  && timeToLoadNextContainer - DELTA_T <= currentTime
246  && stop.startPos <= (*i)->getEdgePos()
247  && (*i)->getEdgePos() <= stop.endPos) {
248  edge->removeContainer(*i);
249  vehicle->addTransportable(*i);
250  if (timeToLoadNextContainer >= 0) { // meso does not have loading times
251  //if the time a person needs to enter the vehicle extends the duration of the stop of the vehicle extend
252  //the duration by setting it to the boarding duration of the person
253  const SUMOTime loadingDuration = vehicle->getVehicleType().getLoadingDuration();
254  //update the time point at which the next container can be loaded on the vehicle
255  if (timeToLoadNextContainer > currentTime - DELTA_T) {
256  timeToLoadNextContainer += loadingDuration;
257  } else {
258  timeToLoadNextContainer = currentTime + loadingDuration;
259  }
260  }
261 
262  static_cast<MSStageDriving*>((*i)->getCurrentStage())->setVehicle(vehicle);
263  if ((*i)->getCurrentStage()->getOriginStop() != nullptr) {
264  (*i)->getCurrentStage()->getOriginStop()->removeTransportable(*i);
265  }
266  i = waitContainers.erase(i);
268  ret = true;
269  } else {
270  ++i;
271  }
272  }
273  if (waitContainers.size() == 0) {
274  myWaiting4Vehicle.erase(myWaiting4Vehicle.find(edge));
275  }
276  if (ret && timeToLoadNextContainer >= 0) {
277  //if the time a container needs to get loaded on the vehicle extends the duration of the stop of the vehicle extend
278  //the duration by setting it to the loading duration of the container
279  stopDuration = MAX2(stopDuration, timeToLoadNextContainer - currentTime);
280  timeToLoadNextContainer -= DELTA_T;
281  }
282  }
283  return ret;
284 }
285 
286 
287 bool
289  return !myTransportables.empty();
290 }
291 
292 
293 bool
296 }
297 
298 
299 int
302 }
303 
304 int
307 }
308 
309 
310 int
313 }
314 
315 int
318 }
319 
320 void
322  for (std::map<const MSEdge*, TransportableVector>::iterator i = myWaiting4Vehicle.begin(); i != myWaiting4Vehicle.end(); ++i) {
323  const MSEdge* edge = (*i).first;
324  for (MSTransportable* const p : i->second) {
325  std::string transportableType;
326  if (p->isPerson()) {
327  edge->removePerson(p);
328  transportableType = "Person";
329  } else {
330  transportableType = "Container";
331  edge->removeContainer(p);
332  }
333  MSStageDriving* stage = dynamic_cast<MSStageDriving*>(p->getCurrentStage());
334  const std::string waitDescription = stage == nullptr ? "waiting" : stage->getWaitingDescription();
335  WRITE_WARNING(transportableType + " '" + p->getID() + "' aborted " + waitDescription + ".");
336  erase(p);
337  }
338  }
339  myWaiting4Vehicle.clear();
341 }
342 
343 void
345  const MSEdge* edge = t->getEdge();
346  auto it = myWaiting4Vehicle.find(edge);
347  if (it != myWaiting4Vehicle.end()) {
348  TransportableVector& waiting = it->second;
349  auto it2 = std::find(waiting.begin(), waiting.end(), t);
350  if (it2 != waiting.end()) {
351  waiting.erase(it2);
352  }
353  }
354 }
355 
356 void
358  for (std::map<SUMOTime, TransportableVector>::iterator it = myWaiting4Departure.begin(); it != myWaiting4Departure.end(); ++it) {
359  TransportableVector& ts = it->second;
360  TransportableVector::iterator it2 = std::find(ts.begin(), ts.end(), t);
361  if (it2 != ts.end()) {
362  ts.erase(it2);
363  }
364  }
365  for (std::map<SUMOTime, TransportableVector>::iterator it = myWaitingUntil.begin(); it != myWaitingUntil.end(); ++it) {
366  TransportableVector& ts = it->second;
367  TransportableVector::iterator it2 = std::find(ts.begin(), ts.end(), t);
368  if (it2 != ts.end()) {
369  ts.erase(it2);
370  }
371  }
372 }
373 
374 
377  std::mt19937* rng) const {
378  const double speedFactor = vtype->computeChosenSpeedDeviation(rng);
379  return new MSPerson(pars, vtype, plan, speedFactor);
380 }
381 
382 
385  return new MSTransportable(pars, vtype, plan, false);
386 }
387 
388 
389 void
391  std::ostringstream oss;
392  oss << myRunningNumber << " " << myLoadedNumber << " " << myEndedNumber << " " << myWaitingForDepartureNumber << " " << myArrivedNumber << " " << myDiscardedNumber;
393  oss << " " << myJammedNumber << " " << myWaitingForVehicleNumber << " " << myWaitingUntilNumber << " " << myHaveNewWaiting;
394  out.writeAttr(SUMO_ATTR_STATE, oss.str());
395  for (const auto& it : myTransportables) {
396  it.second->saveState(out);
397  }
398 }
399 
400 
401 void
402 MSTransportableControl::loadState(const std::string& state) {
403  std::istringstream iss(state);
406 }
407 
408 
409 /****************************************************************************/
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
long long int SUMOTime
Definition: SUMOTime.h:31
@ SUMO_ATTR_STATE
The state of a link.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:29
T MAX2(T a, T b)
Definition: StdDefs.h:79
A road/street connecting two junctions.
Definition: MSEdge.h:77
virtual void removeContainer(MSTransportable *container) const
Remove container from myContainers.
Definition: MSEdge.h:667
virtual void removePerson(MSTransportable *p) const
Definition: MSEdge.cpp:953
static double gStopTolerance
The tolerance to apply when matching waiting persons and vehicles.
Definition: MSGlobals.h:133
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
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
The pedestrian following model.
The pedestrian following model.
virtual int getActiveNumber()=0
return the number of active objects
std::string getWaitingDescription() const
Return where the person waits and for what.
MSStoppingPlace * getOriginStop() const
returns the origin stop (if any). only needed for MSStageTrip
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
void loadState(const std::string &state)
Reconstruct the current state.
void setWaitEnd(SUMOTime time, MSTransportable *transportable)
sets the arrival time for a waiting transportable
bool hasTransportables() const
checks whether any transportable waits to finish her plan
int myWaitingForDepartureNumber
The number of transportables waiting for departure.
void forceDeparture()
register forced (traci) departure
void checkWaiting(MSNet *net, const SUMOTime time)
checks whether any transportables waiting time is over
void saveState(OutputDevice &out)
Saves the current state into the given stream.
MSTransportableControl(const bool isPerson)
Constructor.
virtual MSTransportable * buildPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan, std::mt19937 *rng) const
Builds a new person.
int myLoadedNumber
The number of build transportables.
std::map< std::string, MSTransportable * > myTransportables
all currently created transportables by id
void abortWaiting(MSTransportable *t)
aborts waiting stage of transportable
void abortWaitingForVehicle(MSTransportable *t)
let the given transportable abort waiting for a vehicle (when removing stage via TraCI)
void abortAnyWaitingForVehicle()
aborts the plan for any transportable that is still waiting for a ride
bool hasNonWaiting() const
checks whether any transportable is still engaged in walking / stopping
virtual MSTransportable * buildContainer(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan) const
Builds a new container.
int myArrivedNumber
The number of transportables that arrived at their destination.
int getMovingNumber() const
Returns the number of transportables moving by themselvs (i.e. walking)
void addWaiting(const MSEdge *edge, MSTransportable *person)
adds a transportable to the list of transportables waiting for a vehicle on the specified edge
int myEndedNumber
The number of transportables that exited the simulation.
bool loadAnyWaiting(MSEdge *edge, SUMOVehicle *vehicle, const SUMOVehicleParameter::Stop &stop, SUMOTime &timeToLoadNextContainer, SUMOTime &stopDuration)
load any applicable containers Loads any container that is waiting on that edge for the given vehicle...
std::map< const MSEdge *, TransportableVector > myWaiting4Vehicle
the lists of waiting transportables
int myWaitingUntilNumber
The number of transportables waiting for a specified time.
virtual void erase(MSTransportable *transportable)
removes a single transportable
int myDiscardedNumber
The number of discarded transportables.
std::map< SUMOTime, TransportableVector > myWaitingUntil
the lists of walking / stopping transportables
bool add(MSTransportable *transportable)
Adds a single transportable, returns false if an id clash occurred.
bool myHaveNewWaiting
whether a new transportable waiting for a vehicle has been added in the last step
virtual ~MSTransportableControl()
Destructor.
int myJammedNumber
The number of jammed transportables.
std::map< SUMOTime, TransportableVector > myWaiting4Departure
Transportables waiting for departure.
bool boardAnyWaiting(MSEdge *edge, SUMOVehicle *vehicle, const SUMOVehicleParameter::Stop &stop, SUMOTime &timeToBoardNextPerson, SUMOTime &stopDuration)
board any applicable persons Boards any people who wait on that edge for the given vehicle and remove...
std::vector< MSTransportable * > TransportableVector
Definition of a list of transportables.
int myRunningNumber
The number of transportables within the network (build and inserted but not removed)
int myWaitingForVehicleNumber
The number of transportables waiting for vehicles.
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
int getActiveCount()
return the number of active transportable objects
int getRidingNumber() const
Returns the number of transportables riding a vehicle.
void routeOutput(OutputDevice &os, const bool withRouteLength) const
Called on writing vehroute output.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
bool isPerson() const
Whether it is a person.
const MSEdge * getEdge() const
Returns the current edge.
MSStage * getCurrentStage() const
Return the current stage.
void tripInfoOutput(OutputDevice &os) const
Called on writing tripinfo output.
std::vector< MSStage * > MSTransportablePlan
the structure holding the plan of a transportable
The car-following model and parameter.
Definition: MSVehicleType.h:62
SUMOTime getLoadingDuration() const
Get this vehicle type's loading duration.
double computeChosenSpeedDeviation(std::mt19937 *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
SUMOTime getBoardingDuration() const
Get this vehicle type's boarding duration.
int getContainerCapacity() const
Get this vehicle type's container capacity.
const std::string & getID() const
Returns the id.
Definition: Named.h:73
A storage for options typed value containers)
Definition: OptionsCont.h:89
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
An output device that encapsulates an ofstream.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
Representation of a vehicle.
Definition: SUMOVehicle.h:58
virtual void addTransportable(MSTransportable *transportable)=0
Adds a person or container to this vehicle.
virtual int getContainerNumber() const =0
Returns the number of containers.
virtual bool isStoppedInRange(const double pos, const double tolerance) const =0
Returns whether the vehicle is stopped in the range of the given position.
virtual bool allowsBoarding(MSTransportable *t) const =0
whether the given transportable is allowed to board this vehicle
Definition of vehicle stop (position and duration)
double startPos
The stopping position start.
double endPos
The stopping position end.
Structure representing possible vehicle parameter.
std::string id
The vehicle's id.