LCOV - code coverage report
Current view: top level - src/microsim/output - MSE2Collector.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 69.8 % 86 60
Test Date: 2025-11-13 15:38:19 Functions: 26.9 % 26 7

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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       600644 :         VehicleInfo(std::string id, std::string type, double length, double minGap, const MSLane* entryLane, double entryOffset,
      89       600644 :                     std::size_t currentOffsetIndex, double exitOffset, double distToDetectorEnd, bool onDetector) :
      90       600644 :             id(id),
      91       600644 :             type(type),
      92       600644 :             length(length),
      93       600644 :             minGap(minGap),
      94       600644 :             entryLaneID(entryLane->getID()),
      95       600644 :             entryOffset(entryOffset),
      96       600644 :             currentLane(entryLane),
      97       600644 :             currentOffsetIndex(currentOffsetIndex),
      98       600644 :             exitOffset(exitOffset),
      99       600644 :             distToDetectorEnd(distToDetectorEnd),
     100       600644 :             totalTimeOnDetector(0.),
     101       600644 :             accumulatedTimeLoss(0.),
     102       600644 :             onDetector(onDetector),
     103       600644 :             hasEntered(false),
     104       600644 :             lastAccel(0),
     105       600644 :             lastSpeed(0),
     106       600644 :             lastPos(0) {
     107              :             assert(exitOffset < 0);
     108       600644 :         }
     109      1201288 :         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     47370516 :         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     47370516 :             id(_vehID),
     162     47370516 :             oldPos(_oldPos),
     163     47370516 :             newPos(_newPos),
     164     47370516 :             speed(_speed),
     165     47370516 :             accel(_accel),
     166     47370516 :             distToDetectorEnd(_distToDetectorEnd),
     167     47370516 :             timeOnDetector(_timeOnDetector),
     168     47370516 :             lengthOnDetector(_lengthOnDetector),
     169     47370516 :             timeLoss(_timeLoss),
     170     47370516 :             waitingTime(_waitingTime),
     171     47370516 :             onDetector(_onDetector) {}
     172              : 
     173     47370516 :         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        10420 :     virtual DetectorUsage getUsageType() const {
     272        10420 :         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          593 :         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          593 :         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         1092 :         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       318871 :         return myTimeSamples != 0 ? myOccupancySum / (double) myTimeSamples : 0;
     522              :     }
     523            0 :     double getIntervalMeanSpeed() const {
     524       318871 :         return myVehicleSamples != 0 ? mySpeedSum / myVehicleSamples : -1;
     525              :     }
     526              :     double getIntervalMeanTimeLoss() const {
     527       318871 :         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              : 
     566           67 :     virtual void setVisible(bool /*show*/) {};
     567              : 
     568              :     /** @brief Remove all vehicles before quick-loading state */
     569              :     virtual void clearState(SUMOTime step);
     570              : 
     571              :     /** @brief Persistently overrides the number of vehicles on top of the detector
     572              :      * Setting a negative value removes the override
     573              :     */
     574              :     void overrideVehicleNumber(int num);
     575              : 
     576              :     double getOverrideVehNumber() const {
     577         5210 :         return myOverrideVehNumber;
     578              :     }
     579              : private:
     580              : 
     581              :     /** @brief checks whether the vehicle stands in a jam
     582              :      *
     583              :      * @param[in] mni
     584              :      * @param[in/out] haltingVehicles
     585              :      * @param[in/out] intervalHaltingVehicles
     586              :      * @return Whether vehicle is in a jam.
     587              :      */
     588              :     bool checkJam(std::vector<MoveNotificationInfo*>::const_iterator mni, std::map<std::string, SUMOTime>& haltingVehicles, std::map<std::string, SUMOTime>& intervalHaltingVehicles);
     589              : 
     590              : 
     591              :     /** @brief Either adds the vehicle to the end of an existing jam, or closes the last jam, and/or creates a new jam
     592              :      *
     593              :      * @param isInJam
     594              :      * @param mni
     595              :      * @param[in/out] currentJam
     596              :      * @param[in/out] jams
     597              :      */
     598              :     void buildJam(bool isInJam, std::vector<MoveNotificationInfo*>::const_iterator mni, JamInfo*& currentJam, std::vector<JamInfo*>& jams);
     599              : 
     600              : 
     601              :     /** @brief Calculates aggregated values from the given jam structure, deletes all jam-pointers
     602              :      *
     603              :      * @param jams
     604              :      */
     605              :     void processJams(std::vector<JamInfo*>& jams, JamInfo* currentJam);
     606              : 
     607              :     /** @brief Calculates the time spent on the detector in the last step and the timeloss suffered in the last step for the given vehicle
     608              :      *
     609              :      * @param[in] veh Vehicle for which the values are to be calculated
     610              :      * @param[in] oldPos Last position (before the last timestep) of the vehicle relative to the beginning of its entry lane
     611              :      * @param[in] newPos Current position of the vehicle
     612              :      * @param[in] vi VehicleInfo corresponding to the vehicle
     613              :      * @param[in/out] timeOnDetector Total time spent on the detector during the last step
     614              :      * @param[in/out] timeLoss Total time loss suffered during the last integration step
     615              :      */
     616              :     void calculateTimeLossAndTimeOnDetector(const SUMOTrafficObject& veh, double oldPos, double newPos, const VehicleInfo& vi, double& timeOnDetector, double& timeLoss) const;
     617              : 
     618              :     /** @brief Checks integrity of myLanes, adds internal-lane information, inits myLength, myFirstLane, myLastLane, myOffsets
     619              :      *         Called once at construction.
     620              :      *  @requires myLanes should form a continuous sequence.
     621              :      */
     622              :     void initAuxiliaries(std::vector<MSLane*>& lanes);
     623              : 
     624              :     /** @brief Adjusts positioning if the detector length is less than POSITION_EPS and tests some assertions
     625              :      */
     626              :     void checkPositioning(bool posGiven = false, double desiredLength = 0.);
     627              : 
     628              :     /** @brief Snaps value to snpPoint if they are closer than snapDist
     629              :      */
     630              :     static double snap(double value, double snapPoint, double snapDist);
     631              : 
     632              :     /** @brief Updates the detector length after myStartPos and myEndPos have been modified
     633              :      */
     634              :     void recalculateDetectorLength();
     635              : 
     636              : 
     637              : 
     638              :     /** @brief This is called if no lane sequence is given to the constructor. Builds myLanes from the given information.
     639              :      *          Also inits startPos (case dir=="bw") / endPos (case dir=="fw").
     640              :      *          Selects lanes heuristically if no unambiguous continuation exists.
     641              :      *
     642              :      *  @param[in] lane Lane, where the detector starts/ends
     643              :      *  @param[in] length Length of the detector
     644              :      *  @param[in] dir Direction of detector extension with value in {"fw", "bw"} (forward / backward)
     645              :      *                 If dir == "fw" lane is interpreted as corresponding to the start lane of the detector,
     646              :      *                 otherwise the lane is interpreted as the end lane.
     647              :      */
     648              :     std::vector<MSLane*> selectLanes(MSLane* endLane, double length, std::string dir);
     649              : 
     650              : 
     651              :     /** @brief This adds the detector as a MoveReminder to the associated lanes.
     652              :      */
     653              :     void addDetectorToLanes(std::vector<MSLane*>& lanes);
     654              : 
     655              : 
     656              :     /** @brief Aggregates and normalize some values for the detector output during detectorUpdate()
     657              :      */
     658              :     void aggregateOutputValues();
     659              : 
     660              : 
     661              :     /** @brief This updates the detector values and the VehicleInfo of a vehicle on the detector
     662              :      *          with the given MoveNotificationInfo generated by the vehicle during the last time step.
     663              :      *
     664              :      * @param[in/out] vi VehicleInfo corresponding to the notifying vehicle
     665              :      * @param[in] mni MoveNotification for the vehicle
     666              :      */
     667              :     void integrateMoveNotification(VehicleInfo* vi, const MoveNotificationInfo* mni);
     668              : 
     669              :     /** @brief Creates and returns a MoveNotificationInfo containing detector specific information on the vehicle's last movement
     670              :      *
     671              :      * @param veh The vehicle sending the notification
     672              :      * @param oldPos The vehicle's position before the last integration step
     673              :      * @param newPos The vehicle's position after the last integration step
     674              :      * @param newSpeed The vehicle's speed after the last integration step
     675              :      * @param vehInfo Info on the detector's memory of the vehicle
     676              :      * @return A MoveNotificationInfo containing quantities of interest for the detector
     677              :      */
     678              :     MoveNotificationInfo* makeMoveNotification(const SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed, const VehicleInfo& vehInfo) const;
     679              : 
     680              :     /** @brief Creates and returns a VehicleInfo (called at the vehicle's entry)
     681              :      *
     682              :      * @param veh The entering vehicle
     683              :      * @param enteredLane The entry lane
     684              :      * @return A vehicle info which can be used to store information about the vehicle's stay on the detector
     685              :      */
     686              :     VehicleInfo* makeVehicleInfo(const SUMOTrafficObject& veh, const MSLane* enteredLane) const;
     687              : 
     688              :     /** @brief Calculates the time loss for a segment with constant vmax
     689              :      *
     690              :      * @param timespan time needed to cover the segment
     691              :      * @param initialSpeed speed at segment entry
     692              :      * @param accel constant acceleration assumed during movement on the segment
     693              :      * @param vmax Maximal possible speed for the considered vehicle on the segment
     694              :      * @return Time loss (== MAX(timespan*(vmax - (initialSpeed + accel/2))/vmax), 0)
     695              :      */
     696              :     static double calculateSegmentTimeLoss(double timespan, double initialSpeed, double accel, double vmax);
     697              : 
     698              :     /** brief returns true if the vehicle corresponding to mni1 is closer to the detector end than the vehicle corresponding to mni2
     699              :      */
     700    215218530 :     static bool compareMoveNotification(MoveNotificationInfo* mni1, MoveNotificationInfo* mni2) {
     701    215218530 :         return mni1->distToDetectorEnd < mni2->distToDetectorEnd;
     702              :     }
     703              : 
     704              :     void notifyMovePerson(MSTransportable* p, int dir, double pos);
     705              : 
     706              : private:
     707              : 
     708              :     /// @brief Information about how this detector is used
     709              :     DetectorUsage myUsage;
     710              : 
     711              :     /// @name Detector parameter
     712              :     /// @{
     713              :     /// @brief name
     714              :     const std::string myName;
     715              :     /// @brief The detector's lane sequence
     716              :     std::vector<std::string> myLanes;
     717              :     /// @brief The distances of the lane-beginnings from the detector start-point
     718              :     std::vector<double> myOffsets;
     719              :     /// @brief The first lane of the detector's lane sequence
     720              :     MSLane* myFirstLane;
     721              :     /// @brief The last lane of the detector's lane sequence
     722              :     MSLane* myLastLane;
     723              :     /// @brief The position the detector starts at on the first lane
     724              :     double myStartPos;
     725              :     /// @brief The position the detector ends at on the last lane
     726              :     double myEndPos;
     727              :     /// @brief The total detector length
     728              :     double myDetectorLength;
     729              : 
     730              :     /// @brief A vehicle must driver slower than this to be counted as a part of a jam
     731              :     double myJamHaltingSpeedThreshold;
     732              :     /// @brief A vehicle must be that long beyond myJamHaltingSpeedThreshold to be counted as a part of a jam
     733              :     SUMOTime myJamHaltingTimeThreshold;
     734              :     /// @brief Two standing vehicles must be closer than this to be counted into the same jam
     735              :     double myJamDistanceThreshold;
     736              :     /// @}
     737              : 
     738              : 
     739              :     /// @name Container
     740              :     /// @{
     741              :     /// @brief List of informations about the vehicles currently on the detector
     742              :     VehicleInfoMap myVehicleInfos;
     743              : 
     744              :     /// @brief Temporal storage for notifications from vehicles that did call the
     745              :     ///        detector's notifyMove() in the last time step.
     746              :     std::vector<MoveNotificationInfo*> myMoveNotifications;
     747              : 
     748              :     /// @brief Keep track of vehicles that left the detector by a regular move along a junction (not lanechange, teleport, etc.)
     749              :     ///        and should be removed from myVehicleInfos after taking into account their movement. Non-longitudinal exits
     750              :     ///        are processed immediately in notifyLeave()
     751              :     std::set<std::string> myLeftVehicles;
     752              : 
     753              :     /// @brief Storage for halting durations of known vehicles (for halting vehicles)
     754              :     std::map<std::string, SUMOTime> myHaltingVehicleDurations;
     755              : 
     756              :     /// @brief Storage for halting durations of known vehicles (current interval)
     757              :     std::map<std::string, SUMOTime> myIntervalHaltingVehicleDurations;
     758              : 
     759              :     /// @brief Halting durations of ended halts [s]
     760              :     std::vector<SUMOTime> myPastStandingDurations;
     761              : 
     762              :     /// @brief Halting durations of ended halts for the current interval [s]
     763              :     std::vector<SUMOTime> myPastIntervalStandingDurations;
     764              :     /// @}
     765              : 
     766              : 
     767              : 
     768              :     /// @name Values generated for aggregated file output
     769              :     /// @{
     770              :     /// @brief The number of collected samples [time x vehicle] since the last reset
     771              :     double myVehicleSamples;
     772              :     /// @brief The total amount of all time losses [time x vehicle] since the last reset
     773              :     double myTotalTimeLoss;
     774              :     /// @brief The sum of collected vehicle speeds [m/s]
     775              :     double mySpeedSum;
     776              :     /// @brief The number of started halts [#]
     777              :     double myStartedHalts;
     778              :     /// @brief The sum of jam lengths [m]
     779              :     double myJamLengthInMetersSum;
     780              :     /// @brief The sum of jam lengths [#veh]
     781              :     int myJamLengthInVehiclesSum;
     782              :     /// @brief The current aggregation duration [#steps]
     783              :     int myTimeSamples;
     784              :     /// @brief The sum of occupancies [%]
     785              :     double myOccupancySum;
     786              :     /// @brief The maximum occupancy [%]
     787              :     double myMaxOccupancy;
     788              :     /// @brief The mean jam length [#veh]
     789              :     int myMeanMaxJamInVehicles;
     790              :     /// @brief The mean jam length [m]
     791              :     double myMeanMaxJamInMeters;
     792              :     /// @brief The max jam length [#veh]
     793              :     int myMaxJamInVehicles;
     794              :     /// @brief The max jam length [m]
     795              :     double myMaxJamInMeters;
     796              :     /// @brief The mean number of vehicles [#veh]
     797              :     int myMeanVehicleNumber;
     798              :     /// @}
     799              : 
     800              : 
     801              :     /// @name Values generated describing the current state
     802              :     /// @{
     803              :     /// @brief The number of vehicles, which have entered the detector since the last reset
     804              :     int myNumberOfEnteredVehicles;
     805              :     /// @brief The number of vehicles, present on the detector at the last reset
     806              :     int myNumberOfSeenVehicles;
     807              :     /// @brief The number of vehicles, which have left the detector since the last reset
     808              :     int myNumberOfLeftVehicles;
     809              :     /// @brief The maximal number of vehicles located on the detector simultaneously since the last reset
     810              :     int myMaxVehicleNumber;
     811              : 
     812              :     /// @brief The current vehicle samples
     813              :     double myCurrentVehicleSamples;
     814              :     /// @brief The current occupancy
     815              :     double myCurrentOccupancy;
     816              :     /// @brief The current mean speed
     817              :     double myCurrentMeanSpeed;
     818              :     /// @brief The current mean timeLoss
     819              :     double myCurrentMeanTimeLoss;
     820              :     /// @brief The current mean length
     821              :     double myCurrentMeanLength;
     822              :     /// @brief The current jam number
     823              :     int myCurrentJamNo;
     824              :     /// @brief the current maximum jam length in meters
     825              :     double myCurrentMaxJamLengthInMeters;
     826              :     /// @brief The current maximum jam length in vehicles
     827              :     int myCurrentMaxJamLengthInVehicles;
     828              :     /// @brief The overall jam length in meters
     829              :     double myCurrentJamLengthInMeters;
     830              :     /// @brief The overall jam length in vehicles
     831              :     int myCurrentJamLengthInVehicles;
     832              :     /// @brief The overall jam duration in s
     833              :     double myCurrentJamDuration;
     834              :     /// @brief The number of started halts in the last step
     835              :     int myCurrentStartedHalts;
     836              :     /// @brief The number of halted vehicles [#]
     837              :     int myCurrentHaltingsNumber;
     838              :     /// @}
     839              : 
     840              :     /// @name Values generated describing the previous interval state
     841              :     /// @{
     842              :     double myPreviousMeanOccupancy;
     843              :     double myPreviousMeanSpeed;
     844              :     double myPreviousMeanTimeLoss;
     845              :     double myPreviousMaxJamLengthInMeters;
     846              :     int myPreviousNumberOfSeenVehicles;
     847              :     /// @}
     848              : 
     849              :     /// @brief stores the overriden (via Traci) number of vehicles on detector
     850              :     int myOverrideVehNumber;
     851              : 
     852              : private:
     853              :     /// @brief Invalidated copy constructor.
     854              :     MSE2Collector(const MSE2Collector&);
     855              : 
     856              :     /// @brief Invalidated assignment operator.
     857              :     MSE2Collector& operator=(const MSE2Collector&);
     858              : };
        

Generated by: LCOV version 2.0-1