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-2014 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 (it may have changed onto this lane
103  // somewhere past the detector)
104  assert(newSpeed > 0 || myVehiclesOnDet.find(&veh) == myVehiclesOnDet.end());
105  SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
106  if (newSpeed > 0) {
107  leaveTime += (myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed;
108  }
109  leaveDetectorByMove(veh, leaveTime);
110  return false;
111  }
112  // vehicle stays on the detector
113  return true;
114 }
115 
116 
117 bool
120  leaveDetectorByLaneChange(veh, lastPos);
121  return false;
122  }
123  return true;
124 }
125 
126 
127 SUMOReal
129  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
130  return d.size() != 0
131  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) d.size()
132  : -1;
133 }
134 
135 
136 SUMOReal
138  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
139  return d.size() != 0
140  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) d.size()
141  : -1;
142 }
143 
144 
145 SUMOReal
148  std::vector<VehicleData> d = collectVehiclesOnDet(tbeg);
149  if (d.size() == 0) {
150  return -1;
151  }
152  SUMOReal occupancy = 0;
153  for (std::vector< VehicleData >::const_iterator i = d.begin(); i != d.end(); ++i) {
154  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(tbeg), (*i).entryTimeM);
155  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, TS);
156  occupancy += timeOnDetDuringInterval;
157  }
158  return occupancy / TS * (SUMOReal) 100.;
159 }
160 
161 
162 unsigned int
164  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
165  return (unsigned int) d.size();
166 }
167 
168 
169 std::vector<std::string>
171  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
172  std::vector<std::string> ret;
173  for (std::vector<VehicleData>::iterator i = d.begin(); i != d.end(); ++i) {
174  ret.push_back((*i).idM);
175  }
176  return ret;
177 }
178 
179 
180 SUMOReal
182  if (myVehiclesOnDet.size() != 0) {
183  // detector is occupied
184  return 0;
185  }
186  return STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) - myLastLeaveTime;
187 }
188 
189 
190 void
192  dev.writeXMLHeader("detector", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/det_e1_file.xsd\"");
193 }
194 
195 
196 void
198  SUMOTime startTime, SUMOTime stopTime) {
199  writeTypedXMLOutput(dev, startTime, stopTime, "", myVehicleDataCont, myVehiclesOnDet);
200  if (mySplitByType) {
201  dev << ">\n";
202  std::map<std::string, std::pair<VehicleDataCont, VehicleMap> > types;
203  // collect / divide
204  for (std::deque< VehicleData >::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
205  if (types.find((*i).typeIDM) == types.end()) {
206  types[(*i).typeIDM] = make_pair(VehicleDataCont(), VehicleMap());
207  }
208  types[(*i).typeIDM].first.push_back(*i);
209  }
210  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
211  const std::string& type = (*i).first->getVehicleType().getID();
212  if (types.find(type) == types.end()) {
213  types[type] = make_pair(VehicleDataCont(), VehicleMap());
214  }
215  types[type].second[(*i).first] = (*i).second;
216  }
217  // write
218  for (std::map<std::string, std::pair<VehicleDataCont, VehicleMap> >::const_iterator i = types.begin(); i != types.end(); ++i) {
219  writeTypedXMLOutput(dev, startTime, stopTime, (*i).first, (*i).second.first, (*i).second.second);
220  dev << "/>\n";
221  }
222  dev << " </interval>\n";
223  } else {
224  dev << "/>\n";
225  }
226  reset();
227 }
228 
229 void
231  const std::string& type, const VehicleDataCont& vdc, const VehicleMap& vm) {
232  SUMOReal t(STEPS2TIME(stopTime - startTime));
233  unsigned nVehCrossed = (unsigned) vdc.size();
234  if (type == "") {
235  nVehCrossed += myDismissedVehicleNumber;
236  }
237  SUMOReal flow = ((SUMOReal) vdc.size() / (SUMOReal) t) * (SUMOReal) 3600.0;
238  SUMOReal occupancy = 0;
239  for (std::deque< VehicleData >::const_iterator i = vdc.begin(); i != vdc.end(); ++i) {
240  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(startTime), (*i).entryTimeM);
241  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, t);
242  occupancy += timeOnDetDuringInterval;
243  }
244  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = vm.begin(); i != vm.end(); ++i) {
245  SUMOReal timeOnDetDuringInterval = STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), (*i).second);
246  occupancy += timeOnDetDuringInterval;
247  }
248  occupancy = occupancy / t * (SUMOReal) 100.;
249  SUMOReal meanSpeed = vdc.size() != 0
250  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) vdc.size()
251  : -1;
252  SUMOReal meanLength = vdc.size() != 0
253  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) vdc.size()
254  : -1;
255  if (type != "") {
256  dev << " <typedInterval type=\"" + type + "\" ";
257  } else {
258  dev << " <interval ";
259  }
260  dev << "begin=\"" << time2string(startTime) << "\" end=\"" <<
261  time2string(stopTime) << "\" " << "id=\"" << StringUtils::escapeXML(getID()) << "\" ";
262  dev << "nVehContrib=\"" << vdc.size() << "\" flow=\"" << flow <<
263  "\" occupancy=\"" << occupancy << "\" speed=\"" << meanSpeed <<
264  "\" length=\"" << meanLength <<
265  "\" nVehEntered=\"" << nVehCrossed << "\"";
266 }
267 
268 
269 void
271  SUMOReal entryTimestep) {
272  myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
273 }
274 
275 
276 void
278  SUMOReal leaveTimestep) {
279  VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
280  if (it != myVehiclesOnDet.end()) {
281  SUMOReal entryTimestep = it->second;
282  myVehiclesOnDet.erase(it);
283  assert(entryTimestep < leaveTimestep);
284  myVehicleDataCont.push_back(VehicleData(veh.getID(), veh.getVehicleType().getLength(), entryTimestep, leaveTimestep, veh.getVehicleType().getID()));
285  myLastOccupancy = leaveTimestep - entryTimestep;
286  }
287  myLastLeaveTime = leaveTimestep;
288 }
289 
290 
291 void
293  // Discard entry data
294  myVehiclesOnDet.erase(&veh);
295  if (lastPos > myPosition) {
296  // vehicle is on detector during lane change or arrival, or ...
298  }
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