Eclipse 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-2019 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)) {
78  std::cout << " assume already known\n";
79  }
80 #endif
81  // if the vehicle changes into a covered section we assume it was already registered on another lane
82  return false;
83  }
84  }
85  }
86  return true;
87 }
88 
89 
90 bool
92  double newPos, double newSpeed) {
93 #ifdef DEBUG_E3_NOTIFY_MOVE
94  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
95  std::cout << SIMTIME
96  << " MSE3EntryReminder::notifyMove() (" << getDescription() << "on lane '" << myLane->getID() << "')"
97  << " vehicle '" << veh.getID() << "'"
98  << " entered. oldPos=" << oldPos << " newPos=" << newPos << " newSpeed=" << newSpeed
99  << " myPosition=" << myPosition
100  << "\n";
101  }
102 #endif
103  if (myCollector.myEnteredContainer.find(&veh) == myCollector.myEnteredContainer.end() && newPos > myPosition) {
104  if (oldPos > myPosition) {
105  // was behind the detector already in the last step
106 #ifdef DEBUG_E3_NOTIFY_MOVE
107  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
108  std::cout << " already behind\n";
109  }
110 #endif
111  return false;
112  } else {
113  // entered in this step
114  const double oldSpeed = veh.getPreviousSpeed();
115  const double entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
116  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
117  const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
118  const double fractionTimeOnDet = TS - timeBeforeEnter;
119  myCollector.enter(veh, entryTime - fractionTimeOnDet, fractionTimeOnDet, this);
120 #ifdef DEBUG_E3_NOTIFY_MOVE
121  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
122  std::cout << " enter\n";
123  }
124 #endif
125  }
126  }
127  return true;
128 }
129 
130 
131 bool
133 #ifdef DEBUG_E3_NOTIFY_LEAVE
134  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
135  std::cout << SIMTIME
136  << " MSE3EntryReminder::notifyLeave() (" << getDescription() << "on lane '" << myLane->getID() << "')"
137  << " vehicle '" << veh.getID() << "'"
138  << " reason=" << reason
139  << "\n";
140  }
141 #endif
142  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
143  if (myCollector.myEnteredContainer.erase(&veh) > 0) {
144  WRITE_WARNING("Vehicle '" + veh.getID() + "' arrived inside " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
145  }
146  return false;
147  }
148  return true;
149 }
150 
151 
152 /* -------------------------------------------------------------------------
153  * MSE3Collector::MSE3LeaveReminder - definitions
154  * ----------------------------------------------------------------------- */
156  const MSCrossSection& crossSection, MSE3Collector& collector) :
157  MSMoveReminder(collector.getID() + "_exit", crossSection.myLane),
158  myCollector(collector), myPosition(crossSection.myPosition) {}
159 
160 
161 bool
163 #ifdef DEBUG_E3_NOTIFY_ENTER
164  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
165  std::cout << SIMTIME
166  << " MSE3LeaveReminder::notifyEnter() (" << getDescription() << "on lane '" << myLane->getID() << "')"
167  << " vehicle '" << veh.getID() << "'"
168  << " enteredLane=" << enteredLane->getID()
169  << " reason=" << reason
170  << "\n";
171  }
172 #endif
173  if (reason != NOTIFICATION_JUNCTION) {
174  const double backPosOnLane = veh.getBackPositionOnLane(enteredLane);
175  if (backPosOnLane > myPosition) {
176  // if the vehicle changes into a covered section we assume it was already registered on another lane
177  // however, if it is not fully past the detector we still need to track it
178 #ifdef DEBUG_E3_NOTIFY_ENTER
179  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
180  std::cout << " assume already known\n";
181  }
182 #endif
183  return false;
184  }
185  }
186  return true;
187 }
188 
189 
190 bool
192  double newPos, double newSpeed) {
193 #ifdef DEBUG_E3_NOTIFY_MOVE
194  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
195  std::cout << SIMTIME
196  << " MSE3LeaveReminder::notifyMove() (" << getDescription() << " on lane '" << myLane->getID() << "')"
197  << " vehicle '" << veh.getID() << "'"
198  << " entered. oldPos=" << oldPos << " newPos=" << newPos << " newSpeed=" << newSpeed
199  << " myPosition=" << myPosition
200  << "\n";
201  }
202 #endif
203  if (newPos < myPosition) {
204  // crossSection not yet reached
205  return true;
206  }
207  const double oldSpeed = veh.getPreviousSpeed();
208  if (oldPos < myPosition) {
209  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
210  const double timeBeforeLeave = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
211 // const double leaveTimeFront = SIMTIME - TS + (myPosition - oldPos) / newSpeed;
212  const double leaveTimeFront = SIMTIME - TS + timeBeforeLeave;
213  myCollector.leaveFront(veh, leaveTimeFront);
214 #ifdef DEBUG_E3_NOTIFY_MOVE
215  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
216  std::cout << " leaveFront\n";
217  }
218 #endif
219  }
220  const double backPos = newPos - veh.getVehicleType().getLength();
221  if (backPos < myPosition) {
222  // crossSection not yet left
223  return true;
224  }
225  // crossSection left
226  const double oldBackPos = oldPos - veh.getVehicleType().getLength();
227  const double leaveStep = SIMTIME;
228  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the detector otherwise
229  const double timeBeforeLeave = MSCFModel::passingTime(oldBackPos, myPosition, backPos, oldSpeed, newSpeed);
230  myCollector.leave(veh, leaveStep - TS + timeBeforeLeave, timeBeforeLeave);
231 #ifdef DEBUG_E3_NOTIFY_MOVE
232  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
233  std::cout << " leave\n";
234  }
235 #endif
236  return false;
237 }
238 
239 
240 bool
242 #ifdef DEBUG_E3_NOTIFY_LEAVE
243  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
244  std::cout << SIMTIME
245  << " MSE3LeaveReminder::notifyLeave() (" << getDescription() << "on lane '" << myLane->getID() << "')"
246  << " vehicle '" << veh.getID() << "'"
247  << " reason=" << reason
248  << "\n";
249  }
250 #endif
251  if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE && &enteredLane->getEdge() == &myLane->getEdge()) {
252  // keep the detector when changing while still on the exit detector but already on a new lane (#4803)
253 #ifdef DEBUG_E3_NOTIFY_LEAVE
254  if (DEBUG_COND(myCollector) && DEBUG_COND_VEH(veh)) {
255  std::cout << " remove reminder, keep in container\n";
256  }
257 #endif
258  return false;
259  }
261  WRITE_WARNING("Vehicle '" + veh.getID() + "' teleported from " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
262  myCollector.myEnteredContainer.erase(&veh);
263  return false;
264  }
265  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
266  if (myCollector.myEnteredContainer.erase(&veh) > 0) {
267  WRITE_WARNING("Vehicle '" + veh.getID() + "' arrived inside " + toString(SUMO_TAG_E3DETECTOR) + " '" + myCollector.getID() + "'.");
268  }
269  return false;
270  }
271  return true;
272 }
273 
274 /* -------------------------------------------------------------------------
275  * MSE3Collector - definitions
276  * ----------------------------------------------------------------------- */
277 MSE3Collector::MSE3Collector(const std::string& id,
278  const CrossSectionVector& entries,
279  const CrossSectionVector& exits,
280  double haltingSpeedThreshold,
281  SUMOTime haltingTimeThreshold,
282  const std::string& vTypes,
283  bool openEntry) :
284  MSDetectorFileOutput(id, vTypes), myEntries(entries), myExits(exits),
285  myHaltingTimeThreshold(haltingTimeThreshold), myHaltingSpeedThreshold(haltingSpeedThreshold),
287  myOpenEntry(openEntry) {
288  // Set MoveReminders to entries and exits
289  for (CrossSectionVectorConstIt crossSec1 = entries.begin(); crossSec1 != entries.end(); ++crossSec1) {
290  myEntryReminders.push_back(new MSE3EntryReminder(*crossSec1, *this));
291  }
292  for (CrossSectionVectorConstIt crossSec2 = exits.begin(); crossSec2 != exits.end(); ++crossSec2) {
293  myLeaveReminders.push_back(new MSE3LeaveReminder(*crossSec2, *this));
294  }
295  reset();
296 }
297 
298 
300  for (std::vector<MSE3EntryReminder*>::iterator i = myEntryReminders.begin(); i != myEntryReminders.end(); ++i) {
301  delete *i;
302  }
303  for (std::vector<MSE3LeaveReminder*>::iterator i = myLeaveReminders.begin(); i != myLeaveReminders.end(); ++i) {
304  delete *i;
305  }
306 }
307 
308 
309 void
311  myLeftContainer.clear();
312 }
313 
314 
315 
316 void
317 MSE3Collector::enter(const SUMOTrafficObject& veh, const double entryTimestep, const double fractionTimeOnDet, MSE3EntryReminder* entryReminder) {
318  if (!vehicleApplies(veh)) {
319  return;
320  }
321  if (myEnteredContainer.find(&veh) != myEnteredContainer.end()) {
322  WRITE_WARNING("Vehicle '" + veh.getID() + "' reentered " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "'.");
323  return;
324  }
325  const double speedFraction = veh.getSpeed() * fractionTimeOnDet;
326  E3Values v;
327  v.entryTime = entryTimestep;
328  v.frontLeaveTime = 0;
329  v.backLeaveTime = 0;
330  v.speedSum = speedFraction;
331  v.haltingBegin = veh.getSpeed() < myHaltingSpeedThreshold ? TIME2STEPS(entryTimestep) : -1;
332  v.intervalSpeedSum = entryTimestep >= STEPS2TIME(myLastResetTime) ? speedFraction : 0;
333  v.haltings = 0;
334  v.intervalHaltings = 0;
335  if (veh.getSpeed() < myHaltingSpeedThreshold) {
336  if (fractionTimeOnDet > myHaltingTimeThreshold) {
337  v.haltings++;
338  v.intervalHaltings++;
339  }
340  }
341  v.hadUpdate = false;
342  if (!MSGlobals::gUseMesoSim) {
343  v.timeLoss = static_cast<const MSVehicle&>(veh).getTimeLoss();
345  }
346  v.entryReminder = entryReminder;
347  myEnteredContainer[&veh] = v;
348 }
349 
350 
351 void
352 MSE3Collector::leaveFront(const SUMOTrafficObject& veh, const double leaveTimestep) {
353  if (!vehicleApplies(veh)) {
354  return;
355  }
356  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
357  if (!myOpenEntry) {
358  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
359  }
360  } else {
361  myEnteredContainer[&veh].frontLeaveTime = leaveTimestep;
362  }
363 }
364 
365 
366 void
367 MSE3Collector::leave(const SUMOTrafficObject& veh, const double leaveTimestep, const double fractionTimeOnDet) {
368  if (!vehicleApplies(veh)) {
369  return;
370  }
371  if (myEnteredContainer.find(&veh) == myEnteredContainer.end()) {
372  if (!myOpenEntry) {
373  WRITE_WARNING("Vehicle '" + veh.getID() + "' left " + toString(SUMO_TAG_E3DETECTOR) + " '" + getID() + "' without entering it.");
374  }
375  } else {
376  E3Values values = myEnteredContainer[&veh];
377  values.backLeaveTime = leaveTimestep;
378  const double speedFraction = veh.getSpeed() * (TS - fractionTimeOnDet);
379  values.speedSum -= speedFraction;
380  values.intervalSpeedSum -= speedFraction;
382  // not yet supported
383  values.timeLoss = 0;
384  } else {
385  // timeLoss was initialized when entering
386  values.timeLoss = static_cast<const MSVehicle&>(veh).getTimeLoss() - values.timeLoss;
387  }
388  myEnteredContainer.erase(&veh);
389  myLeftContainer.push_back(values);
390  }
391 }
392 
393 
394 void
396  SUMOTime startTime, SUMOTime stopTime) {
397  dev << " <interval begin=\"" << time2string(startTime) << "\" end=\"" << time2string(stopTime) << "\" " << "id=\"" << myID << "\" ";
398  // collect values about vehicles that have left the area
399  const int vehicleSum = (int) myLeftContainer.size();
400  double meanTravelTime = 0.;
401  double meanOverlapTravelTime = 0.;
402  double meanSpeed = 0.;
403  double meanHaltsPerVehicle = 0.;
404  double meanTimeLoss = 0.;
405  for (const E3Values& values : myLeftContainer) {
406  meanHaltsPerVehicle += (double)values.haltings;
407  meanTravelTime += values.frontLeaveTime - values.entryTime;
408  const double steps = values.backLeaveTime - values.entryTime;
409  meanOverlapTravelTime += steps;
410  meanSpeed += (values.speedSum / steps);
411  meanTimeLoss += STEPS2TIME(values.timeLoss);
412  }
413  meanTravelTime = vehicleSum != 0 ? meanTravelTime / (double)vehicleSum : -1;
414  meanOverlapTravelTime = vehicleSum != 0 ? meanOverlapTravelTime / (double)vehicleSum : -1;
415  meanSpeed = vehicleSum != 0 ? meanSpeed / (double)vehicleSum : -1;
416  meanHaltsPerVehicle = vehicleSum != 0 ? meanHaltsPerVehicle / (double) vehicleSum : -1;
417  meanTimeLoss = vehicleSum != 0 ? meanTimeLoss / (double) vehicleSum : -1;
418  // clear container
419  myLeftContainer.clear();
420 
421  // collect values about vehicles within the container
422  const int vehicleSumWithin = (int) myEnteredContainer.size();
423  double meanSpeedWithin = 0.;
424  double meanDurationWithin = 0.;
425  double meanHaltsPerVehicleWithin = 0.;
426  double meanIntervalSpeedWithin = 0.;
427  double meanIntervalHaltsPerVehicleWithin = 0.;
428  double meanIntervalDurationWithin = 0.;
429  double meanTimeLossWithin = 0.;
430  for (std::map<const SUMOTrafficObject*, E3Values>::iterator i = myEnteredContainer.begin(); i != myEnteredContainer.end(); ++i) {
431  meanHaltsPerVehicleWithin += (double)(*i).second.haltings;
432  meanIntervalHaltsPerVehicleWithin += (double)(*i).second.intervalHaltings;
433  const double end = (*i).second.backLeaveTime == 0 ? STEPS2TIME(stopTime) : (*i).second.backLeaveTime;
434  const double time = end - (*i).second.entryTime;
435  const double timeWithin = MIN2(time, end - STEPS2TIME(startTime));
436  if (i->second.speedSum > 0.) {
437  meanSpeedWithin += i->second.speedSum / time;
438  }
439  if (i->second.intervalSpeedSum > 0.) {
440  meanIntervalSpeedWithin += i->second.intervalSpeedSum / timeWithin;
441  }
442  meanDurationWithin += time;
443  meanIntervalDurationWithin += timeWithin;
444  // reset interval values
445  (*i).second.intervalHaltings = 0;
446  (*i).second.intervalSpeedSum = 0;
447 
448  if (!MSGlobals::gUseMesoSim) {
449  const SUMOTime currentTimeLoss = static_cast<const MSVehicle*>(i->first)->getTimeLoss();
450  meanTimeLossWithin += STEPS2TIME(currentTimeLoss - (*i).second.intervalTimeLoss);
451  (*i).second.intervalTimeLoss = currentTimeLoss;
452  }
453  }
454  myLastResetTime = stopTime;
455  meanSpeedWithin = vehicleSumWithin != 0 ? meanSpeedWithin / (double) vehicleSumWithin : -1;
456  meanHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanHaltsPerVehicleWithin / (double) vehicleSumWithin : -1;
457  meanDurationWithin = vehicleSumWithin != 0 ? meanDurationWithin / (double) vehicleSumWithin : -1;
458  meanIntervalSpeedWithin = vehicleSumWithin != 0 ? meanIntervalSpeedWithin / (double) vehicleSumWithin : -1;
459  meanIntervalHaltsPerVehicleWithin = vehicleSumWithin != 0 ? meanIntervalHaltsPerVehicleWithin / (double) vehicleSumWithin : -1;
460  meanIntervalDurationWithin = vehicleSumWithin != 0 ? meanIntervalDurationWithin / (double) vehicleSumWithin : -1;
461  meanTimeLossWithin = vehicleSumWithin != 0 ? meanTimeLossWithin / (double) vehicleSumWithin : -1;
462 
463  // write values
464  dev << "meanTravelTime=\"" << meanTravelTime
465  << "\" meanOverlapTravelTime=\"" << meanOverlapTravelTime
466  << "\" meanSpeed=\"" << meanSpeed
467  << "\" meanHaltsPerVehicle=\"" << meanHaltsPerVehicle
468  << "\" meanTimeLoss=\"" << meanTimeLoss
469  << "\" vehicleSum=\"" << vehicleSum
470  << "\" meanSpeedWithin=\"" << meanSpeedWithin
471  << "\" meanHaltsPerVehicleWithin=\"" << meanHaltsPerVehicleWithin
472  << "\" meanDurationWithin=\"" << meanDurationWithin
473  << "\" vehicleSumWithin=\"" << vehicleSumWithin
474  << "\" meanIntervalSpeedWithin=\"" << meanIntervalSpeedWithin
475  << "\" meanIntervalHaltsPerVehicleWithin=\"" << meanIntervalHaltsPerVehicleWithin
476  << "\" meanIntervalDurationWithin=\"" << meanIntervalDurationWithin
477  << "\" meanTimeLossWithin=\"" << meanTimeLossWithin
478  << "\"/>\n";
479 }
480 
481 
482 void
484  dev.writeXMLHeader("e3Detector", "det_e3_file.xsd");
485 }
486 
487 
488 void
490  myCurrentMeanSpeed = 0;
492  for (std::map<const SUMOTrafficObject*, E3Values>::iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
493  const SUMOTrafficObject* veh = pair->first;
494 #ifdef DEBUG_E3_DETECTORUPDATE
495  //if (DEBUG_COND(*this) && DEBUG_COND_VEH(*veh)) {
496  if (DEBUG_COND(*this)) {
497  std::cout << SIMTIME << " vehPtr=" << veh << "\n";
498  std::cout << " veh=" << veh->getID() << "\n";
499  }
500 #endif
501  E3Values& values = pair->second;
502  myCurrentMeanSpeed += veh->getSpeed();
503  values.hadUpdate = true;
504  values.speedSum += veh->getSpeed() * TS;
505  values.intervalSpeedSum += veh->getSpeed() * TS;
506  if (veh->getSpeed() < myHaltingSpeedThreshold) {
507  if (values.haltingBegin == -1) {
508  values.haltingBegin = step;
509  }
510  SUMOTime haltingDuration = step - values.haltingBegin;
511  if (haltingDuration >= myHaltingTimeThreshold
512  && haltingDuration < (myHaltingTimeThreshold + DELTA_T)) {
513  values.haltings++;
514  values.intervalHaltings++;
516  }
517  } else {
518  values.haltingBegin = -1;
519  }
520  }
521  if (myEnteredContainer.size() == 0) {
522  myCurrentMeanSpeed = -1;
523  } else {
525  }
526 }
527 
528 
529 double
531  return myCurrentMeanSpeed;
532 }
533 
534 
535 int
538 }
539 
540 
541 int
543  return (int) myEnteredContainer.size();
544 }
545 
546 
547 std::vector<std::string>
549  std::vector<std::string> ret;
550  for (std::map<const SUMOTrafficObject*, E3Values>::const_iterator pair = myEnteredContainer.begin(); pair != myEnteredContainer.end(); ++pair) {
551  ret.push_back((*pair).first->getID());
552  }
553  std::sort(ret.begin(), ret.end());
554  return ret;
555 }
556 
557 
558 /****************************************************************************/
559 
double intervalSpeedSum
The sum of registered speeds the vehicle has/had inside the area during the current interval...
bool vehicleApplies(const SUMOTrafficObject &veh) const
Checks whether the detector measures vehicles of the given type.
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:670
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
long long int SUMOTime
Definition: SUMOTime.h:35
bool notifyMove(SUMOTrafficObject &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.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Processes state changes of a vehicle.
A simple description of a position on a lane (crossing of a lane)
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
std::vector< MSE3EntryReminder * > myEntryReminders
The detector&#39;s built entry reminder.
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.
void leaveFront(const SUMOTrafficObject &veh, const double leaveTimestep)
Called if a vehicle front passes a leave-cross-section.
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:168
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:77
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
std::vector< MSE3LeaveReminder * > myLeaveReminders
The detector&#39;s built exit reminder.
#define TS
Definition: SUMOTime.h:44
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
#define SIMTIME
Definition: SUMOTime.h:64
double backLeaveTime
The time the vehicle&#39;s back was crossing the leave line.
virtual double getBackPositionOnLane(const MSLane *lane) const =0
Get the vehicle&#39;s back position along the given lane.
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:48
Internal storage for values from a vehicle.
void leave(const SUMOTrafficObject &veh, const double leaveTimestep, const double fractionTimeOnDet)
Called if a vehicle back passes a leave-cross-section.
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.
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:57
T MIN2(T a, T b)
Definition: StdDefs.h:74
const bool myOpenEntry
whether this dector is declared as having incomplete entry detectors
bool notifyEnter(SUMOTrafficObject &veh, Notification reason, const MSLane *enteredLane)
Checks whether the reminder is activated by a vehicle entering the lane.
MSE3Collector & myCollector
The parent collector.
Something on a lane to be noticed about vehicle movement.
#define DEBUG_COND
Definition: Vehicle.cpp:55
MSE3LeaveReminder(const MSCrossSection &crossSection, MSE3Collector &collector)
Constructor.
std::vector< E3Values > myLeftContainer
Container for vehicles that have left the area.
virtual double getPreviousSpeed() const =0
Returns the vehicle&#39;s previous speed.
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.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Processes state changes of a vehicle.
bool notifyEnter(SUMOTrafficObject &veh, Notification reason, const MSLane *enteredLane)
Checks whether the reminder is activated by a vehicle entering 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
std::string myID
The name of the object.
Definition: Named.h:134
Representation of a vehicle or person.
double speedSum
The sum of registered speeds the vehicle has/had inside the area.
const std::string & getDescription() const
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double)
Checks whether the vehicle leaves.
std::map< const SUMOTrafficObject *, E3Values > myEnteredContainer
Container for vehicles that have entered the area.
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
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.
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:83
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.
void enter(const SUMOTrafficObject &veh, const double entryTimestep, const double fractionTimeOnDet, MSE3EntryReminder *entryReminder)
Called if a vehicle touches an entry-cross-section.