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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // Network state mean data collector for edges/lanes
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <microsim/MSEdgeControl.h>
27 #include <microsim/MSEdge.h>
28 #include <microsim/MSLane.h>
29 #include <microsim/MSVehicle.h>
30 #include <utils/common/SUMOTime.h>
31 #include <utils/common/ToString.h>
33 #include "MSMeanData_Net.h"
34 
35 #include <microsim/MSGlobals.h>
36 #include <mesosim/MELoop.h>
37 #include <mesosim/MESegment.h>
38 
39 // ===========================================================================
40 // debug constants
41 // ===========================================================================
42 //#define DEBUG_OCCUPANCY
43 //#define DEBUG_OCCUPANCY2
44 //#define DEBUG_NOTIFY_ENTER
45 //#define DEBUG_COND (veh.getLane()->getID() == "31to211_0")
46 #define DEBUG_COND (false)
47 
48 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
52 // ---------------------------------------------------------------------------
53 // MSMeanData_Net::MSLaneMeanDataValues - methods
54 // ---------------------------------------------------------------------------
56  const double length,
57  const bool doAdd,
58  const MSMeanData_Net* parent)
59  : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
60  nVehDeparted(0), nVehArrived(0), nVehEntered(0), nVehLeft(0),
61  nVehVaporized(0), waitSeconds(0),
62  nVehLaneChangeFrom(0), nVehLaneChangeTo(0),
63  frontSampleSeconds(0), frontTravelledDistance(0),
64  vehLengthSum(0), occupationSum(0),
65  minimalVehicleLength(INVALID_DOUBLE),
66  myParent(parent) {}
67 
68 
70 }
71 
72 
73 void
75  nVehDeparted = 0;
76  nVehArrived = 0;
77  nVehEntered = 0;
78  nVehLeft = 0;
79  nVehVaporized = 0;
81  nVehLaneChangeTo = 0;
82  sampleSeconds = 0.;
84  waitSeconds = 0;
87  vehLengthSum = 0;
88  occupationSum = 0;
90 }
91 
92 
93 void
99  v.nVehLeft += nVehLeft;
112  } else {
114  }
115 }
116 
117 
118 void
120  const SUMOVehicle& veh, const double frontOnLane,
121  const double timeOnLane, const double /* meanSpeedFrontOnLane */,
122  const double meanSpeedVehicleOnLane,
123  const double travelledDistanceFrontOnLane,
124  const double travelledDistanceVehicleOnLane,
125  const double meanLengthOnLane) {
126 #ifdef DEBUG_OCCUPANCY
127  if DEBUG_COND {
128  std::cout << SIMTIME << "\n MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal()\n"
129  << " veh '" << veh.getID() << "' on lane '" << veh.getLane()->getID() << "'"
130  << ", timeOnLane=" << timeOnLane
131  << ", meanSpeedVehicleOnLane=" << meanSpeedVehicleOnLane
132  << ",\ntravelledDistanceFrontOnLane=" << travelledDistanceFrontOnLane
133  << ", travelledDistanceVehicleOnLane=" << travelledDistanceVehicleOnLane
134  << ", meanLengthOnLane=" << meanLengthOnLane
135  << std::endl;
136  }
137 #endif
138  sampleSeconds += timeOnLane;
139  travelledDistance += travelledDistanceVehicleOnLane;
140  vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
142  // For the mesosim case no information on whether the vehicle was occupying
143  // the lane with its whole length is available. We assume the whole length
144  // Therefore this increment is taken out with more information on the vehicle movement.
145  occupationSum += veh.getVehicleType().getLength() * timeOnLane;
146  } else {
147  // for the microsim case more elaborate calculation of the average length on the lane,
148  // is taken out in notifyMove(), refs #153
149  occupationSum += meanLengthOnLane * TS;
150  }
151  if (myParent != nullptr && meanSpeedVehicleOnLane < myParent->myHaltSpeed) {
152  waitSeconds += timeOnLane;
153  }
154  frontSampleSeconds += frontOnLane;
155  frontTravelledDistance += travelledDistanceFrontOnLane;
158  } else {
160  }
161 #ifdef DEBUG_OCCUPANCY2
162  // refs #3265
163  std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength << std::endl;
164 #endif
165 }
166 
167 
168 bool
169 MSMeanData_Net::MSLaneMeanDataValues::notifyLeave(SUMOVehicle& veh, double /*lastPos*/, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
170  if ((myParent == nullptr || myParent->vehicleApplies(veh)) && (getLane() == nullptr || getLane() == static_cast<MSVehicle&>(veh).getLane())) {
173  }
174  if (reason == MSMoveReminder::NOTIFICATION_ARRIVED) {
175  ++nVehArrived;
176  } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
178  } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
179  ++nVehLeft;
181  ++nVehVaporized;
182  }
183  }
184  }
186  return false;
187  }
188  return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
189 }
190 
191 
192 bool
194 #ifdef DEBUG_NOTIFY_ENTER
195  std::cout << "\n" << SIMTIME << " MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
196 #else
197  UNUSED_PARAMETER(enteredLane);
198 #endif
199  if (myParent == nullptr || myParent->vehicleApplies(veh)) {
200  if (getLane() == nullptr || getLane() == static_cast<MSVehicle&>(veh).getLane()) {
202  ++nVehDeparted;
203  } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
205  } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
206  ++nVehEntered;
207  }
208  }
209  return true;
210  }
211  return false;
212 }
213 
214 
215 bool
217  return sampleSeconds == 0 && nVehDeparted == 0 && nVehArrived == 0 && nVehEntered == 0
218  && nVehLeft == 0 && nVehVaporized == 0 && nVehLaneChangeFrom == 0 && nVehLaneChangeTo == 0;
219 }
220 
221 
222 void
224  const double numLanes, const double defaultTravelTime, const int numVehicles) const {
225 
226 #ifdef DEBUG_OCCUPANCY2
227  // tests #3264
228  double occupancy = occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 100;
229  if (occupancy > 100) {
230  std::cout << SIMTIME << " Encountered bad occupancy: " << occupancy
231  << ", myLaneLength=" << myLaneLength << ", period=" << STEPS2TIME(period) << ", occupationSum=" << occupationSum
232  << std::endl;
233  }
234  // refs #3265
235  std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength
236  << "\ndensity=" << MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength, 1. / MAX2(minimalVehicleLength, NUMERICAL_EPS)) << std::endl;
237 #endif
238 
239  if (myParent == nullptr) {
240  if (sampleSeconds > 0) {
241  dev.writeAttr("density", MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength, 1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS)))
242  .writeAttr("occupancy", occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 100)
243  .writeAttr("waitingTime", waitSeconds).writeAttr("speed", travelledDistance / sampleSeconds);
244  }
245  dev.writeAttr("departed", nVehDeparted).writeAttr("arrived", nVehArrived).writeAttr("entered", nVehEntered).writeAttr("left", nVehLeft);
246  if (nVehVaporized > 0) {
247  dev.writeAttr("vaporized", nVehVaporized);
248  }
249  dev.closeTag();
250  return;
251  }
253  double overlapTraveltime = myParent->myMaxTravelTime;
254  if (travelledDistance > 0.f) {
255  // one vehicle has to drive lane length + vehicle length before it has left the lane
256  // thus we need to scale with an extended length, approximated by lane length + average vehicle length
257  overlapTraveltime = MIN2(overlapTraveltime, (myLaneLength + vehLengthSum / sampleSeconds) * sampleSeconds / travelledDistance);
258  }
259  if (numVehicles > 0) {
260  dev.writeAttr("traveltime", sampleSeconds / numVehicles).writeAttr("waitingTime", waitSeconds).writeAttr("speed", travelledDistance / sampleSeconds);
261  } else {
262  double traveltime = myParent->myMaxTravelTime;
264  traveltime = MIN2(traveltime, myLaneLength * frontSampleSeconds / frontTravelledDistance);
265  dev.writeAttr("traveltime", traveltime);
266  } else if (defaultTravelTime >= 0.) {
267  dev.writeAttr("traveltime", defaultTravelTime);
268  }
269  dev.writeAttr("overlapTraveltime", overlapTraveltime)
270  .writeAttr("density", MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength, 1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS)))
271  .writeAttr("occupancy", occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 100)
272  .writeAttr("waitingTime", waitSeconds).writeAttr("speed", travelledDistance / sampleSeconds);
273  }
274  } else if (defaultTravelTime >= 0.) {
275  dev.writeAttr("traveltime", defaultTravelTime).writeAttr("speed", myLaneLength / defaultTravelTime);
276  }
277  dev.writeAttr("departed", nVehDeparted).writeAttr("arrived", nVehArrived).writeAttr("entered", nVehEntered).writeAttr("left", nVehLeft)
278  .writeAttr("laneChangedFrom", nVehLaneChangeFrom).writeAttr("laneChangedTo", nVehLaneChangeTo);
279  if (nVehVaporized > 0) {
280  dev.writeAttr("vaporized", nVehVaporized);
281  }
282  dev.closeTag();
283 }
284 
285 // ---------------------------------------------------------------------------
286 // MSMeanData_Net - methods
287 // ---------------------------------------------------------------------------
288 MSMeanData_Net::MSMeanData_Net(const std::string& id,
289  const SUMOTime dumpBegin,
290  const SUMOTime dumpEnd, const bool useLanes,
291  const bool withEmpty, const bool printDefaults,
292  const bool withInternal,
293  const bool trackVehicles,
294  const double maxTravelTime,
295  const double minSamples,
296  const double haltSpeed,
297  const std::string& vTypes)
298  : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, printDefaults,
299  withInternal, trackVehicles, maxTravelTime, minSamples, vTypes),
300  myHaltSpeed(haltSpeed) {
301 }
302 
303 
305 
306 
308 MSMeanData_Net::createValues(MSLane* const lane, const double length, const bool doAdd) const {
309  return new MSLaneMeanDataValues(lane, length, doAdd, this);
310 }
311 
312 
313 /****************************************************************************/
314 
Data collector for edges/lanes.
Definition: MSMeanData.h:60
const MSLane * getLane() const
Returns the lane the reminder works on.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
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:79
long long int SUMOTime
Definition: SUMOTime.h:36
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:425
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:76
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:78
#define TS
Definition: SUMOTime.h:45
#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:33
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:65
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:176
Representation of a vehicle.
Definition: SUMOVehicle.h:60
Data structure for mean (aggregated) edge/lane values.
Definition: MSMeanData.h:69
virtual ~MSMeanData_Net()
Destructor.
The vehicle arrived at its destination (is deleted)
#define STEPS2TIME(x)
Definition: SUMOTime.h:58
T MIN2(T a, T b)
Definition: StdDefs.h:70
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:168
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:422
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:64
Network state mean data collector for edges/lanes.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
#define NUMERICAL_EPS
Definition: config.h:148
void reset(bool afterWrite=false)
Resets values so they may be used for the next interval.
const double INVALID_DOUBLE
Definition: StdDefs.h:62
double minimalVehicleLength
minimal vehicle length in the current interval (used to determine a maximal density, see #3265)
static bool gUseMesoSim
Definition: MSGlobals.h:91
Representation of a lane in the micro simulation.
Definition: MSLane.h:78
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.