SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSInductLoop.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // An unextended detector measuring at a fixed position on a fixed lane.
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
15 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #ifdef _MSC_VER
31 #include <windows_config.h>
32 #else
33 #include <config.h>
34 #endif
35 
36 #include "MSInductLoop.h"
37 #include <cassert>
38 #include <numeric>
39 #include <utility>
41 #include <utils/common/ToString.h>
43 #include <microsim/MSLane.h>
44 #include <microsim/MSVehicle.h>
45 #include <microsim/MSNet.h>
50 
51 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
59 MSInductLoop::MSInductLoop(const std::string& id, MSLane* const lane,
60  SUMOReal positionInMeters, bool splitByType) :
62  myPosition(positionInMeters), mySplitByType(splitByType),
63  myLastLeaveTime(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())),
64  myVehicleDataCont(),
65  myVehiclesOnDet() {
66  assert(myPosition >= 0 && myPosition <= myLane->getLength());
67  reset();
68 }
69 
70 
72 }
73 
74 
75 void
79  myVehicleDataCont.clear();
80 }
81 
82 
83 bool
85  SUMOReal newPos, SUMOReal newSpeed) {
86  if (newPos < myPosition) {
87  // detector not reached yet
88  return true;
89  }
90  if (newPos >= myPosition && oldPos < myPosition) {
91  // entered the detector by move
92  SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
93  if (newSpeed != 0) {
94  if (myPosition > oldPos) {
95  entryTime += (myPosition - oldPos) / newSpeed;
96  }
97  }
98  enterDetectorByMove(veh, entryTime);
99  }
100  if (newPos - veh.getVehicleType().getLength() > myPosition && oldPos - veh.getVehicleType().getLength() <= myPosition) {
101  // vehicle passed the detector
102  SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
103  leaveTime += (myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed;
104  leaveDetectorByMove(veh, leaveTime);
105  return false;
106  }
107  // vehicle stays on the detector
108  return true;
109 }
110 
111 
112 bool
115  // vehicle is on detector during lane change or arrival, or ...
117  return false;
118  }
119  return true;
120 }
121 
122 
123 bool
125  if (veh.getPositionOnLane() - veh.getVehicleType().getLength() > myPosition) {
126  // vehicle-front is beyond detector. Ignore
127  return false;
128  }
129  // vehicle is in front of detector
130  return true;
131 }
132 
133 
134 SUMOReal
136  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
137  return d.size() != 0
138  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) d.size()
139  : -1;
140 }
141 
142 
143 SUMOReal
145  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
146  return d.size() != 0
147  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) d.size()
148  : -1;
149 }
150 
151 
152 SUMOReal
155  std::vector<VehicleData> d = collectVehiclesOnDet(tbeg);
156  if (d.size() == 0) {
157  return -1;
158  }
159  SUMOReal occupancy = 0;
160  for (std::vector< VehicleData >::const_iterator i = d.begin(); i != d.end(); ++i) {
161  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(tbeg), (*i).entryTimeM);
162  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, TS);
163  occupancy += timeOnDetDuringInterval;
164  }
165  return occupancy / TS * (SUMOReal) 100.;
166 }
167 
168 
169 unsigned int
171  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
172  return (unsigned int) d.size();
173 }
174 
175 
176 std::vector<std::string>
178  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
179  std::vector<std::string> ret;
180  for (std::vector<VehicleData>::iterator i = d.begin(); i != d.end(); ++i) {
181  ret.push_back((*i).idM);
182  }
183  return ret;
184 }
185 
186 
187 SUMOReal
189  if (myVehiclesOnDet.size() != 0) {
190  // detector is occupied
191  return 0;
192  }
193  return STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) - myLastLeaveTime;
194 }
195 
196 
197 void
199  dev.writeXMLHeader("detector");
200 }
201 
202 
203 void
205  SUMOTime startTime, SUMOTime stopTime) {
206  writeTypedXMLOutput(dev, startTime, stopTime, "", myVehicleDataCont, myVehiclesOnDet);
207  if (mySplitByType) {
208  dev << ">\n";
209  std::map<std::string, std::pair<VehicleDataCont, VehicleMap> > types;
210  // collect / divide
211  for (std::deque< VehicleData >::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
212  if (types.find((*i).typeIDM) == types.end()) {
213  types[(*i).typeIDM] = make_pair(VehicleDataCont(), VehicleMap());
214  }
215  types[(*i).typeIDM].first.push_back(*i);
216  }
217  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
218  const std::string& type = (*i).first->getVehicleType().getID();
219  if (types.find(type) == types.end()) {
220  types[type] = make_pair(VehicleDataCont(), VehicleMap());
221  }
222  types[type].second[(*i).first] = (*i).second;
223  }
224  // write
225  for (std::map<std::string, std::pair<VehicleDataCont, VehicleMap> >::const_iterator i = types.begin(); i != types.end(); ++i) {
226  writeTypedXMLOutput(dev, startTime, stopTime, (*i).first, (*i).second.first, (*i).second.second);
227  dev << "/>\n";
228  }
229  dev << " </interval>\n";
230  } else {
231  dev << "/>\n";
232  }
233  reset();
234 }
235 
236 void
238  const std::string& type, const VehicleDataCont& vdc, const VehicleMap& vm) {
239  SUMOReal t(STEPS2TIME(stopTime - startTime));
240  unsigned nVehCrossed = (unsigned) vdc.size();
241  if (type == "") {
242  nVehCrossed += myDismissedVehicleNumber;
243  }
244  SUMOReal flow = ((SUMOReal) vdc.size() / (SUMOReal) t) * (SUMOReal) 3600.0;
245  SUMOReal occupancy = 0;
246  for (std::deque< VehicleData >::const_iterator i = vdc.begin(); i != vdc.end(); ++i) {
247  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(startTime), (*i).entryTimeM);
248  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, t);
249  occupancy += timeOnDetDuringInterval;
250  }
251  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = vm.begin(); i != vm.end(); ++i) {
252  SUMOReal timeOnDetDuringInterval = STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), (*i).second);
253  occupancy += timeOnDetDuringInterval;
254  }
255  occupancy = occupancy / t * (SUMOReal) 100.;
256  SUMOReal meanSpeed = vdc.size() != 0
257  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) vdc.size()
258  : -1;
259  SUMOReal meanLength = vdc.size() != 0
260  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) vdc.size()
261  : -1;
262  if (type != "") {
263  dev << " <typedInterval type=\"" + type + "\" ";
264  } else {
265  dev << " <interval ";
266  }
267  dev << "begin=\"" << time2string(startTime) << "\" end=\"" <<
268  time2string(stopTime) << "\" " << "id=\"" << StringUtils::escapeXML(getID()) << "\" ";
269  dev << "nVehContrib=\"" << vdc.size() << "\" flow=\"" << flow <<
270  "\" occupancy=\"" << occupancy << "\" speed=\"" << meanSpeed <<
271  "\" length=\"" << meanLength <<
272  "\" nVehEntered=\"" << nVehCrossed << "\"";
273 }
274 
275 
276 void
278  SUMOReal entryTimestep) {
279  myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
280 }
281 
282 
283 void
285  SUMOReal leaveTimestep) {
286  VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
287  if (it != myVehiclesOnDet.end()) {
288  SUMOReal entryTimestep = it->second;
289  myVehiclesOnDet.erase(it);
290  assert(entryTimestep < leaveTimestep);
291  myVehicleDataCont.push_back(VehicleData(veh.getID(), veh.getVehicleType().getLength(), entryTimestep, leaveTimestep, veh.getVehicleType().getID()));
292  myLastOccupancy = leaveTimestep - entryTimestep;
293  }
294  myLastLeaveTime = leaveTimestep;
295 }
296 
297 
298 void
300  // Discard entry data
301  myVehiclesOnDet.erase(&veh);
303 }
304 
305 
306 std::vector<MSInductLoop::VehicleData>
308  SUMOReal t = STEPS2TIME(tMS);
309  std::vector<VehicleData> ret;
310  for (VehicleDataCont::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
311  if ((*i).leaveTimeM >= t) {
312  ret.push_back(*i);
313  }
314  }
315  for (VehicleDataCont::const_iterator i = myLastVehicleDataCont.begin(); i != myLastVehicleDataCont.end(); ++i) {
316  if ((*i).leaveTimeM >= t) {
317  ret.push_back(*i);
318  }
319  }
321  for (VehicleMap::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
322  SUMOVehicle* v = (*i).first;
323  VehicleData d(v->getID(), v->getVehicleType().getLength(), (*i).second, STEPS2TIME(ct), v->getVehicleType().getID());
324  d.speedM = v->getSpeed();
325  ret.push_back(d);
326  }
327  return ret;
328 }
329 
330 
331 /****************************************************************************/
332