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-2016 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  myEnteredContainer[&veh] = v;
200 }
201 
202 
203 void
204 MSE3Collector::leaveFront(const SUMOVehicle& veh, const SUMOReal leaveTimestep) {
205  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
206  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
207  } else {
208  myEnteredContainer[&veh].frontLeaveTime = leaveTimestep;
209  }
210 }
211 
212 
213 void
214 MSE3Collector::leave(const SUMOVehicle& veh, const SUMOReal leaveTimestep, const SUMOReal fractionTimeOnDet) {
215  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
216  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
217  } else {
218  E3Values values = myEnteredContainer[&veh];
219  values.backLeaveTime = leaveTimestep;
220  const SUMOReal speedFraction = veh.getSpeed() * (TS - fractionTimeOnDet);
221  values.speedSum -= speedFraction;
222  values.intervalSpeedSum -= speedFraction;
223  myEnteredContainer.erase(&veh);
224  myLeftContainer[&veh] = values;
225  }
226 }
227 
228 
229 void
231  SUMOTime startTime, SUMOTime stopTime) {
232  dev << " <interval begin=\"" << time2string(startTime) << "\" end=\"" << time2string(stopTime) << "\" " << "id=\"" << myID << "\" ";
233  // collect values about vehicles that have left the area
234  int vehicleSum = (int) myLeftContainer.size();
235  SUMOReal meanTravelTime = 0.;
236  SUMOReal meanOverlapTravelTime = 0.;
237  SUMOReal meanSpeed = 0.;
238  SUMOReal meanHaltsPerVehicle = 0.;
239  for (std::map<const SUMOVehicle*, E3Values>::iterator i = myLeftContainer.begin(); i != myLeftContainer.end(); ++i) {
240  meanHaltsPerVehicle += (SUMOReal)(*i).second.haltings;
241  meanTravelTime += (*i).second.frontLeaveTime - (*i).second.entryTime;
242  const SUMOReal steps = (*i).second.backLeaveTime - (*i).second.entryTime;
243  meanOverlapTravelTime += steps;
244  meanSpeed += ((*i).second.speedSum / steps);
245  }
246  meanTravelTime = vehicleSum != 0 ? meanTravelTime / (SUMOReal)vehicleSum : -1;
247  meanOverlapTravelTime = vehicleSum != 0 ? meanOverlapTravelTime / (SUMOReal)vehicleSum : -1;
248  meanSpeed = vehicleSum != 0 ? meanSpeed / (SUMOReal)vehicleSum : -1;
249  meanHaltsPerVehicle = vehicleSum != 0 ? meanHaltsPerVehicle / (SUMOReal) vehicleSum : -1;
250  // clear container
251  myLeftContainer.clear();
252 
253  // collect values about vehicles within the container
254  int vehicleSumWithin = (int) myEnteredContainer.size();
255  SUMOReal meanSpeedWithin = 0.;
256  SUMOReal meanDurationWithin = 0.;
257  SUMOReal meanHaltsPerVehicleWithin = 0.;
258  SUMOReal meanIntervalSpeedWithin = 0.;
259  SUMOReal meanIntervalHaltsPerVehicleWithin = 0.;
260  SUMOReal meanIntervalDurationWithin = 0.;
261  for (std::map<const SUMOVehicle*, E3Values>::iterator i = myEnteredContainer.begin(); i != myEnteredContainer.end(); ++i) {
262  meanHaltsPerVehicleWithin += (SUMOReal)(*i).second.haltings;
263  meanIntervalHaltsPerVehicleWithin += (SUMOReal)(*i).second.intervalHaltings;
264  const SUMOReal end = (*i).second.backLeaveTime == 0 ? STEPS2TIME(stopTime) : (*i).second.backLeaveTime;
265  const SUMOReal time = end - (*i).second.entryTime;
266  const SUMOReal timeWithin = MIN2(time, end - STEPS2TIME(startTime));
267  if (i->second.speedSum > 0.) {
268  meanSpeedWithin += i->second.speedSum / time;
269  }
270  if (i->second.intervalSpeedSum > 0.) {
271  meanIntervalSpeedWithin += i->second.intervalSpeedSum / timeWithin;
272  }
273  meanDurationWithin += time;
274  meanIntervalDurationWithin += timeWithin;
275  // reset interval values
276  (*i).second.intervalHaltings = 0;
277  (*i).second.intervalSpeedSum = 0;
278  }
279  myLastResetTime = stopTime;
280  meanSpeedWithin = vehicleSumWithin != 0 ? meanSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
281  meanHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
282  meanDurationWithin = vehicleSumWithin != 0 ? meanDurationWithin / (SUMOReal) vehicleSumWithin : -1;
283  meanIntervalSpeedWithin = vehicleSumWithin != 0 ? meanIntervalSpeedWithin / (SUMOReal) vehicleSumWithin : -1;
284  meanIntervalHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanIntervalHaltsPerVehicleWithin / (SUMOReal) vehicleSumWithin : -1;
285  meanIntervalDurationWithin = vehicleSumWithin != 0 ? meanIntervalDurationWithin / (SUMOReal) vehicleSumWithin : -1;
286 
287  // write values
288  dev << "meanTravelTime=\"" << meanTravelTime
289  << "\" meanOverlapTravelTime=\"" << meanOverlapTravelTime
290  << "\" meanSpeed=\"" << meanSpeed
291  << "\" meanHaltsPerVehicle=\"" << meanHaltsPerVehicle
292  << "\" vehicleSum=\"" << vehicleSum
293  << "\" meanSpeedWithin=\"" << meanSpeedWithin
294  << "\" meanHaltsPerVehicleWithin=\"" << meanHaltsPerVehicleWithin
295  << "\" meanDurationWithin=\"" << meanDurationWithin
296  << "\" vehicleSumWithin=\"" << vehicleSumWithin
297  << "\" meanIntervalSpeedWithin=\"" << meanIntervalSpeedWithin
298  << "\" meanIntervalHaltsPerVehicleWithin=\"" << meanIntervalHaltsPerVehicleWithin
299  << "\" meanIntervalDurationWithin=\"" << meanIntervalDurationWithin
300  << "\"/>\n";
301 }
302 
303 
304 void
306  dev.writeXMLHeader("e3Detector", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/det_e3_file.xsd\"");
307 }
308 
309 
310 void
312  myCurrentMeanSpeed = 0;
314  for (std::map<const SUMOVehicle*, E3Values>::iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
315  const SUMOVehicle* veh = pair->first;
316  E3Values& values = pair->second;
317  myCurrentMeanSpeed += veh->getSpeed();
318  values.hadUpdate = true;
319  values.speedSum += veh->getSpeed() * TS;
320  values.intervalSpeedSum += veh->getSpeed() * TS;
321  if (veh->getSpeed() < myHaltingSpeedThreshold) {
322  if (values.haltingBegin == -1) {
323  values.haltingBegin = STEPS2TIME(step);
324  }
325  if (step - values.haltingBegin > myHaltingTimeThreshold) {
326  values.haltings++;
327  values.intervalHaltings++;
329  }
330  } else {
331  values.haltingBegin = -1;
332  }
333  }
334  if (myEnteredContainer.size() == 0) {
335  myCurrentMeanSpeed = -1;
336  } else {
338  }
339 }
340 
341 
342 SUMOReal
344  return myCurrentMeanSpeed;
345 }
346 
347 
348 int
351 }
352 
353 
354 int
356  return (int) myEnteredContainer.size();
357 }
358 
359 
360 std::vector<std::string>
362  std::vector<std::string> ret;
363  for (std::map<const SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
364  ret.push_back((*pair).first->getID());
365  }
366  std::sort(ret.begin(), ret.end());
367  return ret;
368 }
369 
370 
371 /****************************************************************************/
372 
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'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:59
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's length [m].
SUMOReal backLeaveTime
The time the vehicle's back was crossing the leave line.
virtual SUMOReal getPreviousSpeed() const =0
Returns the vehicle's previous speed.
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.
#define SIMTIME
Definition: SUMOTime.h:70
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: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's front was crossing the leave line.
Representation of a vehicle.
Definition: SUMOVehicle.h:66
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:69
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
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:55
MSE3LeaveReminder(const MSCrossSection &crossSection, MSE3Collector &collector)
Constructor.
CrossSectionVector myEntries
The detector's entries.
std::string myID
The name of the object.
Definition: Named.h:136
virtual SUMOReal getSpeed() const =0
Returns the vehicle's current speed.
void leaveFront(const SUMOVehicle &veh, const SUMOReal leaveTimestep)
Called if a vehicle front passes a leave-cross-section.
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:214
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.
void detectorUpdate(const SUMOTime step)
Computes the detector values in each time step.
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.
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.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.
std::map< const SUMOVehicle *, E3Values > myLeftContainer
Container for vehicles that have left the area.
SUMOReal myCurrentMeanSpeed
The current mean speed of known vehicles (inside)