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.sourceforge.net/
13 // Copyright (C) 2001-2012 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
236 #ifdef HAVE_INTERNAL
237  if (MSGlobals::gStateLoaded) {
238  break;
239  }
240 #endif
241  throw ProcessError("Another vehicle with the id '" + newPars->id + "' exists.");
242  }
243  }
244  if (pars->repetitionsDone == pars->repetitionNumber) {
245  i = myFlows.erase(i);
246  delete(pars);
247  } else {
248  ++i;
249  }
250  }
251  return noEmitted;
252 }
253 
254 
255 unsigned int
257  return (unsigned int)(myRefusedEmits1.size() + myRefusedEmits2.size());
258 }
259 
260 
261 int
263  return (int)myFlows.size();
264 }
265 
266 
267 void
269  myAbortedEmits.insert(veh);
270 }
271 
272 /****************************************************************************/
273