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() == "")
47 : //#define DEBUG_COND (false)
48 : //#define DEBUG_COND2 (veh.getEdge()->getID() == "")
49 :
50 :
51 : // ===========================================================================
52 : // method definitions
53 : // ===========================================================================
54 : // ---------------------------------------------------------------------------
55 : // MSMeanData_Net::MSLaneMeanDataValues - methods
56 : // ---------------------------------------------------------------------------
57 8203860 : MSMeanData_Net::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
58 : const double length,
59 : const bool doAdd,
60 8203860 : const MSMeanData_Net* parent)
61 : : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
62 8203860 : nVehDeparted(0), nVehArrived(0), nVehEntered(0), nVehLeft(0),
63 8203860 : nVehVaporized(0), nVehTeleported(0), waitSeconds(0), timeLoss(0),
64 8203860 : nVehLaneChangeFrom(0), nVehLaneChangeTo(0),
65 8203860 : frontSampleSeconds(0), frontTravelledDistance(0),
66 8203860 : vehLengthSum(0), occupationSum(0),
67 8203860 : minimalVehicleLength(INVALID_DOUBLE),
68 8203860 : myParent(parent) {}
69 :
70 :
71 16259699 : MSMeanData_Net::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
72 16259699 : }
73 :
74 :
75 : void
76 16743354 : MSMeanData_Net::MSLaneMeanDataValues::reset(bool) {
77 16743354 : nVehDeparted = 0;
78 16743354 : nVehArrived = 0;
79 16743354 : nVehEntered = 0;
80 16743354 : nVehLeft = 0;
81 16743354 : nVehVaporized = 0;
82 16743354 : nVehTeleported = 0;
83 16743354 : nVehLaneChangeFrom = 0;
84 16743354 : nVehLaneChangeTo = 0;
85 16743354 : sampleSeconds = 0.;
86 16743354 : travelledDistance = 0;
87 16743354 : waitSeconds = 0;
88 16743354 : timeLoss = 0;
89 16743354 : frontSampleSeconds = 0;
90 16743354 : frontTravelledDistance = 0;
91 16743354 : vehLengthSum = 0;
92 16743354 : occupationSum = 0;
93 16743354 : minimalVehicleLength = INVALID_DOUBLE;
94 16743354 : resetTime = SIMSTEP;
95 16743354 : }
96 :
97 :
98 : void
99 8474439 : MSMeanData_Net::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
100 : MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
101 8474439 : v.nVehDeparted += nVehDeparted;
102 8474439 : v.nVehArrived += nVehArrived;
103 8474439 : v.nVehEntered += nVehEntered;
104 8474439 : v.nVehLeft += nVehLeft;
105 8474439 : v.nVehVaporized += nVehVaporized;
106 8474439 : v.nVehTeleported += nVehTeleported;
107 8474439 : v.nVehLaneChangeFrom += nVehLaneChangeFrom;
108 8474439 : v.nVehLaneChangeTo += nVehLaneChangeTo;
109 8474439 : v.sampleSeconds += sampleSeconds;
110 8474439 : v.travelledDistance += travelledDistance;
111 8474439 : v.waitSeconds += waitSeconds;
112 8474439 : v.timeLoss += timeLoss;
113 8474439 : v.frontSampleSeconds += frontSampleSeconds;
114 8474439 : v.frontTravelledDistance += frontTravelledDistance;
115 8474439 : v.vehLengthSum += vehLengthSum;
116 8474439 : v.occupationSum += occupationSum;
117 8474439 : if (v.minimalVehicleLength == INVALID_DOUBLE) {
118 8419474 : v.minimalVehicleLength = minimalVehicleLength;
119 : } else {
120 103410 : v.minimalVehicleLength = MIN2(minimalVehicleLength, v.minimalVehicleLength);
121 : }
122 8474439 : }
123 :
124 :
125 : void
126 381291874 : MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal(
127 : const SUMOTrafficObject& veh, const double frontOnLane,
128 : const double timeOnLane, const double /* meanSpeedFrontOnLane */,
129 : const double meanSpeedVehicleOnLane,
130 : const double travelledDistanceFrontOnLane,
131 : const double travelledDistanceVehicleOnLane,
132 : const double meanLengthOnLane) {
133 : #ifdef DEBUG_OCCUPANCY
134 : if (DEBUG_COND2) {
135 : std::cout << SIMTIME << "\n MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal()\n"
136 : << " veh '" << veh.getID() << "' on edge '" << veh.getEdge()->getID() << "'"
137 : << ", timeOnLane=" << timeOnLane
138 : << ", meanSpeedVehicleOnLane=" << meanSpeedVehicleOnLane
139 : << ",\ntravelledDistanceFrontOnLane=" << travelledDistanceFrontOnLane
140 : << ", travelledDistanceVehicleOnLane=" << travelledDistanceVehicleOnLane
141 : << ", meanLengthOnLane=" << meanLengthOnLane
142 : << std::endl;
143 : }
144 : #endif
145 381291874 : if (myParent != nullptr && !myParent->vehicleApplies(veh)) {
146 : return;
147 : }
148 381249554 : sampleSeconds += timeOnLane;
149 381249554 : travelledDistance += travelledDistanceVehicleOnLane;
150 381249554 : vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
151 381249554 : if (MSGlobals::gUseMesoSim) {
152 : // For the mesosim case no information on whether the vehicle was occupying
153 : // the lane with its whole length is available. We assume the whole length
154 : // Therefore this increment is taken out with more information on the vehicle movement.
155 10362802 : occupationSum += veh.getVehicleType().getLength() * timeOnLane;
156 : } else {
157 : // for the microsim case more elaborate calculation of the average length on the lane,
158 : // is taken out in notifyMove(), refs #153
159 370886752 : occupationSum += meanLengthOnLane * TS;
160 : }
161 381249554 : if (!veh.isStopped()) {
162 365238386 : if (myParent != nullptr && meanSpeedVehicleOnLane < myParent->myHaltSpeed) {
163 48590031 : waitSeconds += timeOnLane;
164 : }
165 365238386 : const double vmax = veh.getLane() == nullptr ? veh.getEdge()->getVehicleMaxSpeed(&veh) : veh.getLane()->getVehicleMaxSpeed(&veh);
166 365238386 : if (vmax > 0) {
167 728718352 : timeLoss += timeOnLane * MAX2(0.0, vmax - meanSpeedVehicleOnLane) / vmax;
168 : }
169 : }
170 381249554 : frontSampleSeconds += frontOnLane;
171 381249554 : frontTravelledDistance += travelledDistanceFrontOnLane;
172 381249554 : if (minimalVehicleLength == INVALID_DOUBLE) {
173 712846 : minimalVehicleLength = veh.getVehicleType().getLengthWithGap();
174 : } else {
175 759681369 : minimalVehicleLength = MIN2(minimalVehicleLength, veh.getVehicleType().getLengthWithGap());
176 : }
177 : #ifdef DEBUG_OCCUPANCY2
178 : // refs #3265
179 : std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength << std::endl;
180 : #endif
181 : }
182 :
183 :
184 : bool
185 24889554 : MSMeanData_Net::MSLaneMeanDataValues::notifyLeave(SUMOTrafficObject& veh, double /*lastPos*/, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
186 24889554 : if ((myParent == nullptr || myParent->vehicleApplies(veh)) && (
187 15837986 : getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane())) {
188 : #ifdef HAVE_FOX
189 20922138 : ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
190 : #endif
191 20922138 : if (MSGlobals::gUseMesoSim) {
192 9051424 : removeFromVehicleUpdateValues(veh);
193 : }
194 20922138 : if (reason == MSMoveReminder::NOTIFICATION_ARRIVED) {
195 2361228 : ++nVehArrived;
196 18560910 : } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
197 99026 : ++nVehLaneChangeFrom;
198 18461884 : } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
199 10588964 : ++nVehLeft;
200 10588964 : if (reason == MSMoveReminder::NOTIFICATION_TELEPORT || reason == MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED) {
201 3726 : ++nVehTeleported;
202 10585238 : } else if (reason >= MSMoveReminder::NOTIFICATION_VAPORIZED_CALIBRATOR) {
203 70057 : ++nVehVaporized;
204 : }
205 : }
206 : }
207 24889554 : if (MSGlobals::gUseMesoSim) {
208 : return false;
209 : }
210 15829290 : return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
211 : }
212 :
213 :
214 : bool
215 22064863 : MSMeanData_Net::MSLaneMeanDataValues::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane) {
216 : #ifdef DEBUG_NOTIFY_ENTER
217 : std::cout << "\n" << SIMTIME << " MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
218 : #else
219 : UNUSED_PARAMETER(enteredLane);
220 : #endif
221 22064863 : if (myParent == nullptr || myParent->vehicleApplies(veh)) {
222 21027486 : if (getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane()) {
223 : #ifdef HAVE_FOX
224 21018646 : ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
225 : #endif
226 21018646 : if (reason == MSMoveReminder::NOTIFICATION_DEPARTED) {
227 2540458 : ++nVehDeparted;
228 18478188 : } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
229 98509 : ++nVehLaneChangeTo;
230 18379679 : } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
231 10536925 : ++nVehEntered;
232 : }
233 : }
234 21027486 : return true;
235 : }
236 : return false;
237 : }
238 :
239 :
240 : bool
241 22473610 : MSMeanData_Net::MSLaneMeanDataValues::isEmpty() const {
242 21819165 : return sampleSeconds == 0 && nVehDeparted == 0 && nVehArrived == 0 && nVehEntered == 0
243 44292333 : && nVehLeft == 0 && nVehVaporized == 0 && nVehTeleported == 0 && nVehLaneChangeFrom == 0 && nVehLaneChangeTo == 0;
244 : }
245 :
246 : double
247 910621 : MSMeanData_Net::MSLaneMeanDataValues::getOccupancy(SUMOTime period, int numLanes) const {
248 910621 : return occupationSum / STEPS2TIME(period) / myLaneLength / (double)numLanes * 100.;
249 : }
250 :
251 : void
252 910501 : MSMeanData_Net::MSLaneMeanDataValues::write(OutputDevice& dev, long long int attributeMask, const SUMOTime period,
253 : const int numLanes, const double speedLimit, const double defaultTravelTime, const int numVehicles) const {
254 :
255 910501 : double density = sampleSeconds / STEPS2TIME(period) * 1000. / myLaneLength;
256 910501 : if (MSGlobals::gLateralResolution < 0) {
257 : // avoid exceeding upper bound
258 858728 : density = MIN2(density, 1000 * (double)numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
259 : }
260 910501 : const double laneDensity = density / (double)numLanes;
261 910501 : const double occupancy = getOccupancy(period, numLanes);
262 : #ifdef DEBUG_OCCUPANCY2
263 : // tests #3264
264 : if (occupancy > 100) {
265 : std::cout << SIMTIME << " Encountered bad occupancy: " << occupancy
266 : << ", myLaneLength=" << myLaneLength << ", period=" << STEPS2TIME(period) << ", occupationSum=" << occupationSum
267 : << std::endl;
268 : }
269 : // refs #3265
270 : std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength
271 : << "\ndensity=" << density << "\n";
272 : #endif
273 :
274 910501 : if (myParent == nullptr) {
275 41512 : if (sampleSeconds > 0) {
276 28633 : dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask);
277 28633 : dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask);
278 28633 : dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask);
279 28633 : dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask);
280 28633 : dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask);
281 28633 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, travelledDistance / sampleSeconds, attributeMask);
282 28633 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit, attributeMask);
283 : }
284 41512 : dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
285 41512 : dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
286 41512 : dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
287 41512 : dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
288 41512 : if (nVehVaporized > 0) {
289 0 : dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask);
290 : }
291 41512 : if (nVehTeleported > 0) {
292 0 : dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask);
293 : }
294 41512 : dev.closeTag();
295 41512 : return;
296 : }
297 868989 : if (sampleSeconds > myParent->myMinSamples) {
298 611497 : double overlapTraveltime = myParent->myMaxTravelTime;
299 611497 : if (travelledDistance > 0.f) {
300 : // one vehicle has to drive lane length + vehicle length before it has left the lane
301 : // thus we need to scale with an extended length, approximated by lane length + average vehicle length
302 833852 : overlapTraveltime = MIN2(overlapTraveltime, (myLaneLength + vehLengthSum / sampleSeconds) * sampleSeconds / travelledDistance);
303 : }
304 611497 : if (numVehicles > 0) {
305 232 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, sampleSeconds / numVehicles, attributeMask);
306 232 : dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask);
307 232 : dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask);
308 232 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, travelledDistance / sampleSeconds, attributeMask);
309 232 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit, attributeMask);
310 : } else {
311 611265 : double traveltime = myParent->myMaxTravelTime;
312 611265 : if (frontTravelledDistance > NUMERICAL_EPS) {
313 414435 : traveltime = MIN2(traveltime, myLaneLength * frontSampleSeconds / frontTravelledDistance);
314 414435 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, traveltime, attributeMask);
315 196830 : } else if (defaultTravelTime >= 0.) {
316 0 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, defaultTravelTime, attributeMask);
317 : }
318 611265 : dev.writeOptionalAttr(SUMO_ATTR_OVERLAPTRAVELTIME, overlapTraveltime, attributeMask);
319 611265 : dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask);
320 611265 : dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask);
321 611265 : dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask);
322 611265 : dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask);
323 611265 : dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask);
324 611265 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, travelledDistance / sampleSeconds, attributeMask);
325 611265 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit, attributeMask);
326 : }
327 257492 : } else if (defaultTravelTime >= 0.) {
328 1056 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, defaultTravelTime, attributeMask);
329 1056 : dev.writeOptionalAttr(SUMO_ATTR_SPEED, myLaneLength / defaultTravelTime, attributeMask);
330 1056 : dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : myLaneLength / defaultTravelTime / speedLimit, attributeMask);
331 : }
332 868989 : dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
333 868989 : dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
334 868989 : dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
335 868989 : dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
336 868989 : dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDFROM, nVehLaneChangeFrom, attributeMask);
337 868989 : dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDTO, nVehLaneChangeTo, attributeMask);
338 868989 : if (nVehVaporized > 0) {
339 131 : dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask);
340 : }
341 868989 : if (nVehTeleported > 0) {
342 1263 : dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask);
343 : }
344 1737978 : dev.closeTag();
345 : }
346 :
347 :
348 : double
349 0 : MSMeanData_Net::MSLaneMeanDataValues::getAttributeValue(SumoXMLAttr a,
350 : const SUMOTime period, const double numLanes, const double speedLimit) const {
351 : /// @todo: remove redundancy in derived values (density, laneDensity)
352 0 : switch (a) {
353 0 : case SUMO_ATTR_DENSITY:
354 0 : return MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
355 0 : 1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
356 0 : case SUMO_ATTR_LANEDENSITY: {
357 0 : const double density = MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
358 0 : 1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
359 0 : return density / numLanes;
360 : }
361 0 : case SUMO_ATTR_OCCUPANCY:
362 0 : return occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 1000;
363 0 : case SUMO_ATTR_WAITINGTIME:
364 0 : return waitSeconds;
365 0 : case SUMO_ATTR_TIMELOSS:
366 0 : return timeLoss;
367 0 : case SUMO_ATTR_SPEED:
368 0 : return travelledDistance / sampleSeconds;
369 0 : case SUMO_ATTR_SPEEDREL:
370 0 : return speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit;
371 0 : case SUMO_ATTR_DEPARTED:
372 0 : return nVehDeparted;
373 0 : case SUMO_ATTR_ARRIVED:
374 0 : return nVehArrived;
375 0 : case SUMO_ATTR_ENTERED:
376 0 : return nVehEntered;
377 0 : case SUMO_ATTR_LEFT:
378 0 : return nVehLeft;
379 0 : case SUMO_ATTR_VAPORIZED:
380 0 : return nVehVaporized;
381 0 : case SUMO_ATTR_TELEPORTED:
382 0 : return nVehTeleported;
383 : default:
384 : return 0;
385 : }
386 : }
387 :
388 : // ---------------------------------------------------------------------------
389 : // MSMeanData_Net - methods
390 : // ---------------------------------------------------------------------------
391 19421 : MSMeanData_Net::MSMeanData_Net(const std::string& id,
392 : const SUMOTime dumpBegin,
393 : const SUMOTime dumpEnd, const bool useLanes,
394 : const bool withEmpty, const bool printDefaults,
395 : const bool withInternal,
396 : const bool trackVehicles,
397 : const int detectPersons,
398 : const double maxTravelTime,
399 : const double minSamples,
400 : const double haltSpeed,
401 : const std::string& vTypes,
402 : const std::string& writeAttributes,
403 : const std::vector<MSEdge*>& edges,
404 19421 : bool aggregate) :
405 : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, printDefaults,
406 : withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate),
407 19421 : myHaltSpeed(haltSpeed)
408 19421 : { }
409 :
410 :
411 37632 : MSMeanData_Net::~MSMeanData_Net() {}
412 :
413 :
414 : MSMeanData::MeanDataValues*
415 8201538 : MSMeanData_Net::createValues(MSLane* const lane, const double length, const bool doAdd) const {
416 8201538 : return new MSLaneMeanDataValues(lane, length, doAdd, this);
417 : }
418 :
419 :
420 : std::vector<std::string>
421 0 : MSMeanData_Net::getAttributeNames() const {
422 : std::vector<std::string> result;
423 0 : result.push_back(toString(SUMO_ATTR_DENSITY));
424 0 : result.push_back(toString(SUMO_ATTR_LANEDENSITY));
425 0 : result.push_back(toString(SUMO_ATTR_OCCUPANCY));
426 0 : result.push_back(toString(SUMO_ATTR_WAITINGTIME));
427 0 : result.push_back(toString(SUMO_ATTR_TIMELOSS));
428 0 : result.push_back(toString(SUMO_ATTR_SPEED));
429 0 : result.push_back(toString(SUMO_ATTR_SPEEDREL));
430 0 : result.push_back(toString(SUMO_ATTR_DEPARTED));
431 0 : result.push_back(toString(SUMO_ATTR_ARRIVED));
432 0 : result.push_back(toString(SUMO_ATTR_ENTERED));
433 0 : result.push_back(toString(SUMO_ATTR_LEFT));
434 0 : result.push_back(toString(SUMO_ATTR_VAPORIZED));
435 0 : result.push_back(toString(SUMO_ATTR_TELEPORTED));
436 0 : return result;
437 0 : }
438 :
439 :
440 : double
441 0 : MSMeanData_Net::getAttributeValue(const MSLane* lane, SumoXMLAttr a, double defaultValue) const {
442 : double result = defaultValue;
443 0 : const std::vector<MeanDataValues*>* edgeValues = getEdgeValues(&lane->getEdge());
444 0 : if (edgeValues == nullptr) {
445 : return result;
446 : }
447 : MeanDataValues* values = nullptr;
448 0 : if (!myAmEdgeBased) {
449 0 : values = (*edgeValues)[lane->getIndex()];
450 : } else {
451 0 : MeanDataValues* sumData = createValues(nullptr, lane->getLength(), false);
452 0 : for (MeanDataValues* meanData : (*edgeValues)) {
453 0 : meanData->addTo(*sumData);
454 : }
455 : values = sumData;
456 : }
457 : const SUMOTime myLastResetTime = 0; // XXX store last reset time
458 0 : const SUMOTime period = SIMSTEP - myLastResetTime;
459 0 : result = values->getAttributeValue(a, period, lane->getEdge().getNumLanes(), lane->getSpeedLimit());
460 0 : if (myAmEdgeBased) {
461 0 : delete values;
462 : }
463 : return result;
464 : }
465 :
466 :
467 : /****************************************************************************/
|