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