LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSActuatedTrafficLightLogic.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 19 20 95.0 %
Date: 2024-05-19 15:37:39 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2002-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    MSActuatedTrafficLightLogic.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Michael Behrisch
      17             : /// @author  Jakob Erdmann
      18             : /// @date    Sept 2002
      19             : ///
      20             : // An actuated (adaptive) traffic light logic
      21             : /****************************************************************************/
      22             : #pragma once
      23             : #include <config.h>
      24             : 
      25             : #include <utility>
      26             : #include <vector>
      27             : #include <bitset>
      28             : #include <map>
      29             : #include <microsim/MSEventControl.h>
      30             : #include <microsim/traffic_lights/MSTrafficLightLogic.h>
      31             : #include <microsim/output/MSDetectorControl.h>
      32             : #include <microsim/output/MSInductLoop.h>
      33             : #include "MSSimpleTrafficLightLogic.h"
      34             : 
      35             : 
      36             : // ===========================================================================
      37             : // class declarations
      38             : // ===========================================================================
      39             : class NLDetectorBuilder;
      40             : 
      41             : // ===========================================================================
      42             : // class definitions
      43             : // ===========================================================================
      44             : /**
      45             :  * @class MSActuatedTrafficLightLogic
      46             :  * @brief An actuated (adaptive) traffic light logic
      47             :  */
      48             : class MSActuatedTrafficLightLogic : public MSSimpleTrafficLightLogic {
      49             : public:
      50             : 
      51             :     typedef Parameterised::Map ConditionMap;
      52             :     typedef std::vector<std::tuple<std::string, std::string, std::string> > AssignmentMap;
      53             : 
      54           4 :     struct Function {
      55       35510 :         Function(const std::string& _id = "", int _nArgs = -1):
      56       35510 :             id(_id), nArgs(_nArgs) {}
      57             :         std::string id;
      58             :         int nArgs;
      59             :         AssignmentMap assignments;
      60             :     };
      61             : 
      62             :     typedef std::map<std::string, Function> FunctionMap;
      63             : 
      64             : 
      65             :     /** @brief Constructor
      66             :      * @param[in] tlcontrol The tls control responsible for this tls
      67             :      * @param[in] id This tls' id
      68             :      * @param[in] programID This tls' sub-id (program id)
      69             :      * @param[in] phases Definitions of the phases
      70             :      * @param[in] step The initial phase index
      71             :      * @param[in] delay The time to wait before the first switch
      72             :      * @param[in] parameter The parameter to use for tls set-up
      73             :      */
      74             :     MSActuatedTrafficLightLogic(MSTLLogicControl& tlcontrol,
      75             :                                 const std::string& id, const std::string& programID,
      76             :                                 const SUMOTime offset,
      77             :                                 const MSSimpleTrafficLightLogic::Phases& phases,
      78             :                                 int step, SUMOTime delay,
      79             :                                 const Parameterised::Map& parameter,
      80             :                                 const std::string& basePath,
      81             :                                 const ConditionMap& conditions = ConditionMap(),
      82             :                                 const AssignmentMap& assignments = AssignmentMap(),
      83             :                                 const FunctionMap& functions = FunctionMap());
      84             : 
      85             : 
      86             :     /** @brief Initialises the tls with information about incoming lanes
      87             :      * @param[in] nb The detector builder
      88             :      * @exception ProcessError If something fails on initialisation
      89             :      */
      90             :     void init(NLDetectorBuilder& nb) override;
      91             : 
      92             : 
      93             :     /// @brief Destructor
      94             :     ~MSActuatedTrafficLightLogic();
      95             : 
      96             : 
      97             : 
      98             :     /// @name Switching and setting current rows
      99             :     /// @{
     100             : 
     101             :     /** @brief Switches to the next phase
     102             :      * @return The time of the next switch
     103             :      * @see MSTrafficLightLogic::trySwitch
     104             :      */
     105             :     SUMOTime trySwitch() override;
     106             :     /// @}
     107             : 
     108             :     SUMOTime getMinDur(int step = -1) const override;
     109             :     SUMOTime getMaxDur(int step = -1) const override;
     110             :     SUMOTime getEarliestEnd(int step = -1) const override;
     111             :     SUMOTime getLatestEnd(int step = -1) const override;
     112             : 
     113             :     /// @name Changing phases and phase durations
     114             :     /// @{
     115             : 
     116             :     /** @brief Changes the current phase and her duration
     117             :      * @param[in] tlcontrol The responsible traffic lights control
     118             :      * @param[in] simStep The current simulation step
     119             :      * @param[in] step Index of the phase to use
     120             :      * @param[in] stepDuration The left duration of the phase
     121             :      * @see MSTrafficLightLogic::changeStepAndDuration
     122             :      */
     123             :     void changeStepAndDuration(MSTLLogicControl& tlcontrol, SUMOTime simStep,
     124             :                                int step, SUMOTime stepDuration) override;
     125             : 
     126             :     /// @brief called when switching programs
     127             :     void activateProgram() override;
     128             :     void deactivateProgram() override;
     129             : 
     130             :     bool showDetectors() const {
     131           0 :         return myShowDetectors;
     132             :     }
     133             : 
     134             :     void setShowDetectors(bool show);
     135             : 
     136             :     /// @brief try to get the value of the given parameter (including prefixed parameters)
     137             :     const std::string getParameter(const std::string& key, const std::string defaultValue = "") const override;
     138             : 
     139             :     /**@brief Sets a parameter and updates internal constants */
     140             :     void setParameter(const std::string& key, const std::string& value) override;
     141             : 
     142             :     /// @brief retrieve all detectors used by this program
     143             :     std::map<std::string, double> getDetectorStates() const override;
     144             : 
     145             :     /// @brief return all named conditions defined for this traffic light
     146             :     std::map<std::string, double> getConditions() const override;
     147             : 
     148             :     void loadState(MSTLLogicControl& tlcontrol, SUMOTime t, int step, SUMOTime spentDuration) override;
     149             : 
     150             : protected:
     151             :     /// @brief initialize custom switching rules
     152             :     void initAttributeOverride();
     153             :     void initSwitchingRules();
     154             : 
     155       76687 :     struct InductLoopInfo {
     156        3902 :         InductLoopInfo(MSInductLoop* _loop, const MSLane* _lane, int numPhases, double _maxGap, double _jamThreshold):
     157        3902 :             loop(_loop),
     158        3902 :             lane(_lane),
     159        7804 :             servedPhase(numPhases, false),
     160        3902 :             maxGap(_maxGap),
     161        3902 :             jamThreshold(_jamThreshold)
     162             :         {}
     163             : 
     164             : 
     165             :         bool isJammed() const {
     166      527481 :             return jamThreshold > 0 && loop->getOccupancyTime() >= jamThreshold;
     167             :         }
     168             : 
     169             :         MSInductLoop* loop;
     170             :         const MSLane* lane;
     171             :         SUMOTime lastGreenTime = 0;
     172             :         std::vector<bool> servedPhase;
     173             :         double maxGap;
     174             :         double jamThreshold;
     175             : 
     176             :     };
     177             : 
     178             :     /// @brief Definition of a map from phases to induct loops controlling them
     179             :     typedef std::vector<std::vector<InductLoopInfo*> > InductLoopMap;
     180             : 
     181             :     /// @name "actuated" algorithm methods
     182             :     /// @{
     183             : 
     184             :     /** @brief Returns the minimum duration of the current phase
     185             :      * @param[in] detectionGap The minimum detection gap for the current phase
     186             :      * @return The minimum duration of the current phase
     187             :      */
     188             :     SUMOTime duration(const double detectionGap) const;
     189             : 
     190             :     /// @brief get the minimum min duration for all stretchable phases that affect the given lane
     191             :     SUMOTime getMinimumMinDuration(MSLane* lane) const;
     192             : 
     193             :     /** @brief Return the minimum detection gap of all detectors if the current phase should be extended and double::max otherwise
     194             :      */
     195             :     double gapControl();
     196             : 
     197             : 
     198             :     /// @brief return whether there is a major link from the given lane in the given phase
     199             :     bool hasMajor(const std::string& state, const LaneVector& lanes) const;
     200             :     /// @}
     201             : 
     202             :     /// @brief select among candidate phases based on detector states
     203             :     int decideNextPhase();
     204             : 
     205             :     /// @brief select among candidate phases based on detector states and custom switching rules
     206             :     int decideNextPhaseCustom(bool mustSwitch);
     207             : 
     208             :     /// @brief evaluate custom switching condition
     209             :     double evalExpression(const std::string& condition) const;
     210             : 
     211             :     /// @brief evaluate atomic expression
     212             :     double evalTernaryExpression(double a, const std::string& o, double b, const std::string& condition) const;
     213             : 
     214             :     /// @brief evaluate atomic expression
     215             :     double evalAtomicExpression(const std::string& expr) const;
     216             : 
     217             :     /// @brief evaluate function expression
     218             :     double evalCustomFunction(const std::string& fun, const std::string& arg) const;
     219             : 
     220             :     /// @brief execute assignemnts of the logic or a custom function
     221             :     void executeAssignments(const AssignmentMap& assignments, ConditionMap& conditions, const ConditionMap& forbidden = ConditionMap()) const;
     222             : 
     223             :     int getDetectorPriority(const InductLoopInfo& loopInfo) const;
     224             : 
     225             :     /// @brief count the number of active detectors for the given step
     226             :     int getPhasePriority(int step) const;
     227             : 
     228             :     /// @brief get the green phase following step
     229             :     int getTarget(int step);
     230             : 
     231             :     /// @brief whether the current phase cannot be continued due to linkMaxDur constraints
     232             :     bool maxLinkDurationReached();
     233             : 
     234             :     /// @brief whether the target phase is acceptable in light of linkMaxDur constraints
     235             :     bool canExtendLinkGreen(int target);
     236             : 
     237             :     /// @brief the minimum duratin for keeping the current phase due to linkMinDur constraints
     238             :     SUMOTime getLinkMinDuration(int target) const;
     239             : 
     240             :     /// @brief whether a given link has only weak mode foes that are green in the given state
     241             :     bool weakConflict(int linkIndex, const std::string& state) const;
     242             : 
     243             :     template<typename T, SumoXMLTag Tag>
     244       49858 :     const T* retrieveDetExpression(const std::string& arg, const std::string& expr, bool tryPrefix) const {
     245       32775 :         const T* det = dynamic_cast<const T*>(
     246      149574 :                            MSNet::getInstance()->getDetectorControl().getTypedDetectors(Tag).get(
     247       49858 :                                (tryPrefix ? myDetectorPrefix : "") + arg));
     248       49858 :         if (det == nullptr) {
     249       17083 :             if (tryPrefix) {
     250             :                 // try again without prefix
     251       12928 :                 return retrieveDetExpression<T, Tag>(arg, expr, false);
     252             :             } else {
     253        8310 :                 throw ProcessError("Unknown detector '" + arg + "' in expression '" + expr + "'");
     254             :             }
     255             :         } else {
     256             :             return det;
     257             :         }
     258             :     }
     259             : 
     260             : protected:
     261             :     /// @brief A map from phase to induction loops to be used for gap control
     262             :     InductLoopMap myInductLoopsForPhase;
     263             : 
     264             :     std::vector<InductLoopInfo> myInductLoops;
     265             : 
     266             :     /// @brief extra loops for output/tracking
     267             :     std::vector<const MSInductLoop*> myExtraLoops;
     268             :     std::vector<const MSE2Collector*> myExtraE2;
     269             : 
     270             :     /// The maximum gap to check in seconds
     271             :     double myMaxGap;
     272             : 
     273             :     /// The minimum continuous occupancy time to mark a detector as jammed
     274             :     double myJamThreshold;
     275             : 
     276             :     /// The passing time used in seconds
     277             :     double myPassingTime;
     278             : 
     279             :     /// The detector distance in seconds
     280             :     double myDetectorGap;
     281             : 
     282             :     /// The time threshold to avoid starved phases
     283             :     SUMOTime myInactiveThreshold;
     284             : 
     285             :     /// Whether the detectors shall be shown in the GUI
     286             :     bool myShowDetectors;
     287             : 
     288             :     /// Whether any of the phases has multiple targets
     289             :     bool myHasMultiTarget;
     290             : 
     291             :     /// The output file for generated detectors
     292             :     std::string myFile;
     293             : 
     294             :     /// The frequency for aggregating detector output
     295             :     SUMOTime myFreq;
     296             : 
     297             :     /// Whether detector output separates by vType
     298             :     std::string myVehicleTypes;
     299             : 
     300             :     /// @brief last time trySwitch was called
     301             :     SUMOTime myLastTrySwitchTime;
     302             : 
     303             :     /// @brief consecutive time that the given link index has been green
     304             :     std::vector<SUMOTime> myLinkGreenTimes;
     305             :     std::vector<SUMOTime> myLinkRedTimes;
     306             :     /// @brief maximum consecutive time that the given link may remain green
     307             :     std::vector<SUMOTime> myLinkMaxGreenTimes;
     308             :     /// @brief minimum consecutive time that the given link must remain green
     309             :     std::vector<SUMOTime> myLinkMinGreenTimes;
     310             : 
     311             :     /// @brief The custom switching conditions
     312             :     ConditionMap myConditions;
     313             : 
     314             :     /// @brief The condition assignments
     315             :     AssignmentMap myAssignments;
     316             : 
     317             :     /// @brief The loaded functions
     318             :     FunctionMap myFunctions;
     319             : 
     320             :     /// @brief The function call stack;
     321             :     mutable std::vector<std::map<std::string, double> > myStack;
     322             : 
     323             :     /// @brief the conditions which shall be listed in GUITLLogicPhasesTrackerWindow
     324             :     std::set<std::string> myListedConditions;
     325             : 
     326             :     /// @brief whether the next switch time was requested via TraCI
     327             :     bool myTraCISwitch;
     328             : 
     329             :     struct SwitchingRules {
     330             :         bool enabled = false;
     331             :     };
     332             : 
     333             :     std::vector<SwitchingRules> mySwitchingRules;
     334             : 
     335             :     const std::string myDetectorPrefix;
     336             : 
     337             :     static const std::vector<std::string> OPERATOR_PRECEDENCE;
     338             : };

Generated by: LCOV version 1.14