SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSMeanData.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Data collector for edges/lanes
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
13 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
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 <microsim/MSEdgeControl.h>
35 #include <microsim/MSEdge.h>
36 #include <microsim/MSLane.h>
37 #include <microsim/MSVehicle.h>
38 #include <microsim/MSNet.h>
39 #include <utils/common/SUMOTime.h>
40 #include <utils/common/ToString.h>
42 #include "MSMeanData.h"
43 #include <limits>
44 
45 #ifdef HAVE_MESOSIM
46 #include <microsim/MSGlobals.h>
47 #include <mesosim/MELoop.h>
48 #include <mesosim/MESegment.h>
49 #endif
50 
51 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
59 // ---------------------------------------------------------------------------
60 // MSMeanData::MeanDataValues - methods
61 // ---------------------------------------------------------------------------
63  MSLane* const lane, const SUMOReal length, const bool doAdd,
64  const std::set<std::string>* const vTypes) :
65  MSMoveReminder(lane, doAdd),
66  myLaneLength(length),
67  sampleSeconds(0),
68  travelledDistance(0),
69  myVehicleTypes(vTypes) {}
70 
71 
73 }
74 
75 
76 bool
78  UNUSED_PARAMETER(reason);
79  return vehicleApplies(veh);
80 }
81 
82 
83 bool
85  SUMOReal timeOnLane = TS;
86  bool ret = true;
87  if (oldPos < 0 && newSpeed != 0) {
88  timeOnLane = newPos / newSpeed;
89  }
90  if (newPos-veh.getVehicleType().getLength() > myLaneLength && newSpeed != 0) {
91  timeOnLane -= (newPos - veh.getVehicleType().getLength() - myLaneLength) / newSpeed;
92  if (fabs(timeOnLane) < 0.001) { // reduce rounding errors
93  timeOnLane = 0.;
94  }
95  ret = false;
96  }
97  if (timeOnLane < 0) {
98  WRITE_ERROR("Negative vehicle step fraction for '" + veh.getID() + "' on lane '" + getLane()->getID() + "'.");
99  return false;
100  }
101  if (timeOnLane == 0) {
102  return false;
103  }
104  notifyMoveInternal(veh, timeOnLane, newSpeed);
105  return ret;
106 }
107 
108 
109 bool
111  return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
112 }
113 
114 
115 bool
117  return myVehicleTypes == 0 || myVehicleTypes->empty() ||
118  myVehicleTypes->find(veh.getVehicleType().getID()) != myVehicleTypes->end();
119 }
120 
121 
122 bool
124  return sampleSeconds == 0;
125 }
126 
127 
128 void
130 }
131 
132 
133 SUMOReal
135  return sampleSeconds;
136 }
137 
138 
139 // ---------------------------------------------------------------------------
140 // MSMeanData::MeanDataValueTracker - methods
141 // ---------------------------------------------------------------------------
143  const SUMOReal length,
144  const std::set<std::string>* const vTypes,
145  const MSMeanData* const parent)
146  : MSMeanData::MeanDataValues(lane, length, true, vTypes), myParent(parent) {
147  myCurrentData.push_back(new TrackerEntry(parent->createValues(lane, length, false)));
148 }
149 
150 
152 }
153 
154 
155 void
157  if (afterWrite) {
158  myCurrentData.pop_front();
159  } else {
160  myCurrentData.push_back(new TrackerEntry(myParent->createValues(myLane, myLaneLength, false)));
161  }
162 }
163 
164 
165 void
167  myCurrentData.front()->myValues->addTo(val);
168 }
169 
170 
171 void
173  myTrackedData[&veh]->myValues->notifyMoveInternal(veh, timeOnLane, speed);
174 }
175 
176 
177 bool
179  if (myParent == 0 || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
180  myTrackedData[&veh]->myNumVehicleLeft++;
181  }
182  return myTrackedData[&veh]->myValues->notifyLeave(veh, lastPos, reason);
183 }
184 
185 
186 bool
188  if (reason == MSMoveReminder::NOTIFICATION_SEGMENT) {
189  return true;
190  }
191  if (vehicleApplies(veh) && myTrackedData.find(&veh) == myTrackedData.end()) {
192  myTrackedData[&veh] = myCurrentData.back();
193  myTrackedData[&veh]->myNumVehicleEntered++;
194  if (!myTrackedData[&veh]->myValues->notifyEnter(veh, reason)) {
195  myTrackedData[&veh]->myNumVehicleLeft++;
196  myTrackedData.erase(&veh);
197  return false;
198  }
199  return true;
200  }
201  return false;
202 }
203 
204 
205 bool
207  return myCurrentData.front()->myValues->isEmpty();
208 }
209 
210 
211 void
213  const SUMOTime period,
214  const SUMOReal numLanes,
215  const SUMOReal defaultTravelTime,
216  const int /*numVehicles*/) const {
217  myCurrentData.front()->myValues->write(dev, period, numLanes,
218  defaultTravelTime,
219  myCurrentData.front()->myNumVehicleEntered);
220 }
221 
222 
223 size_t
225  size_t result = 0;
226  for (std::list<TrackerEntry*>::const_iterator it = myCurrentData.begin(); it != myCurrentData.end(); ++it) {
227  if ((*it)->myNumVehicleEntered == (*it)->myNumVehicleLeft) {
228  result++;
229  } else {
230  break;
231  }
232  }
233  return result;
234 }
235 
236 
237 SUMOReal
239  return myCurrentData.front()->myValues->getSamples();
240 }
241 
242 
243 // ---------------------------------------------------------------------------
244 // MSMeanData - methods
245 // ---------------------------------------------------------------------------
246 MSMeanData::MSMeanData(const std::string& id,
247  const SUMOTime dumpBegin, const SUMOTime dumpEnd,
248  const bool useLanes, const bool withEmpty,
249  const bool printDefaults, const bool withInternal, const bool trackVehicles,
250  const SUMOReal maxTravelTime,
251  const SUMOReal minSamples,
252  const std::set<std::string> vTypes) :
254  myMinSamples(minSamples),
255  myMaxTravelTime(maxTravelTime),
256  myVehicleTypes(vTypes),
257  myAmEdgeBased(!useLanes),
258  myDumpBegin(dumpBegin),
259  myDumpEnd(dumpEnd),
260  myDumpEmpty(withEmpty),
261  myPrintDefaults(printDefaults),
262  myDumpInternal(withInternal),
263  myTrackVehicles(trackVehicles) {
264 }
265 
266 
267 void
269  const std::vector<MSEdge*> &edges = MSNet::getInstance()->getEdgeControl().getEdges();
270  for (std::vector<MSEdge*>::const_iterator e = edges.begin(); e != edges.end(); ++e) {
271  if (myDumpInternal || (*e)->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
272  myEdges.push_back(*e);
273  myMeasures.push_back(std::vector<MeanDataValues*>());
274  const std::vector<MSLane*> &lanes = (*e)->getLanes();
275 #ifdef HAVE_MESOSIM
277  MeanDataValues* data;
278  if (myTrackVehicles) {
279  data = new MeanDataValueTracker(0, lanes[0]->getLength(), &myVehicleTypes, this);
280  } else {
281  data = createValues(0, lanes[0]->getLength(), false);
282  }
283  myMeasures.back().push_back(data);
284  MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(**e);
285  while (s != 0) {
286  s->addDetector(data);
287  s->prepareDetectorForWriting(*data);
288  s = s->getNextSegment();
289  }
290  data->reset();
291  data->reset(true);
292  continue;
293  }
294 #endif
296  myMeasures.back().push_back(new MeanDataValueTracker(0, lanes[0]->getLength(), &myVehicleTypes, this));
297  }
298  for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
299  if (myTrackVehicles) {
300  if (myAmEdgeBased) {
301  (*lane)->addMoveReminder(myMeasures.back().back());
302  } else {
303  myMeasures.back().push_back(new MeanDataValueTracker(*lane, (*lane)->getLength(), &myVehicleTypes, this));
304  }
305  } else {
306  myMeasures.back().push_back(createValues(*lane, (*lane)->getLength(), true));
307  }
308  }
309  }
310  }
311 }
312 
313 
315  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
316  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
317  delete *j;
318  }
319  }
320 }
321 
322 
323 void
325  UNUSED_PARAMETER(stopTime);
326 #ifdef HAVE_MESOSIM
328  std::vector<MSEdge*>::iterator edge = myEdges.begin();
329  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i, ++edge) {
330  MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(**edge);
331  MeanDataValues* data = i->front();
332  while (s != 0) {
333  s->prepareDetectorForWriting(*data);
334  s = s->getNextSegment();
335  }
336  data->reset();
337  }
338  return;
339  }
340 #endif
341  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
342  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
343  (*j)->reset();
344  }
345  }
346 }
347 
348 
349 void
351  const std::vector<MeanDataValues*> &edgeValues,
352  MSEdge* edge, SUMOTime startTime, SUMOTime stopTime) {
353 #ifdef HAVE_MESOSIM
355  MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(*edge);
356  MeanDataValues* data = edgeValues.front();
357  while (s != 0) {
358  s->prepareDetectorForWriting(*data);
359  s = s->getNextSegment();
360  }
361  if (writePrefix(dev, *data, "edge", edge->getID())) {
362  data->write(dev, stopTime - startTime,
363  (SUMOReal)edge->getLanes().size(),
364  myPrintDefaults ? edge->getLength() / edge->getMaxSpeed() : -1.);
365  }
366  data->reset(true);
367  return;
368  }
369 #endif
370  std::vector<MeanDataValues*>::const_iterator lane;
371  if (!myAmEdgeBased) {
372  bool writeCheck = myDumpEmpty;
373  if (!writeCheck) {
374  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
375  if (!(*lane)->isEmpty()) {
376  writeCheck = true;
377  break;
378  }
379  }
380  }
381  if (writeCheck) {
382  dev.openTag("edge").writeAttr(SUMO_ATTR_ID, edge->getID()).closeOpener();
383  }
384  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
385  MeanDataValues& meanData = **lane;
386  if (writePrefix(dev, meanData, "lane", meanData.getLane()->getID())) {
387  meanData.write(dev, stopTime - startTime, 1.f,
388  myPrintDefaults ? meanData.getLane()->getLength() / meanData.getLane()->getMaxSpeed() : -1.);
389  }
390  meanData.reset(true);
391  }
392  if (writeCheck) {
393  dev.closeTag();
394  }
395  } else {
396  if (myTrackVehicles) {
397  MeanDataValues& meanData = **edgeValues.begin();
398  if (writePrefix(dev, meanData, "edge", edge->getID())) {
399  meanData.write(dev, stopTime - startTime, (SUMOReal)edge->getLanes().size(),
400  myPrintDefaults ? edge->getLength() / edge->getMaxSpeed() : -1.);
401  }
402  meanData.reset(true);
403  } else {
404  MeanDataValues* sumData = createValues(0, edge->getLength(), false);
405  for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
406  MeanDataValues& meanData = **lane;
407  meanData.addTo(*sumData);
408  meanData.reset();
409  }
410  if (writePrefix(dev, *sumData, "edge", edge->getID())) {
411  sumData->write(dev, stopTime - startTime, (SUMOReal)edge->getLanes().size(),
412  myPrintDefaults ? edge->getLength() / edge->getMaxSpeed() : -1.);
413  }
414  delete sumData;
415  }
416  }
417 }
418 
419 
420 bool
421 MSMeanData::writePrefix(OutputDevice& dev, const MeanDataValues& values, const std::string tag, const std::string id) const {
422  if (myDumpEmpty || !values.isEmpty()) {
423  dev.openTag(tag).writeAttr(SUMO_ATTR_ID, id) << " sampledSeconds=\"" << values.getSamples();
424  return true;
425  }
426  return false;
427 }
428 
429 
430 void
432  SUMOTime startTime, SUMOTime stopTime) {
433  // check whether this dump shall be written for the current time
434  size_t numReady = myDumpBegin < stopTime && myDumpEnd - DELTA_T >= startTime;
435  if (myTrackVehicles && myDumpBegin < stopTime) {
436  myPendingIntervals.push_back(std::make_pair(startTime, stopTime));
437  numReady = myPendingIntervals.size();
438  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i) {
439  for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
440  numReady = MIN2(numReady, ((MeanDataValueTracker*)*j)->getNumReady());
441  if (numReady == 0) {
442  break;
443  }
444  }
445  if (numReady == 0) {
446  break;
447  }
448  }
449  }
450  if (numReady == 0 || myTrackVehicles) {
451  resetOnly(stopTime);
452  }
453  while (numReady-- > 0) {
454  if (!myPendingIntervals.empty()) {
455  startTime = myPendingIntervals.front().first;
456  stopTime = myPendingIntervals.front().second;
457  myPendingIntervals.pop_front();
458  }
459  dev.openTag("interval") << " begin=\"" << time2string(startTime) << "\" end=\"" <<
460  time2string(stopTime) << "\" " << "id=\"" << myID << "\">\n";
461  std::vector<MSEdge*>::iterator edge = myEdges.begin();
462  for (std::vector<std::vector<MeanDataValues*> >::const_iterator i = myMeasures.begin(); i != myMeasures.end(); ++i, ++edge) {
463  writeEdge(dev, (*i), *edge, startTime, stopTime);
464  }
465  dev.closeTag();
466  }
467 }
468 
469 
470 void
472  dev.writeXMLHeader("netstats");
473 }
474 
475 
476 void
478  if (step + DELTA_T == myDumpBegin) {
479  init();
480  }
481 }
482 
483 
484 /****************************************************************************/
485