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