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 /****************************************************************************/
10 // Inserts vehicles into the network when their departure time is reached
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <iostream>
35 #include <algorithm>
36 #include <cassert>
37 #include <iterator>
38 #include "MSInsertionControl.h"
39 #include "MSVehicle.h"
40 #include "MSLane.h"
41 #include "MSEdge.h"
42 
43 #ifdef CHECK_MEMORY_LEAKS
44 #include <foreign/nvwa/debug_new.h>
45 #endif // CHECK_MEMORY_LEAKS
46 
47 
48 // ===========================================================================
49 // member method definitions
50 // ===========================================================================
52  SUMOTime maxDepartDelay,
53  bool checkEdgesOnce)
54  : myVehicleControl(vc), myMaxDepartDelay(maxDepartDelay),
55  myCheckEdgesOnce(checkEdgesOnce) {}
56 
57 
59  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end(); ++i) {
60  delete(i->pars);
61  }
62 }
63 
64 
65 void
67  myAllVeh.add(veh);
68 }
69 
70 
71 void
73  Flow flow;
74  flow.pars = pars;
78  if (!flow.isVolatile) {
80  if (dist != 0) {
81  const std::vector<const MSRoute*>& routes = dist->getVals();
82  const MSEdge* e = 0;
83  for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
84  if (e == 0) {
85  e = (*i)->getEdges()[0];
86  } else {
87  if (e != (*i)->getEdges()[0]) {
88  flow.isVolatile = true;
89  break;
90  }
91  }
92  }
93  }
94  }
95  flow.vehicle = 0;
96  myFlows.push_back(flow);
97 }
98 
99 
100 unsigned int
102  checkPrevious(time);
103  // check whether any vehicles shall be emitted within this time step
104  if (!myAllVeh.anyWaitingFor(time) && myRefusedEmits1.empty() && myRefusedEmits2.empty() && myFlows.empty()) {
105  return 0;
106  }
107  unsigned int noEmitted = 0;
108  // we use buffering for the refused emits to save time
109  // for this, we have two lists; one contains previously refused emits, the second
110  // will be used to append those vehicles that will not be able to depart in this
111  // time step
112  assert(myRefusedEmits1.size() == 0 || myRefusedEmits2.size() == 0);
113  MSVehicleContainer::VehicleVector& refusedEmits =
115  MSVehicleContainer::VehicleVector& previousRefused =
117 
118  // go through the list of previously refused vehicles, first
119  MSVehicleContainer::VehicleVector::const_iterator veh;
120  for (veh = previousRefused.begin(); veh != previousRefused.end(); veh++) {
121  noEmitted += tryInsert(time, *veh, refusedEmits);
122  }
123  // clear previously refused vehicle container
124  previousRefused.clear();
125 
126  // Insert vehicles from myTrips into the net until the next vehicle's
127  // departure time is greater than the current time.
128  // Retrieve the list of vehicles to emit within this time step
129 
130  noEmitted += checkFlows(time, refusedEmits);
131  while (myAllVeh.anyWaitingFor(time)) {
133  // go through the list and try to emit
134  for (veh = next.begin(); veh != next.end(); veh++) {
135  noEmitted += tryInsert(time, *veh, refusedEmits);
136  }
137  // let the MSVehicleContainer clear the vehicles
138  myAllVeh.pop();
139  }
140  // Return the number of emitted vehicles
141  return noEmitted;
142 }
143 
144 
145 unsigned int
147  MSVehicleContainer::VehicleVector& refusedEmits) {
148  assert(veh->getParameter().depart < time + DELTA_T);
149  const MSEdge& edge = *veh->getEdge();
150  if ((!myCheckEdgesOnce || edge.getLastFailedInsertionTime() != time) && edge.insertVehicle(*veh, time)) {
151  // Successful emission.
152  checkFlowWait(veh);
153  veh->onDepart();
154  return 1;
155  }
156  if (myMaxDepartDelay >= 0 && time - veh->getParameter().depart > myMaxDepartDelay) {
157  // remove vehicles waiting too long for departure
158  checkFlowWait(veh);
159  myVehicleControl.deleteVehicle(veh, true);
160  } else if (edge.isVaporizing()) {
161  // remove vehicles if the edge shall be empty
162  checkFlowWait(veh);
163  myVehicleControl.deleteVehicle(veh, true);
164  } else if (myAbortedEmits.count(veh) > 0) {
165  // remove vehicles which shall not be inserted for some reason
166  myAbortedEmits.erase(veh);
167  checkFlowWait(veh);
168  myVehicleControl.deleteVehicle(veh, true);
169  } else {
170  // let the vehicle wait one step, we'll retry then
171  refusedEmits.push_back(veh);
172  }
173  edge.setLastFailedInsertionTime(time);
174  return 0;
175 }
176 
177 
178 void
180  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end(); ++i) {
181  if (i->vehicle == veh) {
182  i->vehicle = 0;
183  break;
184  }
185  }
186 }
187 
188 
189 void
191  // check to which list append to
192  MSVehicleContainer::VehicleVector& previousRefused =
194  while (!myAllVeh.isEmpty() && myAllVeh.topTime() < time) {
196  copy(top.begin(), top.end(), back_inserter(previousRefused));
197  myAllVeh.pop();
198  }
199 }
200 
201 
202 unsigned int
204  MSVehicleContainer::VehicleVector& refusedEmits) {
206  unsigned int noEmitted = 0;
207  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end();) {
208  SUMOVehicleParameter* pars = i->pars;
209  if (!i->isVolatile && i->vehicle != 0) {
210  ++i;
211  continue;
212  }
213  while (pars->repetitionsDone < pars->repetitionNumber &&
214  pars->depart + pars->repetitionsDone * pars->repetitionOffset < time + DELTA_T) {
215  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
216  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
217  newPars->depart = static_cast<SUMOTime>(pars->depart + pars->repetitionsDone * pars->repetitionOffset);
218  pars->repetitionsDone++;
219  // try to build the vehicle
220  if (vehControl.getVehicle(newPars->id) == 0) {
221  const MSRoute* route = MSRoute::dictionary(pars->routeid);
222  const MSVehicleType* vtype = vehControl.getVType(pars->vtypeid);
223  i->vehicle = vehControl.buildVehicle(newPars, route, vtype);
224  if (vehControl.isInQuota()) {
225  vehControl.addVehicle(newPars->id, i->vehicle);
226  noEmitted += tryInsert(time, i->vehicle, refusedEmits);
227  if (!i->isVolatile && i->vehicle != 0) {
228  break;
229  }
230  } else {
231  vehControl.deleteVehicle(i->vehicle, true);
232  i->vehicle = 0;
233  }
234  } else {
235  // strange: another vehicle with the same id already exists
237  break;
238  }
239  throw ProcessError("Another vehicle with the id '" + newPars->id + "' exists.");
240  }
241  }
242  if (pars->repetitionsDone == pars->repetitionNumber) {
243  i = myFlows.erase(i);
244  delete(pars);
245  } else {
246  ++i;
247  }
248  }
249  return noEmitted;
250 }
251 
252 
253 unsigned int
255  return (unsigned int)(myRefusedEmits1.size() + myRefusedEmits2.size());
256 }
257 
258 
259 int
261  return (int)myFlows.size();
262 }
263 
264 
265 void
267  myAbortedEmits.insert(veh);
268 }
269 
270 /****************************************************************************/
271 
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&#39;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:82
bool isEmpty() const
Returns the information whether the container is empty.
int repetitionsDone
The number of times the vehicle was already inserted.
SUMOVehicle * vehicle
The last created vehicle.
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:150
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
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:73
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&#39;s route id.
Representation of a vehicle.
Definition: SUMOVehicle.h:63
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:248
SUMOTime depart
The vehicle&#39;s departure time.
SUMOTime myMaxDepartDelay
The maximum waiting time; vehicles waiting longer are deleted (-1: no deletion)
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:51
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&#39;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 isInQuota(SUMOReal frac=-1) const
Returns the information whether the currently vehicle number shall be emitted considering that only f...
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.
std::string id
The vehicle&#39;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