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