Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2004-2024 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file MSMeanData_Net.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Michael Behrisch
17 : /// @author Jakob Erdmann
18 : /// @date Mon, 10.05.2004
19 : ///
20 : // Network state mean data collector for edges/lanes
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #ifdef HAVE_FOX
25 : #include <utils/common/ScopedLocker.h>
26 : #endif
27 : #include <utils/common/SUMOTime.h>
28 : #include <utils/common/ToString.h>
29 : #include <utils/iodevices/OutputDevice.h>
30 : #include <microsim/MSEdgeControl.h>
31 : #include <microsim/MSEdge.h>
32 : #include <microsim/MSLane.h>
33 : #include <microsim/MSVehicle.h>
34 : #include <microsim/MSGlobals.h>
35 : #include <mesosim/MELoop.h>
36 : #include <mesosim/MESegment.h>
37 : #include "MSMeanData_Net.h"
38 :
39 :
40 : // ===========================================================================
41 : // debug constants
42 : // ===========================================================================
43 : //#define DEBUG_OCCUPANCY
44 : //#define DEBUG_OCCUPANCY2
45 : //#define DEBUG_NOTIFY_ENTER
46 : //#define DEBUG_COND (veh.getLane()->getID() == "31to211_0")
47 : #define DEBUG_COND (false)
48 :
49 :
50 : // ===========================================================================
51 : // method definitions
52 : // ===========================================================================
53 : // ---------------------------------------------------------------------------
54 : // MSMeanData_Net::MSLaneMeanDataValues - methods
55 : // ---------------------------------------------------------------------------
56 14468790 : MSMeanData_Net::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
57 : const double length,
58 : const bool doAdd,
59 14468790 : const MSMeanData_Net* parent)
60 : : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
61 14468790 : nVehDeparted(0), nVehArrived(0), nVehEntered(0), nVehLeft(0),
62 14468790 : nVehVaporized(0), nVehTeleported(0), waitSeconds(0), timeLoss(0),
63 14468790 : nVehLaneChangeFrom(0), nVehLaneChangeTo(0),
64 14468790 : frontSampleSeconds(0), frontTravelledDistance(0),
65 14468790 : vehLengthSum(0), occupationSum(0),
66 14468790 : minimalVehicleLength(INVALID_DOUBLE),
67 14468790 : myParent(parent) {}
68 :
69 :
70 28796150 : MSMeanData_Net::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
71 28796150 : }
72 :
73 :
74 : void
75 29686216 : MSMeanData_Net::MSLaneMeanDataValues::reset(bool) {
76 29686216 : nVehDeparted = 0;
77 29686216 : nVehArrived = 0;
78 29686216 : nVehEntered = 0;
79 29686216 : nVehLeft = 0;
80 29686216 : nVehVaporized = 0;
81 29686216 : nVehTeleported = 0;
82 29686216 : nVehLaneChangeFrom = 0;
83 29686216 : nVehLaneChangeTo = 0;
84 29686216 : sampleSeconds = 0.;
85 29686216 : travelledDistance = 0;
86 29686216 : waitSeconds = 0;
87 29686216 : timeLoss = 0;
88 29686216 : frontSampleSeconds = 0;
89 29686216 : frontTravelledDistance = 0;
90 29686216 : vehLengthSum = 0;
91 29686216 : occupationSum = 0;
92 29686216 : minimalVehicleLength = INVALID_DOUBLE;
93 29686216 : resetTime = SIMSTEP;
94 29686216 : }
95 :
96 :
97 : void
98 14926581 : MSMeanData_Net::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
99 : MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
100 14926581 : v.nVehDeparted += nVehDeparted;
101 14926581 : v.nVehArrived += nVehArrived;
102 14926581 : v.nVehEntered += nVehEntered;
103 14926581 : v.nVehLeft += nVehLeft;
104 14926581 : v.nVehVaporized += nVehVaporized;
105 14926581 : v.nVehTeleported += nVehTeleported;
106 14926581 : v.nVehLaneChangeFrom += nVehLaneChangeFrom;
107 14926581 : v.nVehLaneChangeTo += nVehLaneChangeTo;
108 14926581 : v.sampleSeconds += sampleSeconds;
109 14926581 : v.travelledDistance += travelledDistance;
110 14926581 : v.waitSeconds += waitSeconds;
111 14926581 : v.timeLoss += timeLoss;
112 14926581 : v.frontSampleSeconds += frontSampleSeconds;
113 14926581 : v.frontTravelledDistance += frontTravelledDistance;
114 14926581 : v.vehLengthSum += vehLengthSum;
115 14926581 : v.occupationSum += occupationSum;
116 14926581 : if (v.minimalVehicleLength == INVALID_DOUBLE) {
117 14871277 : v.minimalVehicleLength = minimalVehicleLength;
118 : } else {
119 104088 : v.minimalVehicleLength = MIN2(minimalVehicleLength, v.minimalVehicleLength);
120 : }
121 14926581 : }
122 :
123 :
124 : void
125 432499859 : MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal(
126 : const SUMOTrafficObject& 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 432499859 : if (myParent != nullptr && !myParent->vehicleApplies(veh)) {
145 : return;
146 : }
147 432457539 : sampleSeconds += timeOnLane;
148 432457539 : travelledDistance += travelledDistanceVehicleOnLane;
149 432457539 : vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
150 432457539 : if (MSGlobals::gUseMesoSim) {
151 : // For the mesosim case no information on whether the vehicle was occupying
152 : // the lane with its whole length is available. We assume the whole length
153 : // Therefore this increment is taken out with more information on the vehicle movement.
154 10344862 : occupationSum += veh.getVehicleType().getLength() * timeOnLane;
155 : } else {
156 : // for the microsim case more elaborate calculation of the average length on the lane,
157 : // is taken out in notifyMove(), refs #153
158 422112677 : occupationSum += meanLengthOnLane * TS;
159 : }
160 432457539 : if (!veh.isStopped()) {
161 401432987 : if (myParent != nullptr && meanSpeedVehicleOnLane < myParent->myHaltSpeed) {
162 78819587 : waitSeconds += timeOnLane;
163 : }
164 401432987 : const double vmax = veh.getLane() == nullptr ? veh.getEdge()->getVehicleMaxSpeed(&veh) : veh.getLane()->getVehicleMaxSpeed(&veh);
165 401432987 : if (vmax > 0) {
166 801101575 : timeLoss += timeOnLane * MAX2(0.0, vmax - meanSpeedVehicleOnLane) / vmax;
167 : }
168 : }
169 432457539 : frontSampleSeconds += frontOnLane;
170 432457539 : frontTravelledDistance += travelledDistanceFrontOnLane;
171 432457539 : if (minimalVehicleLength == INVALID_DOUBLE) {
172 998631 : minimalVehicleLength = veh.getVehicleType().getLengthWithGap();
173 : } else {
174 861501526 : minimalVehicleLength = MIN2(minimalVehicleLength, veh.getVehicleType().getLengthWithGap());
175 : }
176 : #ifdef DEBUG_OCCUPANCY2
177 : // refs #3265
178 : std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength << std::endl;
179 : #endif
180 : }
181 :
182 :
183 : bool
184 19706117 : MSMeanData_Net::MSLaneMeanDataValues::notifyLeave(SUMOTrafficObject& veh, double /*lastPos*/, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
185 19706117 : if ((myParent == nullptr || myParent->vehicleApplies(veh)) && (
186 10661429 : getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane())) {
187 : #ifdef HAVE_FOX
188 16130532 : ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
189 : #endif
190 16130532 : if (MSGlobals::gUseMesoSim) {
191 9044544 : removeFromVehicleUpdateValues(veh);
192 : }
193 16130532 : if (reason == MSMoveReminder::NOTIFICATION_ARRIVED) {
194 1003162 : ++nVehArrived;
195 15127370 : } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
196 100100 : ++nVehLaneChangeFrom;
197 15027270 : } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
198 7157520 : ++nVehLeft;
199 7157520 : if (reason == MSMoveReminder::NOTIFICATION_TELEPORT || reason == MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED) {
200 1527 : ++nVehTeleported;
201 7155993 : } else if (reason >= MSMoveReminder::NOTIFICATION_VAPORIZED_CALIBRATOR) {
202 69006 : ++nVehVaporized;
203 : }
204 : }
205 : }
206 19706117 : if (MSGlobals::gUseMesoSim) {
207 : return false;
208 : }
209 10658873 : return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
210 : }
211 :
212 :
213 : bool
214 16318892 : MSMeanData_Net::MSLaneMeanDataValues::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane) {
215 : #ifdef DEBUG_NOTIFY_ENTER
216 : std::cout << "\n" << SIMTIME << " MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
217 : #else
218 : UNUSED_PARAMETER(enteredLane);
219 : #endif
220 16318892 : if (myParent == nullptr || myParent->vehicleApplies(veh)) {
221 16224256 : if (getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane()) {
222 : #ifdef HAVE_FOX
223 16221556 : ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
224 : #endif
225 16221556 : if (reason == MSMoveReminder::NOTIFICATION_DEPARTED) {
226 1154650 : ++nVehDeparted;
227 15066906 : } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
228 99315 : ++nVehLaneChangeTo;
229 14967591 : } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
230 7128007 : ++nVehEntered;
231 : }
232 : }
233 16224256 : return true;
234 : }
235 : return false;
236 : }
237 :
238 :
239 : bool
240 42568416 : MSMeanData_Net::MSLaneMeanDataValues::isEmpty() const {
241 41390933 : return sampleSeconds == 0 && nVehDeparted == 0 && nVehArrived == 0 && nVehEntered == 0
242 83958601 : && nVehLeft == 0 && nVehVaporized == 0 && nVehTeleported == 0 && nVehLaneChangeFrom == 0 && nVehLaneChangeTo == 0;
243 : }
244 :
245 : double
246 962467 : MSMeanData_Net::MSLaneMeanDataValues::getOccupancy(SUMOTime period, int numLanes) const {
247 962467 : return occupationSum / STEPS2TIME(period) / myLaneLength / (double)numLanes * 100.;
248 : }
249 :
250 : void
251 962347 : MSMeanData_Net::MSLaneMeanDataValues::write(OutputDevice& dev, long long int attributeMask, const SUMOTime period,
252 : const int numLanes, const double speedLimit, const double defaultTravelTime, const int numVehicles) const {
253 :
254 962347 : const double density = MIN2(sampleSeconds / STEPS2TIME(period) * 1000. / myLaneLength,
255 962347 : 1000. * (double)numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
256 962347 : const double laneDensity = density / (double)numLanes;
257 962347 : const double occupancy = getOccupancy(period, numLanes);
258 : #ifdef DEBUG_OCCUPANCY2
259 : // tests #3264
260 : if (occupancy > 100) {
261 : std::cout << SIMTIME << " Encountered bad occupancy: " << occupancy
262 : << ", myLaneLength=" << myLaneLength << ", period=" << STEPS2TIME(period) << ", occupationSum=" << occupationSum
263 : << std::endl;
264 : }
265 : // refs #3265
266 : std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength
267 : << "\ndensity=" << density << "\n";
268 : #endif
269 :
270 962347 : if (myParent == nullptr) {
271 41492 : if (sampleSeconds > 0) {
272 28617 : dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask);
273 28617 : dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask);
274 28617 : dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask);
275 28617 : dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask);
276 28617 : dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask);
277 28617 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, travelledDistance / sampleSeconds, attributeMask);
278 28617 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit, attributeMask);
279 : }
280 41492 : dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
281 41492 : dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
282 41492 : dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
283 41492 : dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
284 41492 : if (nVehVaporized > 0) {
285 0 : dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask);
286 : }
287 41492 : if (nVehTeleported > 0) {
288 0 : dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask);
289 : }
290 41492 : dev.closeTag();
291 41492 : return;
292 : }
293 920855 : if (sampleSeconds > myParent->myMinSamples) {
294 900681 : double overlapTraveltime = myParent->myMaxTravelTime;
295 900681 : if (travelledDistance > 0.f) {
296 : // one vehicle has to drive lane length + vehicle length before it has left the lane
297 : // thus we need to scale with an extended length, approximated by lane length + average vehicle length
298 1026182 : overlapTraveltime = MIN2(overlapTraveltime, (myLaneLength + vehLengthSum / sampleSeconds) * sampleSeconds / travelledDistance);
299 : }
300 900681 : if (numVehicles > 0) {
301 232 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, sampleSeconds / numVehicles, attributeMask);
302 232 : dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask);
303 232 : dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask);
304 232 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, travelledDistance / sampleSeconds, attributeMask);
305 232 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit, attributeMask);
306 : } else {
307 900449 : double traveltime = myParent->myMaxTravelTime;
308 900449 : if (frontTravelledDistance > NUMERICAL_EPS) {
309 509328 : traveltime = MIN2(traveltime, myLaneLength * frontSampleSeconds / frontTravelledDistance);
310 509328 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, traveltime, attributeMask);
311 391121 : } else if (defaultTravelTime >= 0.) {
312 0 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, defaultTravelTime, attributeMask);
313 : }
314 900449 : dev.writeOptionalAttr(SUMO_ATTR_OVERLAPTRAVELTIME, overlapTraveltime, attributeMask);
315 900449 : dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask);
316 900449 : dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask);
317 900449 : dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask);
318 900449 : dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask);
319 900449 : dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask);
320 900449 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, travelledDistance / sampleSeconds, attributeMask);
321 900449 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit, attributeMask);
322 : }
323 20174 : } else if (defaultTravelTime >= 0.) {
324 1056 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, defaultTravelTime, attributeMask);
325 1056 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, myLaneLength / defaultTravelTime, attributeMask);
326 1056 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : myLaneLength / defaultTravelTime / speedLimit, attributeMask);
327 : }
328 920855 : dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
329 920855 : dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
330 920855 : dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
331 920855 : dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
332 920855 : dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDFROM, nVehLaneChangeFrom, attributeMask);
333 920855 : dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDTO, nVehLaneChangeTo, attributeMask);
334 920855 : if (nVehVaporized > 0) {
335 117 : dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask);
336 : }
337 920855 : if (nVehTeleported > 0) {
338 952 : dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask);
339 : }
340 1841710 : dev.closeTag();
341 : }
342 :
343 :
344 : double
345 0 : MSMeanData_Net::MSLaneMeanDataValues::getAttributeValue(SumoXMLAttr a,
346 : const SUMOTime period, const double numLanes, const double speedLimit) const {
347 : /// @todo: remove redundancy in derived values (density, laneDensity)
348 0 : switch (a) {
349 0 : case SUMO_ATTR_DENSITY:
350 0 : return MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
351 0 : 1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
352 0 : case SUMO_ATTR_LANEDENSITY: {
353 0 : const double density = MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
354 0 : 1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
355 0 : return density / numLanes;
356 : }
357 0 : case SUMO_ATTR_OCCUPANCY:
358 0 : return occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 1000;
359 0 : case SUMO_ATTR_WAITINGTIME:
360 0 : return waitSeconds;
361 0 : case SUMO_ATTR_TIMELOSS:
362 0 : return timeLoss;
363 0 : case SUMO_ATTR_SPEED:
364 0 : return travelledDistance / sampleSeconds;
365 0 : case SUMO_ATTR_SPEEDREL:
366 0 : return speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit;
367 0 : case SUMO_ATTR_DEPARTED:
368 0 : return nVehDeparted;
369 0 : case SUMO_ATTR_ARRIVED:
370 0 : return nVehArrived;
371 0 : case SUMO_ATTR_ENTERED:
372 0 : return nVehEntered;
373 0 : case SUMO_ATTR_LEFT:
374 0 : return nVehLeft;
375 0 : case SUMO_ATTR_VAPORIZED:
376 0 : return nVehVaporized;
377 0 : case SUMO_ATTR_TELEPORTED:
378 0 : return nVehTeleported;
379 : default:
380 : return 0;
381 : }
382 : }
383 :
384 : // ---------------------------------------------------------------------------
385 : // MSMeanData_Net - methods
386 : // ---------------------------------------------------------------------------
387 4341 : MSMeanData_Net::MSMeanData_Net(const std::string& id,
388 : const SUMOTime dumpBegin,
389 : const SUMOTime dumpEnd, const bool useLanes,
390 : const bool withEmpty, const bool printDefaults,
391 : const bool withInternal,
392 : const bool trackVehicles,
393 : const int detectPersons,
394 : const double maxTravelTime,
395 : const double minSamples,
396 : const double haltSpeed,
397 : const std::string& vTypes,
398 : const std::string& writeAttributes,
399 : const std::vector<MSEdge*>& edges,
400 4341 : bool aggregate) :
401 : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, printDefaults,
402 : withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate),
403 4341 : myHaltSpeed(haltSpeed)
404 4341 : { }
405 :
406 :
407 8203 : MSMeanData_Net::~MSMeanData_Net() {}
408 :
409 :
410 : MSMeanData::MeanDataValues*
411 14467403 : MSMeanData_Net::createValues(MSLane* const lane, const double length, const bool doAdd) const {
412 14467403 : return new MSLaneMeanDataValues(lane, length, doAdd, this);
413 : }
414 :
415 :
416 : std::vector<std::string>
417 0 : MSMeanData_Net::getAttributeNames() const {
418 : std::vector<std::string> result;
419 0 : result.push_back(toString(SUMO_ATTR_DENSITY));
420 0 : result.push_back(toString(SUMO_ATTR_LANEDENSITY));
421 0 : result.push_back(toString(SUMO_ATTR_OCCUPANCY));
422 0 : result.push_back(toString(SUMO_ATTR_WAITINGTIME));
423 0 : result.push_back(toString(SUMO_ATTR_TIMELOSS));
424 0 : result.push_back(toString(SUMO_ATTR_SPEED));
425 0 : result.push_back(toString(SUMO_ATTR_SPEEDREL));
426 0 : result.push_back(toString(SUMO_ATTR_DEPARTED));
427 0 : result.push_back(toString(SUMO_ATTR_ARRIVED));
428 0 : result.push_back(toString(SUMO_ATTR_ENTERED));
429 0 : result.push_back(toString(SUMO_ATTR_LEFT));
430 0 : result.push_back(toString(SUMO_ATTR_VAPORIZED));
431 0 : result.push_back(toString(SUMO_ATTR_TELEPORTED));
432 0 : return result;
433 0 : }
434 :
435 :
436 : double
437 0 : MSMeanData_Net::getAttributeValue(const MSLane* lane, SumoXMLAttr a, double defaultValue) const {
438 : double result = defaultValue;
439 0 : const std::vector<MeanDataValues*>* edgeValues = getEdgeValues(&lane->getEdge());
440 0 : if (edgeValues == nullptr) {
441 : return result;
442 : }
443 : MeanDataValues* values = nullptr;
444 0 : if (!myAmEdgeBased) {
445 0 : values = (*edgeValues)[lane->getIndex()];
446 : } else {
447 0 : MeanDataValues* sumData = createValues(nullptr, lane->getLength(), false);
448 0 : for (MeanDataValues* meanData : (*edgeValues)) {
449 0 : meanData->addTo(*sumData);
450 : }
451 : values = sumData;
452 : }
453 : const SUMOTime myLastResetTime = 0; // XXX store last reset time
454 0 : const SUMOTime period = SIMSTEP - myLastResetTime;
455 0 : result = values->getAttributeValue(a, period, lane->getEdge().getNumLanes(), lane->getSpeedLimit());
456 0 : if (myAmEdgeBased) {
457 0 : delete values;
458 : }
459 : return result;
460 : }
461 :
462 :
463 : /****************************************************************************/
|