SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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.dlr.de/
14 // Copyright (C) 2001-2015 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  const SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
66  assert(newSpeed != 0); // how could it move across the detector otherwise
67  const SUMOReal fractionTimeOnDet = (newPos - myPosition) / newSpeed;
68  myCollector.enter(veh, entryTime - fractionTimeOnDet, fractionTimeOnDet);
69  }
70  }
71  return true;
72 }
73 
74 
75 bool
78  WRITE_WARNING("Vehicle '" + veh.getID() + "' arrived inside " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
79  myCollector.myEnteredContainer.erase(&veh);
80  return false;
81  }
82  return true;
83 }
84 
85 
86 /* -------------------------------------------------------------------------
87  * MSE3Collector::MSE3LeaveReminder - definitions
88  * ----------------------------------------------------------------------- */
90  const MSCrossSection& crossSection, MSE3Collector& collector) :
91  MSMoveReminder(collector.getID() + "_exit", crossSection.myLane),
92  myCollector(collector), myPosition(crossSection.myPosition) {}
93 
94 
95 bool
97  SUMOReal newPos, SUMOReal newSpeed) {
98  if (newPos <= myPosition) {
99  // crossSection not yet reached
100  return true;
101  }
102  if (oldPos > myPosition) {
103  // crossSection was not passed
104  return false;
105  }
106  // crossSection left
107  const SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
108  assert(newSpeed != 0); // how could it move across the detector otherwise
109  const SUMOReal fractionTimeOnDet = (myPosition - oldPos) / newSpeed;
110  myCollector.leave(veh, leaveTime - TS + fractionTimeOnDet, fractionTimeOnDet);
111  return false;
112 }
113 
114 
115 bool
118  return false;
119  }
120  return true;
121 }
122 
123 /* -------------------------------------------------------------------------
124  * MSE3Collector - definitions
125  * ----------------------------------------------------------------------- */
126 MSE3Collector::MSE3Collector(const std::string& id,
127  const CrossSectionVector& entries,
128  const CrossSectionVector& exits,
129  SUMOReal haltingSpeedThreshold,
130  SUMOTime haltingTimeThreshold)
131  : MSDetectorFileOutput(id), myEntries(entries), myExits(exits),
132  myHaltingTimeThreshold(haltingTimeThreshold), myHaltingSpeedThreshold(haltingSpeedThreshold),
134  // Set MoveReminders to entries and exits
135  for (CrossSectionVectorConstIt crossSec1 = entries.begin(); crossSec1 != entries.end(); ++crossSec1) {
136  myEntryReminders.push_back(new MSE3EntryReminder(*crossSec1, *this));
137  }
138  for (CrossSectionVectorConstIt crossSec2 = exits.begin(); crossSec2 != exits.end(); ++crossSec2) {
139  myLeaveReminders.push_back(new MSE3LeaveReminder(*crossSec2, *this));
140  }
141  reset();
142 }
143 
144 
146  for (std::vector<MSE3EntryReminder*>::iterator i = myEntryReminders.begin(); i != myEntryReminders.end(); ++i) {
147  delete *i;
148  }
149  for (std::vector<MSE3LeaveReminder*>::iterator i = myLeaveReminders.begin(); i != myLeaveReminders.end(); ++i) {
150  delete *i;
151  }
152 }
153 
154 
155 void
157  myLeftContainer.clear();
158 }
159 
160 
161 
162 void
163 MSE3Collector::enter(const SUMOVehicle& veh, const SUMOReal entryTimestep, const SUMOReal fractionTimeOnDet) {
164  if (myEnteredContainer.find(&veh) != myEnteredContainer.end()) {
165  WRITE_WARNING("Vehicle '" + veh.getID() + "' reentered " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "'.");
166  return;
167  }
168  const SUMOReal speedFraction = veh.getSpeed() * fractionTimeOnDet;
169  E3Values v;
170  v.entryTime = entryTimestep;
171  v.leaveTime = 0;
172  v.speedSum = speedFraction;
173  v.haltingBegin = veh.getSpeed() < myHaltingSpeedThreshold ? entryTimestep : -1;
174  v.intervalSpeedSum = entryTimestep >= STEPS2TIME(myLastResetTime) ? speedFraction : 0;
175  v.haltings = 0;
176  v.intervalHaltings = 0;
177  if (veh.getSpeed() < myHaltingSpeedThreshold) {
178  if (fractionTimeOnDet > myHaltingTimeThreshold) {
179  v.haltings++;
180  v.intervalHaltings++;
181  }
182  }
183  v.hadUpdate = false;
184  myEnteredContainer[&veh] = v;
185 }
186 
187 
188 void
189 MSE3Collector::leave(const SUMOVehicle& veh, const SUMOReal leaveTimestep, const SUMOReal fractionTimeOnDet) {
190  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
191  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' before entering it.");
192  } else {
193  E3Values values = myEnteredContainer[&veh];
194  values.leaveTime = leaveTimestep;
195  const SUMOReal speedFraction = veh.getSpeed() * (TS - fractionTimeOnDet);
196  values.speedSum -= speedFraction;
197  values.intervalSpeedSum -= speedFraction;
198  myEnteredContainer.erase(&veh);
199  myLeftContainer[&veh] = values;
200  }
201 }
202 
203 
204 void
206  SUMOTime startTime, SUMOTime stopTime) {
207  dev << " <interval begin=\"" << time2string(startTime) << "\" end=\"" << time2string(stopTime) << "\" " << "id=\"" << myID << "\" ";
208  // collect values about vehicles that have left the area
209  unsigned vehicleSum = (unsigned) myLeftContainer.size();
210  SUMOReal meanTravelTime = 0.;
211  SUMOReal meanSpeed = 0.;
212  SUMOReal meanHaltsPerVehicle = 0.;
213  for (std::map<const SUMOVehicle*, E3Values>::iterator i = myLeftContainer.begin(); i != myLeftContainer.end(); ++i) {
214  meanHaltsPerVehicle += (SUMOReal)(*i).second.haltings;
215  SUMOReal steps = (*i).second.leaveTime - (*i).second.entryTime;
216  meanTravelTime += steps;
217  meanSpeed += ((*i).second.speedSum / steps);
218  }
219  meanTravelTime = vehicleSum != 0 ? meanTravelTime / (SUMOReal) vehicleSum : -1;
220  meanSpeed = vehicleSum != 0 ? meanSpeed / (SUMOReal) vehicleSum : -1;
221  meanHaltsPerVehicle = vehicleSum != 0 ? meanHaltsPerVehicle / (SUMOReal) vehicleSum : -1;
222  // clear container
223  myLeftContainer.clear();
224 
225  // collect values about vehicles within the container
226  unsigned vehicleSumWithin = (unsigned) myEnteredContainer.size();
227  SUMOReal meanSpeedWithin = 0.;
228  SUMOReal meanDurationWithin = 0.;
229  SUMOReal meanHaltsPerVehicleWithin = 0.;
230  SUMOReal meanIntervalSpeedWithin = 0.;
231  SUMOReal meanIntervalHaltsPerVehicleWithin = 0.;
232  SUMOReal meanIntervalDurationWithin = 0.;
233  for (std::map<const SUMOVehicle*, E3Values>::iterator i = myEnteredContainer.begin(); i != myEnteredContainer.end(); ++i) {
234  meanHaltsPerVehicleWithin += (SUMOReal)(*i).second.haltings;
235  meanIntervalHaltsPerVehicleWithin += (SUMOReal)(*i).second.intervalHaltings;
236  const SUMOReal end = (*i).second.leaveTime == 0 ? STEPS2TIME(stopTime) : (*i).second.leaveTime;
237  const SUMOReal time = end - (*i).second.entryTime;
238  const SUMOReal timeWithin = MIN2(time, end - STEPS2TIME(startTime));
239  if (i->second.speedSum > 0.) {
240  meanSpeedWithin += i->second.speedSum / time;
241  }
242  if (i->second.intervalSpeedSum > 0.) {
243  meanIntervalSpeedWithin += i->second.intervalSpeedSum / timeWithin;
244  }
245  meanDurationWithin += time;
246  meanIntervalDurationWithin += timeWithin;
247  // reset interval values
248  (*i).second.intervalHaltings = 0;
249  (*i).second.intervalSpeedSum = 0;
250  }
251  myLastResetTime = stopTime;
252  meanSpeedWithin = vehicleSumWithin != 0 ? meanSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
253  meanHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
254  meanDurationWithin = vehicleSumWithin != 0 ? meanDurationWithin / (SUMOReal) vehicleSumWithin : -1;
255  meanIntervalSpeedWithin = vehicleSumWithin != 0 ? meanIntervalSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
256  meanIntervalHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanIntervalHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
257  meanIntervalDurationWithin = vehicleSumWithin != 0 ? meanIntervalDurationWithin / (SUMOReal) vehicleSumWithin : -1;
258 
259  // write values
260  dev << "meanTravelTime=\"" << meanTravelTime
261  << "\" meanSpeed=\"" << meanSpeed
262  << "\" meanHaltsPerVehicle=\"" << meanHaltsPerVehicle
263  << "\" vehicleSum=\"" << vehicleSum
264  << "\" meanSpeedWithin=\"" << meanSpeedWithin
265  << "\" meanHaltsPerVehicleWithin=\"" << meanHaltsPerVehicleWithin
266  << "\" meanDurationWithin=\"" << meanDurationWithin
267  << "\" vehicleSumWithin=\"" << vehicleSumWithin
268  << "\" meanIntervalSpeedWithin=\"" << meanIntervalSpeedWithin
269  << "\" meanIntervalHaltsPerVehicleWithin=\"" << meanIntervalHaltsPerVehicleWithin
270  << "\" meanIntervalDurationWithin=\"" << meanIntervalDurationWithin
271  << "\"/>\n";
272 }
273 
274 
275 void
277  dev.writeXMLHeader("e3Detector");
278 }
279 
280 
281 void
283  myCurrentMeanSpeed = 0;
285  for (std::map<const SUMOVehicle*, E3Values>::iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
286  const SUMOVehicle* veh = pair->first;
287  E3Values& values = pair->second;
288  myCurrentMeanSpeed += veh->getSpeed();
289  values.hadUpdate = true;
290  values.speedSum += veh->getSpeed() * TS;
291  values.intervalSpeedSum += veh->getSpeed() * TS;
292  if (veh->getSpeed() < myHaltingSpeedThreshold) {
293  if (values.haltingBegin == -1) {
294  values.haltingBegin = step;
295  }
296  if (step - values.haltingBegin > myHaltingTimeThreshold) {
297  values.haltings++;
298  values.intervalHaltings++;
300  }
301  } else {
302  values.haltingBegin = -1;
303  }
304  }
305  if (myEnteredContainer.size() == 0) {
306  myCurrentMeanSpeed = -1;
307  } else {
309  }
310 }
311 
312 
313 SUMOReal
315  return myCurrentMeanSpeed;
316 }
317 
318 
319 int
322 }
323 
324 
325 int
327  return (int) myEnteredContainer.size();
328 }
329 
330 
331 std::vector<std::string>
333  std::vector<std::string> ret;
334  for (std::map<const SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
335  ret.push_back((*pair).first->getID());
336  }
337  std::sort(ret.begin(), ret.end());
338  return ret;
339 }
340 
341 
342 /****************************************************************************/
343 
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:71
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
void enter(const SUMOVehicle &veh, const SUMOReal entryTimestep, const SUMOReal fractionTimeOnDet)
Called if a vehicle touches an entry-cross-section.
std::vector< MSCrossSection > CrossSectionVector
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'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 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.
int myCurrentHaltingsNumber
The current number of haltings (inside)
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:65
std::map< const SUMOVehicle *, E3Values > myEnteredContainer
Container for vehicles that have entered the area.
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:68
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.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
MSE3LeaveReminder(const MSCrossSection &crossSection, MSE3Collector &collector)
Constructor.
CrossSectionVector myEntries
The detector's entries.
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.
int SUMOTime
Definition: SUMOTime.h:43
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.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
#define SUMOReal
Definition: config.h:218
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.
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.
MSE3Collector(const std::string &id, const CrossSectionVector &entries, const CrossSectionVector &exits, SUMOReal haltingSpeedThreshold, SUMOTime haltingTimeThreshold)
Constructor.
void leave(const SUMOVehicle &veh, const SUMOReal leaveTimestep, const SUMOReal fractionTimeOnDet)
Called if a vehicle passes a leave-cross-section.
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.
std::map< const SUMOVehicle *, E3Values > myLeftContainer
Container for vehicles that have left the area.
SUMOReal myCurrentMeanSpeed
The current mean speed of known vehicles (inside)