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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
19 // 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(SUMOVehicle& 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(SUMOVehicle& /*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<SUMOVehicle*, 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 {
315  }
316 }
317 
318 
319 void
321  myCurrentData.front()->myValues->addTo(val);
322 }
323 
324 
325 void
326 MSMeanData::MeanDataValueTracker::notifyMoveInternal(const SUMOVehicle& 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
332 MSMeanData::MeanDataValueTracker::notifyLeave(SUMOVehicle& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
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, const bool trackVehicles,
409  const double maxTravelTime,
410  const double minSamples,
411  const std::string& vTypes) :
412  MSDetectorFileOutput(id, vTypes),
413  myMinSamples(minSamples),
414  myMaxTravelTime(maxTravelTime),
415  myDumpEmpty(withEmpty),
416  myAmEdgeBased(!useLanes),
417  myDumpBegin(dumpBegin),
418  myDumpEnd(dumpEnd),
419  myPrintDefaults(printDefaults),
420  myDumpInternal(withInternal),
421  myTrackVehicles(trackVehicles) {
422 }
423 
424 
425 void
428  for (MSEdgeVector::const_iterator e = edges.begin(); e != edges.end(); ++e) {
429  if ((myDumpInternal || !(*e)->isInternal()) && !(*e)->isCrossing() && !(*e)->isWalkingArea()) {
430  myEdges.push_back(*e);
431  myMeasures.push_back(std::vector<MeanDataValues*>());
432  const std::vector<MSLane*>& lanes = (*e)->getLanes();
434  MeanDataValues* data;
435  if (myTrackVehicles) {
436  data = new MeanDataValueTracker(nullptr, lanes[0]->getLength(), this);
437  } else {
438  data = createValues(nullptr, lanes[0]->getLength(), false);
439  }
440  data->setDescription("meandata_" + (*e)->getID());
441  myMeasures.back().push_back(data);
443  while (s != nullptr) {
444  s->addDetector(data);
445  s->prepareDetectorForWriting(*data);
446  s = s->getNextSegment();
447  }
448  data->reset();
449  data->reset(true);
450  continue;
451  }
453  myMeasures.back().push_back(new MeanDataValueTracker(nullptr, lanes[0]->getLength(), this));
454  }
455  for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
456  if (myTrackVehicles) {
457  if (myAmEdgeBased) {
458  (*lane)->addMoveReminder(myMeasures.back().back());
459  } else {
460  myMeasures.back().push_back(new MeanDataValueTracker(*lane, (*lane)->getLength(), this));
461  }
462  } else {
463  myMeasures.back().push_back(createValues(*lane, (*lane)->getLength(), true));
464  }
465  }
466  }
467  }
468 }
469 
470 
472  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
473  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
474  delete *j;
475  }
476  }
477 }
478 
479 
480 void
482  UNUSED_PARAMETER(stopTime);
484  MSEdgeVector::iterator edge = myEdges.begin();
485  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i, ++edge) {
487  MeanDataValues* data = i->front();
488  while (s != nullptr) {
489  s->prepareDetectorForWriting(*data);
490  s = s->getNextSegment();
491  }
492  data->reset();
493  }
494  return;
495  }
496  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
497  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
498  (*j)->reset();
499  }
500  }
501 }
502 
503 
504 std::string
505 MSMeanData::getEdgeID(const MSEdge* const edge) {
506  return edge->getID();
507 }
508 
509 
510 void
512  const std::vector<MeanDataValues*>& edgeValues,
513  MSEdge* edge, SUMOTime startTime, SUMOTime stopTime) {
516  MeanDataValues* data = edgeValues.front();
517  while (s != nullptr) {
518  s->prepareDetectorForWriting(*data);
519  s = s->getNextSegment();
520  }
521  if (writePrefix(dev, *data, SUMO_TAG_EDGE, getEdgeID(edge))) {
522  data->write(dev, stopTime - startTime,
523  (double)edge->getLanes().size(),
524  myPrintDefaults ? edge->getLength() / edge->getSpeedLimit() : -1.);
525  }
526  data->reset(true);
527  return;
528  }
529  std::vector<MeanDataValues*>::const_iterator lane;
530  if (!myAmEdgeBased) {
531  bool writeCheck = myDumpEmpty;
532  if (!writeCheck) {
533  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
534  if (!(*lane)->isEmpty()) {
535  writeCheck = true;
536  break;
537  }
538  }
539  }
540  if (writeCheck) {
542  }
543  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
544  MeanDataValues& meanData = **lane;
545  if (writePrefix(dev, meanData, SUMO_TAG_LANE, meanData.getLane()->getID())) {
546  meanData.write(dev, stopTime - startTime, 1.f, myPrintDefaults ? meanData.getLane()->getLength() / meanData.getLane()->getSpeedLimit() : -1.);
547  }
548  meanData.reset(true);
549  }
550  if (writeCheck) {
551  dev.closeTag();
552  }
553  } else {
554  if (myTrackVehicles) {
555  MeanDataValues& meanData = **edgeValues.begin();
556  if (writePrefix(dev, meanData, SUMO_TAG_EDGE, edge->getID())) {
557  meanData.write(dev, stopTime - startTime, (double)edge->getLanes().size(), myPrintDefaults ? edge->getLength() / edge->getSpeedLimit() : -1.);
558  }
559  meanData.reset(true);
560  } else {
561  MeanDataValues* sumData = createValues(nullptr, edge->getLength(), false);
562  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
563  MeanDataValues& meanData = **lane;
564  meanData.addTo(*sumData);
565  meanData.reset();
566  }
567  if (writePrefix(dev, *sumData, SUMO_TAG_EDGE, getEdgeID(edge))) {
568  sumData->write(dev, stopTime - startTime, (double)edge->getLanes().size(), myPrintDefaults ? edge->getLength() / edge->getSpeedLimit() : -1.);
569  }
570  delete sumData;
571  }
572  }
573 }
574 
575 
576 void
577 MSMeanData::openInterval(OutputDevice& dev, const SUMOTime startTime, const SUMOTime stopTime) {
580 }
581 
582 
583 bool
584 MSMeanData::writePrefix(OutputDevice& dev, const MeanDataValues& values, const SumoXMLTag tag, const std::string id) const {
585  if (myDumpEmpty || !values.isEmpty()) {
586  dev.openTag(tag).writeAttr(SUMO_ATTR_ID, id).writeAttr("sampledSeconds", values.getSamples());
587  return true;
588  }
589  return false;
590 }
591 
592 
593 void
595  SUMOTime startTime, SUMOTime stopTime) {
596  // check whether this dump shall be written for the current time
597  int numReady = myDumpBegin < stopTime && myDumpEnd - DELTA_T >= startTime ? 1 : 0;
598  if (myTrackVehicles && myDumpBegin < stopTime) {
599  myPendingIntervals.push_back(std::make_pair(startTime, stopTime));
600  numReady = (int)myPendingIntervals.size();
601  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
602  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
603  numReady = MIN2(numReady, ((MeanDataValueTracker*)*j)->getNumReady());
604  if (numReady == 0) {
605  break;
606  }
607  }
608  if (numReady == 0) {
609  break;
610  }
611  }
612  }
613  if (numReady == 0 || myTrackVehicles) {
614  resetOnly(stopTime);
615  }
616  while (numReady-- > 0) {
617  if (!myPendingIntervals.empty()) {
618  startTime = myPendingIntervals.front().first;
619  stopTime = myPendingIntervals.front().second;
620  myPendingIntervals.pop_front();
621  }
622  openInterval(dev, startTime, stopTime);
623  MSEdgeVector::iterator edge = myEdges.begin();
624  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i, ++edge) {
625  writeEdge(dev, (*i), *edge, startTime, stopTime);
626  }
627  dev.closeTag();
628  dev.flush();
629  }
630 }
631 
632 
633 void
635  dev.writeXMLHeader("meandata", "meandata_file.xsd");
636 }
637 
638 
639 void
641  if (step + DELTA_T == myDumpBegin) {
642  init();
643  }
644 }
645 
646 
647 /****************************************************************************/
648 
static double speedAfterTime(const double t, const double oldSpeed, const double dist)
Calculates the speed after a time t [0,TS] given the initial speed and the distance traveled in an i...
Definition: MSCFModel.cpp:671
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:152
Data collector for edges/lanes.
Definition: MSMeanData.h:60
virtual ~MeanDataValueTracker()
Destructor.
Definition: MSMeanData.cpp:291
const MSLane * getLane() const
Returns the lane the reminder works on.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
SumoXMLTag
Numbers representing SUMO-XML - element names.
long long int SUMOTime
Definition: SUMOTime.h:36
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:283
std::vector< std::vector< MeanDataValues * > > myMeasures
Value collectors; sorted by edge, then by lane.
Definition: MSMeanData.h:428
begin/end of the description of a single lane
const bool myDumpInternal
Whether internal lanes/edges shall be written.
Definition: MSMeanData.h:447
MeanDataValueTracker(MSLane *const lane, const double length, const MSMeanData *const parent)
Constructor.
Definition: MSMeanData.cpp:283
virtual bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle enters the reminder&#39;s lane.
Definition: MSMeanData.cpp:73
bool vehicleApplies(const SUMOVehicle &veh) const
Checks whether the detector measures vehicles of the given type.
double getSamples() const
Returns the number of collected sample seconds.
Definition: MSMeanData.cpp:397
const SUMOTime myDumpEnd
Definition: MSMeanData.h:438
const double myMaxTravelTime
the maximum travel time to write
Definition: MSMeanData.h:425
The vehicle arrived at a junction.
T MIN4(T a, T b, T c, T d)
Definition: StdDefs.h:97
MSLane *const myLane
Lane on which the reminder works.
bool isEmpty() const
Returns whether any data was collected.
Definition: MSMeanData.cpp:365
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
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.
weights: time range begin
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:162
std::map< const SUMOVehicle *, TrackerEntry * > myTrackedData
The map of vehicles to data entries.
Definition: MSMeanData.h:282
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:165
T MAX2(T a, T b)
Definition: StdDefs.h:76
virtual bool isEmpty() const
Returns whether any data was collected.
Definition: MSMeanData.cpp:264
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:514
The vehicle changes the segment (meso only)
virtual void notifyMoveInternal(const SUMOVehicle &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.
const std::string & getID() const
Returns the id.
Definition: Named.h:78
#define TS
Definition: SUMOTime.h:45
double getLength() const
return the length of the edge
Definition: MSEdge.h:568
void notifyMoveInternal(const SUMOVehicle &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
double getSpeedLimit() const
Returns the speed limit of the edge The speed limit of the first lane is retured; should probably be...
Definition: MSEdge.cpp:899
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
#define SIMTIME
Definition: SUMOTime.h:65
std::list< TrackerEntry * > myCurrentData
The currently active meandata "intervals".
Definition: MSMeanData.h:285
virtual MSMeanData::MeanDataValues * createValues(MSLane *const lane, const double length, const bool doAdd) const =0
Create an instance of MeanDataValues.
void addTo(MSMeanData::MeanDataValues &val) const
Add the values of this to the given one and store them there.
Definition: MSMeanData.cpp:320
bool notifyMove(SUMOVehicle &veh, double oldPos, double newPos, double newSpeed)
Checks whether the reminder still has to be notified about the vehicle moves.
Definition: MSMeanData.cpp:85
A road/street connecting two junctions.
Definition: MSEdge.h:75
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Computes current values and adds them to their sums.
Definition: MSMeanData.cpp:341
const bool myPrintDefaults
Whether empty lanes/edges shall be written.
Definition: MSMeanData.h:444
Representation of a vehicle.
Definition: SUMOVehicle.h:60
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder&#39;s lane.
Definition: MSMeanData.cpp:332
Data structure for mean (aggregated) edge/lane values.
Definition: MSMeanData.h:69
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: MSMeanData.h:260
MSEdgeVector myEdges
The corresponding first edges.
Definition: MSMeanData.h:441
const bool myAmEdgeBased
Information whether the output shall be edge-based (not lane-based)
Definition: MSMeanData.h:435
double getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:506
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 double minSamples, const double maxTravelTime, const std::string &vTypes)
Constructor.
Definition: MSMeanData.cpp:405
T MIN2(T a, T b)
Definition: StdDefs.h:70
void addDetector(MSMoveReminder *data)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:212
Something on a lane to be noticed about vehicle movement.
const SUMOTime myDumpBegin
The first and the last time step to write information (-1 indicates always)
Definition: MSMeanData.h:438
const double myLaneLength
The length of the lane / edge the data collector is on.
Definition: MSMeanData.h:168
virtual ~MSMeanData()
Destructor.
Definition: MSMeanData.cpp:471
const double myMinSamples
the minimum sample seconds
Definition: MSMeanData.h:422
virtual void addTo(MeanDataValues &val) const =0
Add the values of this to the given one and store them there.
begin/end of the description of an edge
virtual void openInterval(OutputDevice &dev, const SUMOTime startTime, const SUMOTime stopTime)
Writes the interval opener.
Definition: MSMeanData.cpp:577
void setDescription(const std::string &description)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:247
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
Definition: MSCFModel.cpp:597
virtual ~MeanDataValues()
Destructor.
Definition: MSMeanData.cpp:68
std::string myID
The name of the object.
Definition: Named.h:130
const MSMeanData *const myParent
The meandata parent.
Definition: MSMeanData.h:165
void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes collected values into the given stream.
Definition: MSMeanData.cpp:594
virtual void reset(bool afterWrite=false)=0
Resets values so they may be used for the next interval.
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:453
virtual bool hasArrived() const =0
Returns whether this vehicle has arrived.
virtual void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using "netstats" as root element.
Definition: MSMeanData.cpp:634
weights: time range end
A single mesoscopic segment (cell)
Definition: MESegment.h:50
virtual void update()
Called if a per timestep update is needed. Default does nothing.
Definition: MSMeanData.cpp:270
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:584
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:106
double getLength() const
Get vehicle&#39;s length [m].
const MSEdgeVector & getEdges() const
Returns loaded edges.
virtual void detectorUpdate(const SUMOTime step)
Updates the detector.
Definition: MSMeanData.cpp:640
an aggreagated-output interval
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
virtual double getSamples() const
Returns the number of collected sample seconds.
Definition: MSMeanData.cpp:275
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:56
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:359
#define NUMERICAL_EPS
Definition: config.h:148
void prepareDetectorForWriting(MSMoveReminder &data)
Updates data of a detector for all vehicle queues.
Definition: MESegment.cpp:238
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:71
void resetOnly(SUMOTime stopTime)
Resets network value in order to allow processing of the next interval.
Definition: MSMeanData.cpp:481
const bool myDumpEmpty
Whether empty lanes/edges shall be written.
Definition: MSMeanData.h:431
MeanDataValues(MSLane *const lane, const double length, const bool doAdd, const MSMeanData *const parent)
Constructor.
Definition: MSMeanData.cpp:58
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
Data structure for mean (aggregated) edge/lane values for tracked vehicles.
Definition: MSMeanData.h:186
const bool myTrackVehicles
Whether vehicles are tracked.
Definition: MSMeanData.h:450
static bool gUseMesoSim
Definition: MSGlobals.h:91
Representation of a lane in the micro simulation.
Definition: MSLane.h:78
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:511
virtual double getPreviousSpeed() const =0
Returns the vehicle&#39;s previous speed.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
virtual std::string getEdgeID(const MSEdge *const edge)
Return the relevant edge id.
Definition: MSMeanData.cpp:505
virtual bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder&#39;s lane.
Definition: MSMeanData.cpp:255
Base of value-generating classes (detectors)
void init()
Adds the value collectors to all relevant edges.
Definition: MSMeanData.cpp:426
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
void reset(bool afterWrite)
Resets values so they may be used for the next interval.
Definition: MSMeanData.cpp:308