SUMO - Simulation of Urban MObility
MSE3Collector.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
19 // A detector of vehicles passing an area between entry/exit points
20 /****************************************************************************/
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <algorithm>
28 
29 #include "MSE3Collector.h"
30 #include <microsim/MSNet.h>
31 #include <microsim/MSVehicle.h>
32 
33 //#define DEBUG_E3_NOTIFY_MOVE
34 //#define DEBUG_E3_NOTIFY_ENTER
35 //#define DEBUG_E3_NOTIFY_LEAVE
36 //#define DEBUG_E3_DETECTORUPDATE
37 
38 //#define DEBUG_COND(obj) ((obj.getID() == ""))
39 //#define DEBUG_COND_VEH(veh) ((veh).getID() == "")
40 //#define DEBUG_COND_VEH(veh) ((veh).isSelected())
41 //#define DEBUG_COND(collector) (true)
42 //#define DEBUG_COND_VEH(veh) (true)
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 
58 bool
60 #ifdef DEBUG_E3_NOTIFY_ENTER
61  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
62  std::cout << SIMTIME
63  << " MSE3EntryReminder::notifyEnter() (" << getDescription() << "on lane '" << myLane->getID() << "')"
64  << " vehicle '" << veh.getID() << "'"
65  << " enteredLane=" << enteredLane->getID()
66  << " reason=" << reason
67  << "\n";
68  }
69 #endif
70  if (reason != NOTIFICATION_JUNCTION) {
71  const double posOnLane = veh.getBackPositionOnLane(enteredLane) + veh.getVehicleType().getLength();
72  if (myLane == enteredLane && posOnLane > myPosition) {
73  const auto& itVeh = myCollector.myEnteredContainer.find(&veh);
74  if (itVeh == myCollector.myEnteredContainer.end() ||
75  itVeh->second.entryReminder != this) {
76 #ifdef DEBUG_E3_NOTIFY_ENTER
77  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) std::cout << " assume already known\n";
78 #endif
79  // if the vehicle changes into a covered section we assume it was already registered on another lane
80  return false;
81  }
82  }
83  }
84  return true;
85 }
86 
87 
88 bool
90  double newPos, double newSpeed) {
91 #ifdef DEBUG_E3_NOTIFY_MOVE
92  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
93  std::cout << SIMTIME
94  << " MSE3EntryReminder::notifyMove() (" << getDescription() << "on lane '" << myLane->getID() << "')"
95  << " vehicle '" << veh.getID() << "'"
96  << " entered. oldPos=" << oldPos << " newPos=" << newPos << " newSpeed=" << newSpeed
97  << " myPosition=" << myPosition
98  << "\n";
99  }
100 #endif
101  if (myCollector.myEnteredContainer.find(&veh) == myCollector.myEnteredContainer.end() && newPos > myPosition) {
102  if (oldPos > myPosition) {
103  // was behind the detector already in the last step
104 #ifdef DEBUG_E3_NOTIFY_MOVE
105  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) std::cout << " already behind\n";
106 #endif
107  return false;
108  } else {
109  // entered in this step
110  const double oldSpeed = veh.getPreviousSpeed();
111  const double entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
112  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
113  const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
114  const double fractionTimeOnDet = TS - timeBeforeEnter;
115  myCollector.enter(veh, entryTime - fractionTimeOnDet, fractionTimeOnDet, this);
116 #ifdef DEBUG_E3_NOTIFY_MOVE
117  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) std::cout << " enter\n";
118 #endif
119  }
120  }
121  return true;
122 }
123 
124 
125 bool
127 #ifdef DEBUG_E3_NOTIFY_LEAVE
128  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
129  std::cout << SIMTIME
130  << " MSE3EntryReminder::notifyLeave() (" << getDescription() << "on lane '" << myLane->getID() << "')"
131  << " vehicle '" << veh.getID() << "'"
132  << " reason=" << reason
133  << "\n";
134  }
135 #endif
136  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
137  if (myCollector.myEnteredContainer.erase(&veh) > 0) {
138  WRITE_WARNING("Vehicle '" + veh.getID() + "' arrived inside " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
139  }
140  return false;
141  }
142  return true;
143 }
144 
145 
146 /* -------------------------------------------------------------------------
147  * MSE3Collector::MSE3LeaveReminder - definitions
148  * ----------------------------------------------------------------------- */
150  const MSCrossSection& crossSection, MSE3Collector& collector) :
151  MSMoveReminder(collector.getID() + "_exit", crossSection.myLane),
152  myCollector(collector), myPosition(crossSection.myPosition) {}
153 
154 
155 bool
157 #ifdef DEBUG_E3_NOTIFY_ENTER
158  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
159  std::cout << SIMTIME
160  << " MSE3LeaveReminder::notifyEnter() (" << getDescription() << "on lane '" << myLane->getID() << "')"
161  << " vehicle '" << veh.getID() << "'"
162  << " enteredLane=" << enteredLane->getID()
163  << " reason=" << reason
164  << "\n";
165  }
166 #endif
167  if (reason != NOTIFICATION_JUNCTION) {
168  const double backPosOnLane = veh.getBackPositionOnLane(enteredLane);
169  if (backPosOnLane > myPosition) {
170  // if the vehicle changes into a covered section we assume it was already registered on another lane
171  // however, if it is not fully past the detector we still need to track it
172 #ifdef DEBUG_E3_NOTIFY_ENTER
173  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) std::cout << " assume already known\n";
174 #endif
175  return false;
176  }
177  }
178  return true;
179 }
180 
181 
182 bool
184  double newPos, double newSpeed) {
185 #ifdef DEBUG_E3_NOTIFY_MOVE
186  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
187  std::cout << SIMTIME
188  << " MSE3LeaveReminder::notifyMove() (" << getDescription() << " on lane '" << myLane->getID() << "')"
189  << " vehicle '" << veh.getID() << "'"
190  << " entered. oldPos=" << oldPos << " newPos=" << newPos << " newSpeed=" << newSpeed
191  << " myPosition=" << myPosition
192  << "\n";
193  }
194 #endif
195  if (newPos < myPosition) {
196  // crossSection not yet reached
197  return true;
198  }
199  const double oldSpeed = veh.getPreviousSpeed();
200  if (oldPos < myPosition) {
201  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
202  const double timeBeforeLeave = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
203 // const double leaveTimeFront = SIMTIME - TS + (myPosition - oldPos) / newSpeed;
204  const double leaveTimeFront = SIMTIME - TS + timeBeforeLeave;
205  myCollector.leaveFront(veh, leaveTimeFront);
206 #ifdef DEBUG_E3_NOTIFY_MOVE
207  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) std::cout << " leaveFront\n";
208 #endif
209  }
210  const double backPos = newPos - veh.getVehicleType().getLength();
211  if (backPos < myPosition) {
212  // crossSection not yet left
213  return true;
214  }
215  // crossSection left
216  const double oldBackPos = oldPos - veh.getVehicleType().getLength();
217  const double leaveStep = SIMTIME;
218  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
219  const double timeBeforeLeave = MSCFModel::passingTime(oldBackPos, myPosition, backPos, oldSpeed, newSpeed);
220  myCollector.leave(veh, leaveStep - TS + timeBeforeLeave, timeBeforeLeave);
221 #ifdef DEBUG_E3_NOTIFY_MOVE
222  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) std::cout << " leave\n";
223 #endif
224  return false;
225 }
226 
227 
228 bool
229 MSE3Collector::MSE3LeaveReminder::notifyLeave(SUMOVehicle& veh , double /* lastPos */, MSMoveReminder::Notification reason, const MSLane* enteredLane) {
230 #ifdef DEBUG_E3_NOTIFY_LEAVE
231  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
232  std::cout << SIMTIME
233  << " MSE3LeaveReminder::notifyLeave() (" << getDescription() << "on lane '" << myLane->getID() << "')"
234  << " vehicle '" << veh.getID() << "'"
235  << " reason=" << reason
236  << "\n";
237  }
238 #endif
239  if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE && &enteredLane->getEdge() == &myLane->getEdge()) {
240  // keep the detector when changing while still on the exit detector but already on a new lane (#4803)
241 #ifdef DEBUG_E3_NOTIFY_LEAVE
242  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) std::cout << " remove reminder, keep in container\n";
243 #endif
244  return false;
245  }
247  WRITE_WARNING("Vehicle '" + veh.getID() + "' teleported from " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
248  myCollector.myEnteredContainer.erase(&veh);
249  return false;
250  }
251  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
252  if (myCollector.myEnteredContainer.erase(&veh) > 0) {
253  WRITE_WARNING("Vehicle '" + veh.getID() + "' arrived inside " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
254  }
255  return false;
256  }
257  return true;
258 }
259 
260 /* -------------------------------------------------------------------------
261  * MSE3Collector - definitions
262  * ----------------------------------------------------------------------- */
263 MSE3Collector::MSE3Collector(const std::string& id,
264  const CrossSectionVector& entries,
265  const CrossSectionVector& exits,
266  double haltingSpeedThreshold,
267  SUMOTime haltingTimeThreshold,
268  const std::string& vTypes,
269  bool openEntry) :
270  MSDetectorFileOutput(id, vTypes), myEntries(entries), myExits(exits),
271  myHaltingTimeThreshold(haltingTimeThreshold), myHaltingSpeedThreshold(haltingSpeedThreshold),
273  myOpenEntry(openEntry) {
274  // Set MoveReminders to entries and exits
275  for (CrossSectionVectorConstIt crossSec1 = entries.begin(); crossSec1 != entries.end(); ++crossSec1) {
276  myEntryReminders.push_back(new MSE3EntryReminder(*crossSec1, *this));
277  }
278  for (CrossSectionVectorConstIt crossSec2 = exits.begin(); crossSec2 != exits.end(); ++crossSec2) {
279  myLeaveReminders.push_back(new MSE3LeaveReminder(*crossSec2, *this));
280  }
281  reset();
282 }
283 
284 
286  for (std::vector<MSE3EntryReminder*>::iterator i = myEntryReminders.begin(); i != myEntryReminders.end(); ++i) {
287  delete *i;
288  }
289  for (std::vector<MSE3LeaveReminder*>::iterator i = myLeaveReminders.begin(); i != myLeaveReminders.end(); ++i) {
290  delete *i;
291  }
292 }
293 
294 
295 void
297  myLeftContainer.clear();
298 }
299 
300 
301 
302 void
303 MSE3Collector::enter(const SUMOVehicle& veh, const double entryTimestep, const double fractionTimeOnDet, MSE3EntryReminder* entryReminder) {
304  if (!vehicleApplies(veh)) {
305  return;
306  }
307  if (myEnteredContainer.find(&veh) != myEnteredContainer.end()) {
308  WRITE_WARNING("Vehicle '" + veh.getID() + "' reentered " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "'.");
309  return;
310  }
311  const double speedFraction = veh.getSpeed() * fractionTimeOnDet;
312  E3Values v;
313  v.entryTime = entryTimestep;
314  v.frontLeaveTime = 0;
315  v.backLeaveTime = 0;
316  v.speedSum = speedFraction;
317  v.haltingBegin = veh.getSpeed() < myHaltingSpeedThreshold ? TIME2STEPS(entryTimestep) : -1;
318  v.intervalSpeedSum = entryTimestep >= STEPS2TIME(myLastResetTime) ? speedFraction : 0;
319  v.haltings = 0;
320  v.intervalHaltings = 0;
321  if (veh.getSpeed() < myHaltingSpeedThreshold) {
322  if (fractionTimeOnDet > myHaltingTimeThreshold) {
323  v.haltings++;
324  v.intervalHaltings++;
325  }
326  }
327  v.hadUpdate = false;
328  if (!MSGlobals::gUseMesoSim) {
329  v.timeLoss = static_cast<const MSVehicle&>(veh).getTimeLoss();
331  }
332  v.entryReminder = entryReminder;
333  myEnteredContainer[&veh] = v;
334 }
335 
336 
337 void
338 MSE3Collector::leaveFront(const SUMOVehicle& veh, const double leaveTimestep) {
339  if (!vehicleApplies(veh)) {
340  return;
341  }
342  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
343  if (!myOpenEntry) {
344  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
345  }
346  } else {
347  myEnteredContainer[&veh].frontLeaveTime = leaveTimestep;
348  }
349 }
350 
351 
352 void
353 MSE3Collector::leave(const SUMOVehicle& veh, const double leaveTimestep, const double fractionTimeOnDet) {
354  if (!vehicleApplies(veh)) {
355  return;
356  }
357  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
358  if (!myOpenEntry) {
359  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
360  }
361  } else {
362  E3Values values = myEnteredContainer[&veh];
363  values.backLeaveTime = leaveTimestep;
364  const double speedFraction = veh.getSpeed() * (TS - fractionTimeOnDet);
365  values.speedSum -= speedFraction;
366  values.intervalSpeedSum -= speedFraction;
368  // not yet supported
369  values.timeLoss = 0;
370  } else {
371  // timeLoss was initialized when entering
372  values.timeLoss = static_cast<const MSVehicle&>(veh).getTimeLoss() - values.timeLoss;
373  }
374  myEnteredContainer.erase(&veh);
375  myLeftContainer.push_back(values);
376  }
377 }
378 
379 
380 void
382  SUMOTime startTime, SUMOTime stopTime) {
383  dev << " <interval begin=\"" << time2string(startTime) << "\" end=\"" << time2string(stopTime) << "\" " << "id=\"" << myID << "\" ";
384  // collect values about vehicles that have left the area
385  const int vehicleSum = (int) myLeftContainer.size();
386  double meanTravelTime = 0.;
387  double meanOverlapTravelTime = 0.;
388  double meanSpeed = 0.;
389  double meanHaltsPerVehicle = 0.;
390  double meanTimeLoss = 0.;
391  for (const E3Values& values : myLeftContainer) {
392  meanHaltsPerVehicle += (double)values.haltings;
393  meanTravelTime += values.frontLeaveTime - values.entryTime;
394  const double steps = values.backLeaveTime - values.entryTime;
395  meanOverlapTravelTime += steps;
396  meanSpeed += (values.speedSum / steps);
397  meanTimeLoss += STEPS2TIME(values.timeLoss);
398  }
399  meanTravelTime = vehicleSum != 0 ? meanTravelTime / (double)vehicleSum : -1;
400  meanOverlapTravelTime = vehicleSum != 0 ? meanOverlapTravelTime / (double)vehicleSum : -1;
401  meanSpeed = vehicleSum != 0 ? meanSpeed / (double)vehicleSum : -1;
402  meanHaltsPerVehicle = vehicleSum != 0 ? meanHaltsPerVehicle / (double) vehicleSum : -1;
403  meanTimeLoss = vehicleSum != 0 ? meanTimeLoss / (double) vehicleSum : -1;
404  // clear container
405  myLeftContainer.clear();
406 
407  // collect values about vehicles within the container
408  const int vehicleSumWithin = (int) myEnteredContainer.size();
409  double meanSpeedWithin = 0.;
410  double meanDurationWithin = 0.;
411  double meanHaltsPerVehicleWithin = 0.;
412  double meanIntervalSpeedWithin = 0.;
413  double meanIntervalHaltsPerVehicleWithin = 0.;
414  double meanIntervalDurationWithin = 0.;
415  double meanTimeLossWithin = 0.;
416  for (std::map<const SUMOVehicle*, E3Values>::iterator i = myEnteredContainer.begin(); i != myEnteredContainer.end(); ++i) {
417  meanHaltsPerVehicleWithin += (double)(*i).second.haltings;
418  meanIntervalHaltsPerVehicleWithin += (double)(*i).second.intervalHaltings;
419  const double end = (*i).second.backLeaveTime == 0 ? STEPS2TIME(stopTime) : (*i).second.backLeaveTime;
420  const double time = end - (*i).second.entryTime;
421  const double timeWithin = MIN2(time, end - STEPS2TIME(startTime));
422  if (i->second.speedSum > 0.) {
423  meanSpeedWithin += i->second.speedSum / time;
424  }
425  if (i->second.intervalSpeedSum > 0.) {
426  meanIntervalSpeedWithin += i->second.intervalSpeedSum / timeWithin;
427  }
428  meanDurationWithin += time;
429  meanIntervalDurationWithin += timeWithin;
430  // reset interval values
431  (*i).second.intervalHaltings = 0;
432  (*i).second.intervalSpeedSum = 0;
433 
434  if (!MSGlobals::gUseMesoSim) {
435  const SUMOTime currentTimeLoss = static_cast<const MSVehicle*>(i->first)->getTimeLoss();
436  meanTimeLossWithin += STEPS2TIME(currentTimeLoss - (*i).second.intervalTimeLoss);
437  (*i).second.intervalTimeLoss = currentTimeLoss;
438  }
439  }
440  myLastResetTime = stopTime;
441  meanSpeedWithin = vehicleSumWithin != 0 ? meanSpeedWithin / (double) vehicleSumWithin : -1;
442  meanHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanHaltsPerVehicleWithin / (double) vehicleSumWithin : -1;
443  meanDurationWithin = vehicleSumWithin != 0 ? meanDurationWithin / (double) vehicleSumWithin : -1;
444  meanIntervalSpeedWithin = vehicleSumWithin != 0 ? meanIntervalSpeedWithin / (double) vehicleSumWithin : -1;
445  meanIntervalHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanIntervalHaltsPerVehicleWithin / (double) vehicleSumWithin : -1;
446  meanIntervalDurationWithin = vehicleSumWithin != 0 ? meanIntervalDurationWithin / (double) vehicleSumWithin : -1;
447  meanTimeLossWithin = vehicleSumWithin != 0 ? meanTimeLossWithin / (double) vehicleSumWithin : -1;
448 
449  // write values
450  dev << "meanTravelTime=\"" << meanTravelTime
451  << "\" meanOverlapTravelTime=\"" << meanOverlapTravelTime
452  << "\" meanSpeed=\"" << meanSpeed
453  << "\" meanHaltsPerVehicle=\"" << meanHaltsPerVehicle
454  << "\" meanTimeLoss=\"" << meanTimeLoss
455  << "\" vehicleSum=\"" << vehicleSum
456  << "\" meanSpeedWithin=\"" << meanSpeedWithin
457  << "\" meanHaltsPerVehicleWithin=\"" << meanHaltsPerVehicleWithin
458  << "\" meanDurationWithin=\"" << meanDurationWithin
459  << "\" vehicleSumWithin=\"" << vehicleSumWithin
460  << "\" meanIntervalSpeedWithin=\"" << meanIntervalSpeedWithin
461  << "\" meanIntervalHaltsPerVehicleWithin=\"" << meanIntervalHaltsPerVehicleWithin
462  << "\" meanIntervalDurationWithin=\"" << meanIntervalDurationWithin
463  << "\" meanTimeLossWithin=\"" << meanTimeLossWithin
464  << "\"/>\n";
465 }
466 
467 
468 void
470  dev.writeXMLHeader("e3Detector", "det_e3_file.xsd");
471 }
472 
473 
474 void
476  myCurrentMeanSpeed = 0;
478  for (std::map<const SUMOVehicle*, E3Values>::iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
479  const SUMOVehicle* veh = pair->first;
480 #ifdef DEBUG_E3_DETECTORUPDATE
481  //if (DEBUG_COND(*this) && DEBUG_COND_VEH(*veh)) {
482  if (DEBUG_COND(*this)) {
483  std::cout << SIMTIME << " vehPtr=" << veh << "\n";
484  std::cout << " veh=" << veh->getID() << "\n";
485  }
486 #endif
487  E3Values& values = pair->second;
488  myCurrentMeanSpeed += veh->getSpeed();
489  values.hadUpdate = true;
490  values.speedSum += veh->getSpeed() * TS;
491  values.intervalSpeedSum += veh->getSpeed() * TS;
492  if (veh->getSpeed() < myHaltingSpeedThreshold) {
493  if (values.haltingBegin == -1) {
494  values.haltingBegin = step;
495  }
496  SUMOTime haltingDuration = step - values.haltingBegin;
497  if (haltingDuration >= myHaltingTimeThreshold
498  && haltingDuration < (myHaltingTimeThreshold + DELTA_T)) {
499  values.haltings++;
500  values.intervalHaltings++;
502  }
503  } else {
504  values.haltingBegin = -1;
505  }
506  }
507  if (myEnteredContainer.size() == 0) {
508  myCurrentMeanSpeed = -1;
509  } else {
511  }
512 }
513 
514 
515 double
517  return myCurrentMeanSpeed;
518 }
519 
520 
521 int
524 }
525 
526 
527 int
529  return (int) myEnteredContainer.size();
530 }
531 
532 
533 std::vector<std::string>
535  std::vector<std::string> ret;
536  for (std::map<const SUMOVehicle*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
537  ret.push_back((*pair).first->getID());
538  }
539  std::sort(ret.begin(), ret.end());
540  return ret;
541 }
542 
543 
544 /****************************************************************************/
545 
double intervalSpeedSum
The sum of registered speeds the vehicle has/had inside the area during the current interval...
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:640
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
long long int SUMOTime
Definition: SUMOTime.h:36
bool notifyMove(SUMOVehicle &veh, double, double newPos, double)
Checks whether the vehicle enters.
int haltings
The sum of haltings the vehicle has/had within the area.
int getCurrentHaltingNumber() const
Returns the number of current haltings within the area.
virtual ~MSE3Collector()
Destructor.
A simple description of a position on a lane (crossing of a lane)
std::vector< MSE3EntryReminder * > myEntryReminders
The detector&#39;s built entry reminder.
bool vehicleApplies(const SUMOVehicle &veh) const
Checks whether the detector measures vehicles of the given type.
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.
The vehicle arrived at a junction.
A place on the road net (at a certain lane and position on it) where the E3 area begins.
Definition: MSE3Collector.h:64
MSLane *const myLane
Lane on which the reminder works.
double myHaltingSpeedThreshold
Speed-threshold to determine if a vehicle is halting.
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
std::vector< MSCrossSection > CrossSectionVector
double frontLeaveTime
The time the vehicle&#39;s front was crossing the leave line.
double myCurrentMeanSpeed
The current mean speed of known vehicles (inside)
CrossSectionVector::const_iterator CrossSectionVectorConstIt
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:165
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
SUMOTime myLastResetTime
Information when the last reset has been done.
std::vector< std::string > getCurrentVehicleIDs() const
Returns the number of vehicles within the area.
const std::string & getID() const
Returns the id.
Definition: Named.h:78
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
std::vector< MSE3LeaveReminder * > myLeaveReminders
The detector&#39;s built exit reminder.
#define TS
Definition: SUMOTime.h:45
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Processes state changes of a vehicle.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
#define SIMTIME
Definition: SUMOTime.h:65
double backLeaveTime
The time the vehicle&#39;s back was crossing the leave line.
int myCurrentHaltingsNumber
The current number of haltings (inside)
The vehicle changes lanes (micro only)
MSE3EntryReminder * entryReminder
the reminder on which the vehicle entered the detector
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
Representation of a vehicle.
Definition: SUMOVehicle.h:60
std::map< const SUMOVehicle *, E3Values > myEnteredContainer
Container for vehicles that have entered the area.
Internal storage for values from a vehicle.
double entryTime
The vehicle&#39;s entry time.
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.
void enter(const SUMOVehicle &veh, const double entryTimestep, const double fractionTimeOnDet, MSE3EntryReminder *entryReminder)
Called if a vehicle touches an entry-cross-section.
bool notifyEnter(SUMOVehicle &veh, Notification reason, const MSLane *enteredLane)
Checks whether the reminder is activated by a vehicle entering the lane.
double getCurrentMeanSpeed() const
Returns the mean speed within the area.
SUMOTime myHaltingTimeThreshold
The vehicle arrived at its destination (is deleted)
MSE3Collector(const std::string &id, const CrossSectionVector &entries, const CrossSectionVector &exits, double haltingSpeedThreshold, SUMOTime haltingTimeThreshold, const std::string &vTypes, bool openEntry)
Constructor.
#define STEPS2TIME(x)
Definition: SUMOTime.h:58
T MIN2(T a, T b)
Definition: StdDefs.h:70
const bool myOpenEntry
whether this dector is declared as having incomplete entry detectors
MSE3Collector & myCollector
The parent collector.
Something on a lane to be noticed about vehicle movement.
bool notifyMove(SUMOVehicle &veh, double oldPos, double newPos, double)
Checks whether the vehicle leaves.
MSE3LeaveReminder(const MSCrossSection &crossSection, MSE3Collector &collector)
Constructor.
void leaveFront(const SUMOVehicle &veh, const double leaveTimestep)
Called if a vehicle front passes a leave-cross-section.
void leave(const SUMOVehicle &veh, const double leaveTimestep, const double fractionTimeOnDet)
Called if a vehicle back passes a leave-cross-section.
std::vector< E3Values > myLeftContainer
Container for vehicles that have left the area.
SUMOTime haltingBegin
Begin time of last halt begin.
SUMOTime intervalTimeLoss
The timeLoss of the vehicle when entering. Updated to the current timeLoss at interval write...
CrossSectionVector myEntries
The detector&#39;s entries.
double myPosition
The position on the lane.
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
Definition: MSCFModel.cpp:597
virtual double getBackPositionOnLane(const MSLane *lane) const =0
Get the vehicle&#39;s back position along the given lane.
std::string myID
The name of the object.
Definition: Named.h:130
double speedSum
The sum of registered speeds the vehicle has/had inside the area.
const std::string & getDescription() const
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Processes state changes of a vehicle.
double getLength() const
Get vehicle&#39;s length [m].
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:58
bool notifyEnter(SUMOVehicle &veh, Notification reason, const MSLane *enteredLane)
Checks whether the reminder is activated by a vehicle entering the lane.
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:64
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:56
int getVehiclesWithin() const
Returns the number of vehicles within the area.
#define DEBUG_COND
Definition: MESegment.cpp:54
void detectorUpdate(const SUMOTime step)
Computes the detector values in each time step.
virtual double getSpeed() const =0
Returns the vehicle&#39;s current speed.
static bool gUseMesoSim
Definition: MSGlobals.h:91
Representation of a lane in the micro simulation.
Definition: MSLane.h:78
virtual double getPreviousSpeed() const =0
Returns the vehicle&#39;s previous speed.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
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)
double myPosition
The position on the lane.
The vehicle is being teleported.
CrossSectionVector myExits
The detector&#39;s exits.
void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using "e3Detector" as root element.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.