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);
160  } else if (edge.isVaporizing()) {
161  // remove vehicles if the edge shall be empty
162  checkFlowWait(veh);
164  } else {
165  // let the vehicle wait one step, we'll retry then
166  refusedEmits.push_back(veh);
167  }
168  edge.setLastFailedInsertionTime(time);
169  return 0;
170 }
171 
172 
173 void
175  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end(); ++i) {
176  if (i->vehicle == veh) {
177  i->vehicle = 0;
178  break;
179  }
180  }
181 }
182 
183 
184 void
186  // check to which list append to
187  MSVehicleContainer::VehicleVector& previousRefused =
189  while (!myAllVeh.isEmpty() && myAllVeh.topTime() < time) {
191  copy(top.begin(), top.end(), back_inserter(previousRefused));
192  myAllVeh.pop();
193  }
194 }
195 
196 
197 unsigned int
199  MSVehicleContainer::VehicleVector& refusedEmits) {
200  unsigned int noEmitted = 0;
201  for (std::vector<Flow>::iterator i = myFlows.begin(); i != myFlows.end();) {
202  SUMOVehicleParameter* pars = i->pars;
203  if (!i->isVolatile && i->vehicle != 0) {
204  ++i;
205  continue;
206  }
207  while (pars->repetitionsDone < pars->repetitionNumber &&
208  pars->depart + pars->repetitionsDone * pars->repetitionOffset < time + DELTA_T) {
209  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
210  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
211  newPars->depart = static_cast<SUMOTime>(pars->depart + pars->repetitionsDone * pars->repetitionOffset);
212  pars->repetitionsDone++;
213  // try to build the vehicle
214  if (MSNet::getInstance()->getVehicleControl().getVehicle(newPars->id) == 0) {
215  const MSRoute* route = MSRoute::dictionary(pars->routeid);
217  i->vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(newPars, route, vtype);
218  MSNet::getInstance()->getVehicleControl().addVehicle(newPars->id, i->vehicle);
219  noEmitted += tryInsert(time, i->vehicle, refusedEmits);
220  if (!i->isVolatile && i->vehicle != 0) {
221  break;
222  }
223  } else {
224  // strange: another vehicle with the same id already exists
225 #ifdef HAVE_MESOSIM
226  if (MSGlobals::gStateLoaded) {
227  break;
228  }
229 #endif
230  throw ProcessError("Another vehicle with the id '" + newPars->id + "' exists.");
231  }
232  }
233  if (pars->repetitionsDone == pars->repetitionNumber) {
234  i = myFlows.erase(i);
235  delete(pars);
236  } else {
237  ++i;
238  }
239  }
240  return noEmitted;
241 }
242 
243 
244 unsigned int
246  return (unsigned int)(myRefusedEmits1.size() + myRefusedEmits2.size());
247 }
248 
249 
250 int
252  return (int)myFlows.size();
253 }
254 
255 
256 /****************************************************************************/
257