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