LCOV - code coverage report
Current view: top level - src/microsim/output - MSInductLoop.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 10 10
Test Date: 2026-04-16 16:39:47 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2004-2026 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSInductLoop.h
      15              : /// @author  Christian Roessel
      16              : /// @author  Daniel Krajzewicz
      17              : /// @author  Sascha Krieg
      18              : /// @author  Michael Behrisch
      19              : /// @author  Jakob Erdmann
      20              : /// @author  Mirko Barthauer
      21              : /// @date    2004-11-23
      22              : ///
      23              : // An unextended detector measuring at a fixed position on a fixed lane.
      24              : /****************************************************************************/
      25              : #pragma once
      26              : #include <config.h>
      27              : 
      28              : #include <string>
      29              : #include <deque>
      30              : #include <map>
      31              : #include <functional>
      32              : #include <microsim/MSMoveReminder.h>
      33              : #include <microsim/output/MSDetectorFileOutput.h>
      34              : 
      35              : 
      36              : // ===========================================================================
      37              : // class declarations
      38              : // ===========================================================================
      39              : class MSLane;
      40              : class MSVehicle;
      41              : class OutputDevice;
      42              : 
      43              : 
      44              : // ===========================================================================
      45              : // class definitions
      46              : // ===========================================================================
      47              : /**
      48              :  * @class MSInductLoop
      49              :  * @brief An unextended detector measuring at a fixed position on a fixed lane.
      50              :  *
      51              :  * Only vehicles that passed the entire detector are counted. We
      52              :  *  ignore vehicles that are emitted onto the detector and vehicles
      53              :  *  that change their lane while they are on the detector, because we
      54              :  *  cannot determine a meaningful enter/leave-times.
      55              :  *
      56              :  * This detector uses the MSMoveReminder mechanism, i.e. the vehicles
      57              :  *  call the detector if they pass it.
      58              :  *
      59              :  * @see MSMoveReminder
      60              :  * @see MSDetectorFileOutput
      61              :  */
      62              : class MSInductLoop
      63              :     : public MSMoveReminder, public MSDetectorFileOutput {
      64              : public:
      65              :     /**
      66              :      * @brief Constructor.
      67              :      *
      68              :      * Adds reminder to MSLane.
      69              :      *
      70              :      * @param[in] id Unique id
      71              :      * @param[in] lane Lane where detector works on
      72              :      * @param[in] position Position of the detector within the lane
      73              :      * @param[in] vTypes which vehicle types are considered
      74              :      * @param[in] needLocking whether internals need to be guarded against concurrent access (GUI)
      75              :      */
      76              :     MSInductLoop(const std::string& id, MSLane* const lane,
      77              :                  double positionInMeters,
      78              :                  double length, std::string name,
      79              :                  const std::string& vTypes,
      80              :                  const std::string& nextEdges,
      81              :                  int detectPersons,
      82              :                  const bool needLocking);
      83              : 
      84              : 
      85              :     /// @brief Destructor
      86              :     ~MSInductLoop();
      87              : 
      88              : 
      89              :     /// @brief Resets all generated values to allow computation of next interval
      90              :     virtual void reset();
      91              : 
      92              :     /// @brief get name
      93              :     std::string getName() const {
      94              :         return myName;
      95              :     }
      96              : 
      97              :     /** @brief Returns the position of the detector on the lane
      98              :      * @return The detector's position in meters
      99              :      */
     100              :     double getPosition() const {
     101          536 :         return myPosition;
     102              :     }
     103              : 
     104              :     /** @brief Returns the end position of the detector on the lane
     105              :      * @return The detector's end position in meters
     106              :      */
     107              :     double getEndPosition() const {
     108         1382 :         return myEndPosition;
     109              :     }
     110              : 
     111              : 
     112              :     /// @name Methods inherited from MSMoveReminder
     113              :     /// @{
     114              :     /** @brief Checks whether the reminder is activated by a vehicle entering the lane
     115              :      *
     116              :      * Lane change means in this case that the vehicle changes to the lane
     117              :      *  the reminder is placed at.
     118              :      *
     119              :      * @param[in] veh The entering vehicle.
     120              :      * @param[in] reason how the vehicle enters the lane
     121              :      * @return True if vehicle enters the induction loop
     122              :      * @see Notification
     123              :      */
     124              :     bool notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* enteredLane = 0);
     125              : 
     126              :     /** @brief Checks whether the vehicle shall be counted and/or shall still touch this MSMoveReminder
     127              :      *
     128              :      * As soon a vehicle enters the detector, its entry time is computed and stored
     129              :      *  in myVehiclesOnDet via enterDetectorByMove. If it passes the detector, the
     130              :      *  according leaving time is computed and stored, too, using leaveDetectorByMove.
     131              :      *
     132              :      * @param[in] veh Vehicle that asks this remider.
     133              :      * @param[in] oldPos Position before move.
     134              :      * @param[in] newPos Position after move with newSpeed.
     135              :      * @param[in] newSpeed Moving speed.
     136              :      * @return True if vehicle hasn't passed the detector completely.
     137              :      * @see MSMoveReminder
     138              :      * @see MSMoveReminder::notifyMove
     139              :      * @see enterDetectorByMove
     140              :      * @see leaveDetectorByMove
     141              :      */
     142              :     bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed);
     143              : 
     144              : 
     145              :     /** @brief Dismisses the vehicle if it is on the detector due to a lane change
     146              :      *
     147              :      * If the vehicle is on the detector, it will be dismissed by incrementing
     148              :      *  myDismissedVehicleNumber and removing this vehicle's entering time from
     149              :      *  myVehiclesOnDet.
     150              :      *
     151              :      * @param[in] veh The leaving vehicle.
     152              :      * @param[in] lastPos Position on the lane when leaving.
     153              :      * @param[in] isArrival whether the vehicle arrived at its destination
     154              :      * @param[in] isLaneChange whether the vehicle changed from the lane
     155              :      * @see discardVehicle
     156              :      * @see MSMoveReminder
     157              :      * @see MSMoveReminder::notifyLeave
     158              :      */
     159              :     bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
     160              : 
     161              : 
     162              :     //@}
     163              : 
     164              : 
     165              : 
     166              :     /// @name Methods returning current values
     167              :     /// @{
     168              : 
     169              :     /** @brief Returns the speed of the vehicle on the detector
     170              :      *
     171              :      * If no vehicle is on the detector, -1 is returned, otherwise
     172              :      *  this vehicle's current speed.
     173              :      *
     174              :      * @return The speed [m/s] of the vehicle if one is on the detector, -1 otherwise
     175              :      */
     176              :     double getSpeed(const int offset) const;
     177              : 
     178              : 
     179              :     /** @brief Returns the length of the vehicle on the detector
     180              :      *
     181              :      * If no vehicle is on the detector, -1 is returned, otherwise
     182              :      *  this vehicle's length.
     183              :      *
     184              :      * @return The length [m] of the vehicle if one is on the detector, -1 otherwise
     185              :      */
     186              :     double getVehicleLength(const int offset) const;
     187              : 
     188              : 
     189              :     /** @brief Returns the current occupancy
     190              :      *
     191              :      * If a vehicle is on the detector, 1 is returned. If a vehicle has passed the detector
     192              :      *  in this timestep, its occupancy value is returned. If no vehicle has passed,
     193              :      *  0 is returned.
     194              :      *
     195              :      * @return This detector's current occupancy
     196              :      * @todo recheck (especially if more than one vehicle has passed)
     197              :      */
     198              :     double getOccupancy() const;
     199              : 
     200              :     /** @brief Returns the number of vehicles that have passed the detector
     201              :      *
     202              :      * If a vehicle is on the detector, 1 is returned. If a vehicle has passed the detector
     203              :      *  in this timestep, 1 is returned. If no vehicle has passed,
     204              :      *  0 is returned.
     205              :      *
     206              :      * @return The number of vehicles that have passed the detector
     207              :      * @todo recheck (especially if more than one vehicle has passed)
     208              :      */
     209              :     double getEnteredNumber(const int offset) const;
     210              : 
     211              : 
     212              :     /** @brief Returns the ids of vehicles that have passed the detector
     213              :      *
     214              :      * @return The ids of vehicles that have passed the detector
     215              :      * @todo recheck (especially if more than one vehicle has passed)
     216              :      */
     217              :     std::vector<std::string> getVehicleIDs(const int offset) const;
     218              : 
     219              :     double getIntervalOccupancy(bool lastInterval = false) const;
     220              :     double getIntervalMeanSpeed(bool lastInterval = false) const;
     221              :     int getIntervalVehicleNumber(bool lastInterval = false) const;
     222              :     std::vector<std::string> getIntervalVehicleIDs(bool lastInterval = false) const;
     223              : 
     224              :     /** @brief Returns the time since the last vehicle left the detector
     225              :      *
     226              :      * @return seconds from last leaving (detection) of the detector
     227              :      */
     228              :     double getTimeSinceLastDetection() const;
     229              : 
     230              :     /** @brief Returns the time of continous occupation by the same vehicle in seconds
     231              :      * or 0 if there is no vehicle on the detector
     232              :      */
     233              :     double getOccupancyTime() const;
     234              : 
     235              :     ///@brief return last time a vehicle was on the detector
     236              :     SUMOTime getLastDetectionTime() const;
     237              : 
     238              :     double getOverrideTime() const {
     239       184700 :         return myOverrideTime;
     240              :     }
     241              :     //@}
     242              : 
     243              : 
     244              :     /* @brief Persistently overrides the measured time since detection with the given value.
     245              :      * Setting a negative value resets the override
     246              :      */
     247              :     void overrideTimeSinceDetection(double time);
     248              : 
     249              :     /* @brief loads the time since detetion (from state)
     250              :      */
     251              :     void loadTimeSinceLastDetection(double time);
     252              : 
     253              :     /// @name Methods inherited from MSDetectorFileOutput.
     254              :     /// @{
     255              : 
     256              :     /** @brief Writes collected values into the given stream
     257              :      *
     258              :      * @param[in] dev The output device to write the data into
     259              :      * @param[in] startTime First time step the data were gathered
     260              :      * @param[in] stopTime Last time step the data were gathered
     261              :      * @see MSDetectorFileOutput::writeXMLOutput
     262              :      * @exception IOError If an error on writing occurs (!!! not yet implemented)
     263              :      */
     264              :     void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime);
     265              : 
     266              : 
     267              :     /** @brief Opens the XML-output using "detector" as root element
     268              :      *
     269              :      * @param[in] dev The output device to write the root into
     270              :      * @see MSDetectorFileOutput::writeXMLDetectorProlog
     271              :      * @exception IOError If an error on writing occurs (!!! not yet implemented)
     272              :      */
     273              :     void writeXMLDetectorProlog(OutputDevice& dev) const;
     274              : 
     275              :     /** @brief Updates the detector (computes values)
     276              :      * only used when detecting persons
     277              :      *
     278              :      * @param[in] step The current time step
     279              :      */
     280              :     void detectorUpdate(const SUMOTime step);
     281              :     /// @}
     282              : 
     283              : 
     284              :     /** @brief Struct to store the data of the counted vehicle internally.
     285              :      *
     286              :      * These data is fed into a container.
     287              :      *
     288              :      * @see myVehicleDataCont
     289              :      */
     290      1398630 :     struct VehicleData {
     291              :         /** @brief Constructor
     292              :          *
     293              :          * Used if the vehicle has left the induction loop completely
     294              :          *
     295              :          * @param[in] vehLength The length of the vehicle
     296              :          * @param[in] entryTimestep The time at which the vehicle entered the detector
     297              :          * @param[in] leaveTimestep The time at which the vehicle left the detector
     298              :          * @param[in] leftEarly Whether the vehicle left the detector with a lane change / teleport etc.
     299              :          * @param[in] detLength The length of the detector in meters
     300              :          */
     301              :         VehicleData(const SUMOTrafficObject& v, double entryTimestep,
     302              :                     double leaveTimestep, const bool leftEarly, const double detLength = 0);
     303              : 
     304              :         /// @brief The id of the vehicle
     305              :         std::string idM;
     306              :         /// @brief Length of the vehicle
     307              :         double lengthM;
     308              :         /// @brief Entry-time of the vehicle in [s]
     309              :         double entryTimeM;
     310              :         /// @brief Leave-time of the vehicle in [s]
     311              :         double leaveTimeM;
     312              :         /// @brief Speed of the vehicle in [m/s]
     313              :         double speedM;
     314              :         /// @brief Type of the vehicle
     315              :         std::string typeIDM;
     316              :         /// @brief whether the vehicle left the detector with a lane change / teleport etc.
     317              :         bool leftEarlyM;
     318              :     };
     319              : 
     320              : 
     321              :     /** @brief Returns vehicle data for vehicles that have been on the detector starting at the given time
     322              :      *
     323              :      * @param[in] t The time from which vehicles shall be counted
     324              :      * @param[in] leaveTime Whether entryTime or leaveTime shall be compared against t
     325              :      *            (the latter gives a more complete picture but may include vehicles in multiple steps even if they did not stay on the detector)
     326              :      * @return The list of vehicles
     327              :      */
     328              :     std::vector<VehicleData> collectVehiclesOnDet(SUMOTime t, bool includeEarly = false, bool leaveTime = false, bool forOccupancy = false, bool lastInterval = false) const;
     329              : 
     330              :     /// @brief allows for special color in the gui version
     331       663399 :     virtual void setSpecialColor(const RGBColor* /*color*/) {};
     332              : 
     333           36 :     virtual void setVisible(bool /*show*/) {};
     334              : 
     335              :     /** @brief Remove all vehicles before quick-loading state */
     336              :     virtual void clearState(SUMOTime time);
     337              : 
     338              : protected:
     339              :     /// @name Function for summing up values
     340              :     ///@{
     341              : 
     342              :     /// @brief Adds up VehicleData::speedM
     343         2333 :     static inline double speedSum(double sumSoFar, const MSInductLoop::VehicleData& data) {
     344         2333 :         return sumSoFar + data.speedM;
     345              :     }
     346              : 
     347              :     /// @brief Adds up VehicleData::lengthM
     348           29 :     static inline double lengthSum(double sumSoFar, const MSInductLoop::VehicleData& data) {
     349           29 :         return sumSoFar + data.lengthM;
     350              :     }
     351              :     ///@}
     352              : 
     353              :     /// @brief helper function for mapping person movement
     354              :     void notifyMovePerson(MSTransportable* p, int dir, double pos);
     355              : 
     356              : protected:
     357              :     /// @brief detecto name
     358              :     std::string myName;
     359              : 
     360              :     /// @brief Detector's position on lane [m]
     361              :     const double myPosition;
     362              : 
     363              :     /// @brief Detector's end position (defaults to myPosition)
     364              :     const double myEndPosition;
     365              : 
     366              :     /// @brief whether internals need to be guarded against concurrent access (GUI or multi threading)
     367              :     const bool myNeedLock;
     368              : 
     369              :     /// @brief Leave-time of the last vehicle detected [s]
     370              :     double myLastLeaveTime;
     371              : 
     372              :     /// @brief overrides the time since last detection
     373              :     double myOverrideTime;
     374              : 
     375              :     /// @brief records the time at which overrideTimeSinceDetection was activated
     376              :     double myOverrideEntryTime;
     377              : 
     378              :     /// @brief The number of entered vehicles
     379              :     int myEnteredVehicleNumber;
     380              : 
     381              :     /// @brief Type of myVehicleDataCont.
     382              :     typedef std::deque< VehicleData > VehicleDataCont;
     383              : 
     384              :     /// @brief Data of vehicles that have completely passed the detector
     385              :     VehicleDataCont myVehicleDataCont;
     386              : 
     387              :     /// @brief Data of vehicles that have completely passed the detector in the last time interval
     388              :     VehicleDataCont myLastVehicleDataCont;
     389              : 
     390              :     /// @brief Data for vehicles that have entered the detector (vehicle -> enter time)
     391              :     std::map<SUMOTrafficObject*, double> myVehiclesOnDet;
     392              : 
     393              :     SUMOTime myLastIntervalEnd;
     394              :     SUMOTime myLastIntervalBegin;
     395              : 
     396              : private:
     397              :     /// @brief Invalidated copy constructor.
     398              :     MSInductLoop(const MSInductLoop&);
     399              : 
     400              :     /// @brief Invalidated assignment operator.
     401              :     MSInductLoop& operator=(const MSInductLoop&);
     402              : 
     403              : 
     404              : };
        

Generated by: LCOV version 2.0-1