Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 MSE2Collector.h
15 : /// @author Christian Roessel
16 : /// @author Daniel Krajzewicz
17 : /// @author Sascha Krieg
18 : /// @author Michael Behrisch
19 : /// @author Robbin Blokpoel
20 : /// @author Jakob Erdmann
21 : /// @author Leonhard Luecken
22 : /// @date Mon Feb 03 2014 14:13 CET
23 : ///
24 : // An areal detector covering to a sequence of consecutive lanes
25 : /****************************************************************************/
26 : #pragma once
27 : #include <config.h>
28 :
29 : #include <vector>
30 : #include <list>
31 : #include <microsim/MSLane.h>
32 : #include <microsim/MSNet.h>
33 : #include <microsim/MSMoveReminder.h>
34 : #include <microsim/output/MSDetectorFileOutput.h>
35 : #include <utils/common/UtilExceptions.h>
36 : #include <cassert>
37 :
38 :
39 : // ===========================================================================
40 : // class declarations
41 : // ===========================================================================
42 : class OutputDevice;
43 : class SUMOVehicle;
44 : class SUMOTrafficObject;
45 :
46 :
47 : // ===========================================================================
48 : // class definitions
49 : // ===========================================================================
50 : /**
51 : * @class MSE2Collector
52 : * @brief An areal detector corresponding to a sequence of consecutive lanes
53 : *
54 : * This detector traces vehicles which are on a sequence of consecutive lanes. A
55 : * vehicle that enters the detector is stored and the stored vehicles' speeds
56 : * are used within each timestep to compute the detector values. As soon as the
57 : * vehicle leaves the detector, it is no longer tracked.
58 : *
59 : * Determining entering and leaving vehicles is done via the MSMoveReminder
60 : * interface. The values are computed by an event-callback (at the end of
61 : * a time step).
62 : *
63 : * @note As soon as a vehicle enters the detector, a VehicleInfo object is created
64 : * and stored in myVehicleInfos. This is constantly updated as long as the
65 : * vehicle stays on the detector (i.e. calls notifyMove()). All movement
66 : * notifications sent by vehicles on the detector are temporarily stored
67 : * in myMoveNotifications, see notifyMove(). Finally they are integrated
68 : * into myVehicleInfos when updateDetector is called.
69 : * @note When subclassing this detector, it is probably sufficient to adapt the
70 : * definition of the structs VehicleInfo and the MoveNotification, as well as
71 : * the methods that define and create those structs, i.e., makeVehicleInfo()
72 : * and makeMoveNotification(). Further the integration of new movement
73 : * notifications of the last time step into the vehicle infos is done
74 : * in updateVehicleInfos().
75 : *
76 : */
77 :
78 :
79 : class MSE2Collector : public MSMoveReminder, public MSDetectorFileOutput {
80 : public:
81 : /** @brief A VehicleInfo stores values that are tracked for the individual vehicles on the detector,
82 : * e.g., accumulated timeloss. These infos are stored in myVehicles. If a vehicle leaves the detector
83 : * (may it be temporarily), the entry in myVehicles is discarded, i.e. all information on the vehicle is reset.
84 : */
85 : struct VehicleInfo {
86 : /** @note Constructor expects an entryLane argument corresponding to a lane, which is part of the detector.
87 : */
88 672593 : VehicleInfo(std::string id, std::string type, double length, double minGap, const MSLane* entryLane, double entryOffset,
89 672593 : std::size_t currentOffsetIndex, double exitOffset, double distToDetectorEnd, bool onDetector) :
90 672593 : id(id),
91 672593 : type(type),
92 672593 : length(length),
93 672593 : minGap(minGap),
94 672593 : entryLaneID(entryLane->getID()),
95 672593 : entryOffset(entryOffset),
96 672593 : currentLane(entryLane),
97 672593 : currentOffsetIndex(currentOffsetIndex),
98 672593 : exitOffset(exitOffset),
99 672593 : distToDetectorEnd(distToDetectorEnd),
100 672593 : totalTimeOnDetector(0.),
101 672593 : accumulatedTimeLoss(0.),
102 672593 : onDetector(onDetector),
103 672593 : hasEntered(false),
104 672593 : lastAccel(0),
105 672593 : lastSpeed(0),
106 672593 : lastPos(0) {
107 : assert(exitOffset < 0);
108 672593 : }
109 1345186 : virtual ~VehicleInfo() {};
110 : /// vehicle's ID
111 : std::string id;
112 : /// vehicle's type
113 : std::string type;
114 : /// vehicle's length
115 : double length;
116 : /// vehicle's minGap
117 : double minGap;
118 : /// ID of the lane, on which the vehicle entered the detector
119 : std::string entryLaneID;
120 : /// Distance of the vehicle's entry lane's beginning to the detector start (can be negative for the first lane)
121 : /// In notifyMove(), the positional input arguments are relative to that position (since the vehicle picks up the MoveReminder
122 : /// on the entry lane)
123 : double entryOffset;
124 : /// Lane, on which the vehicle currently resides (always the one for which the last notifyEnter was received)
125 : const MSLane* currentLane;
126 : /// Index of currentLane in the detector's myLanes vector.
127 : std::size_t currentOffsetIndex;
128 : /// Offset from the detector start, where the vehicle has leaves the detector (defaults to detector length and is updated
129 : /// if the vehicle leaves the detector via a junction before reaching its end, i.e. enters a lane not part of the detector)
130 : double exitOffset;
131 : /// Distance left till the detector end after the last integration step (may become negative if the vehicle passes beyond the detector end)
132 : double distToDetectorEnd;
133 : /// Accumulated time that this vehicle has spent on the detector since its last entry
134 : double totalTimeOnDetector;
135 : /// Accumulated time loss that this vehicle suffered since it entered the detector
136 : double accumulatedTimeLoss;
137 :
138 : /// whether the vehicle is on the detector at the end of the current timestep
139 : bool onDetector;
140 : /// Whether the vehicle has already entered the detector (don't count twice!)
141 : bool hasEntered;
142 : /// Last value of the acceleration
143 : double lastAccel;
144 : /// Last value of the speed
145 : double lastSpeed;
146 : /// Last value of the vehicle position in reference to the start lane
147 : /// @note NOT in reference to the entry lane as newPos argument in notifyMove()!
148 : double lastPos;
149 : };
150 :
151 : typedef std::map<std::string, VehicleInfo*> VehicleInfoMap;
152 :
153 :
154 : private:
155 : /** @brief Values collected in notifyMove and needed in detectorUpdate() to
156 : * calculate the accumulated quantities for the detector. These are
157 : * temporarily stored in myMoveNotifications for each step.
158 : */
159 : struct MoveNotificationInfo {
160 49000640 : MoveNotificationInfo(std::string _vehID, double _oldPos, double _newPos, double _speed, double _accel, double _distToDetectorEnd, double _timeOnDetector, double _lengthOnDetector, double _timeLoss, double _waitingTime, bool _onDetector) :
161 49000640 : id(_vehID),
162 49000640 : oldPos(_oldPos),
163 49000640 : newPos(_newPos),
164 49000640 : speed(_speed),
165 49000640 : accel(_accel),
166 49000640 : distToDetectorEnd(_distToDetectorEnd),
167 49000640 : timeOnDetector(_timeOnDetector),
168 49000640 : lengthOnDetector(_lengthOnDetector),
169 49000640 : timeLoss(_timeLoss),
170 49000640 : waitingTime(_waitingTime),
171 49000640 : onDetector(_onDetector) {}
172 :
173 49000640 : virtual ~MoveNotificationInfo() {};
174 :
175 : /// Vehicle's id
176 : std::string id;
177 : /// Position before the last integration step (relative to the vehicle's entry lane on the detector)
178 : double oldPos;
179 : /// Position after the last integration step (relative to the vehicle's entry lane on the detector)
180 : double newPos;
181 : /// Speed after the last integration step
182 : double speed;
183 : /// Acceleration in the last integration step
184 : double accel;
185 : /// Distance left till the detector end after the last integration step (may become negative if the vehicle passes beyond the detector end)
186 : double distToDetectorEnd;
187 : /// Time spent on the detector during the last integration step
188 : double timeOnDetector;
189 : /// The length of the part of the vehicle on the detector at the end of the last time step
190 : double lengthOnDetector;
191 : /// timeloss during the last integration step
192 : double timeLoss;
193 : /// the current (consecutive) waitingTime on the detector in s
194 : double waitingTime;
195 : /// whether the vehicle is on the detector at the end of the current timestep
196 : bool onDetector;
197 : };
198 :
199 :
200 :
201 : /** @brief Internal representation of a jam
202 : *
203 : * Used in execute, instances of this structure are used to track
204 : * begin and end positions (as vehicles) of a jam.
205 : */
206 : struct JamInfo {
207 : /// @brief The first standing vehicle
208 : std::vector<MoveNotificationInfo*>::const_iterator firstStandingVehicle;
209 :
210 : /// @brief The last standing vehicle
211 : std::vector<MoveNotificationInfo*>::const_iterator lastStandingVehicle;
212 : };
213 :
214 :
215 : public:
216 :
217 : /** @brief Constructor with given end position and detector length
218 : *
219 : * @param[in] id The detector's unique id.
220 : * @param[in] usage Information how the detector is used
221 : * @param[in] lane The lane the detector ends
222 : * @param[in] startPos The start position on the lane the detector is placed at
223 : * @param[in] endPos The end position on the lane the detector is placed at
224 : * @param[in] length The length the detector has (heuristic lane selection is done if the continuation is not unique)
225 : * @param[in] haltingTimeThreshold The time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed
226 : * @param[in] haltingSpeedThreshold The speed a vehicle's speed must be below to be assigned as jammed
227 : * @param[in] jamDistThreshold The distance between two vehicles in order to not count them to one jam
228 : * @param[in] vTypes Vehicle types, that the detector takes into account
229 : *
230 : * @note Exactly one of the arguments startPos, endPos and length should be invalid (i.e. equal to std::numeric_limits<double>::max()).
231 : * If length is invalid, it is required that 0 <= startPos < endPos <= lane->length
232 : * If endPos is invalid, the detector may span over several lanes downstream of the lane
233 : * If pos is invalid, the detector may span over several lanes upstream of the lane
234 : */
235 : MSE2Collector(const std::string& id,
236 : DetectorUsage usage, MSLane* lane, double startPos, double endPos, double length,
237 : SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
238 : const std::string name, const std::string& vTypes,
239 : const std::string& nextEdges,
240 : int detectPersons);
241 :
242 :
243 : /** @brief Constructor with a sequence of lanes and given start and end position on the first and last lanes
244 : *
245 : * @param[in] id The detector's unique id.
246 : * @param[in] usage Information how the detector is used
247 : * @param[in] lanes A sequence of lanes the detector covers (must form a continuous piece)
248 : * @param[in] startPos The position of the detector start on the first lane the detector is placed at
249 : * @param[in] endPos The position of the detector end on the last lane the detector is placed at
250 : * @param[in] haltingTimeThreshold The time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed
251 : * @param[in] haltingSpeedThreshold The speed a vehicle's speed must be below to be assigned as jammed
252 : * @param[in] jamDistThreshold The distance between two vehicles in order to not count them to one jam
253 : * @param[in] vTypes Vehicle types, that the detector takes into account
254 : */
255 : MSE2Collector(const std::string& id,
256 : DetectorUsage usage, std::vector<MSLane*> lanes, double startPos, double endPos,
257 : SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
258 : const std::string name, const std::string& vTypes,
259 : const std::string& nextEdges,
260 : int detectPersons);
261 :
262 :
263 : /// @brief Destructor
264 : virtual ~MSE2Collector();
265 :
266 : /** @brief Returns the detector's usage type
267 : *
268 : * @see DetectorUsage
269 : * @return How the detector is used.
270 : */
271 282264 : virtual DetectorUsage getUsageType() const {
272 282264 : return myUsage;
273 : }
274 :
275 :
276 :
277 : /// @name Methods inherited from MSMoveReminder
278 : /// @{
279 :
280 : /** @brief Adds/removes vehicles from the list of vehicles to regard
281 : *
282 : * As soon as the reported vehicle enters the detector area (position>myStartPos)
283 : * it is added to the list of vehicles to regard (myKnownVehicles). It
284 : * is removed from this list if it leaves the detector (position<length>myEndPos).
285 : * The method returns true as long as the vehicle is not beyond the detector.
286 : *
287 : * @param[in] veh The vehicle in question.
288 : * @param[in] oldPos Position before the move-micro-timestep.
289 : * @param[in] newPos Position after the move-micro-timestep.
290 : * Note that this position is given in reference
291 : * to the begin of the entry lane of the vehicle.
292 : * @param[in] newSpeed Unused here.
293 : * @return False, if vehicle passed the detector entirely, else true.
294 : * @see MSMoveReminder
295 : * @see MSMoveReminder::notifyMove
296 : */
297 : virtual bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos,
298 : double newSpeed);
299 :
300 :
301 : /** @brief Removes a known vehicle due to its lane-change
302 : *
303 : * If the reported vehicle is known, it is removed from the list of
304 : * vehicles to regard (myKnownVehicles).
305 : *
306 : * @param[in] veh The leaving vehicle.
307 : * @param[in] lastPos Position on the lane when leaving.
308 : * @param[in] isArrival whether the vehicle arrived at its destination
309 : * @param[in] isLaneChange whether the vehicle changed from the lane
310 : * @see MSMoveReminder::notifyLeave
311 : */
312 : virtual bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
313 :
314 :
315 : /** @brief Adds the vehicle to known vehicles if not beyond the dector
316 : *
317 : * If the vehicles is within the detector are, it is added to the list
318 : * of known vehicles.
319 : * The method returns true as long as the vehicle is not beyond the detector.
320 : *
321 : * @param[in] veh The entering vehicle.
322 : * @param[in] reason how the vehicle enters the lane
323 : * @return False, if vehicle passed the detector entirely, else true.
324 : * @see MSMoveReminder::notifyEnter
325 : * @see MSMoveReminder::Notification
326 : */
327 : virtual bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane);
328 : /// @}
329 :
330 :
331 :
332 :
333 :
334 : /// @name Methods inherited from MSDetectorFileOutput.
335 : /// @{
336 :
337 : /** @brief Computes the detector values in each time step
338 : *
339 : * This method should be called at the end of a simulation step, when
340 : * all vehicles have moved. The current values are computed and
341 : * summed up with the previous.
342 : *
343 : * @param[in] currentTime The current simulation time
344 : */
345 : virtual void detectorUpdate(const SUMOTime step);
346 :
347 :
348 : /** @brief Write the generated output to the given device
349 : * @param[in] dev The output device to write the data into
350 : * @param[in] startTime First time step the data were gathered
351 : * @param[in] stopTime Last time step the data were gathered
352 : * @exception IOError If an error on writing occurs
353 : */
354 : virtual void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime);
355 :
356 :
357 : /** @brief Open the XML-output
358 : *
359 : * The implementing function should open an xml element using
360 : * OutputDevice::writeXMLHeader.
361 : *
362 : * @param[in] dev The output device to write the root into
363 : * @exception IOError If an error on writing occurs
364 : */
365 : virtual void writeXMLDetectorProlog(OutputDevice& dev) const;
366 :
367 : /// @}
368 :
369 : /// @brief get name
370 : const std::string& getName() {
371 : return myName;
372 : }
373 :
374 : /** @brief Returns the begin position of the detector
375 : *
376 : * @return The detector's begin position
377 : */
378 : double getStartPos() const {
379 1091 : return myStartPos;
380 : }
381 :
382 :
383 : /** @brief Returns the end position of the detector
384 : *
385 : * @return The detector's end position
386 : */
387 : double getEndPos() const {
388 1091 : return myEndPos;
389 : }
390 :
391 : /** @brief Returns the length of the detector
392 : *
393 : * @return The detector's length
394 : */
395 : double getLength() const {
396 429 : return myDetectorLength;
397 : }
398 :
399 :
400 : /** @brief Returns the id of the detector's last lane
401 : *
402 : * @return The detector's end position
403 : */
404 : MSLane* getLastLane() const {
405 8 : return myLastLane;
406 : }
407 :
408 :
409 : /** @brief Returns a vector containing pointers to the lanes covered by the detector ordered from its first to its last lane
410 : */
411 : std::vector<MSLane*> getLanes();
412 :
413 : /** @brief Resets all values
414 : *
415 : * This method is called on initialisation and as soon as the values
416 : * were written. Values for the next interval may be collected, then.
417 : * The list of known vehicles stays untouched.
418 : */
419 : virtual void reset();
420 :
421 :
422 : /// @name Methods returning current values
423 : /// @{
424 :
425 : /** @brief Returns the number of vehicles currently on the detector */
426 : int getCurrentVehicleNumber() const;
427 :
428 : /** @brief Returns the current detector occupancy */
429 0 : double getCurrentOccupancy() const {
430 428 : return myCurrentOccupancy;
431 : }
432 :
433 : /** @brief Returns the mean vehicle speed of vehicles currently on the detector*/
434 0 : double getCurrentMeanSpeed() const {
435 128236 : return myCurrentMeanSpeed;
436 : }
437 :
438 : /** @brief Returns the mean vehicle length of vehicles currently on the detector*/
439 0 : double getCurrentMeanLength() const {
440 0 : return myCurrentMeanLength;
441 : }
442 :
443 : /** @brief Returns the current number of jams */
444 0 : int getCurrentJamNumber() const {
445 0 : return myCurrentJamNo;
446 : }
447 :
448 : /** @brief Returns the length in vehicles of the currently largest jam */
449 0 : int getCurrentMaxJamLengthInVehicles() const {
450 0 : return myCurrentMaxJamLengthInVehicles;
451 : }
452 :
453 : /** @brief Returns the length in meters of the currently largest jam */
454 0 : double getCurrentMaxJamLengthInMeters() const {
455 0 : return myCurrentMaxJamLengthInMeters;
456 : }
457 :
458 : /** @brief Returns the length of all jams in vehicles */
459 0 : int getCurrentJamLengthInVehicles() const {
460 428 : return myCurrentJamLengthInVehicles;
461 : }
462 :
463 : /** @brief Returns the length of all jams in meters */
464 0 : double getCurrentJamLengthInMeters() const {
465 428 : return myCurrentJamLengthInMeters;
466 : }
467 :
468 : /** @brief Returns the length of the longest-duration jam in s */
469 : double getCurrentJamDuration() const {
470 2184 : return myCurrentJamDuration;
471 : }
472 :
473 : /** @brief Returns the length of all jams in meters */
474 0 : int getCurrentStartedHalts() const {
475 0 : return myCurrentStartedHalts;
476 : }
477 :
478 : /** @brief Returns the number of current haltings within the area
479 : *
480 : * If no vehicle is within the area, 0 is returned.
481 : *
482 : * @return The mean number of haltings within the area
483 : */
484 : int getCurrentHaltingNumber() const {
485 428 : return myCurrentHaltingsNumber;
486 : }
487 :
488 : /** @brief Returns the IDs of the vehicles within the area
489 : *
490 : * @return The IDs of the vehicles that have passed the entry, but not yet an exit point
491 : */
492 : std::vector<std::string> getCurrentVehicleIDs() const;
493 :
494 : /** @brief Returns the VehicleInfos for the vehicles currently on the detector
495 : */
496 : std::vector<VehicleInfo*> getCurrentVehicles() const;
497 :
498 : /** \brief Returns the number of vehicles passed over the sensor (i.e. entered the sensor)
499 : *
500 : * @return number of cars passed over the sensor
501 : */
502 0 : int getPassedVeh() {
503 0 : return myNumberOfEnteredVehicles;
504 : }
505 :
506 : /** \brief Subtract the number of vehicles indicated from passed from the sensor count.
507 : *
508 : * @param[in] passed - int that indicates the number of vehicles to subtract
509 : */
510 : void subtractPassedVeh(int passed) {
511 0 : myNumberOfEnteredVehicles -= passed;
512 0 : }
513 :
514 : /// @}
515 :
516 :
517 : /// @name Methods returning aggregated values
518 : /// @{
519 :
520 0 : double getIntervalOccupancy() const {
521 320797 : return myTimeSamples != 0 ? myOccupancySum / (double) myTimeSamples : 0;
522 : }
523 0 : double getIntervalMeanSpeed() const {
524 320797 : return myVehicleSamples != 0 ? mySpeedSum / myVehicleSamples : -1;
525 : }
526 : double getIntervalMeanTimeLoss() const {
527 320797 : return myNumberOfSeenVehicles != 0 ? myTotalTimeLoss / myNumberOfSeenVehicles : -1;
528 : }
529 0 : double getIntervalMaxJamLengthInMeters() const {
530 608 : return myMaxJamInMeters;
531 : }
532 0 : int getIntervalVehicleNumber() const {
533 608 : return myNumberOfSeenVehicles;
534 : }
535 :
536 0 : double getLastIntervalOccupancy() const {
537 608 : return myPreviousMeanOccupancy;
538 : }
539 0 : double getLastIntervalMeanSpeed() const {
540 608 : return myPreviousMeanSpeed;
541 : }
542 : double getLastIntervalMeanTimeLoss() const {
543 608 : return myPreviousMeanTimeLoss;
544 : }
545 0 : double getLastIntervalMaxJamLengthInMeters() const {
546 608 : return myPreviousMaxJamLengthInMeters;
547 : }
548 0 : int getLastIntervalVehicleNumber() const {
549 608 : return myPreviousNumberOfSeenVehicles;
550 : }
551 :
552 : /// @}
553 :
554 :
555 : /// @name Estimation methods
556 : /// TODO: Need documentation, used for tls control in MSSOTLE2Sensors (->Daniel?)
557 : /// @{
558 : /** @brief Returns an estimate of the number of vehicles currently on the detector */
559 : int getEstimatedCurrentVehicleNumber(double speedThreshold) const;
560 :
561 : /** @brief Returns an estimate of the length of the queue of vehicles currently stopped on the detector */
562 : double getEstimateQueueLength() const;
563 : /// @}
564 :
565 : /** @brief Returns the maximum stop arrival delay of public transport vehicles that are on the detector
566 : * or passed the detector in the last step or -DOUBLE_VALUE
567 : */
568 : double getArrivalDelay() const;
569 :
570 :
571 67 : virtual void setVisible(bool /*show*/) {};
572 :
573 : /** @brief Remove all vehicles before quick-loading state */
574 : virtual void clearState(SUMOTime step);
575 :
576 : /** @brief Persistently overrides the number of vehicles on top of the detector
577 : * Setting a negative value removes the override
578 : */
579 : void overrideVehicleNumber(int num);
580 :
581 : double getOverrideVehNumber() const {
582 141132 : return myOverrideVehNumber;
583 : }
584 : private:
585 :
586 : /** @brief checks whether the vehicle stands in a jam
587 : *
588 : * @param[in] mni
589 : * @param[in/out] haltingVehicles
590 : * @param[in/out] intervalHaltingVehicles
591 : * @return Whether vehicle is in a jam.
592 : */
593 : bool checkJam(std::vector<MoveNotificationInfo*>::const_iterator mni, std::map<std::string, SUMOTime>& haltingVehicles, std::map<std::string, SUMOTime>& intervalHaltingVehicles);
594 :
595 :
596 : /** @brief Either adds the vehicle to the end of an existing jam, or closes the last jam, and/or creates a new jam
597 : *
598 : * @param isInJam
599 : * @param mni
600 : * @param[in/out] currentJam
601 : * @param[in/out] jams
602 : */
603 : void buildJam(bool isInJam, std::vector<MoveNotificationInfo*>::const_iterator mni, JamInfo*& currentJam, std::vector<JamInfo*>& jams);
604 :
605 :
606 : /** @brief Calculates aggregated values from the given jam structure, deletes all jam-pointers
607 : *
608 : * @param jams
609 : */
610 : void processJams(std::vector<JamInfo*>& jams, JamInfo* currentJam);
611 :
612 : /** @brief Calculates the time spent on the detector in the last step and the timeloss suffered in the last step for the given vehicle
613 : *
614 : * @param[in] veh Vehicle for which the values are to be calculated
615 : * @param[in] oldPos Last position (before the last timestep) of the vehicle relative to the beginning of its entry lane
616 : * @param[in] newPos Current position of the vehicle
617 : * @param[in] vi VehicleInfo corresponding to the vehicle
618 : * @param[in/out] timeOnDetector Total time spent on the detector during the last step
619 : * @param[in/out] timeLoss Total time loss suffered during the last integration step
620 : */
621 : void calculateTimeLossAndTimeOnDetector(const SUMOTrafficObject& veh, double oldPos, double newPos, const VehicleInfo& vi, double& timeOnDetector, double& timeLoss) const;
622 :
623 : /** @brief Checks integrity of myLanes, adds internal-lane information, inits myLength, myFirstLane, myLastLane, myOffsets
624 : * Called once at construction.
625 : * @requires myLanes should form a continuous sequence.
626 : */
627 : void initAuxiliaries(std::vector<MSLane*>& lanes);
628 :
629 : /** @brief Adjusts positioning if the detector length is less than POSITION_EPS and tests some assertions
630 : */
631 : void checkPositioning(bool posGiven = false, double desiredLength = 0.);
632 :
633 : /** @brief Snaps value to snpPoint if they are closer than snapDist
634 : */
635 : static double snap(double value, double snapPoint, double snapDist);
636 :
637 : /** @brief Updates the detector length after myStartPos and myEndPos have been modified
638 : */
639 : void recalculateDetectorLength();
640 :
641 :
642 :
643 : /** @brief This is called if no lane sequence is given to the constructor. Builds myLanes from the given information.
644 : * Also inits startPos (case dir=="bw") / endPos (case dir=="fw").
645 : * Selects lanes heuristically if no unambiguous continuation exists.
646 : *
647 : * @param[in] lane Lane, where the detector starts/ends
648 : * @param[in] length Length of the detector
649 : * @param[in] dir Direction of detector extension with value in {"fw", "bw"} (forward / backward)
650 : * If dir == "fw" lane is interpreted as corresponding to the start lane of the detector,
651 : * otherwise the lane is interpreted as the end lane.
652 : */
653 : std::vector<MSLane*> selectLanes(MSLane* endLane, double length, std::string dir);
654 :
655 :
656 : /** @brief This adds the detector as a MoveReminder to the associated lanes.
657 : */
658 : void addDetectorToLanes(std::vector<MSLane*>& lanes);
659 :
660 :
661 : /** @brief Aggregates and normalize some values for the detector output during detectorUpdate()
662 : */
663 : void aggregateOutputValues();
664 :
665 :
666 : /** @brief This updates the detector values and the VehicleInfo of a vehicle on the detector
667 : * with the given MoveNotificationInfo generated by the vehicle during the last time step.
668 : *
669 : * @param[in/out] vi VehicleInfo corresponding to the notifying vehicle
670 : * @param[in] mni MoveNotification for the vehicle
671 : */
672 : void integrateMoveNotification(VehicleInfo* vi, const MoveNotificationInfo* mni);
673 :
674 : /** @brief Creates and returns a MoveNotificationInfo containing detector specific information on the vehicle's last movement
675 : *
676 : * @param veh The vehicle sending the notification
677 : * @param oldPos The vehicle's position before the last integration step
678 : * @param newPos The vehicle's position after the last integration step
679 : * @param newSpeed The vehicle's speed after the last integration step
680 : * @param vehInfo Info on the detector's memory of the vehicle
681 : * @return A MoveNotificationInfo containing quantities of interest for the detector
682 : */
683 : MoveNotificationInfo* makeMoveNotification(const SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed, const VehicleInfo& vehInfo) const;
684 :
685 : /** @brief Creates and returns a VehicleInfo (called at the vehicle's entry)
686 : *
687 : * @param veh The entering vehicle
688 : * @param enteredLane The entry lane
689 : * @return A vehicle info which can be used to store information about the vehicle's stay on the detector
690 : */
691 : VehicleInfo* makeVehicleInfo(const SUMOTrafficObject& veh, const MSLane* enteredLane) const;
692 :
693 : /** @brief Calculates the time loss for a segment with constant vmax
694 : *
695 : * @param timespan time needed to cover the segment
696 : * @param initialSpeed speed at segment entry
697 : * @param accel constant acceleration assumed during movement on the segment
698 : * @param vmax Maximal possible speed for the considered vehicle on the segment
699 : * @return Time loss (== MAX(timespan*(vmax - (initialSpeed + accel/2))/vmax), 0)
700 : */
701 : static double calculateSegmentTimeLoss(double timespan, double initialSpeed, double accel, double vmax);
702 :
703 : /** brief returns true if the vehicle corresponding to mni1 is closer to the detector end than the vehicle corresponding to mni2
704 : */
705 217622627 : static bool compareMoveNotification(MoveNotificationInfo* mni1, MoveNotificationInfo* mni2) {
706 217622627 : return mni1->distToDetectorEnd < mni2->distToDetectorEnd;
707 : }
708 :
709 : void notifyMovePerson(MSTransportable* p, int dir, double pos);
710 :
711 : private:
712 :
713 : /// @brief Information about how this detector is used
714 : DetectorUsage myUsage;
715 :
716 : /// @name Detector parameter
717 : /// @{
718 : /// @brief name
719 : const std::string myName;
720 : /// @brief The detector's lane sequence
721 : std::vector<std::string> myLanes;
722 : /// @brief The distances of the lane-beginnings from the detector start-point
723 : std::vector<double> myOffsets;
724 : /// @brief The first lane of the detector's lane sequence
725 : MSLane* myFirstLane;
726 : /// @brief The last lane of the detector's lane sequence
727 : MSLane* myLastLane;
728 : /// @brief The position the detector starts at on the first lane
729 : double myStartPos;
730 : /// @brief The position the detector ends at on the last lane
731 : double myEndPos;
732 : /// @brief The total detector length
733 : double myDetectorLength;
734 :
735 : /// @brief A vehicle must driver slower than this to be counted as a part of a jam
736 : double myJamHaltingSpeedThreshold;
737 : /// @brief A vehicle must be that long beyond myJamHaltingSpeedThreshold to be counted as a part of a jam
738 : SUMOTime myJamHaltingTimeThreshold;
739 : /// @brief Two standing vehicles must be closer than this to be counted into the same jam
740 : double myJamDistanceThreshold;
741 : /// @}
742 :
743 :
744 : /// @name Container
745 : /// @{
746 : /// @brief List of informations about the vehicles currently on the detector
747 : VehicleInfoMap myVehicleInfos;
748 :
749 : /// @brief Temporal storage for notifications from vehicles that did call the
750 : /// detector's notifyMove() in the last time step.
751 : std::vector<MoveNotificationInfo*> myMoveNotifications;
752 :
753 : /// @brief Keep track of vehicles that left the detector by a regular move along a junction (not lanechange, teleport, etc.)
754 : /// and should be removed from myVehicleInfos after taking into account their movement. Non-longitudinal exits
755 : /// are processed immediately in notifyLeave()
756 : std::set<std::string> myLeftVehicles;
757 :
758 : /// @brief Storage for halting durations of known vehicles (for halting vehicles)
759 : std::map<std::string, SUMOTime> myHaltingVehicleDurations;
760 :
761 : /// @brief Storage for halting durations of known vehicles (current interval)
762 : std::map<std::string, SUMOTime> myIntervalHaltingVehicleDurations;
763 :
764 : /// @brief Halting durations of ended halts [s]
765 : std::vector<SUMOTime> myPastStandingDurations;
766 :
767 : /// @brief Halting durations of ended halts for the current interval [s]
768 : std::vector<SUMOTime> myPastIntervalStandingDurations;
769 : /// @}
770 :
771 :
772 :
773 : /// @name Values generated for aggregated file output
774 : /// @{
775 : /// @brief The number of collected samples [time x vehicle] since the last reset
776 : double myVehicleSamples = 0.;
777 : /// @brief The total amount of all time losses [time x vehicle] since the last reset
778 : double myTotalTimeLoss = 0.;
779 : /// @brief The sum of collected vehicle speeds [m/s]
780 : double mySpeedSum = 0.;
781 : /// @brief The number of started halts [#]
782 : int myStartedHalts = 0;
783 : /// @brief The sum of jam lengths [m]
784 : double myJamLengthInMetersSum = 0.;
785 : /// @brief The sum of jam lengths [#veh]
786 : int myJamLengthInVehiclesSum = 0;
787 : /// @brief The current aggregation duration [#steps]
788 : int myTimeSamples = 0;
789 : /// @brief The sum of occupancies [%]
790 : double myOccupancySum = 0.;
791 : /// @brief The maximum occupancy [%]
792 : double myMaxOccupancy = 0.;
793 : /// @brief The mean jam length [#veh]
794 : int myMeanMaxJamInVehicles = 0;
795 : /// @brief The mean jam length [m]
796 : double myMeanMaxJamInMeters = 0.;
797 : /// @brief The max jam length [#veh]
798 : int myMaxJamInVehicles = 0;
799 : /// @brief The max jam length [m]
800 : double myMaxJamInMeters = 0.;
801 : /// @brief The mean number of vehicles [#veh]
802 : int myMeanVehicleNumber = 0;
803 : /// @}
804 :
805 :
806 : /// @name Values generated describing the current state
807 : /// @{
808 : /// @brief The number of vehicles, which have entered the detector since the last reset
809 : int myNumberOfEnteredVehicles = 0;
810 : /// @brief The number of vehicles, present on the detector at the last reset
811 : int myNumberOfSeenVehicles = 0;
812 : /// @brief The number of vehicles, which have left the detector since the last reset
813 : int myNumberOfLeftVehicles = 0;
814 : /// @brief The maximal number of vehicles located on the detector simultaneously since the last reset
815 : int myMaxVehicleNumber = 0;
816 :
817 : /// @brief The current vehicle samples
818 : double myCurrentVehicleSamples = 0.;
819 : /// @brief The current occupancy
820 : double myCurrentOccupancy = 0.;
821 : /// @brief The current mean speed
822 : double myCurrentMeanSpeed = 0.;
823 : /// @brief The current mean timeLoss
824 : double myCurrentMeanTimeLoss = 0.;
825 : /// @brief The current mean length
826 : double myCurrentMeanLength = 0.;
827 : /// @brief The current jam number
828 : int myCurrentJamNo = 0;
829 : /// @brief the current maximum jam length in meters
830 : double myCurrentMaxJamLengthInMeters = 0.;
831 : /// @brief The current maximum jam length in vehicles
832 : int myCurrentMaxJamLengthInVehicles = 0;
833 : /// @brief The overall jam length in meters
834 : double myCurrentJamLengthInMeters = 0.;
835 : /// @brief The overall jam length in vehicles
836 : int myCurrentJamLengthInVehicles = 0;
837 : /// @brief The overall jam duration in s
838 : double myCurrentJamDuration = 0.;
839 : /// @brief The number of started halts in the last step
840 : int myCurrentStartedHalts = 0;
841 : /// @brief The number of halted vehicles [#]
842 : int myCurrentHaltingsNumber = 0;
843 : /// @}
844 :
845 : /// @name Values generated describing the previous interval state
846 : /// @{
847 : double myPreviousMeanOccupancy = 0.;
848 : double myPreviousMeanSpeed = 0.;
849 : double myPreviousMeanTimeLoss = 0.;
850 : double myPreviousMaxJamLengthInMeters = 0.;
851 : int myPreviousNumberOfSeenVehicles = 0;
852 : /// @}
853 :
854 : /// @brief stores the overriden (via Traci) number of vehicles on detector
855 : int myOverrideVehNumber = -1;
856 :
857 : private:
858 : /// @brief Invalidated copy constructor.
859 : MSE2Collector(const MSE2Collector&);
860 :
861 : /// @brief Invalidated assignment operator.
862 : MSE2Collector& operator=(const MSE2Collector&);
863 : };
|