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