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-sim.org/
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) :
61  MSMoveReminder(id, lane),
63  myPosition(positionInMeters), mySplitByType(splitByType),
64  myLastLeaveTime(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())),
65  myVehicleDataCont(),
66  myVehiclesOnDet() {
67  assert(myPosition >= 0 && myPosition <= myLane->getLength());
68  reset();
69 }
70 
71 
73 }
74 
75 
76 void
80  myVehicleDataCont.clear();
81 }
82 
83 
84 bool
86  SUMOReal newPos, SUMOReal newSpeed) {
87  if (newPos < myPosition) {
88  // detector not reached yet
89  return true;
90  }
91  if (newPos >= myPosition && oldPos < myPosition) {
92  // entered the detector by move
93  SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
94  if (newSpeed != 0) {
95  if (myPosition > oldPos) {
96  entryTime += (myPosition - oldPos) / newSpeed;
97  }
98  }
99  enterDetectorByMove(veh, entryTime);
100  }
101  if (newPos - veh.getVehicleType().getLength() > myPosition && oldPos - veh.getVehicleType().getLength() <= myPosition) {
102  // vehicle passed the detector
103  SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
104  leaveTime += (myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed;
105  leaveDetectorByMove(veh, leaveTime);
106  return false;
107  }
108  // vehicle stays on the detector
109  return true;
110 }
111 
112 
113 bool
116  // vehicle is on detector during lane change or arrival, or ...
118  return false;
119  }
120  return true;
121 }
122 
123 
124 bool
126  return true;
127 }
128 
129 
130 SUMOReal
132  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
133  return d.size() != 0
134  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) d.size()
135  : -1;
136 }
137 
138 
139 SUMOReal
141  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
142  return d.size() != 0
143  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) d.size()
144  : -1;
145 }
146 
147 
148 SUMOReal
151  std::vector<VehicleData> d = collectVehiclesOnDet(tbeg);
152  if (d.size() == 0) {
153  return -1;
154  }
155  SUMOReal occupancy = 0;
156  for (std::vector< VehicleData >::const_iterator i = d.begin(); i != d.end(); ++i) {
157  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(tbeg), (*i).entryTimeM);
158  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, TS);
159  occupancy += timeOnDetDuringInterval;
160  }
161  return occupancy / TS * (SUMOReal) 100.;
162 }
163 
164 
165 unsigned int
167  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
168  return (unsigned int) d.size();
169 }
170 
171 
172 std::vector<std::string>
174  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
175  std::vector<std::string> ret;
176  for (std::vector<VehicleData>::iterator i = d.begin(); i != d.end(); ++i) {
177  ret.push_back((*i).idM);
178  }
179  return ret;
180 }
181 
182 
183 SUMOReal
185  if (myVehiclesOnDet.size() != 0) {
186  // detector is occupied
187  return 0;
188  }
189  return STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) - myLastLeaveTime;
190 }
191 
192 
193 void
195  dev.writeXMLHeader("detector", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/det_e1_file.xsd\"");
196 }
197 
198 
199 void
201  SUMOTime startTime, SUMOTime stopTime) {
202  writeTypedXMLOutput(dev, startTime, stopTime, "", myVehicleDataCont, myVehiclesOnDet);
203  if (mySplitByType) {
204  dev << ">\n";
205  std::map<std::string, std::pair<VehicleDataCont, VehicleMap> > types;
206  // collect / divide
207  for (std::deque< VehicleData >::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
208  if (types.find((*i).typeIDM) == types.end()) {
209  types[(*i).typeIDM] = make_pair(VehicleDataCont(), VehicleMap());
210  }
211  types[(*i).typeIDM].first.push_back(*i);
212  }
213  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
214  const std::string& type = (*i).first->getVehicleType().getID();
215  if (types.find(type) == types.end()) {
216  types[type] = make_pair(VehicleDataCont(), VehicleMap());
217  }
218  types[type].second[(*i).first] = (*i).second;
219  }
220  // write
221  for (std::map<std::string, std::pair<VehicleDataCont, VehicleMap> >::const_iterator i = types.begin(); i != types.end(); ++i) {
222  writeTypedXMLOutput(dev, startTime, stopTime, (*i).first, (*i).second.first, (*i).second.second);
223  dev << "/>\n";
224  }
225  dev << " </interval>\n";
226  } else {
227  dev << "/>\n";
228  }
229  reset();
230 }
231 
232 void
234  const std::string& type, const VehicleDataCont& vdc, const VehicleMap& vm) {
235  SUMOReal t(STEPS2TIME(stopTime - startTime));
236  unsigned nVehCrossed = (unsigned) vdc.size();
237  if (type == "") {
238  nVehCrossed += myDismissedVehicleNumber;
239  }
240  SUMOReal flow = ((SUMOReal) vdc.size() / (SUMOReal) t) * (SUMOReal) 3600.0;
241  SUMOReal occupancy = 0;
242  for (std::deque< VehicleData >::const_iterator i = vdc.begin(); i != vdc.end(); ++i) {
243  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(startTime), (*i).entryTimeM);
244  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, t);
245  occupancy += timeOnDetDuringInterval;
246  }
247  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = vm.begin(); i != vm.end(); ++i) {
248  SUMOReal timeOnDetDuringInterval = STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), (*i).second);
249  occupancy += timeOnDetDuringInterval;
250  }
251  occupancy = occupancy / t * (SUMOReal) 100.;
252  SUMOReal meanSpeed = vdc.size() != 0
253  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) vdc.size()
254  : -1;
255  SUMOReal meanLength = vdc.size() != 0
256  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) vdc.size()
257  : -1;
258  if (type != "") {
259  dev << " <typedInterval type=\"" + type + "\" ";
260  } else {
261  dev << " <interval ";
262  }
263  dev << "begin=\"" << time2string(startTime) << "\" end=\"" <<
264  time2string(stopTime) << "\" " << "id=\"" << StringUtils::escapeXML(getID()) << "\" ";
265  dev << "nVehContrib=\"" << vdc.size() << "\" flow=\"" << flow <<
266  "\" occupancy=\"" << occupancy << "\" speed=\"" << meanSpeed <<
267  "\" length=\"" << meanLength <<
268  "\" nVehEntered=\"" << nVehCrossed << "\"";
269 }
270 
271 
272 void
274  SUMOReal entryTimestep) {
275  myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
276 }
277 
278 
279 void
281  SUMOReal leaveTimestep) {
282  VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
283  if (it != myVehiclesOnDet.end()) {
284  SUMOReal entryTimestep = it->second;
285  myVehiclesOnDet.erase(it);
286  assert(entryTimestep < leaveTimestep);
287  myVehicleDataCont.push_back(VehicleData(veh.getID(), veh.getVehicleType().getLength(), entryTimestep, leaveTimestep, veh.getVehicleType().getID()));
288  myLastOccupancy = leaveTimestep - entryTimestep;
289  }
290  myLastLeaveTime = leaveTimestep;
291 }
292 
293 
294 void
296  // Discard entry data
297  myVehiclesOnDet.erase(&veh);
299 }
300 
301 
302 std::vector<MSInductLoop::VehicleData>
304  SUMOReal t = STEPS2TIME(tMS);
305  std::vector<VehicleData> ret;
306  for (VehicleDataCont::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
307  if ((*i).leaveTimeM >= t) {
308  ret.push_back(*i);
309  }
310  }
311  for (VehicleDataCont::const_iterator i = myLastVehicleDataCont.begin(); i != myLastVehicleDataCont.end(); ++i) {
312  if ((*i).leaveTimeM >= t) {
313  ret.push_back(*i);
314  }
315  }
317  for (VehicleMap::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
318  SUMOVehicle* v = (*i).first;
319  VehicleData d(v->getID(), v->getVehicleType().getLength(), (*i).second, STEPS2TIME(ct), v->getVehicleType().getID());
320  d.speedM = v->getSpeed();
321  ret.push_back(d);
322  }
323  return ret;
324 }
325 
326 
327 /****************************************************************************/
328