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