LCOV - code coverage report
Current view: top level - src/microsim/output - MSE2Collector.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 56 82 68.3 %
Date: 2024-05-06 15:32:35 Functions: 7 26 26.9 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4             : // This program and the accompanying materials are made available under the
       5             : // terms of the Eclipse Public License 2.0 which is available at
       6             : // https://www.eclipse.org/legal/epl-2.0/
       7             : // This Source Code may also be made available under the following Secondary
       8             : // Licenses when the conditions for such availability set forth in the Eclipse
       9             : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10             : // or later which is available at
      11             : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12             : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13             : /****************************************************************************/
      14             : /// @file    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     1036102 :         VehicleInfo(std::string id, std::string type, double length, double minGap, const MSLane* entryLane, double entryOffset,
      89     1036102 :                     std::size_t currentOffsetIndex, double exitOffset, double distToDetectorEnd, bool onDetector) :
      90     1036102 :             id(id),
      91     1036102 :             type(type),
      92     1036102 :             length(length),
      93     1036102 :             minGap(minGap),
      94     1036102 :             entryLaneID(entryLane->getID()),
      95     1036102 :             entryOffset(entryOffset),
      96     1036102 :             currentLane(entryLane),
      97     1036102 :             currentOffsetIndex(currentOffsetIndex),
      98     1036102 :             exitOffset(exitOffset),
      99     1036102 :             distToDetectorEnd(distToDetectorEnd),
     100     1036102 :             totalTimeOnDetector(0.),
     101     1036102 :             accumulatedTimeLoss(0.),
     102     1036102 :             onDetector(onDetector),
     103     1036102 :             hasEntered(false),
     104     1036102 :             lastAccel(0),
     105     1036102 :             lastSpeed(0),
     106     1036102 :             lastPos(0) {
     107             :             assert(exitOffset < 0);
     108     1036102 :         }
     109     2072204 :         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    92113174 :         MoveNotificationInfo(std::string _vehID, double _oldPos, double _newPos, double _speed, double _accel, double _distToDetectorEnd, double _timeOnDetector, double _lengthOnDetector, double _timeLoss, bool _onDetector) :
     161    92113174 :             id(_vehID),
     162    92113174 :             oldPos(_oldPos),
     163    92113174 :             newPos(_newPos),
     164    92113174 :             speed(_speed),
     165    92113174 :             accel(_accel),
     166    92113174 :             distToDetectorEnd(_distToDetectorEnd),
     167    92113174 :             timeOnDetector(_timeOnDetector),
     168    92113174 :             lengthOnDetector(_lengthOnDetector),
     169    92113174 :             timeLoss(_timeLoss),
     170    92113174 :             onDetector(_onDetector) {}
     171             : 
     172    92113174 :         virtual ~MoveNotificationInfo() {};
     173             : 
     174             :         /// Vehicle's id
     175             :         std::string id;
     176             :         /// Position before the last integration step (relative to the vehicle's entry lane on the detector)
     177             :         double oldPos;
     178             :         /// Position after the last integration step (relative to the vehicle's entry lane on the detector)
     179             :         double newPos;
     180             :         /// Speed after the last integration step
     181             :         double speed;
     182             :         /// Acceleration in the last integration step
     183             :         double accel;
     184             :         /// Distance left till the detector end after the last integration step (may become negative if the vehicle passes beyond the detector end)
     185             :         double distToDetectorEnd;
     186             :         /// Time spent on the detector during the last integration step
     187             :         double timeOnDetector;
     188             :         /// The length of the part of the vehicle on the detector at the end of the last time step
     189             :         double lengthOnDetector;
     190             :         /// timeloss during the last integration step
     191             :         double timeLoss;
     192             :         /// whether the vehicle is on the detector at the end of the current timestep
     193             :         bool onDetector;
     194             :     };
     195             : 
     196             : 
     197             : 
     198             :     /** @brief Internal representation of a jam
     199             :      *
     200             :      * Used in execute, instances of this structure are used to track
     201             :      *  begin and end positions (as vehicles) of a jam.
     202             :      */
     203             :     struct JamInfo {
     204             :         /// @brief The first standing vehicle
     205             :         std::vector<MoveNotificationInfo*>::const_iterator firstStandingVehicle;
     206             : 
     207             :         /// @brief The last standing vehicle
     208             :         std::vector<MoveNotificationInfo*>::const_iterator lastStandingVehicle;
     209             :     };
     210             : 
     211             : 
     212             : public:
     213             : 
     214             :     /** @brief Constructor with given end position and detector length
     215             :     *
     216             :     * @param[in] id The detector's unique id.
     217             :     * @param[in] usage Information how the detector is used
     218             :     * @param[in] lane The lane the detector ends
     219             :     * @param[in] startPos The start position on the lane the detector is placed at
     220             :     * @param[in] endPos The end position on the lane the detector is placed at
     221             :     * @param[in] length The length the detector has (heuristic lane selection is done if the continuation is not unique)
     222             :     * @param[in] haltingTimeThreshold The time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed
     223             :     * @param[in] haltingSpeedThreshold The speed a vehicle's speed must be below to be assigned as jammed
     224             :     * @param[in] jamDistThreshold The distance between two vehicles in order to not count them to one jam
     225             :     * @param[in] vTypes Vehicle types, that the detector takes into account
     226             :     *
     227             :     * @note Exactly one of the arguments startPos, endPos and length should be invalid (i.e. equal to std::numeric_limits<double>::max()).
     228             :     *        If length is invalid, it is required that 0 <= startPos < endPos <= lane->length
     229             :     *        If endPos is invalid, the detector may span over several lanes downstream of the lane
     230             :     *        If pos is invalid, the detector may span over several lanes upstream of the lane
     231             :     */
     232             :     MSE2Collector(const std::string& id,
     233             :                   DetectorUsage usage, MSLane* lane, double startPos, double endPos, double length,
     234             :                   SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
     235             :                   const std::string name, const std::string& vTypes,
     236             :                   const std::string& nextEdges,
     237             :                   int detectPersons);
     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 name, const std::string& vTypes,
     256             :                   const std::string& nextEdges,
     257             :                   int detectPersons);
     258             : 
     259             : 
     260             :     /// @brief Destructor
     261             :     virtual ~MSE2Collector();
     262             : 
     263             :     /** @brief Returns the detector's usage type
     264             :      *
     265             :      * @see DetectorUsage
     266             :      * @return How the detector is used.
     267             :      */
     268        7264 :     virtual DetectorUsage getUsageType() const {
     269        7264 :         return myUsage;
     270             :     }
     271             : 
     272             : 
     273             : 
     274             :     /// @name Methods inherited from MSMoveReminder
     275             :     /// @{
     276             : 
     277             :     /** @brief Adds/removes vehicles from the list of vehicles to regard
     278             :      *
     279             :      * As soon as the reported vehicle enters the detector area (position>myStartPos)
     280             :      *  it is added to the list of vehicles to regard (myKnownVehicles). It
     281             :      *  is removed from this list if it leaves the detector (position<length>myEndPos).
     282             :      * The method returns true as long as the vehicle is not beyond the detector.
     283             :      *
     284             :      * @param[in] veh The vehicle in question.
     285             :      * @param[in] oldPos Position before the move-micro-timestep.
     286             :      * @param[in] newPos Position after the move-micro-timestep.
     287             :      *                   Note that this position is given in reference
     288             :      *                   to the begin of the entry lane of the vehicle.
     289             :      * @param[in] newSpeed Unused here.
     290             :      * @return False, if vehicle passed the detector entirely, else true.
     291             :      * @see MSMoveReminder
     292             :      * @see MSMoveReminder::notifyMove
     293             :      */
     294             :     virtual bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos,
     295             :                             double newSpeed);
     296             : 
     297             : 
     298             :     /** @brief Removes a known vehicle due to its lane-change
     299             :      *
     300             :      * If the reported vehicle is known, it is removed from the list of
     301             :      *  vehicles to regard (myKnownVehicles).
     302             :      *
     303             :      * @param[in] veh The leaving vehicle.
     304             :      * @param[in] lastPos Position on the lane when leaving.
     305             :      * @param[in] isArrival whether the vehicle arrived at its destination
     306             :      * @param[in] isLaneChange whether the vehicle changed from the lane
     307             :      * @see MSMoveReminder::notifyLeave
     308             :      */
     309             :     virtual bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
     310             : 
     311             : 
     312             :     /** @brief Adds the vehicle to known vehicles if not beyond the dector
     313             :      *
     314             :      * If the vehicles is within the detector are, it is added to the list
     315             :      *  of known vehicles.
     316             :      * The method returns true as long as the vehicle is not beyond the detector.
     317             :      *
     318             :      * @param[in] veh The entering vehicle.
     319             :      * @param[in] reason how the vehicle enters the lane
     320             :      * @return False, if vehicle passed the detector entirely, else true.
     321             :      * @see MSMoveReminder::notifyEnter
     322             :      * @see MSMoveReminder::Notification
     323             :      */
     324             :     virtual bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane);
     325             :     /// @}
     326             : 
     327             : 
     328             : 
     329             : 
     330             : 
     331             :     /// @name Methods inherited from MSDetectorFileOutput.
     332             :     /// @{
     333             : 
     334             :     /** @brief Computes the detector values in each time step
     335             :      *
     336             :      * This method should be called at the end of a simulation step, when
     337             :      *  all vehicles have moved. The current values are computed and
     338             :      *  summed up with the previous.
     339             :      *
     340             :      * @param[in] currentTime The current simulation time
     341             :      */
     342             :     virtual void detectorUpdate(const SUMOTime step);
     343             : 
     344             : 
     345             :     /** @brief Write the generated output to the given device
     346             :      * @param[in] dev The output device to write the data into
     347             :      * @param[in] startTime First time step the data were gathered
     348             :      * @param[in] stopTime Last time step the data were gathered
     349             :      * @exception IOError If an error on writing occurs
     350             :      */
     351             :     virtual void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime);
     352             : 
     353             : 
     354             :     /** @brief Open the XML-output
     355             :      *
     356             :      * The implementing function should open an xml element using
     357             :      *  OutputDevice::writeXMLHeader.
     358             :      *
     359             :      * @param[in] dev The output device to write the root into
     360             :      * @exception IOError If an error on writing occurs
     361             :      */
     362             :     virtual void writeXMLDetectorProlog(OutputDevice& dev) const;
     363             : 
     364             :     /// @}
     365             : 
     366             :     /// @brief get name
     367             :     const std::string& getName() {
     368             :         return myName;
     369             :     }
     370             : 
     371             :     /** @brief Returns the begin position of the detector
     372             :      *
     373             :      * @return The detector's begin position
     374             :      */
     375             :     double getStartPos() const {
     376         433 :         return myStartPos;
     377             :     }
     378             : 
     379             : 
     380             :     /** @brief Returns the end position of the detector
     381             :      *
     382             :      * @return The detector's end position
     383             :      */
     384             :     double getEndPos() const {
     385         433 :         return myEndPos;
     386             :     }
     387             : 
     388             :     /** @brief Returns the length of the detector
     389             :      *
     390             :      * @return The detector's length
     391             :      */
     392             :     double getLength() const {
     393         505 :         return myDetectorLength;
     394             :     }
     395             : 
     396             : 
     397             :     /** @brief Returns the id of the detector's last lane
     398             :      *
     399             :      * @return The detector's end position
     400             :      */
     401             :     MSLane* getLastLane() const {
     402           8 :         return myLastLane;
     403             :     }
     404             : 
     405             : 
     406             :     /** @brief Returns a vector containing pointers to the lanes covered by the detector ordered from its first to its last lane
     407             :      */
     408             :     std::vector<MSLane*> getLanes();
     409             : 
     410             :     /** @brief Resets all values
     411             :      *
     412             :      * This method is called on initialisation and as soon as the values
     413             :      *  were written. Values for the next interval may be collected, then.
     414             :      * The list of known vehicles stays untouched.
     415             :      */
     416             :     virtual void reset();
     417             : 
     418             : 
     419             :     /// @name Methods returning current values
     420             :     /// @{
     421             : 
     422             :     /** @brief Returns the number of vehicles currently on the detector */
     423             :     int getCurrentVehicleNumber() const;
     424             : 
     425             :     /** @brief Returns the current detector occupancy */
     426           0 :     double getCurrentOccupancy() const {
     427         504 :         return myCurrentOccupancy;
     428             :     }
     429             : 
     430             :     /** @brief Returns the mean vehicle speed of vehicles currently on the detector*/
     431           0 :     double getCurrentMeanSpeed() const {
     432      256120 :         return myCurrentMeanSpeed;
     433             :     }
     434             : 
     435             :     /** @brief Returns the mean vehicle length of vehicles currently on the detector*/
     436           0 :     double getCurrentMeanLength() const {
     437           0 :         return myCurrentMeanLength;
     438             :     }
     439             : 
     440             :     /** @brief Returns the current number of jams */
     441           0 :     int getCurrentJamNumber() const {
     442           0 :         return myCurrentJamNo;
     443             :     }
     444             : 
     445             :     /** @brief Returns the length in vehicles of the currently largest jam */
     446           0 :     int getCurrentMaxJamLengthInVehicles() const {
     447           0 :         return myCurrentMaxJamLengthInVehicles;
     448             :     }
     449             : 
     450             :     /** @brief Returns the length in meters of the currently largest jam */
     451           0 :     double getCurrentMaxJamLengthInMeters() const {
     452           0 :         return myCurrentMaxJamLengthInMeters;
     453             :     }
     454             : 
     455             :     /** @brief Returns the length of all jams in vehicles */
     456           0 :     int getCurrentJamLengthInVehicles() const {
     457         504 :         return myCurrentJamLengthInVehicles;
     458             :     }
     459             : 
     460             :     /** @brief Returns the length of all jams in meters */
     461           0 :     double getCurrentJamLengthInMeters() const {
     462         504 :         return myCurrentJamLengthInMeters;
     463             :     }
     464             : 
     465             :     /** @brief Returns the length of all jams in meters */
     466           0 :     int getCurrentStartedHalts() const {
     467           0 :         return myCurrentStartedHalts;
     468             :     }
     469             : 
     470             :     /** @brief Returns the number of current haltings within the area
     471             :     *
     472             :     * If no vehicle is within the area, 0 is returned.
     473             :     *
     474             :     * @return The mean number of haltings within the area
     475             :     */
     476             :     int getCurrentHaltingNumber() const {
     477         504 :         return myCurrentHaltingsNumber;
     478             :     }
     479             : 
     480             :     /** @brief Returns the IDs of the vehicles within the area
     481             :      *
     482             :      * @return The IDs of the vehicles that have passed the entry, but not yet an exit point
     483             :      */
     484             :     std::vector<std::string> getCurrentVehicleIDs() const;
     485             : 
     486             :     /** @brief Returns the VehicleInfos for the vehicles currently on the detector
     487             :      */
     488             :     std::vector<VehicleInfo*> getCurrentVehicles() const;
     489             : 
     490             :     /** \brief Returns the number of vehicles passed over the sensor (i.e. entered the sensor)
     491             :      *
     492             :      * @return number of cars passed over the sensor
     493             :      */
     494           0 :     int getPassedVeh() {
     495           0 :         return myNumberOfEnteredVehicles;
     496             :     }
     497             : 
     498             :     /** \brief Subtract the number of vehicles indicated from passed from the sensor count.
     499             :      *
     500             :      * @param[in] passed - int that indicates the number of vehicles to subtract
     501             :      */
     502             :     void subtractPassedVeh(int passed) {
     503           0 :         myNumberOfEnteredVehicles -= passed;
     504           0 :     }
     505             : 
     506             :     /// @}
     507             : 
     508             : 
     509             :     /// @name Methods returning aggregated values
     510             :     /// @{
     511             : 
     512           0 :     double getIntervalOccupancy() const {
     513      559354 :         return myTimeSamples != 0 ? myOccupancySum / (double) myTimeSamples : 0;
     514             :     }
     515           0 :     double getIntervalMeanSpeed() const {
     516      559354 :         return myVehicleSamples != 0 ? mySpeedSum / myVehicleSamples : -1;
     517             :     }
     518           0 :     double getIntervalMaxJamLengthInMeters() const {
     519         720 :         return myMaxJamInMeters;
     520             :     }
     521           0 :     int getIntervalVehicleNumber() const {
     522         720 :         return myNumberOfSeenVehicles;
     523             :     }
     524             : 
     525           0 :     double getLastIntervalOccupancy() const {
     526         720 :         return myPreviousMeanOccupancy;
     527             :     }
     528           0 :     double getLastIntervalMeanSpeed() const {
     529         720 :         return myPreviousMeanSpeed;
     530             :     }
     531           0 :     double getLastIntervalMaxJamLengthInMeters() const {
     532         720 :         return myPreviousMaxJamLengthInMeters;
     533             :     }
     534           0 :     int getLastIntervalVehicleNumber() const {
     535         720 :         return myPreviousNumberOfSeenVehicles;
     536             :     }
     537             : 
     538             :     /// @}
     539             : 
     540             : 
     541             :     /// @name Estimation methods
     542             :     /// TODO: Need documentation, used for tls control in MSSOTLE2Sensors (->Daniel?)
     543             :     /// @{
     544             :     /** @brief Returns an estimate of the number of vehicles currently on the detector */
     545             :     int getEstimatedCurrentVehicleNumber(double speedThreshold) const;
     546             : 
     547             :     /** @brief Returns an estimate of the length of the queue of vehicles currently stopped on the detector */
     548             :     double getEstimateQueueLength() const;
     549             :     /// @}
     550             : 
     551             : 
     552          67 :     virtual void setVisible(bool /*show*/) {};
     553             : 
     554             :     /** @brief Remove all vehicles before quick-loading state */
     555             :     virtual void clearState(SUMOTime step);
     556             : 
     557             :     /** @brief Persistently overrides the number of vehicles on top of the detector
     558             :      * Setting a negative value removes the override
     559             :     */
     560             :     void overrideVehicleNumber(int num);
     561             : 
     562             :     double getOverrideVehNumber() const {
     563        3632 :         return myOverrideVehNumber;
     564             :     }
     565             : private:
     566             : 
     567             :     /** @brief checks whether the vehicle stands in a jam
     568             :      *
     569             :      * @param[in] mni
     570             :      * @param[in/out] haltingVehicles
     571             :      * @param[in/out] intervalHaltingVehicles
     572             :      * @return Whether vehicle is in a jam.
     573             :      */
     574             :     bool checkJam(std::vector<MoveNotificationInfo*>::const_iterator mni, std::map<std::string, SUMOTime>& haltingVehicles, std::map<std::string, SUMOTime>& intervalHaltingVehicles);
     575             : 
     576             : 
     577             :     /** @brief Either adds the vehicle to the end of an existing jam, or closes the last jam, and/or creates a new jam
     578             :      *
     579             :      * @param isInJam
     580             :      * @param mni
     581             :      * @param[in/out] currentJam
     582             :      * @param[in/out] jams
     583             :      */
     584             :     void buildJam(bool isInJam, std::vector<MoveNotificationInfo*>::const_iterator mni, JamInfo*& currentJam, std::vector<JamInfo*>& jams);
     585             : 
     586             : 
     587             :     /** @brief Calculates aggregated values from the given jam structure, deletes all jam-pointers
     588             :      *
     589             :      * @param jams
     590             :      */
     591             :     void processJams(std::vector<JamInfo*>& jams, JamInfo* currentJam);
     592             : 
     593             :     /** @brief Calculates the time spent on the detector in the last step and the timeloss suffered in the last step for the given vehicle
     594             :      *
     595             :      * @param[in] veh Vehicle for which the values are to be calculated
     596             :      * @param[in] oldPos Last position (before the last timestep) of the vehicle relative to the beginning of its entry lane
     597             :      * @param[in] newPos Current position of the vehicle
     598             :      * @param[in] vi VehicleInfo corresponding to the vehicle
     599             :      * @param[in/out] timeOnDetector Total time spent on the detector during the last step
     600             :      * @param[in/out] timeLoss Total time loss suffered during the last integration step
     601             :      */
     602             :     void calculateTimeLossAndTimeOnDetector(const SUMOTrafficObject& veh, double oldPos, double newPos, const VehicleInfo& vi, double& timeOnDetector, double& timeLoss) const;
     603             : 
     604             :     /** @brief Checks integrity of myLanes, adds internal-lane information, inits myLength, myFirstLane, myLastLane, myOffsets
     605             :      *         Called once at construction.
     606             :      *  @requires myLanes should form a continuous sequence.
     607             :      */
     608             :     void initAuxiliaries(std::vector<MSLane*>& lanes);
     609             : 
     610             :     /** @brief Adjusts positioning if the detector length is less than POSITION_EPS and tests some assertions
     611             :      */
     612             :     void checkPositioning(bool posGiven = false, double desiredLength = 0.);
     613             : 
     614             :     /** @brief Snaps value to snpPoint if they are closer than snapDist
     615             :      */
     616             :     static double snap(double value, double snapPoint, double snapDist);
     617             : 
     618             :     /** @brief Updates the detector length after myStartPos and myEndPos have been modified
     619             :      */
     620             :     void recalculateDetectorLength();
     621             : 
     622             : 
     623             : 
     624             :     /** @brief This is called if no lane sequence is given to the constructor. Builds myLanes from the given information.
     625             :      *          Also inits startPos (case dir=="bw") / endPos (case dir=="fw").
     626             :      *          Selects lanes heuristically if no unambiguous continuation exists.
     627             :      *
     628             :      *  @param[in] lane Lane, where the detector starts/ends
     629             :      *  @param[in] length Length of the detector
     630             :      *  @param[in] dir Direction of detector extension with value in {"fw", "bw"} (forward / backward)
     631             :      *                 If dir == "fw" lane is interpreted as corresponding to the start lane of the detector,
     632             :      *                 otherwise the lane is interpreted as the end lane.
     633             :      */
     634             :     std::vector<MSLane*> selectLanes(MSLane* endLane, double length, std::string dir);
     635             : 
     636             : 
     637             :     /** @brief This adds the detector as a MoveReminder to the associated lanes.
     638             :      */
     639             :     void addDetectorToLanes(std::vector<MSLane*>& lanes);
     640             : 
     641             : 
     642             :     /** @brief Aggregates and normalize some values for the detector output during detectorUpdate()
     643             :      */
     644             :     void aggregateOutputValues();
     645             : 
     646             : 
     647             :     /** @brief This updates the detector values and the VehicleInfo of a vehicle on the detector
     648             :      *          with the given MoveNotificationInfo generated by the vehicle during the last time step.
     649             :      *
     650             :      * @param[in/out] vi VehicleInfo corresponding to the notifying vehicle
     651             :      * @param[in] mni MoveNotification for the vehicle
     652             :      */
     653             :     void integrateMoveNotification(VehicleInfo* vi, const MoveNotificationInfo* mni);
     654             : 
     655             :     /** @brief Creates and returns a MoveNotificationInfo containing detector specific information on the vehicle's last movement
     656             :      *
     657             :      * @param veh The vehicle sending the notification
     658             :      * @param oldPos The vehicle's position before the last integration step
     659             :      * @param newPos The vehicle's position after the last integration step
     660             :      * @param newSpeed The vehicle's speed after the last integration step
     661             :      * @param vehInfo Info on the detector's memory of the vehicle
     662             :      * @return A MoveNotificationInfo containing quantities of interest for the detector
     663             :      */
     664             :     MoveNotificationInfo* makeMoveNotification(const SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed, const VehicleInfo& vehInfo) const;
     665             : 
     666             :     /** @brief Creates and returns a VehicleInfo (called at the vehicle's entry)
     667             :      *
     668             :      * @param veh The entering vehicle
     669             :      * @param enteredLane The entry lane
     670             :      * @return A vehicle info which can be used to store information about the vehicle's stay on the detector
     671             :      */
     672             :     VehicleInfo* makeVehicleInfo(const SUMOTrafficObject& veh, const MSLane* enteredLane) const;
     673             : 
     674             :     /** @brief Calculates the time loss for a segment with constant vmax
     675             :      *
     676             :      * @param timespan time needed to cover the segment
     677             :      * @param initialSpeed speed at segment entry
     678             :      * @param accel constant acceleration assumed during movement on the segment
     679             :      * @param vmax Maximal possible speed for the considered vehicle on the segment
     680             :      * @return Time loss (== MAX(timespan*(vmax - (initialSpeed + accel/2))/vmax), 0)
     681             :      */
     682             :     static double calculateSegmentTimeLoss(double timespan, double initialSpeed, double accel, double vmax);
     683             : 
     684             :     /** brief returns true if the vehicle corresponding to mni1 is closer to the detector end than the vehicle corresponding to mni2
     685             :      */
     686   427556907 :     static bool compareMoveNotification(MoveNotificationInfo* mni1, MoveNotificationInfo* mni2) {
     687   427556907 :         return mni1->distToDetectorEnd < mni2->distToDetectorEnd;
     688             :     }
     689             : 
     690             :     void notifyMovePerson(MSTransportable* p, int dir, double pos);
     691             : 
     692             : private:
     693             : 
     694             :     /// @brief Information about how this detector is used
     695             :     DetectorUsage myUsage;
     696             : 
     697             :     /// @name Detector parameter
     698             :     /// @{
     699             :     /// @brief name
     700             :     const std::string myName;
     701             :     /// @brief The detector's lane sequence
     702             :     std::vector<std::string> myLanes;
     703             :     /// @brief The distances of the lane-beginnings from the detector start-point
     704             :     std::vector<double> myOffsets;
     705             :     /// @brief The first lane of the detector's lane sequence
     706             :     MSLane* myFirstLane;
     707             :     /// @brief The last lane of the detector's lane sequence
     708             :     MSLane* myLastLane;
     709             :     /// @brief The position the detector starts at on the first lane
     710             :     double myStartPos;
     711             :     /// @brief The position the detector ends at on the last lane
     712             :     double myEndPos;
     713             :     /// @brief The total detector length
     714             :     double myDetectorLength;
     715             : 
     716             :     /// @brief A vehicle must driver slower than this to be counted as a part of a jam
     717             :     double myJamHaltingSpeedThreshold;
     718             :     /// @brief A vehicle must be that long beyond myJamHaltingSpeedThreshold to be counted as a part of a jam
     719             :     SUMOTime myJamHaltingTimeThreshold;
     720             :     /// @brief Two standing vehicles must be closer than this to be counted into the same jam
     721             :     double myJamDistanceThreshold;
     722             :     /// @}
     723             : 
     724             : 
     725             :     /// @name Container
     726             :     /// @{
     727             :     /// @brief List of informations about the vehicles currently on the detector
     728             :     VehicleInfoMap myVehicleInfos;
     729             : 
     730             :     /// @brief Temporal storage for notifications from vehicles that did call the
     731             :     ///        detector's notifyMove() in the last time step.
     732             :     std::vector<MoveNotificationInfo*> myMoveNotifications;
     733             : 
     734             :     /// @brief Keep track of vehicles that left the detector by a regular move along a junction (not lanechange, teleport, etc.)
     735             :     ///        and should be removed from myVehicleInfos after taking into account their movement. Non-longitudinal exits
     736             :     ///        are processed immediately in notifyLeave()
     737             :     std::set<std::string> myLeftVehicles;
     738             : 
     739             :     /// @brief Storage for halting durations of known vehicles (for halting vehicles)
     740             :     std::map<std::string, SUMOTime> myHaltingVehicleDurations;
     741             : 
     742             :     /// @brief Storage for halting durations of known vehicles (current interval)
     743             :     std::map<std::string, SUMOTime> myIntervalHaltingVehicleDurations;
     744             : 
     745             :     /// @brief Halting durations of ended halts [s]
     746             :     std::vector<SUMOTime> myPastStandingDurations;
     747             : 
     748             :     /// @brief Halting durations of ended halts for the current interval [s]
     749             :     std::vector<SUMOTime> myPastIntervalStandingDurations;
     750             :     /// @}
     751             : 
     752             : 
     753             : 
     754             :     /// @name Values generated for aggregated file output
     755             :     /// @{
     756             :     /// @brief The number of collected samples [time x vehicle] since the last reset
     757             :     double myVehicleSamples;
     758             :     /// @brief The total amount of all time losses [time x vehicle] since the last reset
     759             :     double myTotalTimeLoss;
     760             :     /// @brief The sum of collected vehicle speeds [m/s]
     761             :     double mySpeedSum;
     762             :     /// @brief The number of started halts [#]
     763             :     double myStartedHalts;
     764             :     /// @brief The sum of jam lengths [m]
     765             :     double myJamLengthInMetersSum;
     766             :     /// @brief The sum of jam lengths [#veh]
     767             :     int myJamLengthInVehiclesSum;
     768             :     /// @brief The current aggregation duration [#steps]
     769             :     int myTimeSamples;
     770             :     /// @brief The sum of occupancies [%]
     771             :     double myOccupancySum;
     772             :     /// @brief The maximum occupancy [%]
     773             :     double myMaxOccupancy;
     774             :     /// @brief The mean jam length [#veh]
     775             :     int myMeanMaxJamInVehicles;
     776             :     /// @brief The mean jam length [m]
     777             :     double myMeanMaxJamInMeters;
     778             :     /// @brief The max jam length [#veh]
     779             :     int myMaxJamInVehicles;
     780             :     /// @brief The max jam length [m]
     781             :     double myMaxJamInMeters;
     782             :     /// @brief The mean number of vehicles [#veh]
     783             :     int myMeanVehicleNumber;
     784             :     /// @}
     785             : 
     786             : 
     787             :     /// @name Values generated describing the current state
     788             :     /// @{
     789             :     /// @brief The number of vehicles, which have entered the detector since the last reset
     790             :     int myNumberOfEnteredVehicles;
     791             :     /// @brief The number of vehicles, present on the detector at the last reset
     792             :     int myNumberOfSeenVehicles;
     793             :     /// @brief The number of vehicles, which have left the detector since the last reset
     794             :     int myNumberOfLeftVehicles;
     795             :     /// @brief The maximal number of vehicles located on the detector simultaneously since the last reset
     796             :     int myMaxVehicleNumber;
     797             : 
     798             :     /// @brief The current vehicle samples
     799             :     double myCurrentVehicleSamples;
     800             :     /// @brief The current occupancy
     801             :     double myCurrentOccupancy;
     802             :     /// @brief The current mean speed
     803             :     double myCurrentMeanSpeed;
     804             :     /// @brief The current mean length
     805             :     double myCurrentMeanLength;
     806             :     /// @brief The current jam number
     807             :     int myCurrentJamNo;
     808             :     /// @brief the current maximum jam length in meters
     809             :     double myCurrentMaxJamLengthInMeters;
     810             :     /// @brief The current maximum jam length in vehicles
     811             :     int myCurrentMaxJamLengthInVehicles;
     812             :     /// @brief The overall jam length in meters
     813             :     double myCurrentJamLengthInMeters;
     814             :     /// @brief The overall jam length in vehicles
     815             :     int myCurrentJamLengthInVehicles;
     816             :     /// @brief The number of started halts in the last step
     817             :     int myCurrentStartedHalts;
     818             :     /// @brief The number of halted vehicles [#]
     819             :     int myCurrentHaltingsNumber;
     820             :     /// @}
     821             : 
     822             :     /// @name Values generated describing the previous interval state
     823             :     /// @{
     824             :     double myPreviousMeanOccupancy;
     825             :     double myPreviousMeanSpeed;
     826             :     double myPreviousMaxJamLengthInMeters;
     827             :     int myPreviousNumberOfSeenVehicles;
     828             :     /// @}
     829             : 
     830             :     /// @brief stores the overriden (via Traci) number of vehicles on detector
     831             :     int myOverrideVehNumber;
     832             : 
     833             : private:
     834             :     /// @brief Invalidated copy constructor.
     835             :     MSE2Collector(const MSE2Collector&);
     836             : 
     837             :     /// @brief Invalidated assignment operator.
     838             :     MSE2Collector& operator=(const MSE2Collector&);
     839             : };

Generated by: LCOV version 1.14