Eclipse SUMO - Simulation of Urban MObility
MSMeanData.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 // Data collector for edges/lanes
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <limits>
29 #include <microsim/MSEdgeControl.h>
30 #include <microsim/MSEdge.h>
31 #include <microsim/MSLane.h>
32 #include <microsim/MSVehicle.h>
34 #include <microsim/MSNet.h>
35 #include <utils/common/SUMOTime.h>
36 #include <utils/common/ToString.h>
38 #include "MSMeanData_Amitran.h"
39 #include "MSMeanData.h"
40 
41 #include <microsim/MSGlobals.h>
42 #include <mesosim/MESegment.h>
43 #include <mesosim/MELoop.h>
44 
45 
46 // ===========================================================================
47 // debug constants
48 // ===========================================================================
49 //#define DEBUG_NOTIFY_MOVE
50 //#define DEBUG_NOTIFY_ENTER
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
55 // ---------------------------------------------------------------------------
56 // MSMeanData::MeanDataValues - methods
57 // ---------------------------------------------------------------------------
59  MSLane* const lane, const double length, const bool doAdd,
60  const MSMeanData* const parent) :
61  MSMoveReminder("meandata_" + (lane == nullptr ? "NULL" : lane->getID()), lane, doAdd),
62  myParent(parent),
63  myLaneLength(length),
64  sampleSeconds(0),
65  travelledDistance(0) {}
66 
67 
69 }
70 
71 
72 bool
74 #ifdef DEBUG_NOTIFY_ENTER
75  std::cout << "\n" << SIMTIME << " MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
76 #else
77  UNUSED_PARAMETER(enteredLane);
78 #endif
79  UNUSED_PARAMETER(reason);
80  return myParent == nullptr || myParent->vehicleApplies(veh);
81 }
82 
83 
84 bool
85 MSMeanData::MeanDataValues::notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed) {
86  // if the vehicle has arrived, the reminder must be kept so it can be
87  // notified of the arrival subsequently
88  const double oldSpeed = veh.getPreviousSpeed();
89  double enterSpeed = MSGlobals::gSemiImplicitEulerUpdate ? newSpeed : oldSpeed; // NOTE: For the euler update, the vehicle is assumed to travel at constant speed for the whole time step
90  double leaveSpeed = newSpeed, leaveSpeedFront = newSpeed;
91 
92  // These values will be further decreased below
93  double timeOnLane = TS;
94  double frontOnLane = oldPos > myLaneLength ? 0. : TS;
95  bool ret = true;
96 
97  // entry and exit times (will be modified below)
98  double timeBeforeEnter = 0.;
99  double timeBeforeEnterBack = 0.;
100  double timeBeforeLeaveFront = newPos < myLaneLength ? TS : 0.;
101  double timeBeforeLeave = TS;
102 
103  // Treat the case that the vehicle entered the lane in the last step
104  if (oldPos < 0 && newPos >= 0) {
105  // Vehicle was not on this lane in the last time step
106  timeBeforeEnter = MSCFModel::passingTime(oldPos, 0, newPos, oldSpeed, newSpeed);
107  timeOnLane = TS - timeBeforeEnter;
108  frontOnLane = timeOnLane;
109  enterSpeed = MSCFModel::speedAfterTime(timeBeforeEnter, oldSpeed, newPos - oldPos);
110  }
111 
112  const double oldBackPos = oldPos - veh.getVehicleType().getLength();
113  const double newBackPos = newPos - veh.getVehicleType().getLength();
114 
115  // Determine the time before the vehicle back enters
116  if (oldBackPos < 0. && newBackPos > 0.) {
117  timeBeforeEnterBack = MSCFModel::passingTime(oldBackPos, 0., newBackPos, oldSpeed, newSpeed);
118  } else if (newBackPos <= 0) {
119  timeBeforeEnterBack = TS;
120  } else {
121  timeBeforeEnterBack = 0.;
122  }
123 
124  // Treat the case that the vehicle's back left the lane in the last step
125  if (newBackPos > myLaneLength // vehicle's back has left the lane
126  && oldBackPos <= myLaneLength) { // and hasn't left the lane before
127  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0); // how could it move across the lane boundary otherwise
128  // (Leo) vehicle left this lane (it can also have skipped over it in one time step -> therefore we use "timeOnLane -= ..." and ( ... - timeOnLane) below)
129  timeBeforeLeave = MSCFModel::passingTime(oldBackPos, myLaneLength, newBackPos, oldSpeed, newSpeed);
130  const double timeAfterLeave = TS - timeBeforeLeave;
131  timeOnLane -= timeAfterLeave;
132  leaveSpeed = MSCFModel::speedAfterTime(timeBeforeLeave, oldSpeed, newPos - oldPos);
133  // XXX: Do we really need this? Why would this "reduce rounding errors"? (Leo) Refs. #2579
134  if (fabs(timeOnLane) < NUMERICAL_EPS) { // reduce rounding errors
135  timeOnLane = 0.;
136  }
137  ret = veh.hasArrived();
138  }
139 
140  // Treat the case that the vehicle's front left the lane in the last step
141  if (newPos > myLaneLength && oldPos <= myLaneLength) {
142  // vehicle's front has left the lane and has not left before
143  assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed != 0);
144  timeBeforeLeaveFront = MSCFModel::passingTime(oldPos, myLaneLength, newPos, oldSpeed, newSpeed);
145  const double timeAfterLeave = TS - timeBeforeLeaveFront;
146  frontOnLane -= timeAfterLeave;
147  // XXX: Do we really need this? Why would this "reduce rounding errors"? (Leo) Refs. #2579
148  if (fabs(frontOnLane) < NUMERICAL_EPS) { // reduce rounding errors
149  frontOnLane = 0.;
150  }
151  leaveSpeedFront = MSCFModel::speedAfterTime(timeBeforeLeaveFront, oldSpeed, newPos - oldPos);
152  }
153 
154  assert(frontOnLane <= TS);
155  assert(timeOnLane <= TS);
156 
157  if (timeOnLane < 0) {
158  WRITE_ERROR("Negative vehicle step fraction for '" + veh.getID() + "' on lane '" + getLane()->getID() + "'.");
159  return veh.hasArrived();
160  }
161  if (timeOnLane == 0) {
162  return veh.hasArrived();
163  }
164 
165 #ifdef DEBUG_NOTIFY_MOVE
166  std::stringstream ss;
167  ss << "\n"
168  << "lane length: " << myLaneLength
169  << "\noldPos: " << oldPos
170  << "\nnewPos: " << newPos
171  << "\noldPosBack: " << oldBackPos
172  << "\nnewPosBack: " << newBackPos
173  << "\ntimeBeforeEnter: " << timeBeforeEnter
174  << "\ntimeBeforeEnterBack: " << timeBeforeEnterBack
175  << "\ntimeBeforeLeaveFront: " << timeBeforeLeaveFront
176  << "\ntimeBeforeLeave: " << timeBeforeLeave;
177  if (!(timeBeforeLeave >= MAX2(timeBeforeEnterBack, timeBeforeLeaveFront))
178  || !(timeBeforeEnter <= MIN2(timeBeforeEnterBack, timeBeforeLeaveFront))) {
179  WRITE_ERROR(ss.str());
180  } else {
181  std::cout << ss.str() << std::endl;
182  }
183 
184 #endif
185 
186  assert(timeBeforeEnter <= MIN2(timeBeforeEnterBack, timeBeforeLeaveFront));
187  assert(timeBeforeLeave >= MAX2(timeBeforeEnterBack, timeBeforeLeaveFront));
188  // compute average vehicle length on lane in last step
189  double vehLength = veh.getVehicleType().getLength();
190  // occupied lane length at timeBeforeEnter (resp. stepStart if already on lane)
191  double lengthOnLaneAtStepStart = MAX2(0., MIN4(myLaneLength, vehLength, vehLength - (oldPos - myLaneLength), oldPos));
192  // occupied lane length at timeBeforeLeave (resp. stepEnd if still on lane)
193  double lengthOnLaneAtStepEnd = MAX2(0., MIN4(myLaneLength, vehLength, vehLength - (newPos - myLaneLength), newPos));
194  double integratedLengthOnLane = 0.;
195  if (timeBeforeEnterBack < timeBeforeLeaveFront) {
196  // => timeBeforeLeaveFront>0, myLaneLength>vehLength
197  // vehicle length on detector at timeBeforeEnterBack
198  double lengthOnLaneAtBackEnter = MIN2(veh.getVehicleType().getLength(), newPos);
199  // linear quadrature of occupancy between timeBeforeEnter and timeBeforeEnterBack
200  integratedLengthOnLane += (timeBeforeEnterBack - timeBeforeEnter) * (lengthOnLaneAtBackEnter + lengthOnLaneAtStepStart) * 0.5;
201  // linear quadrature of occupancy between timeBeforeEnterBack and timeBeforeLeaveFront
202  // (vehicle is completely on the edge in between)
203  integratedLengthOnLane += (timeBeforeLeaveFront - timeBeforeEnterBack) * vehLength;
204  // and until vehicle leaves/stepEnd
205  integratedLengthOnLane += (timeBeforeLeave - timeBeforeLeaveFront) * (vehLength + lengthOnLaneAtStepEnd) * 0.5;
206  } else if (timeBeforeEnterBack >= timeBeforeLeaveFront) {
207  // => myLaneLength <= vehLength or (timeBeforeLeaveFront == timeBeforeEnterBack == 0)
208  // vehicle length on detector at timeBeforeLeaveFront
209  double lengthOnLaneAtLeaveFront;
210  if (timeBeforeLeaveFront == timeBeforeEnter) {
211  // for the case that front already left
212  lengthOnLaneAtLeaveFront = lengthOnLaneAtStepStart;
213  } else if (timeBeforeLeaveFront == timeBeforeLeave) {
214  // for the case that front doesn't leave in this step
215  lengthOnLaneAtLeaveFront = lengthOnLaneAtStepEnd;
216  } else {
217  lengthOnLaneAtLeaveFront = myLaneLength;
218  }
219 #ifdef DEBUG_NOTIFY_MOVE
220  std::cout << "lengthOnLaneAtLeaveFront=" << lengthOnLaneAtLeaveFront << std::endl;
221 #endif
222  // linear quadrature of occupancy between timeBeforeEnter and timeBeforeLeaveFront
223  integratedLengthOnLane += (timeBeforeLeaveFront - timeBeforeEnter) * (lengthOnLaneAtLeaveFront + lengthOnLaneAtStepStart) * 0.5;
224  // linear quadrature of occupancy between timeBeforeLeaveFront and timeBeforeEnterBack
225  integratedLengthOnLane += (timeBeforeEnterBack - timeBeforeLeaveFront) * lengthOnLaneAtLeaveFront;
226  // and until vehicle leaves/stepEnd
227  integratedLengthOnLane += (timeBeforeLeave - timeBeforeEnterBack) * (lengthOnLaneAtLeaveFront + lengthOnLaneAtStepEnd) * 0.5;
228  }
229 
230  double meanLengthOnLane = integratedLengthOnLane / TS;
231 #ifdef DEBUG_NOTIFY_MOVE
232  std::cout << "Calculated mean length on lane '" << myLane->getID() << "' in last step as " << meanLengthOnLane
233  << "\nlengthOnLaneAtStepStart=" << lengthOnLaneAtStepStart << ", lengthOnLaneAtStepEnd=" << lengthOnLaneAtStepEnd << ", integratedLengthOnLane=" << integratedLengthOnLane
234  << std::endl;
235 #endif
236 
237 // // XXX: use this, when #2556 is fixed! Refs. #2575
238 // const double travelledDistanceFrontOnLane = MAX2(0., MIN2(newPos, myLaneLength) - MAX2(oldPos, 0.));
239 // const double travelledDistanceVehicleOnLane = MIN2(newPos, myLaneLength) - MAX2(oldPos, 0.) + MIN2(MAX2(0., newPos - myLaneLength), veh.getVehicleType().getLength());
240 // // XXX: #2556 fixed for ballistic update
241  const double travelledDistanceFrontOnLane = MSGlobals::gSemiImplicitEulerUpdate ? frontOnLane * newSpeed
242  : MAX2(0., MIN2(newPos, myLaneLength) - MAX2(oldPos, 0.));
243  const double travelledDistanceVehicleOnLane = MSGlobals::gSemiImplicitEulerUpdate ? timeOnLane * newSpeed
244  : MIN2(newPos, myLaneLength) - MAX2(oldPos, 0.) + MIN2(MAX2(0., newPos - myLaneLength), veh.getVehicleType().getLength());
245 // // XXX: no fix
246 // const double travelledDistanceFrontOnLane = frontOnLane*newSpeed;
247 // const double travelledDistanceVehicleOnLane = timeOnLane*newSpeed;
248 
249  notifyMoveInternal(veh, frontOnLane, timeOnLane, (enterSpeed + leaveSpeedFront) / 2., (enterSpeed + leaveSpeed) / 2., travelledDistanceFrontOnLane, travelledDistanceVehicleOnLane, meanLengthOnLane);
250  return ret;
251 }
252 
253 
254 bool
255 MSMeanData::MeanDataValues::notifyLeave(SUMOTrafficObject& /*veh*/, double /*lastPos*/, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
257  return false; // reminder is re-added on every segment (@recheck for performance)
258  }
259  return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
260 }
261 
262 
263 bool
265  return sampleSeconds == 0;
266 }
267 
268 
269 void
271 }
272 
273 
274 double
276  return sampleSeconds;
277 }
278 
279 
280 // ---------------------------------------------------------------------------
281 // MSMeanData::MeanDataValueTracker - methods
282 // ---------------------------------------------------------------------------
284  const double length,
285  const MSMeanData* const parent)
286  : MSMeanData::MeanDataValues(lane, length, true, parent) {
287  myCurrentData.push_back(new TrackerEntry(parent->createValues(lane, length, false)));
288 }
289 
290 
292  std::list<TrackerEntry*>::iterator i;
293  for (i = myCurrentData.begin(); i != myCurrentData.end(); i++) {
294  delete *i;
295  }
296 
297  // FIXME: myTrackedData may still hold some undeleted TrackerEntries. When to delete those? (Leo), refers to #2251
298  // code below fails
299 
300 // std::map<SUMOTrafficObject*, TrackerEntry*>::iterator j;
301 // for(j=myTrackedData.begin(); j!=myTrackedData.end();j++){
302 // delete j->second;
303 // }
304 }
305 
306 
307 void
309  if (afterWrite) {
310  if (myCurrentData.begin() != myCurrentData.end()) {
311  myCurrentData.pop_front();
312  }
313  } else {
314  myCurrentData.push_back(new TrackerEntry(myParent->createValues(myLane, myLaneLength, false)));
315  }
316 }
317 
318 
319 void
321  myCurrentData.front()->myValues->addTo(val);
322 }
323 
324 
325 void
326 MSMeanData::MeanDataValueTracker::notifyMoveInternal(const SUMOTrafficObject& veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane) {
327  myTrackedData[&veh]->myValues->notifyMoveInternal(veh, frontOnLane, timeOnLane, meanSpeedFrontOnLane, meanSpeedVehicleOnLane, travelledDistanceFrontOnLane, travelledDistanceVehicleOnLane, meanLengthOnLane);
328 }
329 
330 
331 bool
333  if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
334  myTrackedData[&veh]->myNumVehicleLeft++;
335  }
336  return myTrackedData[&veh]->myValues->notifyLeave(veh, lastPos, reason);
337 }
338 
339 
340 bool
342 #ifdef DEBUG_NOTIFY_ENTER
343  std::cout << "\n" << SIMTIME << " MSMeanData::MeanDataValueTracker: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
344 #else
345  UNUSED_PARAMETER(enteredLane);
346 #endif
347  if (reason == MSMoveReminder::NOTIFICATION_SEGMENT) {
348  return true;
349  }
350  if (myParent->vehicleApplies(veh) && myTrackedData.find(&veh) == myTrackedData.end()) {
351  myTrackedData[&veh] = myCurrentData.back();
352  myTrackedData[&veh]->myNumVehicleEntered++;
353  if (!myTrackedData[&veh]->myValues->notifyEnter(veh, reason)) {
354  myTrackedData[&veh]->myNumVehicleLeft++;
355  myTrackedData.erase(&veh);
356  return false;
357  }
358  return true;
359  }
360  return false;
361 }
362 
363 
364 bool
366  return myCurrentData.front()->myValues->isEmpty();
367 }
368 
369 
370 void
372  const SUMOTime period,
373  const double numLanes,
374  const double defaultTravelTime,
375  const int /*numVehicles*/) const {
376  myCurrentData.front()->myValues->write(dev, period, numLanes,
377  defaultTravelTime,
378  myCurrentData.front()->myNumVehicleEntered);
379 }
380 
381 
382 int
384  int result = 0;
385  for (std::list<TrackerEntry*>::const_iterator it = myCurrentData.begin(); it != myCurrentData.end(); ++it) {
386  if ((*it)->myNumVehicleEntered == (*it)->myNumVehicleLeft) {
387  result++;
388  } else {
389  break;
390  }
391  }
392  return result;
393 }
394 
395 
396 double
398  return myCurrentData.front()->myValues->getSamples();
399 }
400 
401 
402 // ---------------------------------------------------------------------------
403 // MSMeanData - methods
404 // ---------------------------------------------------------------------------
405 MSMeanData::MSMeanData(const std::string& id,
406  const SUMOTime dumpBegin, const SUMOTime dumpEnd,
407  const bool useLanes, const bool withEmpty,
408  const bool printDefaults, const bool withInternal,
409  const bool trackVehicles,
410  const int detectPersons,
411  const double maxTravelTime,
412  const double minSamples,
413  const std::string& vTypes) :
414  MSDetectorFileOutput(id, vTypes, detectPersons),
415  myMinSamples(minSamples),
416  myMaxTravelTime(maxTravelTime),
417  myDumpEmpty(withEmpty),
418  myAmEdgeBased(!useLanes),
419  myDumpBegin(dumpBegin),
420  myDumpEnd(dumpEnd),
421  myPrintDefaults(printDefaults),
422  myDumpInternal(withInternal),
423  myTrackVehicles(trackVehicles) {
424 }
425 
426 
427 void
430  for (MSEdgeVector::const_iterator e = edges.begin(); e != edges.end(); ++e) {
431  if ((myDumpInternal || !(*e)->isInternal()) &&
432  ((detectPersons() && myDumpInternal) || (!(*e)->isCrossing() && !(*e)->isWalkingArea()))) {
433  myEdges.push_back(*e);
434  myMeasures.push_back(std::vector<MeanDataValues*>());
435  const std::vector<MSLane*>& lanes = (*e)->getLanes();
437  MeanDataValues* data;
438  if (myTrackVehicles) {
439  data = new MeanDataValueTracker(nullptr, lanes[0]->getLength(), this);
440  } else {
441  data = createValues(nullptr, lanes[0]->getLength(), false);
442  }
443  data->setDescription("meandata_" + (*e)->getID());
444  myMeasures.back().push_back(data);
446  while (s != nullptr) {
447  s->addDetector(data);
448  s->prepareDetectorForWriting(*data);
449  s = s->getNextSegment();
450  }
451  data->reset();
452  data->reset(true);
453  continue;
454  }
456  myMeasures.back().push_back(new MeanDataValueTracker(nullptr, lanes[0]->getLength(), this));
457  }
458  for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
459  if (myTrackVehicles) {
460  if (myAmEdgeBased) {
461  (*lane)->addMoveReminder(myMeasures.back().back());
462  } else {
463  myMeasures.back().push_back(new MeanDataValueTracker(*lane, (*lane)->getLength(), this));
464  }
465  } else {
466  myMeasures.back().push_back(createValues(*lane, (*lane)->getLength(), true));
467  }
468  }
469  }
470  }
471 }
472 
473 
475  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
476  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
477  delete *j;
478  }
479  }
480 }
481 
482 
483 void
485  UNUSED_PARAMETER(stopTime);
487  MSEdgeVector::iterator edge = myEdges.begin();
488  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i, ++edge) {
490  MeanDataValues* data = i->front();
491  while (s != nullptr) {
492  s->prepareDetectorForWriting(*data);
493  s = s->getNextSegment();
494  }
495  data->reset();
496  }
497  return;
498  }
499  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
500  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
501  (*j)->reset();
502  }
503  }
504 }
505 
506 
507 std::string
508 MSMeanData::getEdgeID(const MSEdge* const edge) {
509  return edge->getID();
510 }
511 
512 
513 void
515  const std::vector<MeanDataValues*>& edgeValues,
516  MSEdge* edge, SUMOTime startTime, SUMOTime stopTime) {
519  MeanDataValues* data = edgeValues.front();
520  while (s != nullptr) {
521  s->prepareDetectorForWriting(*data);
522  s = s->getNextSegment();
523  }
524  if (writePrefix(dev, *data, SUMO_TAG_EDGE, getEdgeID(edge))) {
525  data->write(dev, stopTime - startTime,
526  (double)edge->getLanes().size(),
527  myPrintDefaults ? edge->getLength() / edge->getSpeedLimit() : -1.);
528  }
529  data->reset(true);
530  return;
531  }
532  std::vector<MeanDataValues*>::const_iterator lane;
533  if (!myAmEdgeBased) {
534  bool writeCheck = myDumpEmpty;
535  if (!writeCheck) {
536  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
537  if (!(*lane)->isEmpty()) {
538  writeCheck = true;
539  break;
540  }
541  }
542  }
543  if (writeCheck) {
545  }
546  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
547  MeanDataValues& meanData = **lane;
548  if (writePrefix(dev, meanData, SUMO_TAG_LANE, meanData.getLane()->getID())) {
549  meanData.write(dev, stopTime - startTime, 1.f, myPrintDefaults ? meanData.getLane()->getLength() / meanData.getLane()->getSpeedLimit() : -1.);
550  }
551  meanData.reset(true);
552  }
553  if (writeCheck) {
554  dev.closeTag();
555  }
556  } else {
557  if (myTrackVehicles) {
558  MeanDataValues& meanData = **edgeValues.begin();
559  if (writePrefix(dev, meanData, SUMO_TAG_EDGE, edge->getID())) {
560  meanData.write(dev, stopTime - startTime, (double)edge->getLanes().size(), myPrintDefaults ? edge->getLength() / edge->getSpeedLimit() : -1.);
561  }
562  meanData.reset(true);
563  } else {
564  MeanDataValues* sumData = createValues(nullptr, edge->getLength(), false);
565  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
566  MeanDataValues& meanData = **lane;
567  meanData.addTo(*sumData);
568  meanData.reset();
569  }
570  if (writePrefix(dev, *sumData, SUMO_TAG_EDGE, getEdgeID(edge))) {
571  sumData->write(dev, stopTime - startTime, (double)edge->getLanes().size(), myPrintDefaults ? edge->getLength() / edge->getSpeedLimit() : -1.);
572  }
573  delete sumData;
574  }
575  }
576 }
577 
578 
579 void
580 MSMeanData::openInterval(OutputDevice& dev, const SUMOTime startTime, const SUMOTime stopTime) {
583 }
584 
585 
586 bool
587 MSMeanData::writePrefix(OutputDevice& dev, const MeanDataValues& values, const SumoXMLTag tag, const std::string id) const {
588  if (myDumpEmpty || !values.isEmpty()) {
589  dev.openTag(tag).writeAttr(SUMO_ATTR_ID, id).writeAttr("sampledSeconds", values.getSamples());
590  return true;
591  }
592  return false;
593 }
594 
595 
596 void
598  SUMOTime startTime, SUMOTime stopTime) {
599  // check whether this dump shall be written for the current time
600  int numReady = myDumpBegin < stopTime && myDumpEnd - DELTA_T >= startTime ? 1 : 0;
601  if (myTrackVehicles && myDumpBegin < stopTime) {
602  myPendingIntervals.push_back(std::make_pair(startTime, stopTime));
603  numReady = (int)myPendingIntervals.size();
604  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
605  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
606  numReady = MIN2(numReady, ((MeanDataValueTracker*)*j)->getNumReady());
607  if (numReady == 0) {
608  break;
609  }
610  }
611  if (numReady == 0) {
612  break;
613  }
614  }
615  }
616  if (numReady == 0 || myTrackVehicles) {
617  resetOnly(stopTime);
618  }
619  while (numReady-- > 0) {
620  if (!myPendingIntervals.empty()) {
621  startTime = myPendingIntervals.front().first;
622  stopTime = myPendingIntervals.front().second;
623  myPendingIntervals.pop_front();
624  }
625  openInterval(dev, startTime, stopTime);
626  MSEdgeVector::iterator edge = myEdges.begin();
627  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i, ++edge) {
628  writeEdge(dev, (*i), *edge, startTime, stopTime);
629  }
630  dev.closeTag();
631  }
632  dev.flush();
633 }
634 
635 
636 void
638  dev.writeXMLHeader("meandata", "meandata_file.xsd");
639 }
640 
641 
642 void
644  if (step + DELTA_T == myDumpBegin) {
645  init();
646  }
647 }
648 
649 
650 /****************************************************************************/
651 
MSMeanData::MeanDataValueTracker::TrackerEntry
Definition: MSMeanData.h:260
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:32
SUMOTrafficObject
Representation of a vehicle or person.
Definition: SUMOTrafficObject.h:48
MSMeanData::writeEdge
void writeEdge(OutputDevice &dev, const std::vector< MeanDataValues * > &edgeValues, MSEdge *edge, SUMOTime startTime, SUMOTime stopTime)
Writes edge values into the given stream.
Definition: MSMeanData.cpp:514
ToString.h
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:74
MSMeanData::myDumpEmpty
const bool myDumpEmpty
Whether empty lanes/edges shall be written.
Definition: MSMeanData.h:433
MSEdge::getSpeedLimit
double getSpeedLimit() const
Returns the speed limit of the edge @caution The speed limit of the first lane is retured; should pro...
Definition: MSEdge.cpp:916
MSMeanData_Amitran.h
SUMOTime.h
MSNet.h
MSDetectorFileOutput
Base of value-generating classes (detectors)
Definition: MSDetectorFileOutput.h:64
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
MSMeanData::myAmEdgeBased
const bool myAmEdgeBased
Information whether the output shall be edge-based (not lane-based)
Definition: MSMeanData.h:437
MESegment
A single mesoscopic segment (cell)
Definition: MESegment.h:50
OutputDevice
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
MSMeanData::MSMeanData
MSMeanData(const std::string &id, const SUMOTime dumpBegin, const SUMOTime dumpEnd, const bool useLanes, const bool withEmpty, const bool printDefaults, const bool withInternal, const bool trackVehicles, const int detectPersons, const double minSamples, const double maxTravelTime, const std::string &vTypes)
Constructor.
Definition: MSMeanData.cpp:405
DELTA_T
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:145
MSMeanData::writeXMLDetectorProlog
virtual void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using "netstats" as root element.
Definition: MSMeanData.cpp:637
SUMOTrafficObject::getVehicleType
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.
MESegment::addDetector
void addDetector(MSMoveReminder *data)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:212
SUMOTrafficObject::getID
virtual const std::string & getID() const =0
Get the vehicle's ID.
MSMeanData::MeanDataValueTracker::getSamples
double getSamples() const
Returns the number of collected sample seconds.
Definition: MSMeanData.cpp:397
SUMO_TAG_LANE
begin/end of the description of a single lane
Definition: SUMOXMLDefinitions.h:50
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:35
MSMeanData::MeanDataValues::notifyEnter
virtual bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle enters the reminder's lane.
Definition: MSMeanData.cpp:73
MSMeanData::MeanDataValues::isEmpty
virtual bool isEmpty() const
Returns whether any data was collected.
Definition: MSMeanData.cpp:264
MSMeanData::MeanDataValueTracker::MeanDataValueTracker
MeanDataValueTracker(MSLane *const lane, const double length, const MSMeanData *const parent)
Constructor.
Definition: MSMeanData.cpp:283
MSGlobals::gUseMesoSim
static bool gUseMesoSim
Definition: MSGlobals.h:91
MSMeanData::myMeasures
std::vector< std::vector< MeanDataValues * > > myMeasures
Value collectors; sorted by edge, then by lane.
Definition: MSMeanData.h:430
MSMeanData::myPrintDefaults
const bool myPrintDefaults
Whether empty lanes/edges shall be written.
Definition: MSMeanData.h:446
MSMeanData::MeanDataValues::write
virtual void write(OutputDevice &dev, const SUMOTime period, const double numLanes, const double defaultTravelTime, const int numVehicles=-1) const =0
Writes output values into the given stream.
SUMO_ATTR_ID
Definition: SUMOXMLDefinitions.h:379
MSEdge.h
MSMeanData::resetOnly
void resetOnly(SUMOTime stopTime)
Resets network value in order to allow processing of the next interval.
Definition: MSMeanData.cpp:484
MSMeanData::myDumpEnd
const SUMOTime myDumpEnd
Definition: MSMeanData.h:440
MSEdge::getLength
double getLength() const
return the length of the edge
Definition: MSEdge.h:582
SumoXMLTag
SumoXMLTag
Numbers representing SUMO-XML - element names.
Definition: SUMOXMLDefinitions.h:42
MSMeanData::writeXMLOutput
void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes collected values into the given stream.
Definition: MSMeanData.cpp:597
MSVehicle.h
MSMoveReminder
Something on a lane to be noticed about vehicle movement.
Definition: MSMoveReminder.h:64
OutputDevice::closeTag
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Definition: OutputDevice.cpp:254
MSMeanData::myEdges
MSEdgeVector myEdges
The corresponding first edges.
Definition: MSMeanData.h:443
SUMO_ATTR_BEGIN
weights: time range begin
Definition: SUMOXMLDefinitions.h:675
MESegment.h
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:80
MSMeanData::myDumpInternal
const bool myDumpInternal
Whether internal lanes/edges shall be written.
Definition: MSMeanData.h:449
MSMeanData::myMinSamples
const double myMinSamples
the minimum sample seconds
Definition: MSMeanData.h:424
OutputDevice::writeAttr
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
MSMeanData::MeanDataValueTracker::notifyEnter
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Computes current values and adds them to their sums.
Definition: MSMeanData.cpp:341
MSMeanData
Data collector for edges/lanes.
Definition: MSMeanData.h:60
MSMeanData::MeanDataValueTracker::~MeanDataValueTracker
virtual ~MeanDataValueTracker()
Destructor.
Definition: MSMeanData.cpp:291
MSMeanData::openInterval
virtual void openInterval(OutputDevice &dev, const SUMOTime startTime, const SUMOTime stopTime)
Writes the interval opener.
Definition: MSMeanData.cpp:580
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:64
MSMeanData::MeanDataValues::notifyMove
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks whether the reminder still has to be notified about the vehicle moves.
Definition: MSMeanData.cpp:85
MESegment::prepareDetectorForWriting
void prepareDetectorForWriting(MSMoveReminder &data)
Updates data of a detector for all vehicle queues.
Definition: MESegment.cpp:238
OutputDevice::flush
void flush()
Definition: OutputDevice.h:332
MSMeanData::MeanDataValueTracker::addTo
void addTo(MSMeanData::MeanDataValues &val) const
Add the values of this to the given one and store them there.
Definition: MSMeanData.cpp:320
MSMeanData::myPendingIntervals
std::list< std::pair< SUMOTime, SUMOTime > > myPendingIntervals
The intervals for which output still has to be generated (only in the tracking case)
Definition: MSMeanData.h:455
TS
#define TS
Definition: SUMOTime.h:44
MSMeanData::~MSMeanData
virtual ~MSMeanData()
Destructor.
Definition: MSMeanData.cpp:474
MSMeanData::MeanDataValues::notifyLeave
virtual bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder's lane.
Definition: MSMeanData.cpp:255
MIN4
T MIN4(T a, T b, T c, T d)
Definition: StdDefs.h:101
MSLane::getLength
double getLength() const
Returns the lane's length.
Definition: MSLane.h:541
MELoop::getSegmentForEdge
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:293
OutputDevice.h
SUMO_TAG_EDGE
begin/end of the description of an edge
Definition: SUMOXMLDefinitions.h:48
MSMeanData::myMaxTravelTime
const double myMaxTravelTime
the maximum travel time to write
Definition: MSMeanData.h:427
time2string
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
MSGlobals.h
MESegment::getNextSegment
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:152
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:76
MSCFModel::speedAfterTime
static double speedAfterTime(const double t, const double oldSpeed, const double dist)
Calculates the speed after a time t \in [0,TS] given the initial speed and the distance traveled in a...
Definition: MSCFModel.cpp:674
MSMeanData::MeanDataValueTracker::isEmpty
bool isEmpty() const
Returns whether any data was collected.
Definition: MSMeanData.cpp:365
MSMeanData::init
void init()
Adds the value collectors to all relevant edges.
Definition: MSMeanData.cpp:428
MSMoveReminder::NOTIFICATION_SEGMENT
The vehicle changes the segment (meso only)
Definition: MSMoveReminder.h:95
MSMeanData::MeanDataValues::update
virtual void update()
Called if a per timestep update is needed. Default does nothing.
Definition: MSMeanData.cpp:270
MSMeanData::MeanDataValues
Data structure for mean (aggregated) edge/lane values.
Definition: MSMeanData.h:69
MSDetectorFileOutput::detectPersons
bool detectPersons() const
Definition: MSDetectorFileOutput.h:167
MSMeanData::MeanDataValueTracker::notifyMoveInternal
void notifyMoveInternal(const SUMOTrafficObject &veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane)
Internal notification about the vehicle moves.
Definition: MSMeanData.cpp:326
MSMeanData::MeanDataValues::~MeanDataValues
virtual ~MeanDataValues()
Destructor.
Definition: MSMeanData.cpp:68
MSEdgeControl.h
MSMeanData::MeanDataValueTracker::myCurrentData
std::list< TrackerEntry * > myCurrentData
The currently active meandata "intervals".
Definition: MSMeanData.h:285
MSMoveReminder::getLane
const MSLane * getLane() const
Returns the lane the reminder works on.
Definition: MSMoveReminder.h:83
OutputDevice::openTag
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
Definition: OutputDevice.cpp:240
MSMeanData::MeanDataValueTracker
Data structure for mean (aggregated) edge/lane values for tracked vehicles.
Definition: MSMeanData.h:186
MSMeanData::myTrackVehicles
const bool myTrackVehicles
Whether vehicles are tracked.
Definition: MSMeanData.h:452
MSMeanData::MeanDataValues::getSamples
virtual double getSamples() const
Returns the number of collected sample seconds.
Definition: MSMeanData.cpp:275
MSMeanData::MeanDataValueTracker::reset
void reset(bool afterWrite)
Resets values so they may be used for the next interval.
Definition: MSMeanData.cpp:308
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
MSGlobals::gMesoNet
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:106
SUMOTrafficObject::getPreviousSpeed
virtual double getPreviousSpeed() const =0
Returns the vehicle's previous speed.
SUMOTrafficObject::hasArrived
virtual bool hasArrived() const =0
Returns whether this vehicle has arrived.
MSVehicleType::getLength
double getLength() const
Get vehicle's length [m].
Definition: MSVehicleType.h:110
MSCFModel.h
MSMeanData::myDumpBegin
const SUMOTime myDumpBegin
The first and the last time step to write information (-1 indicates always)
Definition: MSMeanData.h:440
MSEdgeVector
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:72
MSMeanData::MeanDataValues::reset
virtual void reset(bool afterWrite=false)=0
Resets values so they may be used for the next interval.
MSMeanData::createValues
virtual MSMeanData::MeanDataValues * createValues(MSLane *const lane, const double length, const bool doAdd) const =0
Create an instance of MeanDataValues.
MSMoveReminder::setDescription
void setDescription(const std::string &description)
Definition: MSMoveReminder.h:224
MSEdge::getLanes
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:165
MSMeanData::MeanDataValues::addTo
virtual void addTo(MeanDataValues &val) const =0
Add the values of this to the given one and store them there.
MSMeanData::getEdgeID
virtual std::string getEdgeID(const MSEdge *const edge)
Return the relevant edge id.
Definition: MSMeanData.cpp:508
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:597
MSMeanData.h
SUMO_ATTR_END
weights: time range end
Definition: SUMOXMLDefinitions.h:677
MELoop.h
MSMeanData::MeanDataValueTracker::write
void write(OutputDevice &dev, const SUMOTime period, const double numLanes, const double defaultTravelTime, const int numVehicles=-1) const
Writes output values into the given stream.
Definition: MSMeanData.cpp:371
SUMO_TAG_INTERVAL
an aggreagated-output interval
Definition: SUMOXMLDefinitions.h:160
MSMeanData::MeanDataValueTracker::notifyLeave
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder's lane.
Definition: MSMeanData.cpp:332
MSLane.h
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:228
MSLane::getSpeedLimit
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:533
MSNet::getEdgeControl
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:380
MSGlobals::gSemiImplicitEulerUpdate
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:56
Named::myID
std::string myID
The name of the object.
Definition: Named.h:134
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:77
MSMoveReminder::Notification
Notification
Definition of a vehicle state.
Definition: MSMoveReminder.h:89
MSMoveReminder::NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
Definition: MSMoveReminder.h:93
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
MSMeanData::writePrefix
virtual bool writePrefix(OutputDevice &dev, const MeanDataValues &values, const SumoXMLTag tag, const std::string id) const
Checks for emptiness and writes prefix into the given stream.
Definition: MSMeanData.cpp:587
MSMeanData::MeanDataValues::MeanDataValues
MeanDataValues(MSLane *const lane, const double length, const bool doAdd, const MSMeanData *const parent)
Constructor.
Definition: MSMeanData.cpp:58
MSEdgeControl::getEdges
const MSEdgeVector & getEdges() const
Returns loaded edges.
Definition: MSEdgeControl.h:168
MSMeanData::detectorUpdate
virtual void detectorUpdate(const SUMOTime step)
Updates the detector.
Definition: MSMeanData.cpp:643
MSMeanData::MeanDataValueTracker::getNumReady
int getNumReady() const
Definition: MSMeanData.cpp:383