LCOV - code coverage report
Current view: top level - src/microsim/trigger - MSCalibrator.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 72.7 % 22 16
Test Date: 2025-12-06 15:35:27 Functions: 40.0 % 5 2

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2005-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    MSCalibrator.h
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Tue, May 2005
      19              : ///
      20              : // Calibrates the flow on an edge by removing an inserting vehicles
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : 
      25              : #include <string>
      26              : #include <vector>
      27              : #include <utils/common/Command.h>
      28              : #include <microsim/MSRouteHandler.h>
      29              : #include <microsim/output/MSMeanData_Net.h>
      30              : #include <microsim/output/MSDetectorFileOutput.h>
      31              : 
      32              : 
      33              : // ===========================================================================
      34              : // class declarations
      35              : // ===========================================================================
      36              : class OutputDevice;
      37              : class MSRouteProbe;
      38              : 
      39              : 
      40              : // ===========================================================================
      41              : // class definitions
      42              : // ===========================================================================
      43              : /**
      44              :  * @class MSCalibrator
      45              :  * @brief Calibrates the flow on a segment to a specified one
      46              :  */
      47              : class MSCalibrator : public MSRouteHandler, public Command, public MSDetectorFileOutput {
      48              : public:
      49              :     /** constructor */
      50              :     MSCalibrator(const std::string& id,
      51              :                  MSEdge* const edge,
      52              :                  MSLane* const lane,
      53              :                  MSJunction* const node,
      54              :                  const double pos,
      55              :                  const std::string& aXMLFilename,
      56              :                  const std::string& outputFilename,
      57              :                  const SUMOTime freq, const double length,
      58              :                  const MSRouteProbe* probe,
      59              :                  const double invalidJamThreshold,
      60              :                  const std::string& vTypes,
      61              :                  const bool local,
      62              :                  const bool addLaneMeanData);
      63              : 
      64              :     /** destructor */
      65              :     virtual ~MSCalibrator();
      66              : 
      67              :     /** @brief Write the generated output to the given device
      68              :      * @param[in] dev The output device to write the data into
      69              :      * @param[in] startTime First time step the data were gathered
      70              :      * @param[in] stopTime Last time step the data were gathered
      71              :      * @exception IOError If an error on writing occurs
      72              :      */
      73              :     void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime);
      74              : 
      75              : 
      76              :     /** @brief Open the XML-output
      77              :      *
      78              :      * The implementing function should open an xml element using
      79              :      *  OutputDevice::writeXMLHeader.
      80              :      *
      81              :      * @param[in] dev The output device to write the root into
      82              :      * @exception IOError If an error on writing occurs
      83              :      */
      84              :     void writeXMLDetectorProlog(OutputDevice& dev) const;
      85              : 
      86              :     /** the implementation of the MSTrigger / Command interface.
      87              :         Calibrating takes place here. */
      88              :     virtual SUMOTime execute(SUMOTime currentTime);
      89              : 
      90              :     /// @brief cleanup remaining data structures
      91              :     static void cleanup();
      92              : 
      93              :     /// @brief return all calibrator instances
      94              :     static const std::map<std::string, MSCalibrator*>& getInstances() {
      95              :         return myInstances;
      96              :     }
      97              : 
      98              :     struct AspiredState {
      99          701 :         AspiredState() : begin(-1), end(-1), q(-1.), v(-1.), vehicleParameter(0) {}
     100              :         SUMOTime begin;
     101              :         SUMOTime end;
     102              :         double q;
     103              :         double v;
     104              :         SUMOVehicleParameter* vehicleParameter;
     105              :     };
     106              : 
     107              :     AspiredState getCurrentStateInterval() const;
     108              : 
     109              :     const MSEdge* getEdge() const {
     110          104 :         return myEdge;
     111              :     }
     112              : 
     113              :     const MSLane* getLane() const {
     114         1179 :         return myLane;
     115              :     }
     116              : 
     117              :     const MSRouteProbe* getRouteProbe() const {
     118           18 :         return myProbe;
     119              :     }
     120              : 
     121       586873 :     inline virtual int passed() const {
     122              :         // calibrator measures at start of segment
     123              :         // vehicles drive to the end of an edge by default so they count as passed
     124              :         // but vaporized vehicles do not count
     125              :         // if the calibrator is located on a short edge, the vehicles are
     126              :         // vaporized on the next edge so we cannot rely on myEdgeMeanData.nVehVaporized
     127       586873 :         return myEdgeMeanData.nVehEntered + myEdgeMeanData.nVehDeparted - myClearedInJam - myRemoved;
     128              :     }
     129              : 
     130              :     int getInserted() const {
     131           18 :         return myEdgeMeanData.nVehDeparted;
     132              :     }
     133              : 
     134              :     int getRemoved() const {
     135           18 :         return myClearedInJam + myRemoved;
     136              :     }
     137              : 
     138              :     void setFlow(SUMOTime begin, SUMOTime end, double vehsPerHour, double speed, SUMOVehicleParameter vehicleParameter);
     139              : 
     140              : protected:
     141              :     class CalibratorCommand : public Command {
     142              :     public:
     143          381 :         CalibratorCommand(MSCalibrator* cali) :
     144          381 :             myCalibrator(cali) {}
     145              : 
     146       629510 :         SUMOTime execute(SUMOTime currentTime) {
     147       629510 :             return myCalibrator->execute(currentTime);
     148              :         }
     149              : 
     150              :         /** @brief Reschedule or deschedule the command when quick-loading state
     151              :          *
     152              :          * The implementations should return -1 if the command shall not be re-scheduled,
     153              :          *  or a value >= 0 that describe the new time at which the command
     154              :          *  shall be executed again.
     155              :          *
     156              :          * @param[in] currentTime The current simulation time
     157              :          * @param[in] execTime The time at which the command would have been executed
     158              :          * @param[in] newTime The simulation time at which the simulation is restarted
     159              :          * @return The time at which the command shall be executed again
     160              :          */
     161              :         SUMOTime shiftTime(SUMOTime currentTime, SUMOTime execTime, SUMOTime newTime);
     162              : 
     163              :     private:
     164              :         MSCalibrator* myCalibrator;
     165              :     };
     166              : 
     167              : 
     168              :     /// @name inherited from GenericSAXHandler
     169              :     //@{
     170              : 
     171              :     /** @brief Called on the opening of a tag;
     172              :      *
     173              :      * @param[in] element ID of the currently opened element
     174              :      * @param[in] attrs Attributes within the currently opened element
     175              :      * @exception ProcessError If something fails
     176              :      * @see GenericSAXHandler::myStartElement
     177              :      */
     178              :     virtual void myStartElement(int element,
     179              :                                 const SUMOSAXAttributes& attrs);
     180              : 
     181              :     /** @brief Called on the closing of a tag;
     182              :      *
     183              :      * @param[in] element ID of the currently closed element
     184              :      * @exception ProcessError If something fails
     185              :      * @see GenericSAXHandler::myEndElement
     186              :      */
     187              :     virtual void myEndElement(int element);
     188              :     //@}
     189              : 
     190              : 
     191              : 
     192              :     class VehicleRemover : public MSMoveReminder {
     193              :     public:
     194         1212 :         VehicleRemover(MSLane* const lane, MSCalibrator* const parent, const bool undo = false) :
     195         1212 :             MSMoveReminder(parent->getID(), lane, true), myParent(parent), myUndoCalibration(undo) {}
     196              : 
     197              :         /// @name inherited from MSMoveReminder
     198              :         //@{
     199              :         /** @brief Checks whether the reminder is activated by a vehicle entering the lane
     200              :          *
     201              :          * Lane change means in this case that the vehicle changes to the lane
     202              :          *  the reminder is placed at.
     203              :          *
     204              :          * @param[in] veh The entering vehicle.
     205              :          * @param[in] reason how the vehicle enters the lane
     206              :          * @return True if vehicle enters the reminder.
     207              :          * @see Notification
     208              :          */
     209              :         //@}
     210              :         virtual bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = nullptr);
     211              : 
     212              :         /** @brief Checks whether any calibrations need to be undone
     213              :          *
     214              :          * @param[in] veh The leaving vehicle.
     215              :          * @param[in] lastPos Position on the lane when leaving.
     216              :          * @param[in] reason how the vehicle leaves the lane
     217              :          * @see Notification
     218              :          *
     219              :          * @return True if the reminder wants to receive further info.
     220              :          */
     221              :         virtual bool notifyLeave(SUMOTrafficObject& veh, double lastPos, Notification reason, const MSLane* enteredLane = nullptr);
     222              : 
     223              :         void disable() {
     224         1212 :             myParent = nullptr;
     225              :         }
     226              : 
     227              :     private:
     228              :         MSCalibrator* myParent;
     229              :         const bool myUndoCalibration;
     230              :     };
     231              :     friend class GUICalibrator;
     232              : 
     233              :     // @return whether the current state is active (GUI)
     234              :     bool isActive() const {
     235       213566 :         return myAmActive;
     236              :     }
     237              : 
     238              : protected:
     239              : 
     240              :     void intervalEnd();
     241              : 
     242              :     bool isCurrentStateActive(SUMOTime time);
     243              : 
     244              :     bool tryEmit(MSLane* lane, MSVehicle* vehicle);
     245              : 
     246              :     void init();
     247              : 
     248              :     /// @brief number of vehicles expected to pass this interval
     249              :     int totalWished() const;
     250              : 
     251              :     /// @brief flow in the current interval in veh/h
     252              :     double currentFlow() const;
     253              : 
     254              :     /// @brief measured speed in the current interval
     255              :     double currentSpeed() const;
     256              : 
     257              :     /* @brief returns whether the lane is jammed although it should not be
     258              :      * @param[in] lane The lane to check or all for negative values
     259              :      */
     260              :     bool invalidJam(int laneIndex) const;
     261              : 
     262            0 :     inline int inserted() const {
     263            0 :         return myInserted;
     264              :     }
     265            0 :     inline int removed() const {
     266            0 :         return myRemoved;
     267              :     }
     268            0 :     inline int clearedInJam() const {
     269            0 :         return myClearedInJam;
     270              :     }
     271              : 
     272              :     /* @brief returns the number of vehicles (of the current type) that still
     273              :      * fit on the given lane
     274              :      * @param[in] lane The lane to check (return the maximum of all lanes for negative values)
     275              :      */
     276              :     int remainingVehicleCapacity(int laneIndex) const;
     277              : 
     278              :     /// @brief reset collected vehicle data
     279              :     virtual void reset();
     280              : 
     281              :     /// @brief aggregate lane values
     282              :     virtual void updateMeanData();
     283              : 
     284              :     /** @brief try to schedule the given vehicle for removal. return true if it
     285              :      * isn't already scheduled */
     286              :     bool scheduleRemoval(SUMOTrafficObject* veh) {
     287              :         return myToRemove.insert(veh->getID()).second;
     288              :     }
     289              : 
     290              : 
     291              :     /** @brief remove any vehicles which are scheduled for removal.
     292              :      * return true if removals took place */
     293              :     bool removePending();
     294              : 
     295              :     /// @brief determine id of new vehicle from calibrator state
     296              :     std::string getNewVehicleID();
     297              : 
     298              : protected:
     299              :     /// @brief the edge on which this calibrator lies
     300              :     MSEdge* const myEdge;
     301              :     /// @brief the lane on which this calibrator lies (nullptr if the whole edge is covered at once)
     302              :     MSLane* const myLane;
     303              :     /// @brief the junction on which this calibrator lies (nullptr if is edge or lane specific)
     304              :     MSJunction* const myNode;
     305              :     /// @brief the position on the edge where this calibrator lies
     306              :     const double myPos;
     307              :     /// @brief the route probe to retrieve routes from
     308              :     const MSRouteProbe* const myProbe;
     309              :     /// @brief dummy parent to retrieve vType filter
     310              :     MSMeanData_Net myMeanDataParent;
     311              :     /// @brief data collector for the calibrator
     312              :     std::vector<MSMeanData_Net::MSLaneMeanDataValues*> myLaneMeanData;
     313              :     /// @brief accumlated data for the whole edge
     314              :     MSMeanData_Net::MSLaneMeanDataValues myEdgeMeanData;
     315              : 
     316              :     /// @brief List of adaptation intervals
     317              :     std::vector<AspiredState> myIntervals;
     318              :     /// @brief Iterator pointing to the current interval
     319              :     std::vector<AspiredState>::const_iterator myCurrentStateInterval;
     320              : 
     321              :     std::vector<VehicleRemover*> myVehicleRemovers;
     322              : 
     323              :     /** @brief set of vehicle ids to remove
     324              :      * @note: we avoid keeping vehicle points because someone else might
     325              :      * invalidate it before look at it again (i.e. another calibrator)
     326              :      */
     327              :     std::set<std::string> myToRemove;
     328              : 
     329              :     /// @brief The device for xml statistics
     330              :     OutputDevice* myOutput;
     331              : 
     332              :     /// @brief The frequeny with which to check for calibration
     333              :     SUMOTime myFrequency;
     334              :     /// @brief The number of vehicles that were removed in the current interval
     335              :     int myRemoved;
     336              :     /// @brief The number of vehicles that were inserted in the current interval
     337              :     int myInserted;
     338              :     /// @brief The number of vehicles that were removed when clearin a jam
     339              :     int myClearedInJam;
     340              :     /// @brief The information whether the speed adaption has been reset
     341              :     bool mySpeedIsDefault;
     342              :     /// @brief The information whether speed was adapted in the current interval
     343              :     bool myDidSpeedAdaption;
     344              :     /// @brief The information whether init was called
     345              :     bool myDidInit;
     346              :     /// @brief The default (maximum) speed on the segment
     347              :     double myDefaultSpeed;
     348              :     /// @brief The default (maximum) speed on the segment
     349              :     bool myHaveWarnedAboutClearingJam;
     350              : 
     351              :     /// @brief whether the calibrator was active when last checking
     352              :     bool myAmActive;
     353              : 
     354              :     /// @brief relative speed threshold for detecting and clearing invalid jam
     355              :     double myInvalidJamThreshold;
     356              : 
     357              :     /// @brief whether the calibrator needs to undo the calibration after the edge / junction has been left
     358              :     bool myAmLocal;
     359              : 
     360              :     /// @brief whether the calibrator has registered an invalid jam in the last execution step
     361              :     bool myHaveInvalidJam;
     362              : 
     363              :     /* @brief objects which need to live longer than the MSCalibrator
     364              :      * instance which created them */
     365              :     static std::vector<MSMoveReminder*> myLeftoverReminders;
     366              :     static std::vector<SUMOVehicleParameter*> myLeftoverVehicleParameters;
     367              :     static std::map<std::string, MSCalibrator*> myInstances;
     368              : 
     369              : };
        

Generated by: LCOV version 2.0-1