SUMO - Simulation of Urban MObility
MSE3Collector.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // A detector of vehicles passing an area between entry/exit points
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
14 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <algorithm>
35 
36 #include "MSE3Collector.h"
37 #include <microsim/MSNet.h>
38 #include <microsim/MSVehicle.h>
39 
40 #ifdef CHECK_MEMORY_LEAKS
41 #include <foreign/nvwa/debug_new.h>
42 #endif // CHECK_MEMORY_LEAKS
43 
44 
45 // ===========================================================================
46 // method definitions
47 // ===========================================================================
48 /* -------------------------------------------------------------------------
49  * MSE3Collector::MSE3EntryReminder - definitions
50  * ----------------------------------------------------------------------- */
52  const MSCrossSection& crossSection, MSE3Collector& collector) :
53  MSMoveReminder(collector.getID() + "_entry", crossSection.myLane),
54  myCollector(collector), myPosition(crossSection.myPosition) {}
55 
56 
57 bool
59  SUMOReal newPos, SUMOReal newSpeed) {
60  if (myCollector.myEnteredContainer.find(&veh) == myCollector.myEnteredContainer.end() && newPos > myPosition) {
61  if (oldPos > myPosition) {
62  // was behind the detector already in the last step
63  return false;
64  } else {
65  // entered in this step
66  const SUMOReal oldSpeed = veh.getPreviousSpeed();
67  const SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
68  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
69  const SUMOReal timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
70  const SUMOReal fractionTimeOnDet = TS - timeBeforeEnter;
71  myCollector.enter(veh, entryTime - fractionTimeOnDet, fractionTimeOnDet);
72  }
73  }
74  return true;
75 }
76 
77 
78 bool
81  WRITE_WARNING("Vehicle '" + veh.getID() + "' arrived inside " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
82  myCollector.myEnteredContainer.erase(&veh);
83  return false;
84  }
85  return true;
86 }
87 
88 
89 /* -------------------------------------------------------------------------
90  * MSE3Collector::MSE3LeaveReminder - definitions
91  * ----------------------------------------------------------------------- */
93  const MSCrossSection& crossSection, MSE3Collector& collector) :
94  MSMoveReminder(collector.getID() + "_exit", crossSection.myLane),
95  myCollector(collector), myPosition(crossSection.myPosition) {}
96 
97 
98 bool
100  SUMOReal newPos, SUMOReal newSpeed) {
101  if (newPos < myPosition) {
102  // crossSection not yet reached
103  return true;
104  }
105  const SUMOReal oldSpeed = veh.getPreviousSpeed();
106  if (oldPos < myPosition) {
107  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
108  const SUMOReal timeBeforeLeave = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
109 // const SUMOReal leaveTimeFront = SIMTIME - TS + (myPosition - oldPos) / newSpeed;
110  const SUMOReal leaveTimeFront = SIMTIME - TS + timeBeforeLeave;
111  myCollector.leaveFront(veh, leaveTimeFront);
112  }
113  const SUMOReal backPos = newPos - veh.getVehicleType().getLength();
114  if (backPos < myPosition) {
115  // crossSection not yet left
116  return true;
117  }
118  // crossSection left
119  const SUMOReal oldBackPos = oldPos - veh.getVehicleType().getLength();
120  const SUMOReal leaveStep = SIMTIME;
121  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
122  const SUMOReal timeBeforeLeave = MSCFModel::passingTime(oldBackPos, myPosition, backPos, oldSpeed, newSpeed);
123  myCollector.leave(veh, leaveStep - TS + timeBeforeLeave, timeBeforeLeave);
124  return false;
125 }
126 
127 
128 bool
131  return false;
132  }
133  return true;
134 }
135 
136 /* -------------------------------------------------------------------------
137  * MSE3Collector - definitions
138  * ----------------------------------------------------------------------- */
139 MSE3Collector::MSE3Collector(const std::string& id,
140  const CrossSectionVector& entries,
141  const CrossSectionVector& exits,
142  SUMOReal haltingSpeedThreshold,
143  SUMOTime haltingTimeThreshold,
144  const std::string& vTypes)
145  : MSDetectorFileOutput(id, vTypes), myEntries(entries), myExits(exits),
146  myHaltingTimeThreshold(haltingTimeThreshold), myHaltingSpeedThreshold(haltingSpeedThreshold),
148  // Set MoveReminders to entries and exits
149  for (CrossSectionVectorConstIt crossSec1 = entries.begin(); crossSec1 != entries.end(); ++crossSec1) {
150  myEntryReminders.push_back(new MSE3EntryReminder(*crossSec1, *this));
151  }
152  for (CrossSectionVectorConstIt crossSec2 = exits.begin(); crossSec2 != exits.end(); ++crossSec2) {
153  myLeaveReminders.push_back(new MSE3LeaveReminder(*crossSec2, *this));
154  }
155  reset();
156 }
157 
158 
160  for (std::vector<MSE3EntryReminder*>::iterator i = myEntryReminders.begin(); i != myEntryReminders.end(); ++i) {
161  delete *i;
162  }
163  for (std::vector<MSE3LeaveReminder*>::iterator i = myLeaveReminders.begin(); i != myLeaveReminders.end(); ++i) {
164  delete *i;
165  }
166 }
167 
168 
169 void
171  myLeftContainer.clear();
172 }
173 
174 
175 
176 void
177 MSE3Collector::enter(const SUMOVehicle& veh, const SUMOReal entryTimestep, const SUMOReal fractionTimeOnDet) {
178  if (myEnteredContainer.find(&veh) != myEnteredContainer.end()) {
179  WRITE_WARNING("Vehicle '" + veh.getID() + "' reentered " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "'.");
180  return;
181  }
182  const SUMOReal speedFraction = veh.getSpeed() * fractionTimeOnDet;
183  E3Values v;
184  v.entryTime = entryTimestep;
185  v.frontLeaveTime = 0;
186  v.backLeaveTime = 0;
187  v.speedSum = speedFraction;
188  v.haltingBegin = veh.getSpeed() < myHaltingSpeedThreshold ? entryTimestep : -1;
189  v.intervalSpeedSum = entryTimestep >= STEPS2TIME(myLastResetTime) ? speedFraction : 0;
190  v.haltings = 0;
191  v.intervalHaltings = 0;
192  if (veh.getSpeed() < myHaltingSpeedThreshold) {
193  if (fractionTimeOnDet > myHaltingTimeThreshold) {
194  v.haltings++;
195  v.intervalHaltings++;
196  }
197  }
198  v.hadUpdate = false;
199  if (!MSGlobals::gUseMesoSim) {
200  v.timeLoss = static_cast<const MSVehicle&>(veh).getTimeLoss();
202  }
203 
204  myEnteredContainer[&veh] = v;
205 }
206 
207 
208 void
209 MSE3Collector::leaveFront(const SUMOVehicle& veh, const SUMOReal leaveTimestep) {
210  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
211  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
212  } else {
213  myEnteredContainer[&veh].frontLeaveTime = leaveTimestep;
214  }
215 }
216 
217 
218 void
219 MSE3Collector::leave(const SUMOVehicle& veh, const SUMOReal leaveTimestep, const SUMOReal fractionTimeOnDet) {
220  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
221  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
222  } else {
223  E3Values values = myEnteredContainer[&veh];
224  values.backLeaveTime = leaveTimestep;
225  const SUMOReal speedFraction = veh.getSpeed() * (TS - fractionTimeOnDet);
226  values.speedSum -= speedFraction;
227  values.intervalSpeedSum -= speedFraction;
229  // not yet supported
230  values.timeLoss = 0;
231  } else {
232  // timeLoss was initialized when entering
233  values.timeLoss = static_cast<const MSVehicle&>(veh).getTimeLoss() - values.timeLoss;
234  }
235  myEnteredContainer.erase(&veh);
236  myLeftContainer[&veh] = values;
237  }
238 }
239 
240 
241 void
243  SUMOTime startTime, SUMOTime stopTime) {
244  dev << " <interval begin=\"" << time2string(startTime) << "\" end=\"" << time2string(stopTime) << "\" " << "id=\"" << myID << "\" ";
245  // collect values about vehicles that have left the area
246  const int vehicleSum = (int) myLeftContainer.size();
247  SUMOReal meanTravelTime = 0.;
248  SUMOReal meanOverlapTravelTime = 0.;
249  SUMOReal meanSpeed = 0.;
250  SUMOReal meanHaltsPerVehicle = 0.;
251  SUMOReal meanTimeLoss = 0.;
252  for (std::map<const SUMOVehicle*, E3Values>::iterator i = myLeftContainer.begin(); i != myLeftContainer.end(); ++i) {
253  meanHaltsPerVehicle += (SUMOReal)(*i).second.haltings;
254  meanTravelTime += (*i).second.frontLeaveTime - (*i).second.entryTime;
255  const SUMOReal steps = (*i).second.backLeaveTime - (*i).second.entryTime;
256  meanOverlapTravelTime += steps;
257  meanSpeed += ((*i).second.speedSum / steps);
258  meanTimeLoss += STEPS2TIME((*i).second.timeLoss);
259  }
260  meanTravelTime = vehicleSum != 0 ? meanTravelTime / (SUMOReal)vehicleSum : -1;
261  meanOverlapTravelTime = vehicleSum != 0 ? meanOverlapTravelTime / (SUMOReal)vehicleSum : -1;
262  meanSpeed = vehicleSum != 0 ? meanSpeed / (SUMOReal)vehicleSum : -1;
263  meanHaltsPerVehicle = vehicleSum != 0 ? meanHaltsPerVehicle / (SUMOReal) vehicleSum : -1;
264  meanTimeLoss = vehicleSum != 0 ? meanTimeLoss / (SUMOReal) vehicleSum : -1;
265  // clear container
266  myLeftContainer.clear();
267 
268  // collect values about vehicles within the container
269  const int vehicleSumWithin = (int) myEnteredContainer.size();
270  SUMOReal meanSpeedWithin = 0.;
271  SUMOReal meanDurationWithin = 0.;
272  SUMOReal meanHaltsPerVehicleWithin = 0.;
273  SUMOReal meanIntervalSpeedWithin = 0.;
274  SUMOReal meanIntervalHaltsPerVehicleWithin = 0.;
275  SUMOReal meanIntervalDurationWithin = 0.;
276  SUMOReal meanTimeLossWithin = 0.;
277  for (std::map<const SUMOVehicle*, E3Values>::iterator i = myEnteredContainer.begin(); i != myEnteredContainer.end(); ++i) {
278  meanHaltsPerVehicleWithin += (SUMOReal)(*i).second.haltings;
279  meanIntervalHaltsPerVehicleWithin += (SUMOReal)(*i).second.intervalHaltings;
280  const SUMOReal end = (*i).second.backLeaveTime == 0 ? STEPS2TIME(stopTime) : (*i).second.backLeaveTime;
281  const SUMOReal time = end - (*i).second.entryTime;
282  const SUMOReal timeWithin = MIN2(time, end - STEPS2TIME(startTime));
283  if (i->second.speedSum > 0.) {
284  meanSpeedWithin += i->second.speedSum / time;
285  }
286  if (i->second.intervalSpeedSum > 0.) {
287  meanIntervalSpeedWithin += i->second.intervalSpeedSum / timeWithin;
288  }
289  meanDurationWithin += time;
290  meanIntervalDurationWithin += timeWithin;
291  // reset interval values
292  (*i).second.intervalHaltings = 0;
293  (*i).second.intervalSpeedSum = 0;
294 
295  if (!MSGlobals::gUseMesoSim) {
296  const SUMOTime currentTimeLoss = static_cast<const MSVehicle*>(i->first)->getTimeLoss();
297  meanTimeLossWithin += STEPS2TIME(currentTimeLoss - (*i).second.intervalTimeLoss);
298  (*i).second.intervalTimeLoss = currentTimeLoss;
299  }
300  }
301  myLastResetTime = stopTime;
302  meanSpeedWithin = vehicleSumWithin != 0 ? meanSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
303  meanHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
304  meanDurationWithin = vehicleSumWithin != 0 ? meanDurationWithin / (SUMOReal) vehicleSumWithin : -1;
305  meanIntervalSpeedWithin = vehicleSumWithin != 0 ? meanIntervalSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
306  meanIntervalHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanIntervalHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
307  meanIntervalDurationWithin = vehicleSumWithin != 0 ? meanIntervalDurationWithin / (SUMOReal) vehicleSumWithin : -1;
308  meanTimeLossWithin = vehicleSumWithin != 0 ? meanTimeLossWithin / (SUMOReal) vehicleSumWithin : -1;
309 
310  // write values
311  dev << "meanTravelTime=\"" << meanTravelTime
312  << "\" meanOverlapTravelTime=\"" << meanOverlapTravelTime
313  << "\" meanSpeed=\"" << meanSpeed
314  << "\" meanHaltsPerVehicle=\"" << meanHaltsPerVehicle
315  << "\" meanTimeLoss=\"" << meanTimeLoss
316  << "\" vehicleSum=\"" << vehicleSum
317  << "\" meanSpeedWithin=\"" << meanSpeedWithin
318  << "\" meanHaltsPerVehicleWithin=\"" << meanHaltsPerVehicleWithin
319  << "\" meanDurationWithin=\"" << meanDurationWithin
320  << "\" vehicleSumWithin=\"" << vehicleSumWithin
321  << "\" meanIntervalSpeedWithin=\"" << meanIntervalSpeedWithin
322  << "\" meanIntervalHaltsPerVehicleWithin=\"" << meanIntervalHaltsPerVehicleWithin
323  << "\" meanIntervalDurationWithin=\"" << meanIntervalDurationWithin
324  << "\" meanTimeLossWithin=\"" << meanTimeLossWithin
325  << "\"/>\n";
326 }
327 
328 
329 void
331  dev.writeXMLHeader("e3Detector", "det_e3_file.xsd");
332 }
333 
334 
335 void
337  myCurrentMeanSpeed = 0;
339  for (std::map<const SUMOVehicle*, E3Values>::iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
340  const SUMOVehicle* veh = pair->first;
341  E3Values& values = pair->second;
342  myCurrentMeanSpeed += veh->getSpeed();
343  values.hadUpdate = true;
344  values.speedSum += veh->getSpeed() * TS;
345  values.intervalSpeedSum += veh->getSpeed() * TS;
346  if (veh->getSpeed() < myHaltingSpeedThreshold) {
347  if (values.haltingBegin == -1) {
348  values.haltingBegin = STEPS2TIME(step);
349  }
350  if (step - values.haltingBegin > myHaltingTimeThreshold) {
351  values.haltings++;
352  values.intervalHaltings++;
354  }
355  } else {
356  values.haltingBegin = -1;
357  }
358  }
359  if (myEnteredContainer.size() == 0) {
360  myCurrentMeanSpeed = -1;
361  } else {
363  }
364 }
365 
366 
367 SUMOReal
369  return myCurrentMeanSpeed;
370 }
371 
372 
373 int
376 }
377 
378 
379 int
381  return (int) myEnteredContainer.size();
382 }
383 
384 
385 std::vector<std::string>
387  std::vector<std::string> ret;
388  for (std::map<const SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
389  ret.push_back((*pair).first->getID());
390  }
391  std::sort(ret.begin(), ret.end());
392  return ret;
393 }
394 
395 
396 /****************************************************************************/
397 
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
long long int SUMOTime
Definition: SUMOTime.h:43
int haltings
The sum of haltings the vehicle has/had within the area.
virtual ~MSE3Collector()
Destructor.
bool notifyLeave(SUMOVehicle &veh, SUMOReal lastPos, MSMoveReminder::Notification reason)
Processes state changes of a vehicle.
A simple description of a position on a lane (crossing of a lane)
std::vector< MSE3EntryReminder * > myEntryReminders
The detector&#39;s built entry reminder.
SUMOReal entryTime
The vehicle&#39;s entry time.
bool hadUpdate
An internal information whether the update step was performed.
A place on the road net (at a certain lane and position on it) where the E3 area ends.
MSE3EntryReminder(const MSCrossSection &crossSection, MSE3Collector &collector)
Constructor.
A place on the road net (at a certain lane and position on it) where the E3 area begins.
Definition: MSE3Collector.h:71
MSLane *const myLane
Lane on which the reminder works.
SUMOReal myPosition
The position on the lane.
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
void enter(const SUMOVehicle &veh, const SUMOReal entryTimestep, const SUMOReal fractionTimeOnDet)
Called if a vehicle touches an entry-cross-section.
std::vector< MSCrossSection > CrossSectionVector
SUMOReal getLength() const
Get vehicle&#39;s length [m].
SUMOReal backLeaveTime
The time the vehicle&#39;s back was crossing the leave line.
CrossSectionVector::const_iterator CrossSectionVectorConstIt
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
SUMOTime myLastResetTime
Information when the last reset has been done.
std::vector< MSE3LeaveReminder * > myLeaveReminders
The detector&#39;s built exit reminder.
#define TS
Definition: SUMOTime.h:52
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
SUMOReal haltingBegin
Begin time of last halt begin.
SUMOReal myPosition
The position on the lane.
#define SIMTIME
Definition: SUMOTime.h:70
int myCurrentHaltingsNumber
The current number of haltings (inside)
const std::string & getID() const
Returns the id.
Definition: Named.h:66
The vehicle changes lanes (micro only) XXX: What if a vehicle changes lanes and passes a junction sim...
SUMOReal frontLeaveTime
The time the vehicle&#39;s front was crossing the leave line.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
Representation of a vehicle.
Definition: SUMOVehicle.h:67
std::map< const SUMOVehicle *, E3Values > myEnteredContainer
Container for vehicles that have entered the area.
Internal storage for values from a vehicle.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >())
Writes an XML header with optional configuration.
virtual SUMOReal getSpeed() const =0
Returns the vehicle&#39;s current speed.
void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using "e3Detector" as root element.
SUMOTime myHaltingTimeThreshold
The vehicle arrived at its destination (is deleted)
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
T MIN2(T a, T b)
Definition: StdDefs.h:64
static SUMOReal passingTime(const SUMOReal lastPos, const SUMOReal passedPos, const SUMOReal currentPos, const SUMOReal lastSpeed, const SUMOReal currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
Definition: MSCFModel.cpp:367
MSE3Collector & myCollector
The parent collector.
SUMOReal myHaltingSpeedThreshold
Speed-threshold to determine if a vehicle is halting.
Something on a lane to be noticed about vehicle movement.
int getVehiclesWithin() const
Returns the number of vehicles within the area.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
MSE3LeaveReminder(const MSCrossSection &crossSection, MSE3Collector &collector)
Constructor.
SUMOTime intervalTimeLoss
The timeLoss of the vehicle when entering. Updated to the current timeLoss at interval write...
CrossSectionVector myEntries
The detector&#39;s entries.
std::string myID
The name of the object.
Definition: Named.h:136
void leaveFront(const SUMOVehicle &veh, const SUMOReal leaveTimestep)
Called if a vehicle front passes a leave-cross-section.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
void reset()
Resets all generated values to allow computation of next interval.
A detector of vehicles passing an area between entry/exit points.
Definition: MSE3Collector.h:65
bool notifyMove(SUMOVehicle &veh, SUMOReal, SUMOReal newPos, SUMOReal)
Checks whether the vehicle enters.
int intervalHaltings
The sum of haltings the vehicle has/had within the area during the current interval.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
#define SUMOReal
Definition: config.h:208
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:63
bool notifyLeave(SUMOVehicle &veh, SUMOReal lastPos, MSMoveReminder::Notification reason)
Processes state changes of a vehicle.
SUMOReal speedSum
The sum of registered speeds the vehicle has/had inside the area.
SUMOReal getCurrentMeanSpeed() const
Returns the mean speed within the area.
bool notifyMove(SUMOVehicle &veh, SUMOReal oldPos, SUMOReal newPos, SUMOReal)
Checks whether the vehicle leaves.
int getCurrentHaltingNumber() const
Returns the number of current haltings within the area.
virtual SUMOReal getPreviousSpeed() const =0
Returns the vehicle&#39;s previous speed.
void detectorUpdate(const SUMOTime step)
Computes the detector values in each time step.
static bool gUseMesoSim
Definition: MSGlobals.h:95
void leave(const SUMOVehicle &veh, const SUMOReal leaveTimestep, const SUMOReal fractionTimeOnDet)
Called if a vehicle back passes a leave-cross-section.
MSE3Collector(const std::string &id, const CrossSectionVector &entries, const CrossSectionVector &exits, SUMOReal haltingSpeedThreshold, SUMOTime haltingTimeThreshold, const std::string &vTypes)
Constructor.
SUMOReal intervalSpeedSum
The sum of registered speeds the vehicle has/had inside the area during the current interval...
void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes collected values into the given stream.
MSE3Collector & myCollector
The parent collector.
SUMOTime timeLoss
The timeLoss of the vehicle when entering. Updated to the actual time loss within the area when leavi...
Base of value-generating classes (detectors)
std::vector< std::string > getCurrentVehicleIDs() const
Returns the number of vehicles within the area.
CrossSectionVector myExits
The detector&#39;s exits.
std::map< const SUMOVehicle *, E3Values > myLeftContainer
Container for vehicles that have left the area.
SUMOReal myCurrentMeanSpeed
The current mean speed of known vehicles (inside)