SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSVehicleControl.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // The class responsible for building and deletion of vehicles
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include "MSVehicleControl.h"
34 #include "MSVehicle.h"
35 #include "MSLane.h"
36 #include "MSNet.h"
39 #include <utils/common/RGBColor.h>
44 
45 #ifdef CHECK_MEMORY_LEAKS
46 #include <foreign/nvwa/debug_new.h>
47 #endif // CHECK_MEMORY_LEAKS
48 
49 
50 // ===========================================================================
51 // static members
52 // ===========================================================================
54 
55 
56 // ===========================================================================
57 // member method definitions
58 // ===========================================================================
60  myLoadedVehNo(0),
61  myRunningVehNo(0),
62  myEndedVehNo(0),
63  myDiscarded(0),
64  myCollisions(0),
65  myTeleportsJam(0),
66  myTeleportsYield(0),
67  myTeleportsWrongLane(0),
68  myEmergencyStops(0),
69  myTotalDepartureDelay(0),
70  myTotalTravelTime(0),
71  myDefaultVTypeMayBeDeleted(true),
72  myWaitingForPerson(0),
73  myScale(-1) {
77  if (oc.isSet("scale")) {
78  myScale = oc.getFloat("scale");
79  }
80  myMaxRandomDepartOffset = string2time(oc.getString("random-depart-offset"));
81 }
82 
83 
85  // delete vehicles
86  for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
87  delete(*i).second;
88  }
89  myVehicleDict.clear();
90  // delete vehicle type distributions
91  for (VTypeDistDictType::iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
92  delete(*i).second;
93  }
94  myVTypeDistDict.clear();
95  // delete vehicle types
96  for (VTypeDictType::iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
97  delete(*i).second;
98  }
99  myVTypeDict.clear();
100 }
101 
102 
105  const MSRoute* route,
106  const MSVehicleType* type) {
107  myLoadedVehNo++;
108  if (myMaxRandomDepartOffset > 0) {
109  // round to the closest usable simulation step
111  }
112  MSVehicle* built = new MSVehicle(defs, route, type, type->computeChosenSpeedDeviation(myVehicleParamsRNG));
114  return built;
115 }
116 
117 
118 void
120  assert(myRunningVehNo > 0);
121  myTotalTravelTime += STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - veh->getDeparture());
122  myRunningVehNo--;
124  for (std::vector<MSDevice*>::const_iterator i = veh->getDevices().begin(); i != veh->getDevices().end(); ++i) {
125  (*i)->generateOutput();
126  }
127  if (OptionsCont::getOptions().isSet("tripinfo-output")) {
128  OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
129  }
130  deleteVehicle(veh);
131 }
132 
133 
134 void
136  ++myRunningVehNo;
139 }
140 
141 
142 void
143 MSVehicleControl::setState(int runningVehNo, int endedVehNo, SUMOReal totalDepartureDelay, SUMOReal totalTravelTime) {
144  myRunningVehNo = runningVehNo;
145  myEndedVehNo = endedVehNo;
146  myTotalDepartureDelay = totalDepartureDelay;
147  myTotalTravelTime = totalTravelTime;
148 }
149 
150 
151 void
155  // save vehicle types
156  for (VTypeDictType::iterator it = myVTypeDict.begin(); it != myVTypeDict.end(); ++it) {
157  it->second->getParameter().write(out);
158  }
159  for (VTypeDistDictType::iterator it = myVTypeDistDict.begin(); it != myVTypeDistDict.end(); ++it) {
161  out.writeAttr(SUMO_ATTR_VTYPES, (*it).second->getVals());
162  out.writeAttr(SUMO_ATTR_PROBS, (*it).second->getProbs());
163  out.closeTag();
164  }
165  for (VehicleDictType::iterator it = myVehicleDict.begin(); it != myVehicleDict.end(); ++it) {
166  (*it).second->saveState(out);
167  }
168 }
169 
170 
171 bool
172 MSVehicleControl::addVehicle(const std::string& id, SUMOVehicle* v) {
173  VehicleDictType::iterator it = myVehicleDict.find(id);
174  if (it == myVehicleDict.end()) {
175  // id not in myVehicleDict.
176  myVehicleDict[id] = v;
177  return true;
178  }
179  return false;
180 }
181 
182 
184 MSVehicleControl::getVehicle(const std::string& id) const {
185  VehicleDictType::const_iterator it = myVehicleDict.find(id);
186  if (it == myVehicleDict.end()) {
187  return 0;
188  }
189  return it->second;
190 }
191 
192 
193 void
195  myEndedVehNo++;
196  if (discard) {
197  myDiscarded++;
198  }
199  myVehicleDict.erase(veh->getID());
200  delete veh;
201 }
202 
203 
206  return myVehicleDict.begin();
207 }
208 
209 
212  return myVehicleDict.end();
213 }
214 
215 
216 bool
217 MSVehicleControl::checkVType(const std::string& id) {
218  if (id == DEFAULT_VTYPE_ID) {
220  delete myVTypeDict[id];
221  myVTypeDict.erase(myVTypeDict.find(id));
223  } else {
224  return false;
225  }
226  } else {
227  if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
228  return false;
229  }
230  }
231  return true;
232 }
233 
234 bool
236  if (checkVType(vehType->getID())) {
237  myVTypeDict[vehType->getID()] = vehType;
238  return true;
239  }
240  return false;
241 }
242 
243 
244 bool
245 MSVehicleControl::addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution) {
246  if (checkVType(id)) {
247  myVTypeDistDict[id] = vehTypeDistribution;
248  return true;
249  }
250  return false;
251 }
252 
253 
254 bool
255 MSVehicleControl::hasVTypeDistribution(const std::string& id) const {
256  return myVTypeDistDict.find(id) != myVTypeDistDict.end();
257 }
258 
259 
261 MSVehicleControl::getVType(const std::string& id) {
262  VTypeDictType::iterator it = myVTypeDict.find(id);
263  if (it == myVTypeDict.end()) {
264  VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
265  if (it2 == myVTypeDistDict.end()) {
266  return 0;
267  }
268  return it2->second->get(&myVehicleParamsRNG);
269  }
270  if (id == DEFAULT_VTYPE_ID) {
272  }
273  return it->second;
274 }
275 
276 
277 void
278 MSVehicleControl::insertVTypeIDs(std::vector<std::string>& into) const {
279  into.reserve(into.size() + myVTypeDict.size() + myVTypeDistDict.size());
280  for (VTypeDictType::const_iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
281  into.push_back((*i).first);
282  }
283  for (VTypeDistDictType::const_iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
284  into.push_back((*i).first);
285  }
286 }
287 
288 
289 void
290 MSVehicleControl::addWaiting(const MSEdge* const edge, SUMOVehicle* vehicle) {
291  if (myWaiting.find(edge) == myWaiting.end()) {
292  myWaiting[edge] = std::vector<SUMOVehicle*>();
293  }
294  myWaiting[edge].push_back(vehicle);
295 }
296 
297 
298 void
299 MSVehicleControl::removeWaiting(const MSEdge* const edge, SUMOVehicle* vehicle) {
300  if (myWaiting.find(edge) != myWaiting.end()) {
301  std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting[edge].begin(), myWaiting[edge].end(), vehicle);
302  if (it != myWaiting[edge].end()) {
303  myWaiting[edge].erase(it);
304  }
305  }
306 }
307 
308 
310 MSVehicleControl::getWaitingVehicle(const MSEdge* const edge, const std::set<std::string>& lines) {
311  if (myWaiting.find(edge) != myWaiting.end()) {
312  for (std::vector<SUMOVehicle*>::const_iterator it = myWaiting[edge].begin(); it != myWaiting[edge].end(); ++it) {
313  const std::string& line = (*it)->getParameter().line == "" ? (*it)->getParameter().id : (*it)->getParameter().line;
314  if (lines.count(line)) {
315  return (*it);
316  }
317  }
318  }
319  return 0;
320 }
321 
322 
323 void
325  for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
326  WRITE_WARNING("Vehicle " + i->first + " aborted waiting for a person that will never come.");
327  }
328 }
329 
330 
331 unsigned int
333  frac = frac < 0 ? myScale : frac;
334  if (frac < 0 || frac == 1.) {
335  return 1;
336  }
337  // the vehicle in question has already been loaded, hence the '-1'
338  const unsigned int loaded = frac > 1. ? (unsigned int)(myLoadedVehNo / frac) : myLoadedVehNo - 1;
339  const unsigned int base = (unsigned int)frac;
340  const unsigned int resolution = 1000;
341  const unsigned int intFrac = (unsigned int)floor((frac - base) * resolution + 0.5);
342  // apply % twice to avoid integer overflow
343  if (((loaded % resolution) * intFrac) % resolution < intFrac) {
344  return base + 1;
345  }
346  return base;
347 }
348 
349 /****************************************************************************/
350