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-2013 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  return true;
126 }
127 
128 
129 SUMOReal
131  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
132  return d.size() != 0
133  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) d.size()
134  : -1;
135 }
136 
137 
138 SUMOReal
140  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
141  return d.size() != 0
142  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) d.size()
143  : -1;
144 }
145 
146 
147 SUMOReal
150  std::vector<VehicleData> d = collectVehiclesOnDet(tbeg);
151  if (d.size() == 0) {
152  return -1;
153  }
154  SUMOReal occupancy = 0;
155  for (std::vector< VehicleData >::const_iterator i = d.begin(); i != d.end(); ++i) {
156  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(tbeg), (*i).entryTimeM);
157  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, TS);
158  occupancy += timeOnDetDuringInterval;
159  }
160  return occupancy / TS * (SUMOReal) 100.;
161 }
162 
163 
164 unsigned int
166  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
167  return (unsigned int) d.size();
168 }
169 
170 
171 std::vector<std::string>
173  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
174  std::vector<std::string> ret;
175  for (std::vector<VehicleData>::iterator i = d.begin(); i != d.end(); ++i) {
176  ret.push_back((*i).idM);
177  }
178  return ret;
179 }
180 
181 
182 SUMOReal
184  if (myVehiclesOnDet.size() != 0) {
185  // detector is occupied
186  return 0;
187  }
188  return STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) - myLastLeaveTime;
189 }
190 
191 
192 void
194  dev.writeXMLHeader("detector", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/det_e1_file.xsd\"");
195 }
196 
197 
198 void
200  SUMOTime startTime, SUMOTime stopTime) {
201  writeTypedXMLOutput(dev, startTime, stopTime, "", myVehicleDataCont, myVehiclesOnDet);
202  if (mySplitByType) {
203  dev << ">\n";
204  std::map<std::string, std::pair<VehicleDataCont, VehicleMap> > types;
205  // collect / divide
206  for (std::deque< VehicleData >::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
207  if (types.find((*i).typeIDM) == types.end()) {
208  types[(*i).typeIDM] = make_pair(VehicleDataCont(), VehicleMap());
209  }
210  types[(*i).typeIDM].first.push_back(*i);
211  }
212  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
213  const std::string& type = (*i).first->getVehicleType().getID();
214  if (types.find(type) == types.end()) {
215  types[type] = make_pair(VehicleDataCont(), VehicleMap());
216  }
217  types[type].second[(*i).first] = (*i).second;
218  }
219  // write
220  for (std::map<std::string, std::pair<VehicleDataCont, VehicleMap> >::const_iterator i = types.begin(); i != types.end(); ++i) {
221  writeTypedXMLOutput(dev, startTime, stopTime, (*i).first, (*i).second.first, (*i).second.second);
222  dev << "/>\n";
223  }
224  dev << " </interval>\n";
225  } else {
226  dev << "/>\n";
227  }
228  reset();
229 }
230 
231 void
233  const std::string& type, const VehicleDataCont& vdc, const VehicleMap& vm) {
234  SUMOReal t(STEPS2TIME(stopTime - startTime));
235  unsigned nVehCrossed = (unsigned) vdc.size();
236  if (type == "") {
237  nVehCrossed += myDismissedVehicleNumber;
238  }
239  SUMOReal flow = ((SUMOReal) vdc.size() / (SUMOReal) t) * (SUMOReal) 3600.0;
240  SUMOReal occupancy = 0;
241  for (std::deque< VehicleData >::const_iterator i = vdc.begin(); i != vdc.end(); ++i) {
242  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(startTime), (*i).entryTimeM);
243  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, t);
244  occupancy += timeOnDetDuringInterval;
245  }
246  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = vm.begin(); i != vm.end(); ++i) {
247  SUMOReal timeOnDetDuringInterval = STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), (*i).second);
248  occupancy += timeOnDetDuringInterval;
249  }
250  occupancy = occupancy / t * (SUMOReal) 100.;
251  SUMOReal meanSpeed = vdc.size() != 0
252  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) vdc.size()
253  : -1;
254  SUMOReal meanLength = vdc.size() != 0
255  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) vdc.size()
256  : -1;
257  if (type != "") {
258  dev << " <typedInterval type=\"" + type + "\" ";
259  } else {
260  dev << " <interval ";
261  }
262  dev << "begin=\"" << time2string(startTime) << "\" end=\"" <<
263  time2string(stopTime) << "\" " << "id=\"" << StringUtils::escapeXML(getID()) << "\" ";
264  dev << "nVehContrib=\"" << vdc.size() << "\" flow=\"" << flow <<
265  "\" occupancy=\"" << occupancy << "\" speed=\"" << meanSpeed <<
266  "\" length=\"" << meanLength <<
267  "\" nVehEntered=\"" << nVehCrossed << "\"";
268 }
269 
270 
271 void
273  SUMOReal entryTimestep) {
274  myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
275 }
276 
277 
278 void
280  SUMOReal leaveTimestep) {
281  VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
282  if (it != myVehiclesOnDet.end()) {
283  SUMOReal entryTimestep = it->second;
284  myVehiclesOnDet.erase(it);
285  assert(entryTimestep < leaveTimestep);
286  myVehicleDataCont.push_back(VehicleData(veh.getID(), veh.getVehicleType().getLength(), entryTimestep, leaveTimestep, veh.getVehicleType().getID()));
287  myLastOccupancy = leaveTimestep - entryTimestep;
288  }
289  myLastLeaveTime = leaveTimestep;
290 }
291 
292 
293 void
295  // Discard entry data
296  myVehiclesOnDet.erase(&veh);
298 }
299 
300 
301 std::vector<MSInductLoop::VehicleData>
303  SUMOReal t = STEPS2TIME(tMS);
304  std::vector<VehicleData> ret;
305  for (VehicleDataCont::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
306  if ((*i).leaveTimeM >= t) {
307  ret.push_back(*i);
308  }
309  }
310  for (VehicleDataCont::const_iterator i = myLastVehicleDataCont.begin(); i != myLastVehicleDataCont.end(); ++i) {
311  if ((*i).leaveTimeM >= t) {
312  ret.push_back(*i);
313  }
314  }
316  for (VehicleMap::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
317  SUMOVehicle* v = (*i).first;
318  VehicleData d(v->getID(), v->getVehicleType().getLength(), (*i).second, STEPS2TIME(ct), v->getVehicleType().getID());
319  d.speedM = v->getSpeed();
320  ret.push_back(d);
321  }
322  return ret;
323 }
324 
325 
326 /****************************************************************************/
327