SUMO - Simulation of Urban MObility
MSMeanData_Net.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2004-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 /****************************************************************************/
19 // Network state mean data collector for edges/lanes
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <microsim/MSEdgeControl.h>
33 #include <microsim/MSEdge.h>
34 #include <microsim/MSLane.h>
35 #include <microsim/MSVehicle.h>
36 #include <utils/common/SUMOTime.h>
37 #include <utils/common/ToString.h>
39 #include "MSMeanData_Net.h"
40 
41 #include <microsim/MSGlobals.h>
42 #include <mesosim/MELoop.h>
43 #include <mesosim/MESegment.h>
44 
45 // ===========================================================================
46 // debug constants
47 // ===========================================================================
48 //#define DEBUG_OCCUPANCY
49 //#define DEBUG_OCCUPANCY2
50 //#define DEBUG_NOTIFY_ENTER
51 //#define DEBUG_COND (veh.getLane()->getID() == "31to211_0")
52 #define DEBUG_COND (false)
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
58 // ---------------------------------------------------------------------------
59 // MSMeanData_Net::MSLaneMeanDataValues - methods
60 // ---------------------------------------------------------------------------
62  const double length,
63  const bool doAdd,
64  const MSMeanData_Net* parent)
65  : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
66  nVehDeparted(0), nVehArrived(0), nVehEntered(0), nVehLeft(0),
67  nVehVaporized(0), waitSeconds(0),
68  nVehLaneChangeFrom(0), nVehLaneChangeTo(0),
69  frontSampleSeconds(0), frontTravelledDistance(0),
70  vehLengthSum(0), occupationSum(0),
71  minimalVehicleLength(INVALID_DOUBLE),
72  myParent(parent) {}
73 
74 
76 }
77 
78 
79 void
81  nVehDeparted = 0;
82  nVehArrived = 0;
83  nVehEntered = 0;
84  nVehLeft = 0;
85  nVehVaporized = 0;
87  nVehLaneChangeTo = 0;
88  sampleSeconds = 0.;
90  waitSeconds = 0;
93  vehLengthSum = 0;
94  occupationSum = 0;
96 }
97 
98 
99 void
105  v.nVehLeft += nVehLeft;
118  } else {
120  }
121 }
122 
123 
124 void
126  const SUMOVehicle& veh, const double frontOnLane,
127  const double timeOnLane, const double /* meanSpeedFrontOnLane */,
128  const double meanSpeedVehicleOnLane,
129  const double travelledDistanceFrontOnLane,
130  const double travelledDistanceVehicleOnLane,
131  const double meanLengthOnLane) {
132 #ifdef DEBUG_OCCUPANCY
133  if DEBUG_COND {
134  std::cout << SIMTIME << "\n MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal()\n"
135  << " veh '" << veh.getID() << "' on lane '" << veh.getLane()->getID() << "'"
136  << ", timeOnLane=" << timeOnLane
137  << ", meanSpeedVehicleOnLane=" << meanSpeedVehicleOnLane
138  << ",\ntravelledDistanceFrontOnLane=" << travelledDistanceFrontOnLane
139  << ", travelledDistanceVehicleOnLane=" << travelledDistanceVehicleOnLane
140  << ", meanLengthOnLane=" << meanLengthOnLane
141  << std::endl;
142  }
143 #endif
144  sampleSeconds += timeOnLane;
145  travelledDistance += travelledDistanceVehicleOnLane;
146  vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
148  // For the mesosim case no information on whether the vehicle was occupying
149  // the lane with its whole length is available. We assume the whole length
150  // Therefore this increment is taken out with more information on the vehicle movement.
151  occupationSum += veh.getVehicleType().getLength() * timeOnLane;
152  } else {
153  // for the microsim case more elaborate calculation of the average length on the lane,
154  // is taken out in notifyMove(), refs #153
155  occupationSum += meanLengthOnLane * TS;
156  }
157  if (myParent != 0 && meanSpeedVehicleOnLane < myParent->myHaltSpeed) {
158  waitSeconds += timeOnLane;
159  }
160  frontSampleSeconds += frontOnLane;
161  frontTravelledDistance += travelledDistanceFrontOnLane;
164  } else {
166  }
167 #ifdef DEBUG_OCCUPANCY2
168  // refs #3265
169  std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength << std::endl;
170 #endif
171 }
172 
173 
174 bool
175 MSMeanData_Net::MSLaneMeanDataValues::notifyLeave(SUMOVehicle& veh, double /*lastPos*/, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
176  if ((myParent == 0 || myParent->vehicleApplies(veh)) && (getLane() == 0 || getLane() == static_cast<MSVehicle&>(veh).getLane())) {
179  }
180  if (reason == MSMoveReminder::NOTIFICATION_ARRIVED) {
181  ++nVehArrived;
182  } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
184  } else if (myParent == 0 || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
185  ++nVehLeft;
187  ++nVehVaporized;
188  }
189  }
190  }
192  return false;
193  }
194  return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
195 }
196 
197 
198 bool
200 #ifdef DEBUG_NOTIFY_ENTER
201  std::cout << "\n" << SIMTIME << " MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
202 #else
203  UNUSED_PARAMETER(enteredLane);
204 #endif
205  if (myParent == 0 || myParent->vehicleApplies(veh)) {
206  if (getLane() == 0 || getLane() == static_cast<MSVehicle&>(veh).getLane()) {
208  ++nVehDeparted;
209  } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
211  } else if (myParent == 0 || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
212  ++nVehEntered;
213  }
214  }
215  return true;
216  }
217  return false;
218 }
219 
220 
221 bool
223  return sampleSeconds == 0 && nVehDeparted == 0 && nVehArrived == 0 && nVehEntered == 0
224  && nVehLeft == 0 && nVehVaporized == 0 && nVehLaneChangeFrom == 0 && nVehLaneChangeTo == 0;
225 }
226 
227 
228 void
230  const double numLanes, const double defaultTravelTime, const int numVehicles) const {
231 
232 #ifdef DEBUG_OCCUPANCY2
233  // tests #3264
234  double occupancy = occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 100;
235  if (occupancy > 100) {
236  std::cout << SIMTIME << " Encountered bad occupancy: " << occupancy
237  << ", myLaneLength=" << myLaneLength << ", period=" << STEPS2TIME(period) << ", occupationSum=" << occupationSum
238  << std::endl;
239  }
240  // refs #3265
241  std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength
242  << "\ndensity=" << MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength, 1. / MAX2(minimalVehicleLength, NUMERICAL_EPS)) << std::endl;
243 #endif
244 
245  if (myParent == 0) {
246  if (sampleSeconds > 0) {
247  dev.writeAttr("density", MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength, 1000. / MAX2(minimalVehicleLength, NUMERICAL_EPS)))
248  .writeAttr("occupancy", occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 100)
249  .writeAttr("waitingTime", waitSeconds).writeAttr("speed", travelledDistance / sampleSeconds);
250  }
251  dev.writeAttr("departed", nVehDeparted).writeAttr("arrived", nVehArrived).writeAttr("entered", nVehEntered).writeAttr("left", nVehLeft);
252  if (nVehVaporized > 0) {
253  dev.writeAttr("vaporized", nVehVaporized);
254  }
255  dev.closeTag();
256  return;
257  }
259  double overlapTraveltime = myParent->myMaxTravelTime;
260  if (travelledDistance > 0.f) {
261  // one vehicle has to drive lane length + vehicle length before it has left the lane
262  // thus we need to scale with an extended length, approximated by lane length + average vehicle length
263  overlapTraveltime = MIN2(overlapTraveltime, (myLaneLength + vehLengthSum / sampleSeconds) * sampleSeconds / travelledDistance);
264  }
265  if (numVehicles > 0) {
266  dev.writeAttr("traveltime", sampleSeconds / numVehicles).writeAttr("waitingTime", waitSeconds).writeAttr("speed", travelledDistance / sampleSeconds);
267  } else {
268  double traveltime = myParent->myMaxTravelTime;
270  traveltime = MIN2(traveltime, myLaneLength * frontSampleSeconds / frontTravelledDistance);
271  dev.writeAttr("traveltime", traveltime);
272  } else if (defaultTravelTime >= 0.) {
273  dev.writeAttr("traveltime", defaultTravelTime);
274  }
275  dev.writeAttr("overlapTraveltime", overlapTraveltime)
276  .writeAttr("density", MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength, 1000. / MAX2(minimalVehicleLength, NUMERICAL_EPS)))
277  .writeAttr("occupancy", occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 100)
278  .writeAttr("waitingTime", waitSeconds).writeAttr("speed", travelledDistance / sampleSeconds);
279  }
280  } else if (defaultTravelTime >= 0.) {
281  dev.writeAttr("traveltime", defaultTravelTime).writeAttr("speed", myLaneLength / defaultTravelTime);
282  }
283  dev.writeAttr("departed", nVehDeparted).writeAttr("arrived", nVehArrived).writeAttr("entered", nVehEntered).writeAttr("left", nVehLeft)
284  .writeAttr("laneChangedFrom", nVehLaneChangeFrom).writeAttr("laneChangedTo", nVehLaneChangeTo);
285  if (nVehVaporized > 0) {
286  dev.writeAttr("vaporized", nVehVaporized);
287  }
288  dev.closeTag();
289 }
290 
291 // ---------------------------------------------------------------------------
292 // MSMeanData_Net - methods
293 // ---------------------------------------------------------------------------
294 MSMeanData_Net::MSMeanData_Net(const std::string& id,
295  const SUMOTime dumpBegin,
296  const SUMOTime dumpEnd, const bool useLanes,
297  const bool withEmpty, const bool printDefaults,
298  const bool withInternal,
299  const bool trackVehicles,
300  const double maxTravelTime,
301  const double minSamples,
302  const double haltSpeed,
303  const std::string& vTypes)
304  : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, printDefaults,
305  withInternal, trackVehicles, maxTravelTime, minSamples, vTypes),
306  myHaltSpeed(haltSpeed) {
307 }
308 
309 
311 
312 
314 MSMeanData_Net::createValues(MSLane* const lane, const double length, const bool doAdd) const {
315  return new MSLaneMeanDataValues(lane, length, doAdd, this);
316 }
317 
318 
319 /****************************************************************************/
320 
Data collector for edges/lanes.
Definition: MSMeanData.h:66
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
double vehLengthSum
The sum of the lengths the vehicles had.
int nVehEntered
The number of vehicles that entered this lane within the sample interval.
virtual ~MSLaneMeanDataValues()
Destructor.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder&#39;s lane.
int nVehVaporized
The number of vehicles that left this lane within the sample interval.
bool vehicleApplies(const SUMOVehicle &veh) const
Checks whether the detector measures vehicles of the given type.
double frontSampleSeconds
The number of vehicle probes regarding the vehicle front.
const double myMaxTravelTime
the maximum travel time to write
Definition: MSMeanData.h:431
The vehicle arrived at a junction.
void removeFromVehicleUpdateValues(SUMOVehicle &veh)
Notification
Definition of a vehicle state.
const MSMeanData_Net * myParent
The meandata parent.
const double myHaltSpeed
the minimum sample seconds
virtual MSLane * getLane() const =0
Returns the lane the vehicle is on.
T MAX2(T a, T b)
Definition: StdDefs.h:73
The vehicle got vaporized.
The vehicle changes the segment (meso only)
MSMeanData::MeanDataValues * createValues(MSLane *const lane, const double length, const bool doAdd) const
Create an instance of MeanDataValues.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
#define TS
Definition: SUMOTime.h:51
#define DEBUG_COND
MSLaneMeanDataValues(MSLane *const lane, const double length, const bool doAdd, const MSMeanData_Net *parent)
Constructor.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
Data structure for mean (aggregated) edge/lane values.
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.
#define SIMTIME
Definition: SUMOTime.h:71
The vehicle changes lanes (micro only)
int nVehLaneChangeTo
The number of vehicles that changed to this lane.
double travelledDistance
The sum of the distances the vehicles travelled.
Definition: MSMeanData.h:182
Representation of a vehicle.
Definition: SUMOVehicle.h:66
Data structure for mean (aggregated) edge/lane values.
Definition: MSMeanData.h:75
virtual ~MSMeanData_Net()
Destructor.
The vehicle arrived at its destination (is deleted)
#define STEPS2TIME(x)
Definition: SUMOTime.h:64
T MIN2(T a, T b)
Definition: StdDefs.h:67
void notifyMoveInternal(const SUMOVehicle &veh, const double frontOnLane, const double timeOnLane, const double, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane)
Internal notification about the vehicle moves.
const double myLaneLength
The length of the lane / edge the data collector is on.
Definition: MSMeanData.h:174
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Computes current values and adds them to their sums.
const double myMinSamples
the minimum sample seconds
Definition: MSMeanData.h:428
MSMeanData_Net(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 maxTravelTime, const double minSamples, const double haltSpeed, const std::string &vTypes)
Constructor.
double waitSeconds
The number of vehicle probes with small speed.
int nVehLeft
The number of vehicles that left this lane within the sample interval.
int nVehArrived
The number of vehicles that finished on the lane.
The vehicle has departed (was inserted into the network)
double frontTravelledDistance
The travelled distance regarding the vehicle front.
const std::string & getDescription() const
int nVehLaneChangeFrom
The number of vehicles that changed from this lane.
double occupationSum
The sum of the occupation of the lane.
double getLength() const
Get vehicle&#39;s length [m].
void addTo(MSMeanData::MeanDataValues &val) const
Add the values of this to the given one and store them there.
bool isEmpty() const
Returns whether any data was collected.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
Network state mean data collector for edges/lanes.
bool closeTag()
Closes the most recently opened tag.
long long int SUMOTime
Definition: TraCIDefs.h:51
#define NUMERICAL_EPS
Definition: config.h:151
void reset(bool afterWrite=false)
Resets values so they may be used for the next interval.
const double INVALID_DOUBLE
Definition: StdDefs.h:59
double minimalVehicleLength
minimal vehicle length in the current interval (used to determine a maximal density, see #3265)
static bool gUseMesoSim
Definition: MSGlobals.h:97
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.