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