SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-sim.org/
14 // Copyright (C) 2001-2014 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
63  return false;
64  } else {
65  SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
66  if (newSpeed != 0) {
67  if (myPosition > oldPos) {
68  entryTime += (myPosition - oldPos) / newSpeed;
69  }
70  }
71  myCollector.enter(veh, entryTime);
72  }
73  }
74  return true;
75 }
76 
77 
78 bool
81  myCollector.myEnteredContainer.erase(&veh);
82  return false;
83  }
84  return true;
85 }
86 
87 
88 /* -------------------------------------------------------------------------
89  * MSE3Collector::MSE3LeaveReminder - definitions
90  * ----------------------------------------------------------------------- */
92  const MSCrossSection& crossSection, MSE3Collector& collector) :
93  MSMoveReminder(collector.getID() + "_exit", crossSection.myLane),
94  myCollector(collector), myPosition(crossSection.myPosition) {}
95 
96 
97 bool
99  SUMOReal newPos, SUMOReal newSpeed) {
100  if (newPos <= myPosition) {
101  // crossSection not yet reached
102  return true;
103  }
104  if (oldPos > myPosition) {
105  // crossSection was not passed
106  return false;
107  }
108  // crossSection left
109  SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
110  if (myPosition > oldPos) {
111  leaveTime += (myPosition - oldPos) / newSpeed;
112  }
113  myCollector.leave(veh, leaveTime);
114  return false;
115 }
116 
117 
118 bool
121  return false;
122  }
123  return true;
124 }
125 
126 /* -------------------------------------------------------------------------
127  * MSE3Collector - definitions
128  * ----------------------------------------------------------------------- */
129 MSE3Collector::MSE3Collector(const std::string& id,
130  const CrossSectionVector& entries,
131  const CrossSectionVector& exits,
132  SUMOReal haltingSpeedThreshold,
133  SUMOTime haltingTimeThreshold)
134  : MSDetectorFileOutput(id), myEntries(entries), myExits(exits),
135  myHaltingTimeThreshold(haltingTimeThreshold), myHaltingSpeedThreshold(haltingSpeedThreshold),
137  myLastResetTime(-1) {
138  // Set MoveReminders to entries and exits
139  for (CrossSectionVectorConstIt crossSec1 = entries.begin(); crossSec1 != entries.end(); ++crossSec1) {
140  myEntryReminders.push_back(new MSE3EntryReminder(*crossSec1, *this));
141  }
142  for (CrossSectionVectorConstIt crossSec2 = exits.begin(); crossSec2 != exits.end(); ++crossSec2) {
143  myLeaveReminders.push_back(new MSE3LeaveReminder(*crossSec2, *this));
144  }
145  reset();
146 }
147 
148 
150  for (std::vector<MSE3EntryReminder*>::iterator i = myEntryReminders.begin(); i != myEntryReminders.end(); ++i) {
151  delete *i;
152  }
153  for (std::vector<MSE3LeaveReminder*>::iterator i = myLeaveReminders.begin(); i != myLeaveReminders.end(); ++i) {
154  delete *i;
155  }
156 }
157 
158 
159 void
161  myLeftContainer.clear();
162 }
163 
164 
165 
166 void
168  if (myEnteredContainer.find(&veh) != myEnteredContainer.end()) {
169  WRITE_WARNING("Vehicle '" + veh.getID() + "' reentered " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "'.");
170  return;
171  }
172  SUMOReal entryTimestepFraction = ((SUMOReal) DELTA_T - fmod(entryTimestep * 1000., 1000.)) / (SUMOReal) DELTA_T;
173  SUMOReal speedFraction = (veh.getSpeed() * entryTimestepFraction);
174  E3Values v;
175  v.entryTime = entryTimestep;
176  v.leaveTime = 0;
177  v.speedSum = speedFraction / (1000. / (SUMOReal) DELTA_T);
178  v.haltingBegin = veh.getSpeed() < myHaltingSpeedThreshold ? entryTimestep : -1;
179  v.intervalSpeedSum = speedFraction / (1000. / (SUMOReal) DELTA_T);
180  v.haltings = 0;
181  v.intervalHaltings = 0;
182  if (veh.getSpeed() < myHaltingSpeedThreshold) {
183  if (1. - entryTimestepFraction > myHaltingTimeThreshold) {
184  v.haltings++;
185  v.intervalHaltings++;
186  }
187  }
188  v.hadUpdate = false;
189  myEnteredContainer[&veh] = v;
190 }
191 
192 
193 void
195  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
196  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' before entering it.");
197  } else {
198  E3Values values = myEnteredContainer[&veh];
199  values.leaveTime = leaveTimestep;
200  SUMOReal leaveTimestepFraction = leaveTimestep - (SUMOReal)((int) leaveTimestep);
201  leaveTimestepFraction = fmod(leaveTimestep * 1000., 1000.) / (SUMOReal) DELTA_T;
202  if (values.hadUpdate) {
203  SUMOReal speedFraction = (veh.getSpeed() * leaveTimestepFraction);
204  values.speedSum += speedFraction / (1000. / (SUMOReal) DELTA_T);
205  values.intervalSpeedSum += speedFraction / (1000. / (SUMOReal) DELTA_T);
206  if (veh.getSpeed() < myHaltingSpeedThreshold && values.haltingBegin != -1 && leaveTimestep - values.haltingBegin > myHaltingTimeThreshold) {
207  values.haltings++;
208  values.intervalHaltings++;
209  }
210  } else {
211  SUMOReal speedFraction = (veh.getSpeed() * SUMOReal(1. - leaveTimestepFraction));
212  values.speedSum -= speedFraction / (1000. / (SUMOReal) DELTA_T);
213  values.intervalSpeedSum -= speedFraction / (1000. / (SUMOReal) DELTA_T);
214  }
215  myEnteredContainer.erase(&veh);
216  myLeftContainer[&veh] = values;
217  }
218 }
219 
220 
221 void
223  SUMOTime startTime, SUMOTime stopTime) {
224  dev << " <interval begin=\"" << time2string(startTime) << "\" end=\"" << time2string(stopTime) << "\" " << "id=\"" << myID << "\" ";
225  // collect values about vehicles that have left the area
226  unsigned vehicleSum = (unsigned) myLeftContainer.size();
227  SUMOReal meanTravelTime = 0.;
228  SUMOReal meanSpeed = 0.;
229  SUMOReal meanHaltsPerVehicle = 0.;
230  for (std::map<SUMOVehicle*, E3Values>::iterator i = myLeftContainer.begin(); i != myLeftContainer.end(); ++i) {
231  meanHaltsPerVehicle += (SUMOReal)(*i).second.haltings;
232  SUMOReal steps = (*i).second.leaveTime - (*i).second.entryTime;
233  meanTravelTime += steps;
234  meanSpeed += ((*i).second.speedSum / steps);
235  }
236  meanTravelTime = vehicleSum != 0 ? meanTravelTime / (SUMOReal) vehicleSum : -1;
237  meanSpeed = vehicleSum != 0 ? meanSpeed / (SUMOReal) vehicleSum : -1;
238  meanHaltsPerVehicle = vehicleSum != 0 ? meanHaltsPerVehicle / (SUMOReal) vehicleSum : -1;
239  // clear container
240  myLeftContainer.clear();
241 
242  // collect values about vehicles within the container
243  unsigned vehicleSumWithin = (unsigned) myEnteredContainer.size();
244  SUMOReal meanSpeedWithin = 0.;
245  SUMOReal meanDurationWithin = 0.;
246  SUMOReal meanHaltsPerVehicleWithin = 0.;
247  SUMOReal meanIntervalSpeedWithin = 0.;
248  SUMOReal meanIntervalHaltsPerVehicleWithin = 0.;
249  SUMOReal meanIntervalDurationWithin = 0.;
250  for (std::map<SUMOVehicle*, E3Values>::iterator i = myEnteredContainer.begin(); i != myEnteredContainer.end(); ++i) {
251  meanHaltsPerVehicleWithin += (SUMOReal)(*i).second.haltings;
252  meanIntervalHaltsPerVehicleWithin += (SUMOReal)(*i).second.intervalHaltings;
253  SUMOReal time = (SUMOReal)stopTime / 1000. - (*i).second.entryTime;
254  SUMOReal intLength = (SUMOReal)(stopTime - startTime) / 1000.;
255  SUMOReal timeWithin = MIN2(time, intLength);
256  meanSpeedWithin += ((*i).second.speedSum / time);
257  meanIntervalSpeedWithin += ((*i).second.intervalSpeedSum / timeWithin);
258  meanDurationWithin += time;
259  meanIntervalDurationWithin += timeWithin;
260  // reset interval values
261  (*i).second.intervalHaltings = 0;
262  (*i).second.intervalSpeedSum = 0;
263  }
264  myLastResetTime = stopTime;
265  meanSpeedWithin = vehicleSumWithin != 0 ? meanSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
266  meanHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
267  meanDurationWithin = vehicleSumWithin != 0 ? meanDurationWithin / (SUMOReal) vehicleSumWithin : -1;
268  meanIntervalSpeedWithin = vehicleSumWithin != 0 ? meanIntervalSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
269  meanIntervalHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanIntervalHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
270  meanIntervalDurationWithin = vehicleSumWithin != 0 ? meanIntervalDurationWithin / (SUMOReal) vehicleSumWithin : -1;
271 
272  // write values
273  dev << "meanTravelTime=\"" << meanTravelTime
274  << "\" meanSpeed=\"" << meanSpeed
275  << "\" meanHaltsPerVehicle=\"" << meanHaltsPerVehicle
276  << "\" vehicleSum=\"" << vehicleSum
277  << "\" meanSpeedWithin=\"" << meanSpeedWithin
278  << "\" meanHaltsPerVehicleWithin=\"" << meanHaltsPerVehicleWithin
279  << "\" meanDurationWithin=\"" << meanDurationWithin
280  << "\" vehicleSumWithin=\"" << vehicleSumWithin
281  << "\" meanIntervalSpeedWithin=\"" << meanIntervalSpeedWithin
282  << "\" meanIntervalHaltsPerVehicleWithin=\"" << meanIntervalHaltsPerVehicleWithin
283  << "\" meanIntervalDurationWithin=\"" << meanIntervalDurationWithin
284  << "\"/>\n";
285 }
286 
287 
288 void
290  dev.writeXMLHeader("e3Detector");
291 }
292 
293 
294 void
296  myCurrentMeanSpeed = 0;
299  for (std::map<SUMOVehicle*, E3Values>::iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
300  SUMOVehicle* veh = pair->first;
301  E3Values& values = pair->second;
302  values.hadUpdate = true;
303  if (values.entryTime * 1000. >= step) {
304  // vehicle entered at this time step
305  SUMOReal fraction = step + 1. - values.entryTime;
306  myCurrentMeanSpeed += fraction * veh->getSpeed();
307  myCurrentTouchedVehicles += fraction;
308  if (values.haltingBegin >= 0) {
310  }
311  continue;
312  }
313  values.speedSum += veh->getSpeed() * TS;
314  values.intervalSpeedSum += veh->getSpeed() * TS;
315  myCurrentMeanSpeed += veh->getSpeed();
317  if (veh->getSpeed() < myHaltingSpeedThreshold) {
318  if (values.haltingBegin == -1) {
319  values.haltingBegin = step;
320  }
321  if (step - values.haltingBegin > myHaltingTimeThreshold) {
322  values.haltings++;
323  values.intervalHaltings++;
325  }
326  } else {
327  values.haltingBegin = -1;
328  }
330  }
331 }
332 
333 
334 SUMOReal
336  SUMOReal ret = 0;
337  if (myEnteredContainer.size() == 0) {
338  return -1;
339  }
340  for (std::map<SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
341  ret += (*pair).first->getSpeed();
342  }
343  return ret / SUMOReal(myEnteredContainer.size());
344 }
345 
346 
347 SUMOReal
350 }
351 
352 
353 SUMOReal
355  return (SUMOReal) myEnteredContainer.size();
356 }
357 
358 
359 std::vector<std::string>
361  std::vector<std::string> ret;
362  for (std::map<SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
363  ret.push_back((*pair).first->getID());
364  }
365  std::sort(ret.begin(), ret.end());
366  return ret;
367 }
368 
369 
370 /****************************************************************************/
371 
SUMOReal getCurrentHaltingNumber() const
Returns the number of current haltings within the area.
std::map< SUMOVehicle *, E3Values > myLeftContainer
Container for vehicles that have left 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's built entry reminder.
SUMOReal entryTime
The vehicle'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:70
SUMOReal myCurrentHaltingsNumber
The current number of haltings (inside)
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
std::vector< MSCrossSection > CrossSectionVector
CrossSectionVector::const_iterator CrossSectionVectorConstIt
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:154
void enter(SUMOVehicle &veh, SUMOReal entryTimestep)
Called if a vehicle touches an entry-cross-section.
SUMOTime myLastResetTime
Information when the last reset has been done.
std::vector< MSE3LeaveReminder * > myLeaveReminders
The detector's built exit reminder.
#define TS
Definition: SUMOTime.h:52
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
SUMOReal haltingBegin
Begin time of last halt begin.
SUMOReal leaveTime
The vehicle's leaving time.
bool writeXMLHeader(const std::string &rootElement, const std::string &attrs="", const std::string &comment="")
Writes an XML header with optional configuration.
const std::string & getID() const
Returns the id.
Definition: Named.h:60
The vehicle changes lanes (micro only)
Representation of a vehicle.
Definition: SUMOVehicle.h:63
Internal storage for values from a vehicle.
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:65
void leave(SUMOVehicle &veh, SUMOReal leaveTimestep)
Called if a vehicle passes a leave-cross-section.
SUMOReal myHaltingSpeedThreshold
Speed-threshold to determine if a vehicle is halting.
Something on a lane to be noticed about vehicle movement.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:52
MSE3LeaveReminder(const MSCrossSection &crossSection, MSE3Collector &collector)
Constructor.
CrossSectionVector myEntries
The detector's entries.
SUMOReal myCurrentTouchedVehicles
The current number of vehicles inside;.
std::string myID
The name of the object.
Definition: Named.h:128
virtual SUMOReal getSpeed() const =0
Returns the vehicle's current speed.
unsigned haltings
The sum of haltings the vehicle has/had within the area.
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:64
bool notifyMove(SUMOVehicle &veh, SUMOReal, SUMOReal newPos, SUMOReal)
Checks whether the vehicle enters.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
#define SUMOReal
Definition: config.h:215
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.
#define DELTA_T
Definition: SUMOTime.h:50
SUMOReal getCurrentMeanSpeed() const
Returns the mean speed within the area.
bool notifyMove(SUMOVehicle &veh, SUMOReal oldPos, SUMOReal newPos, SUMOReal)
Checks whether the vehicle leaves.
SUMOReal getVehiclesWithin() const
Returns the number of vehicles within the area.
unsigned intervalHaltings
The sum of haltings the vehicle has/had within the area during the current interval.
void detectorUpdate(const SUMOTime step)
Computes the detector values in each time step.
std::map< SUMOVehicle *, E3Values > myEnteredContainer
Container for vehicles that have entered the area.
MSE3Collector(const std::string &id, const CrossSectionVector &entries, const CrossSectionVector &exits, SUMOReal haltingSpeedThreshold, SUMOTime haltingTimeThreshold)
Constructor.
virtual const std::string & getID() const =0
Get the vehicle's ID.
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.
Base of value-generating classes (detectors)
std::vector< std::string > getCurrentVehicleIDs() const
Returns the number of vehicles within the area.
CrossSectionVector myExits
The detector's exits.
SUMOReal myCurrentMeanSpeed
The current mean speed of known vehicles (inside)