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  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  if (oldPos > myPosition) {
106  // crossSection was not passed
107  return false;
108  }
109  // crossSection left
110  SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
111  if (myPosition > oldPos) {
112  leaveTime += (myPosition - oldPos) / newSpeed;
113  }
114  myCollector.leave(veh, leaveTime);
115  return false;
116 }
117 
118 
119 bool
122  return false;
123  }
124  return true;
125 }
126 
127 /* -------------------------------------------------------------------------
128  * MSE3Collector - definitions
129  * ----------------------------------------------------------------------- */
130 MSE3Collector::MSE3Collector(const std::string& id,
131  const CrossSectionVector& entries,
132  const CrossSectionVector& exits,
133  SUMOReal haltingSpeedThreshold,
134  SUMOTime haltingTimeThreshold)
135  : MSDetectorFileOutput(id), myEntries(entries), myExits(exits),
136  myHaltingTimeThreshold(haltingTimeThreshold), myHaltingSpeedThreshold(haltingSpeedThreshold),
138  myLastResetTime(-1) {
139  // Set MoveReminders to entries and exits
140  for (CrossSectionVectorConstIt crossSec1 = entries.begin(); crossSec1 != entries.end(); ++crossSec1) {
141  myEntryReminders.push_back(new MSE3EntryReminder(*crossSec1, *this));
142  }
143  for (CrossSectionVectorConstIt crossSec2 = exits.begin(); crossSec2 != exits.end(); ++crossSec2) {
144  myLeaveReminders.push_back(new MSE3LeaveReminder(*crossSec2, *this));
145  }
146  reset();
147 }
148 
149 
151  for (std::vector<MSE3EntryReminder*>::iterator i = myEntryReminders.begin(); i != myEntryReminders.end(); ++i) {
152  delete *i;
153  }
154  for (std::vector<MSE3LeaveReminder*>::iterator i = myLeaveReminders.begin(); i != myLeaveReminders.end(); ++i) {
155  delete *i;
156  }
157 }
158 
159 
160 void
162  myLeftContainer.clear();
163 }
164 
165 
166 
167 void
169  if (myEnteredContainer.find(&veh) != myEnteredContainer.end()) {
170  WRITE_WARNING("Vehicle '" + veh.getID() + "' reentered " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "'.");
171  return;
172  }
173  const SUMOReal entryTimestepFraction = ((SUMOReal) DELTA_T - fmod(entryTimestep * 1000., 1000.)) / (SUMOReal) DELTA_T;
174  const SUMOReal speedFraction = veh.getSpeed() * entryTimestepFraction;
175  E3Values v;
176  v.entryTime = entryTimestep;
177  v.leaveTime = 0;
178  v.speedSum = speedFraction * TS;
179  v.haltingBegin = veh.getSpeed() < myHaltingSpeedThreshold ? entryTimestep : -1;
180  v.intervalSpeedSum = speedFraction * TS;
181  v.haltings = 0;
182  v.intervalHaltings = 0;
183  if (veh.getSpeed() < myHaltingSpeedThreshold) {
184  if (1. - entryTimestepFraction > myHaltingTimeThreshold) {
185  v.haltings++;
186  v.intervalHaltings++;
187  }
188  }
189  v.hadUpdate = false;
190  myEnteredContainer[&veh] = v;
191 }
192 
193 
194 void
196  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
197  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' before entering it.");
198  } else {
199  E3Values values = myEnteredContainer[&veh];
200  values.leaveTime = leaveTimestep;
201  SUMOReal leaveTimestepFraction = leaveTimestep - (SUMOReal)((int) leaveTimestep);
202  leaveTimestepFraction = fmod(leaveTimestep * 1000., 1000.) / (SUMOReal) DELTA_T;
203  if (values.hadUpdate) {
204  SUMOReal speedFraction = (veh.getSpeed() * leaveTimestepFraction);
205  values.speedSum += speedFraction * TS;
206  values.intervalSpeedSum += speedFraction * TS;
207  if (veh.getSpeed() < myHaltingSpeedThreshold && values.haltingBegin != -1 && leaveTimestep - values.haltingBegin > myHaltingTimeThreshold) {
208  values.haltings++;
209  values.intervalHaltings++;
210  }
211  } else {
212  SUMOReal speedFraction = (veh.getSpeed() * SUMOReal(1. - leaveTimestepFraction));
213  values.speedSum -= speedFraction * TS;
214  values.intervalSpeedSum -= speedFraction * TS;
215  }
216  myEnteredContainer.erase(&veh);
217  myLeftContainer[&veh] = values;
218  }
219 }
220 
221 
222 void
224  SUMOTime startTime, SUMOTime stopTime) {
225  dev << " <interval begin=\"" << time2string(startTime) << "\" end=\"" << time2string(stopTime) << "\" " << "id=\"" << myID << "\" ";
226  // collect values about vehicles that have left the area
227  unsigned vehicleSum = (unsigned) myLeftContainer.size();
228  SUMOReal meanTravelTime = 0.;
229  SUMOReal meanSpeed = 0.;
230  SUMOReal meanHaltsPerVehicle = 0.;
231  for (std::map<SUMOVehicle*, E3Values>::iterator i = myLeftContainer.begin(); i != myLeftContainer.end(); ++i) {
232  meanHaltsPerVehicle += (SUMOReal)(*i).second.haltings;
233  SUMOReal steps = (*i).second.leaveTime - (*i).second.entryTime;
234  meanTravelTime += steps;
235  meanSpeed += ((*i).second.speedSum / steps);
236  }
237  meanTravelTime = vehicleSum != 0 ? meanTravelTime / (SUMOReal) vehicleSum : -1;
238  meanSpeed = vehicleSum != 0 ? meanSpeed / (SUMOReal) vehicleSum : -1;
239  meanHaltsPerVehicle = vehicleSum != 0 ? meanHaltsPerVehicle / (SUMOReal) vehicleSum : -1;
240  // clear container
241  myLeftContainer.clear();
242 
243  // collect values about vehicles within the container
244  unsigned vehicleSumWithin = (unsigned) myEnteredContainer.size();
245  SUMOReal meanSpeedWithin = 0.;
246  SUMOReal meanDurationWithin = 0.;
247  SUMOReal meanHaltsPerVehicleWithin = 0.;
248  SUMOReal meanIntervalSpeedWithin = 0.;
249  SUMOReal meanIntervalHaltsPerVehicleWithin = 0.;
250  SUMOReal meanIntervalDurationWithin = 0.;
251  for (std::map<SUMOVehicle*, E3Values>::iterator i = myEnteredContainer.begin(); i != myEnteredContainer.end(); ++i) {
252  meanHaltsPerVehicleWithin += (SUMOReal)(*i).second.haltings;
253  meanIntervalHaltsPerVehicleWithin += (SUMOReal)(*i).second.intervalHaltings;
254  const SUMOReal time = STEPS2TIME(stopTime) - (*i).second.entryTime;
255  const SUMOReal timeWithin = MIN2(time, STEPS2TIME(stopTime - startTime));
256  if (i->second.speedSum > 0.) {
257  meanSpeedWithin += i->second.speedSum / time;
258  }
259  if (i->second.intervalSpeedSum > 0.) {
260  meanIntervalSpeedWithin += i->second.intervalSpeedSum / timeWithin;
261  }
262  meanDurationWithin += time;
263  meanIntervalDurationWithin += timeWithin;
264  // reset interval values
265  (*i).second.intervalHaltings = 0;
266  (*i).second.intervalSpeedSum = 0;
267  }
268  myLastResetTime = stopTime;
269  meanSpeedWithin = vehicleSumWithin != 0 ? meanSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
270  meanHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
271  meanDurationWithin = vehicleSumWithin != 0 ? meanDurationWithin / (SUMOReal) vehicleSumWithin : -1;
272  meanIntervalSpeedWithin = vehicleSumWithin != 0 ? meanIntervalSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
273  meanIntervalHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanIntervalHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
274  meanIntervalDurationWithin = vehicleSumWithin != 0 ? meanIntervalDurationWithin / (SUMOReal) vehicleSumWithin : -1;
275 
276  // write values
277  dev << "meanTravelTime=\"" << meanTravelTime
278  << "\" meanSpeed=\"" << meanSpeed
279  << "\" meanHaltsPerVehicle=\"" << meanHaltsPerVehicle
280  << "\" vehicleSum=\"" << vehicleSum
281  << "\" meanSpeedWithin=\"" << meanSpeedWithin
282  << "\" meanHaltsPerVehicleWithin=\"" << meanHaltsPerVehicleWithin
283  << "\" meanDurationWithin=\"" << meanDurationWithin
284  << "\" vehicleSumWithin=\"" << vehicleSumWithin
285  << "\" meanIntervalSpeedWithin=\"" << meanIntervalSpeedWithin
286  << "\" meanIntervalHaltsPerVehicleWithin=\"" << meanIntervalHaltsPerVehicleWithin
287  << "\" meanIntervalDurationWithin=\"" << meanIntervalDurationWithin
288  << "\"/>\n";
289 }
290 
291 
292 void
294  dev.writeXMLHeader("e3Detector");
295 }
296 
297 
298 void
300  myCurrentMeanSpeed = 0;
303  for (std::map<SUMOVehicle*, E3Values>::iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
304  SUMOVehicle* veh = pair->first;
305  E3Values& values = pair->second;
306  values.hadUpdate = true;
307  if (values.entryTime * 1000. >= step) {
308  // vehicle entered at this time step
309  SUMOReal fraction = step + 1. - values.entryTime;
310  myCurrentMeanSpeed += fraction * veh->getSpeed();
311  myCurrentTouchedVehicles += fraction;
312  if (values.haltingBegin >= 0) {
314  }
315  continue;
316  }
317  values.speedSum += veh->getSpeed() * TS;
318  values.intervalSpeedSum += veh->getSpeed() * TS;
319  myCurrentMeanSpeed += veh->getSpeed();
321  if (veh->getSpeed() < myHaltingSpeedThreshold) {
322  if (values.haltingBegin == -1) {
323  values.haltingBegin = step;
324  }
325  if (step - values.haltingBegin > myHaltingTimeThreshold) {
326  values.haltings++;
327  values.intervalHaltings++;
329  }
330  } else {
331  values.haltingBegin = -1;
332  }
334  }
335 }
336 
337 
338 SUMOReal
340  SUMOReal ret = 0;
341  if (myEnteredContainer.size() == 0) {
342  return -1;
343  }
344  for (std::map<SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
345  ret += (*pair).first->getSpeed();
346  }
347  return ret / SUMOReal(myEnteredContainer.size());
348 }
349 
350 
351 SUMOReal
354 }
355 
356 
357 SUMOReal
359  return (SUMOReal) myEnteredContainer.size();
360 }
361 
362 
363 std::vector<std::string>
365  std::vector<std::string> ret;
366  for (std::map<SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
367  ret.push_back((*pair).first->getID());
368  }
369  std::sort(ret.begin(), ret.end());
370  return ret;
371 }
372 
373 
374 /****************************************************************************/
375 
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:71
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:159
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: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.
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:64
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:66
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:53
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: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: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)