SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSInsertionControl.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // Inserts vehicles into the network when their departure time is reached
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
14 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <iostream>
36 #include <algorithm>
37 #include <cassert>
38 #include <iterator>
39 #include "MSInsertionControl.h"
40 #include "MSVehicle.h"
41 #include "MSLane.h"
42 #include "MSEdge.h"
43 
44 #ifdef CHECK_MEMORY_LEAKS
45 #include <foreign/nvwa/debug_new.h>
46 #endif // CHECK_MEMORY_LEAKS
47 
48 
49 // ===========================================================================
50 // member method definitions
51 // ===========================================================================
53  SUMOTime maxDepartDelay,
54  bool checkEdgesOnce)
55  : myVehicleControl(vc), myMaxDepartDelay(maxDepartDelay),
56  myCheckEdgesOnce(checkEdgesOnce) {}
57 
58 
60  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end(); ++i) {
61  delete(i->pars);
62  }
63 }
64 
65 
66 void
68  myAllVeh.add(veh);
69 }
70 
71 
72 void
74  Flow flow;
75  flow.pars = pars;
79  flow.index = 0;
80  if (!flow.isVolatile) {
82  if (dist != 0) {
83  const std::vector<const MSRoute*>& routes = dist->getVals();
84  const MSEdge* e = 0;
85  for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
86  if (e == 0) {
87  e = (*i)->getEdges()[0];
88  } else {
89  if (e != (*i)->getEdges()[0]) {
90  flow.isVolatile = true;
91  break;
92  }
93  }
94  }
95  }
96  }
97  flow.vehicle = 0;
98  myFlows.push_back(flow);
99 }
100 
101 
102 unsigned int
104  checkPrevious(time);
105  // check whether any vehicles shall be emitted within this time step
106  if (!myAllVeh.anyWaitingFor(time) && myRefusedEmits1.empty() && myRefusedEmits2.empty() && myFlows.empty()) {
107  return 0;
108  }
109  unsigned int noEmitted = 0;
110  // we use buffering for the refused emits to save time
111  // for this, we have two lists; one contains previously refused emits, the second
112  // will be used to append those vehicles that will not be able to depart in this
113  // time step
114  assert(myRefusedEmits1.size() == 0 || myRefusedEmits2.size() == 0);
115  MSVehicleContainer::VehicleVector& refusedEmits =
117  MSVehicleContainer::VehicleVector& previousRefused =
119 
120  // go through the list of previously refused vehicles, first
121  MSVehicleContainer::VehicleVector::const_iterator veh;
122  for (veh = previousRefused.begin(); veh != previousRefused.end(); veh++) {
123  noEmitted += tryInsert(time, *veh, refusedEmits);
124  }
125  // clear previously refused vehicle container
126  previousRefused.clear();
127 
128  // Insert vehicles from myTrips into the net until the next vehicle's
129  // departure time is greater than the current time.
130  // Retrieve the list of vehicles to emit within this time step
131 
132  noEmitted += checkFlows(time, refusedEmits);
133  while (myAllVeh.anyWaitingFor(time)) {
135  // go through the list and try to emit
136  for (veh = next.begin(); veh != next.end(); veh++) {
137  noEmitted += tryInsert(time, *veh, refusedEmits);
138  }
139  // let the MSVehicleContainer clear the vehicles
140  myAllVeh.pop();
141  }
142  // Return the number of emitted vehicles
143  return noEmitted;
144 }
145 
146 
147 unsigned int
149  MSVehicleContainer::VehicleVector& refusedEmits) {
150  assert(veh->getParameter().depart < time + DELTA_T);
151  const MSEdge& edge = *veh->getEdge();
152  if ((!myCheckEdgesOnce || edge.getLastFailedInsertionTime() != time) && edge.insertVehicle(*veh, time)) {
153  // Successful emission.
154  checkFlowWait(veh);
155  veh->onDepart();
156  return 1;
157  }
158  if (myMaxDepartDelay >= 0 && time - veh->getParameter().depart > myMaxDepartDelay) {
159  // remove vehicles waiting too long for departure
160  checkFlowWait(veh);
161  myVehicleControl.deleteVehicle(veh, true);
162  } else if (edge.isVaporizing()) {
163  // remove vehicles if the edge shall be empty
164  checkFlowWait(veh);
165  myVehicleControl.deleteVehicle(veh, true);
166  } else if (myAbortedEmits.count(veh) > 0) {
167  // remove vehicles which shall not be inserted for some reason
168  myAbortedEmits.erase(veh);
169  checkFlowWait(veh);
170  myVehicleControl.deleteVehicle(veh, true);
171  } else {
172  // let the vehicle wait one step, we'll retry then
173  refusedEmits.push_back(veh);
174  }
175  edge.setLastFailedInsertionTime(time);
176  return 0;
177 }
178 
179 
180 void
182  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end(); ++i) {
183  if (i->vehicle == veh) {
184  i->vehicle = 0;
185  break;
186  }
187  }
188 }
189 
190 
191 void
193  // check to which list append to
194  MSVehicleContainer::VehicleVector& previousRefused =
196  while (!myAllVeh.isEmpty() && myAllVeh.topTime() < time) {
198  copy(top.begin(), top.end(), back_inserter(previousRefused));
199  myAllVeh.pop();
200  }
201 }
202 
203 
204 unsigned int
206  MSVehicleContainer::VehicleVector& refusedEmits) {
208  unsigned int noEmitted = 0;
209  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end();) {
210  SUMOVehicleParameter* pars = i->pars;
211  if (!i->isVolatile && i->vehicle != 0 && pars->repetitionProbability < 0) {
212  ++i;
213  //std::cout << SIMTIME << " volatile=" << i->isVolatile << " veh=" << i->vehicle << "\n";
214  continue;
215  }
216  bool emitByProb = pars->repetitionProbability > 0 && RandHelper::rand() < (pars->repetitionProbability * TS);
217  //std::cout << emitByProb << "\n";
218  //std::cout << SIMTIME
219  // << " flow=" << pars->id
220  // << " rDo=" << pars->repetitionsDone
221  // << " rN=" << pars->repetitionNumber
222  // << " rDe=" << pars->depart
223  // << " rRo=" << pars->repetitionOffset
224  // << " rPo=" << pars->repetitionProbability
225  // << " emit=" << emitByProb
226  // << "\n";
227  while (pars->repetitionsDone < pars->repetitionNumber &&
228  ((pars->repetitionProbability < 0 && pars->depart + pars->repetitionsDone * pars->repetitionOffset < time + DELTA_T)
229  || emitByProb)) {
230  emitByProb = false;
231  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
232  newPars->id = pars->id + "." + toString(i->index);
233  newPars->depart = static_cast<SUMOTime>(pars->depart + pars->repetitionsDone * pars->repetitionOffset);
234  pars->repetitionsDone++;
235  // try to build the vehicle
236  if (vehControl.getVehicle(newPars->id) == 0) {
237  const MSRoute* route = MSRoute::dictionary(pars->routeid);
238  const MSVehicleType* vtype = vehControl.getVType(pars->vtypeid);
239  i->vehicle = vehControl.buildVehicle(newPars, route, vtype);
240  unsigned int quota = vehControl.getQuota();
241  if (quota > 0) {
242  vehControl.addVehicle(newPars->id, i->vehicle);
243  noEmitted += tryInsert(time, i->vehicle, refusedEmits);
244  i->index++;
245  if (quota == 1 && !i->isVolatile && i->vehicle != 0) {
246  break;
247  }
248  while (--quota > 0) {
249  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
250  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
251  i->vehicle = vehControl.buildVehicle(newPars, route, vtype);
252  vehControl.addVehicle(newPars->id, i->vehicle);
253  noEmitted += tryInsert(time, i->vehicle, refusedEmits);
254  i->index++;
255  }
256  } else {
257  vehControl.deleteVehicle(i->vehicle, true);
258  i->vehicle = 0;
259  }
260  } else {
261  // strange: another vehicle with the same id already exists
263  break;
264  }
265  throw ProcessError("Another vehicle with the id '" + newPars->id + "' exists.");
266  }
267  }
268  if (pars->repetitionsDone == pars->repetitionNumber) {
269  i = myFlows.erase(i);
271  delete pars;
272  } else {
273  ++i;
274  }
275  }
276  return noEmitted;
277 }
278 
279 
280 unsigned int
282  return (unsigned int)(myRefusedEmits1.size() + myRefusedEmits2.size());
283 }
284 
285 
286 int
288  return (int)myFlows.size();
289 }
290 
291 
292 void
294  myAbortedEmits.insert(veh);
295 }
296 
297 void
299  //clear out the refused vehicle lists, deleting the vehicles entirely
300  MSVehicleContainer::VehicleVector::iterator veh;
301  for (veh = myRefusedEmits1.begin(); veh != myRefusedEmits1.end();) {
302  if ((*veh)->getRoute().getID() == route || route == "") {
303  myVehicleControl.deleteVehicle(*veh, true);
304  veh = myRefusedEmits1.erase(veh);
305  } else {
306  ++veh;
307  }
308  }
309 
310  for (veh = myRefusedEmits2.begin(); veh != myRefusedEmits2.end();) {
311  if ((*veh)->getRoute().getID() == route || route == "") {
312  myVehicleControl.deleteVehicle(*veh, true);
313  veh = myRefusedEmits2.erase(veh);
314  } else {
315  ++veh;
316  }
317  }
318 }
319 
320 
321 /****************************************************************************/
322 
SUMOReal repetitionProbability
The probability for emitting a vehicle per second.
int getPendingFlowCount() const
Returns the number of flows that are still active.
void checkFlowWait(SUMOVehicle *veh)
Checks whether any flow is blocked due to this vehicle and clears the block.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
void descheduleDeparture(SUMOVehicle *veh)
stops trying to emit the given vehicle
SUMOTime topTime() const
Returns the time the uppermost vehicle vector is assigned to.
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
std::set< SUMOVehicle * > myAbortedEmits
Set of vehicles which shall not be inserted anymore.
std::string vtypeid
The vehicle's type id.
virtual void onDepart()=0
Called when the vehicle is inserted into the network.
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID)
Returns the named vehicle type or a sample from the named distribution.
static bool gStateLoaded
Information whether a state has been loaded.
Definition: MSGlobals.h:86
bool isEmpty() const
Returns the information whether the container is empty.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
int repetitionsDone
The number of times the vehicle was already inserted.
SUMOVehicle * vehicle
The last created vehicle.
unsigned int index
the running index
MSVehicleContainer myAllVeh
All loaded vehicles sorted by their departure time.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
The lane is chosen randomly.
static RandomDistributor< const MSRoute * > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:150
#define TS
Definition: SUMOTime.h:52
SUMOReal repetitionOffset
The time offset between vehicle reinsertions.
The position is chosen randomly.
~MSInsertionControl()
Destructor.
The car-following model and parameter.
Definition: MSVehicleType.h:74
const std::vector< T > & getVals() const
Returns the members of the distribution.
std::vector< SUMOVehicle * > VehicleVector
definition of a list of vehicles which have the same departure time
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type)
Builds a vehicle, increases the number of built vehicles.
A road/street connecting two junctions.
Definition: MSEdge.h:74
unsigned int checkFlows(SUMOTime time, MSVehicleContainer::VehicleVector &refusedEmits)
Checks for all vehicles coming from flows whether they can be emitted.
void pop()
Removes the uppermost vehicle vector.
unsigned int getWaitingVehicleNo() const
Returns the number of waiting vehicles.
std::string routeid
The vehicle's route id.
Representation of a vehicle.
Definition: SUMOVehicle.h:64
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
bool myCheckEdgesOnce
Whether an edge on which a vehicle could not depart should be ignored in the same step...
unsigned int tryInsert(SUMOTime time, SUMOVehicle *veh, MSVehicleContainer::VehicleVector &refusedEmits)
Tries to emit the vehicle.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:269
SUMOTime depart
The vehicle's departure time.
SUMOTime myMaxDepartDelay
The maximum waiting time; vehicles waiting longer are deleted (-1: no deletion)
void clearPendingVehicles(std::string &route)
clears out all pending vehicles from a route, "" for all routes
void add(SUMOVehicle *veh)
Adds a single vehicle.
MSVehicleContainer::VehicleVector myRefusedEmits1
Buffers for vehicles that could not be inserted.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
const VehicleVector & top()
Returns the uppermost vehicle vector.
bool isVolatile
whether it has route or vehicle type distribution
bool anyWaitingFor(SUMOTime time) const
Returns the information whether any vehicles want to depart at the given time.
std::vector< Flow > myFlows
Container for periodical vehicle parameters.
MSVehicleContainer::VehicleVector myRefusedEmits2
Structure representing possible vehicle parameter.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
MSVehicleControl & myVehicleControl
The assigned vehicle control (needed for vehicle re-insertion and deletion)
MSInsertionControl(MSVehicleControl &vc, SUMOTime maxDepartDelay, bool checkEdgesOnce)
Constructor.
unsigned int emitVehicles(SUMOTime time)
Emits vehicles that want to depart at the given time.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
bool hasVTypeDistribution(const std::string &id) const
Asks for a vehicle type distribution.
#define DELTA_T
Definition: SUMOTime.h:50
The class responsible for building and deletion of vehicles.
SUMOVehicleParameter * pars
The paramters.
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:173
unsigned int getQuota(SUMOReal frac=-1) const
Returns the number of instances of the current vehicle that shall be emitted considering that "frac" ...
std::string id
The vehicle's id.
void checkPrevious(SUMOTime time)
Adds all vehicles that should have been emitted earlier to the refuse container.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:116