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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // Stores all persons in the net and handles their waiting for cars.
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <vector>
28 #include <algorithm>
29 #include "MSNet.h"
30 #include "MSEdge.h"
32 #include "MSContainer.h"
33 #include "MSVehicle.h"
34 #include "MSTransportableControl.h"
38 
39 
40 // ===========================================================================
41 // method definitions
42 // ===========================================================================
44  myLoadedNumber(0),
45  myRunningNumber(0),
46  myJammedNumber(0),
47  myWaitingForVehicleNumber(0),
48  myHaveNewWaiting(false) {
49 }
50 
51 
53  for (std::map<std::string, MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end(); ++i) {
54  delete(*i).second;
55  }
56  myTransportables.clear();
57  myWaiting4Vehicle.clear();
58 }
59 
60 
61 bool
63  const SUMOVehicleParameter& param = transportable->getParameter();
64  if (myTransportables.find(param.id) == myTransportables.end()) {
65  myTransportables[param.id] = transportable;
66  const SUMOTime step = param.depart % DELTA_T == 0 ? param.depart : (param.depart / DELTA_T + 1) * DELTA_T;
67  myWaiting4Departure[step].push_back(transportable);
69  return true;
70  }
71  return false;
72 }
73 
74 
76 MSTransportableControl::get(const std::string& id) const {
77  std::map<std::string, MSTransportable*>::const_iterator i = myTransportables.find(id);
78  if (i == myTransportables.end()) {
79  return nullptr;
80  }
81  return (*i).second;
82 }
83 
84 
85 void
87  if (OptionsCont::getOptions().isSet("tripinfo-output")) {
88  transportable->tripInfoOutput(OutputDevice::getDeviceByOption("tripinfo-output"));
89  } else if (OptionsCont::getOptions().getBool("duration-log.statistics")) {
90  // collecting statistics is a sideffect
92  transportable->tripInfoOutput(dev);
93  }
94  if (OptionsCont::getOptions().isSet("vehroute-output")) {
95  transportable->routeOutput(OutputDevice::getDeviceByOption("vehroute-output"), OptionsCont::getOptions().getBool("vehroute-output.route-length"));
96  }
97  const std::map<std::string, MSTransportable*>::iterator i = myTransportables.find(transportable->getID());
98  if (i != myTransportables.end()) {
100  delete i->second;
101  myTransportables.erase(i);
102  }
103 }
104 
105 
106 void
108  const SUMOTime step = time % DELTA_T == 0 ? time : (time / DELTA_T + 1) * DELTA_T;
109  // avoid double registration
110  const TransportableVector& transportables = myWaiting4Departure[step];
111  if (std::find(transportables.begin(), transportables.end(), transportable) == transportables.end()) {
112  myWaitingUntil[step].push_back(transportable);
113  }
114 }
115 
116 
117 void
119  myHaveNewWaiting = false;
120  while (myWaiting4Departure.find(time) != myWaiting4Departure.end()) {
121  const TransportableVector& transportables = myWaiting4Departure[time];
122  // we cannot use an iterator here because there might be additions to the vector while proceeding
123  for (int i = 0; i < (int)transportables.size(); ++i) {
124  if (transportables[i]->proceed(net, time)) {
125  myRunningNumber++;
126  } else {
127  erase(transportables[i]);
128  }
129  }
130  myWaiting4Departure.erase(time);
131  }
132  while (myWaitingUntil.find(time) != myWaitingUntil.end()) {
133  const TransportableVector& transportables = myWaitingUntil[time];
134  // we cannot use an iterator here because there might be additions to the vector while proceeding
135  for (int i = 0; i < (int)transportables.size(); ++i) {
136  if (!transportables[i]->proceed(net, time)) {
137  erase(transportables[i]);
138  }
139  }
140  myWaitingUntil.erase(time);
141  }
142 }
143 
144 
145 void
146 MSTransportableControl::addWaiting(const MSEdge* const edge, MSTransportable* transportable) {
147  myWaiting4Vehicle[edge].push_back(transportable);
149  myHaveNewWaiting = true;
150 }
151 
152 
153 bool
154 MSTransportableControl::boardAnyWaiting(MSEdge* edge, SUMOVehicle* vehicle, const SUMOVehicleParameter::Stop& stop, SUMOTime& timeToBoardNextPerson, SUMOTime& stopDuration) {
155  bool ret = false;
156  if (myWaiting4Vehicle.find(edge) != myWaiting4Vehicle.end()) {
158  const std::string& line = vehicle->getParameter().line == "" ? vehicle->getParameter().id : vehicle->getParameter().line;
160  for (TransportableVector::iterator i = wait.begin(); i != wait.end();) {
161  if ((*i)->isWaitingFor(line) && vehicle->getVehicleType().getPersonCapacity() > vehicle->getPersonNumber() && timeToBoardNextPerson <= currentTime && stop.startPos <= (*i)->getEdgePos() && (*i)->getEdgePos() <= stop.endPos) {
162  edge->removePerson(*i);
163  vehicle->addPerson(*i);
164  //if the time a person needs to enter the vehicle extends the duration of the stop of the vehicle extend
165  //the duration by setting it to the boarding duration of the person
166  const SUMOTime boardingDuration = vehicle->getVehicleType().getBoardingDuration();
167  if (boardingDuration >= stopDuration) {
168  stopDuration = boardingDuration;
169  }
170  //update the time point at which the next person can board the vehicle
171  if (timeToBoardNextPerson > currentTime - DELTA_T) {
172  timeToBoardNextPerson += boardingDuration;
173  } else {
174  timeToBoardNextPerson = currentTime + boardingDuration;
175  }
176 
177  static_cast<MSTransportable::Stage_Driving*>((*i)->getCurrentStage())->setVehicle(vehicle);
178  i = wait.erase(i);
180  ret = true;
181  } else {
182  ++i;
183  }
184  }
185  if (wait.size() == 0) {
186  myWaiting4Vehicle.erase(myWaiting4Vehicle.find(edge));
187  }
188  }
189  return ret;
190 }
191 
192 
193 bool
194 MSTransportableControl::loadAnyWaiting(MSEdge* edge, SUMOVehicle* vehicle, const SUMOVehicleParameter::Stop& stop, SUMOTime& timeToLoadNextContainer, SUMOTime& stopDuration) {
195  bool ret = false;
196  if (myWaiting4Vehicle.find(edge) != myWaiting4Vehicle.end()) {
197  TransportableVector& waitContainers = myWaiting4Vehicle[edge];
198  for (TransportableVector::iterator i = waitContainers.begin(); i != waitContainers.end();) {
199  const std::string& line = vehicle->getParameter().line == "" ? vehicle->getParameter().id : vehicle->getParameter().line;
201  if ((*i)->isWaitingFor(line) && vehicle->getVehicleType().getContainerCapacity() > vehicle->getContainerNumber()
202  && timeToLoadNextContainer <= currentTime
203  && stop.startPos <= (*i)->getEdgePos() && (*i)->getEdgePos() <= stop.endPos) {
204  edge->removeContainer(*i);
205  vehicle->addContainer(*i);
206  //if the time a container needs to get loaded on the vehicle extends the duration of the stop of the vehicle extend
207  //the duration by setting it to the loading duration of the container
208  const SUMOTime loadingDuration = vehicle->getVehicleType().getLoadingDuration();
209  if (loadingDuration >= stopDuration) {
210  stopDuration = loadingDuration;
211  }
212  //update the time point at which the next container can be loaded on the vehicle
213  timeToLoadNextContainer = currentTime + loadingDuration;
214 
215  static_cast<MSContainer::MSContainerStage_Driving*>((*i)->getCurrentStage())->setVehicle(vehicle);
216  i = waitContainers.erase(i);
218  ret = true;
219  } else {
220  ++i;
221  }
222  }
223  if (waitContainers.size() == 0) {
224  myWaiting4Vehicle.erase(myWaiting4Vehicle.find(edge));
225  }
226  }
227  return ret;
228 }
229 
230 
231 bool
233  return !myTransportables.empty();
234 }
235 
236 
237 bool
240 }
241 
242 
243 int
246 }
247 
248 
249 void
251  for (std::map<const MSEdge*, TransportableVector>::const_iterator i = myWaiting4Vehicle.begin(); i != myWaiting4Vehicle.end(); ++i) {
252  const MSEdge* edge = (*i).first;
253  const TransportableVector& pv = (*i).second;
254  for (TransportableVector::const_iterator j = pv.begin(); j != pv.end(); ++j) {
255  MSTransportable* p = (*j);
256  p->setDeparted(MSNet::getInstance()->getCurrentTimeStep());
257  std::string transportableType;
258  if (dynamic_cast<MSPerson*>(p) != nullptr) {
259  edge->removePerson(p);
260  transportableType = "Person";
261  } else {
262  transportableType = "Container";
263  edge->removeContainer(p);
264  }
266  const std::string waitDescription = stage == nullptr ? "waiting" : stage->getWaitingDescription();
267  WRITE_WARNING(transportableType + " '" + p->getID() + "' aborted " + waitDescription + ".");
268  erase(p);
269  }
270  }
271 }
272 
273 
274 void
276  for (std::map<SUMOTime, TransportableVector>::iterator it = myWaiting4Departure.begin(); it != myWaiting4Departure.end(); ++it) {
277  TransportableVector& ts = it->second;
278  TransportableVector::iterator it2 = std::find(ts.begin(), ts.end(), t);
279  if (it2 != ts.end()) {
280  ts.erase(it2);
281  }
282  }
283  for (std::map<SUMOTime, TransportableVector>::iterator it = myWaiting4Departure.begin(); it != myWaiting4Departure.end(); ++it) {
284  TransportableVector& ts = it->second;
285  TransportableVector::iterator it2 = std::find(ts.begin(), ts.end(), t);
286  if (it2 != ts.end()) {
287  ts.erase(it2);
288  }
289  }
290 }
291 
292 
295  std::mt19937* rng) const {
296  const double speedFactor = vtype->computeChosenSpeedDeviation(rng);
297  return new MSPerson(pars, vtype, plan, speedFactor);
298 }
299 
300 
303  return new MSContainer(pars, vtype, plan);
304 }
305 
306 /****************************************************************************/
void abortWaiting(MSTransportable *t)
aborts waiting stage of transportable
void addWaiting(const MSEdge *edge, MSTransportable *person)
adds a transportable to the list of transportables waiting for a vehicle on the specified edge ...
bool hasNonWaiting() const
checks whether any transportable is still engaged in walking / stopping
long long int SUMOTime
Definition: SUMOTime.h:36
std::string getWaitingDescription() const
Return where the person waits and for what.
virtual void tripInfoOutput(OutputDevice &os) const =0
Called on writing tripinfo output.
int getActiveCount()
return the number of active transportable objects
virtual void routeOutput(OutputDevice &os, const bool withRouteLength) const =0
Called on writing vehroute output.
std::map< SUMOTime, TransportableVector > myWaiting4Departure
Transportables waiting for departure.
void setWaitEnd(SUMOTime time, MSTransportable *transportable)
sets the arrival time for a waiting transportable
virtual ~MSTransportableControl()
Destructor.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:165
std::map< std::string, MSTransportable * > myTransportables
all currently created transportables by id
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
const SUMOVehicleParameter & getParameter() const
int getPersonCapacity() const
Get this vehicle type&#39;s person capacity.
std::map< const MSEdge *, TransportableVector > myWaiting4Vehicle
the lists of waiting transportables
virtual MSTransportable * buildContainer(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan) const
Builds a new container.
int getContainerCapacity() const
Get this vehicle type&#39;s container capacity.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
The simulated network and simulation perfomer.
Definition: MSNet.h:84
int myLoadedNumber
The number of build transportables.
The car-following model and parameter.
Definition: MSVehicleType.h:66
virtual void erase(MSTransportable *transportable)
removes a single transportable
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
SUMOTime getBoardingDuration() const
Get this vehicle type&#39;s boarding duration.
void abortWaitingForVehicle()
aborts the plan for any transportable that is still waiting for a ride
virtual void addContainer(MSTransportable *container)=0
Adds a container to this vehicle.
A road/street connecting two junctions.
Definition: MSEdge.h:75
std::vector< MSTransportable::Stage * > MSTransportablePlan
the structure holding the plan of a transportable
MSTransportable::Stage * getCurrentStage() const
Return the current stage.
void setDeparted(SUMOTime now)
logs depart time of the current stage
Representation of a vehicle.
Definition: SUMOVehicle.h:60
double startPos
The stopping position start.
SUMOTime getLoadingDuration() const
Get this vehicle type&#39;s loading duration.
bool myHaveNewWaiting
whether a new transportable waiting for a vehicle has been added in the last step ...
SUMOTime depart
The vehicle&#39;s departure time.
virtual int getPersonNumber() const =0
Returns the number of persons.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:263
const std::string & getID() const
returns the id of the transportable
virtual void removePerson(MSTransportable *p) const
Definition: MSEdge.h:599
bool hasTransportables() const
checks whether any transportable waits to finish her plan
double endPos
The stopping position end.
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...
virtual void removeContainer(MSTransportable *container) const
Remove container from myContainers.
Definition: MSEdge.h:612
std::string line
The vehicle&#39;s line (mainly for public transport)
int myWaitingForVehicleNumber
The number of transportables waiting for vehicles.
Structure representing possible vehicle parameter.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
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...
Definition of vehicle stop (position and duration)
bool add(MSTransportable *transportable)
Adds a single transportable, returns false if an id clash occurred.
void checkWaiting(MSNet *net, const SUMOTime time)
checks whether any transportables waiting time is over
virtual void addPerson(MSTransportable *person)=0
Adds a person to this vehicle.
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
virtual int getContainerNumber() const =0
Returns the number of containers.
std::vector< MSTransportable * > TransportableVector
Definition of a list of transportables.
virtual MSTransportable * buildPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan, std::mt19937 *rng) const
Builds a new person.
int myRunningNumber
The number of transportables within the network (build and inserted but not removed) ...
double computeChosenSpeedDeviation(std::mt19937 *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
std::map< SUMOTime, TransportableVector > myWaitingUntil
the lists of walking / stopping transportables
An output device that encapsulates an ofstream.
std::string id
The vehicle&#39;s id.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.