LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSRailSignal.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 12 14 85.7 %
Date: 2024-05-19 15:37:39 Functions: 2 3 66.7 %

          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    MSRailSignal.h
      15             : /// @author  Melanie Weber
      16             : /// @author  Andreas Kendziorra
      17             : /// @author  Jakob Erdmann
      18             : /// @date    Jan 2015
      19             : ///
      20             : // A rail signal logic
      21             : /****************************************************************************/
      22             : #pragma once
      23             : #include <config.h>
      24             : 
      25             : #include <vector>
      26             : #include <microsim/MSRoute.h>
      27             : #include <microsim/traffic_lights/MSTrafficLightLogic.h>
      28             : #include <microsim/traffic_lights/MSTLLogicControl.h>
      29             : 
      30             : 
      31             : // ===========================================================================
      32             : // class declarations
      33             : // ===========================================================================
      34             : class MSLink;
      35             : class MSPhaseDefinition;
      36             : class MSRailSignalConstraint;
      37             : 
      38             : 
      39             : // ===========================================================================
      40             : // class definitions
      41             : // ===========================================================================
      42             : /**
      43             :  * @class MSRailSignal
      44             :  * @brief A signal for rails
      45             :  */
      46             : class MSRailSignal : public MSTrafficLightLogic {
      47             : public:
      48             :     /** @brief Constructor
      49             :      * @param[in] tlcontrol The tls control responsible for this tls
      50             :      * @param[in] id This tls' id
      51             :      * @param[in] programID This tls' sub-id (program id)
      52             :      * @param[in] parameters This tls' parameters
      53             :      * @param[in] delay The time to wait before the first switch
      54             :      */
      55             :     MSRailSignal(MSTLLogicControl& tlcontrol,
      56             :                  const std::string& id, const std::string& programID, SUMOTime delay,
      57             :                  const Parameterised::Map& parameters);
      58             : 
      59             : 
      60             :     /** @brief Initialises the rail signal with information about adjacent rail signals
      61             :      * @param[in] nb The detector builder
      62             :      * @exception ProcessError If something fails on initialisation
      63             :      */
      64             :     void init(NLDetectorBuilder& nb) override;
      65             : 
      66             : 
      67             :     /// @brief Destructor
      68             :     ~MSRailSignal();
      69             : 
      70             :     /**@brief Sets a parameter and updates internal constants */
      71             :     void setParameter(const std::string& key, const std::string& value) override;
      72             : 
      73             :     /** @brief Adds a link on building
      74             :      * @param[in] link The controlled link
      75             :      * @param[in] lane The lane this link starts at
      76             :      * @param[in] pos The link's index (signal group) within this program
      77             :      */
      78             :     void addLink(MSLink* link, MSLane* lane, int pos) override;
      79             : 
      80             :     /// @name Handling of controlled links
      81             :     /// @{
      82             : 
      83             :     /** @brief Applies information about controlled links and lanes from the given logic
      84             :      * @param[in] logic The logic to use the information about controlled links/lanes from
      85             :      * @see MSTrafficLightLogic::adaptLinkInformationFrom
      86             :      */
      87             :     void adaptLinkInformationFrom(const MSTrafficLightLogic& logic) override;
      88             :     /// @}
      89             : 
      90             : 
      91             :     /// @name Switching and setting current rows
      92             :     /// @{
      93             : 
      94             : 
      95             :     /** @brief returns the state of the signal that actually required
      96             :      *
      97             :      * Returns the state of the rail signal that is actually required based on the
      98             :      *  occupation of the adjoining blocks.
      99             :      *
     100             :      * @return The state actually required for this signal.
     101             :      */
     102             : 
     103             :     /// @brief updates the current phase of the signal
     104             :     void updateCurrentPhase();
     105             : 
     106             :     /** @brief Switches to the next phase
     107             :     * @return The time of the next switch (always the next step)
     108             :     * @see MSTrafficLightLogic::trySwitch
     109             :     */
     110             :     SUMOTime trySwitch() override;
     111             : 
     112             :     /// @}
     113             : 
     114             : 
     115             :     /// @name Static Information Retrieval
     116             :     /// @{
     117             : 
     118             :     /** @brief Returns the number of phases
     119             :      * @return The number of this tls program's phases (always zero)
     120             :      * @see MSTrafficLightLogic::getPhaseNumber
     121             :      */
     122             :     int getPhaseNumber() const override;
     123             : 
     124             :     /** @brief Returns the phases of this tls program
     125             :      * @return The phases of this tls program
     126             :      * @see MSTrafficLightLogic::getPhases
     127             :      */
     128             :     const Phases& getPhases() const override;
     129             : 
     130             :     /** @brief Returns the definition of the phase from the given position within the plan
     131             :     *
     132             :     * Returns the current phase as there does not exist a plan of the phases.
     133             :     *
     134             :     * @param[in] givenstep The index of the phase within the plan
     135             :     * @return The definition of the phase at the given position
     136             :     * @see MSTrafficLightLogic::getPhase
     137             :     */
     138             :     const MSPhaseDefinition& getPhase(int givenstep) const override;
     139             : 
     140             :     /// @brief whether the given link index ever turns 'G'
     141         684 :     bool getsMajorGreen(int /*linkIndex*/) const override {
     142         684 :         return true;
     143             :     }
     144             :     /// @}
     145             : 
     146             : 
     147             :     /// @name Dynamic Information Retrieval
     148             :     /// @{
     149             : 
     150             :     /** @brief Returns the current index within the program
     151             :      * @return The index of the current phase within the tls (here, always zero will be returned)
     152             :      * @see MSTrafficLightLogic::getCurrentPhaseIndex
     153             :      */
     154             :     int getCurrentPhaseIndex() const override;
     155             : 
     156             :     /** @brief Returns the definition of the current phase
     157             :     * @return The current phase
     158             :     */
     159             :     const MSPhaseDefinition& getCurrentPhaseDef() const override;
     160             :     /// @}
     161             : 
     162             : 
     163             :     /// @name Conversion between time and phase
     164             :     /// @{
     165             : 
     166             :     /** @brief Returns the index of the logic at the given simulation step
     167             :      * @return The (estimated) index of the tls at the given simulation time step (here, always zero will be returned)
     168             :      * @see MSTrafficLightLogic::getPhaseIndexAtTime
     169             :      */
     170             :     SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const override;
     171             : 
     172             :     /** @brief Returns the position (start of a phase during a cycle) from of a given step
     173             :      * @param[in] index The index of the phase to return the begin of
     174             :      * @return The begin time of the phase (here, always zero will be returned)
     175             :      * @see MSTrafficLightLogic::getOffsetFromIndex
     176             :      */
     177             :     SUMOTime getOffsetFromIndex(int index) const override;
     178             : 
     179             :     /** @brief Returns the step (the phasenumber) of a given position of the cycle
     180             :     * @param[in] offset The offset (time) for which the according phase shall be returned
     181             :     * @return The according phase (here, always zero will be returned)
     182             :     * @see MSTrafficLightLogic::getIndexFromOffset
     183             :     */
     184             :     int getIndexFromOffset(SUMOTime offset) const override;
     185             :     /// @}
     186             : 
     187             : 
     188             :     /// @name Changing phases and phase durations
     189             :     /// @{
     190             : 
     191             :     /** @brief Changes the current phase and her duration
     192             :      * @param[in] tlcontrol The responsible traffic lights control
     193             :      * @param[in] simStep The current simulation step
     194             :      * @param[in] step Index of the phase to use
     195             :      * @param[in] stepDuration The left duration of the phase
     196             :      * @see MSTrafficLightLogic::changeStepAndDuration
     197             :      */
     198           0 :     void changeStepAndDuration(MSTLLogicControl& tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration) override {
     199             :         UNUSED_PARAMETER(tlcontrol);
     200             :         UNUSED_PARAMETER(simStep);
     201             :         UNUSED_PARAMETER(step);
     202             :         UNUSED_PARAMETER(stepDuration);
     203           0 :     }
     204             :     /// @}
     205             : 
     206             :     /// @brief return vehicles that block the intersection/rail signal for vehicles that wish to pass the given linkIndex
     207             :     VehicleVector getBlockingVehicles(int linkIndex) override;
     208             :     std::string getBlockingVehicleIDs() const;
     209             : 
     210             :     /// @brief return vehicles that approach the intersection/rail signal and are in conflict with vehicles that wish to pass the given linkIndex
     211             :     VehicleVector getRivalVehicles(int linkIndex) override;
     212             :     std::string getRivalVehicleIDs() const;
     213             : 
     214             :     /// @brief return vehicles that approach the intersection/rail signal and have priority over vehicles that wish to pass the given linkIndex
     215             :     VehicleVector getPriorityVehicles(int linkIndex) override;
     216             :     std::string getPriorityVehicleIDs() const;
     217             : 
     218             :     /// @brief return information regarding active rail signal constraints for the closest approaching vehicle
     219             :     std::string getConstraintInfo(int linkIndex);
     220             :     std::string getConstraintInfo() const;
     221             : 
     222             :     /// @brief write rail signal block output for all links and driveways
     223             :     void writeBlocks(OutputDevice& od) const;
     224             : 
     225             :     /// @brief register constraint for signal switching
     226             :     void addConstraint(const std::string& tripId, MSRailSignalConstraint* constraint);
     227             : 
     228             :     /// @name TraCI access to constraints
     229             :     /// @{
     230             :     const std::map<std::string, std::vector<MSRailSignalConstraint*> >&  getConstraints() const {
     231             :         return myConstraints;
     232             :     }
     233             : 
     234             :     /// @brief remove constraint for signal switching
     235             :     bool removeConstraint(const std::string& tripId, MSRailSignalConstraint* constraint);
     236             :     void removeConstraints();
     237             :     /// @}
     238             : 
     239             :     /// update driveway for extended deadlock protection
     240             :     void updateDriveway(int numericalID);
     241             : 
     242             :     /* @brief return whether vehicle insertion must be delayed for an oncoming train
     243             :      * @param[in] link The rail signal link before which the vehicle is being inserted
     244             :      * @param[in] veh The vehicle being inserted
     245             :      * @param[in] brakeBeforeSignal Whether the vehicle may brake before the signal,
     246             :      *                              Returns true if the vehicle has to brake before the signal
     247             :      */
     248             :     static bool hasOncomingRailTraffic(MSLink* link, const MSVehicle* ego, bool& brakeBeforeSignal);
     249             : 
     250             :     static bool hasInsertionConstraint(MSLink* link, const MSVehicle* veh, std::string& info, bool& isInsertionOrder);
     251             : 
     252             :     static void initDriveWays(const SUMOVehicle* ego, bool update);
     253             : 
     254             :     typedef std::pair<const SUMOVehicle* const, const MSLink::ApproachingVehicleInformation> Approaching;
     255             :     typedef std::set<const MSLane*, ComparatorNumericalIdLess> LaneSet;
     256             :     typedef std::map<const MSLane*, int, ComparatorNumericalIdLess> LaneVisitedMap;
     257             : 
     258             :     /*  The driveways (Fahrstrassen) for each link index
     259             :      *  Each link index has at least one driveway
     260             :      *  A driveway describes one possible route that passes the signal up
     261             :      *  the next secure point
     262             :      *  When a signal guards a switch (indirect guard) that signal stores two
     263             :      *  or more driveways
     264             :      */
     265             :     struct DriveWay {
     266             : 
     267             :         /// @brief Constructor
     268        6569 :         DriveWay(bool temporary = false) :
     269        6569 :             myNumericalID(temporary ? -1 : myDriveWayIndex++),
     270        6569 :             myMaxFlankLength(0),
     271        6569 :             myActive(nullptr),
     272        6569 :             myProtectedBidi(nullptr),
     273        6569 :             myCoreSize(0),
     274        6569 :             myFoundSignal(false),
     275        6569 :             myFoundReversal(false)
     276        6569 :         {}
     277             : 
     278             :         /// @brief global driveway index
     279             :         int myNumericalID;
     280             : 
     281             :         /// @brief the maximum flank length searched while building this driveway
     282             :         double myMaxFlankLength;
     283             : 
     284             :         /// @brief whether the current signal is switched green for a train approaching this block
     285             :         const SUMOVehicle* myActive;
     286             : 
     287             :         /// @brief switch assumed safe from bidi-traffic
     288             :         const MSEdge* myProtectedBidi;
     289             : 
     290             :         /// @brief list of edges for matching against train routes
     291             :         std::vector<const MSEdge*> myRoute;
     292             : 
     293             :         /// @brief number of edges in myRoute where overlap with other driveways is forbidden
     294             :         int myCoreSize;
     295             : 
     296             :         /// @brief whether this driveway ends its forward section with a rail signal (and thus comprises a full block)
     297             :         bool myFoundSignal;
     298             :         bool myFoundReversal;
     299             : 
     300             :         /* @brief the actual driveway part up to the next railsignal (halting position)
     301             :          * This must be free of other trains */
     302             :         std::vector<const MSLane*> myForward;
     303             : 
     304             :         /* @brief the list of bidirectional edges that can enter the forward
     305             :          * section and which must also be free of traffic
     306             :          * (up to the first element that could give protection) */
     307             :         std::vector<const MSLane*> myBidi;
     308             : 
     309             :         /* @brief the list of bidirectional edges that can enter the forward
     310             :          * section and which might contain deadlock-relevant traffic */
     311             :         std::vector<const MSLane*> myBidiExtended;
     312             : 
     313             :         /* @brief the list of edges that merge with the forward section
     314             :          * (found via backward search, up to the first element that could give protection) */
     315             :         std::vector<const MSLane*> myFlank;
     316             : 
     317             :         /// @brief the lanes that must be clear of trains before this signal can switch to green
     318             :         std::vector<const MSLane*> myConflictLanes;
     319             : 
     320             :         /* @brief the list of switches that threaten the driveway and for which protection must be found
     321             :          */
     322             :         std::vector<MSLink*> myFlankSwitches;
     323             : 
     324             :         /* @brief the list of (first) switches that could give protection from oncoming/flanking vehicles
     325             :          * if any of them fails to do so, upstream search must be performed
     326             :          * until protection or conflict is found
     327             :          */
     328             :         std::vector<MSLink*> myProtectingSwitches;
     329             :         /// @brief subset of myProtectingSwitches that protects from oncoming trains
     330             :         std::vector<MSLink*> myProtectingSwitchesBidi;
     331             : 
     332             :         /* The conflict links for this block
     333             :          * Conflict resolution must be performed if vehicles are approaching the
     334             :          * current link and any of the conflict links */
     335             :         std::vector<MSLink*> myConflictLinks;
     336             : 
     337             :         /// @brief whether any of myConflictLanes is occupied (vehicles that are the target of a join must be ignored)
     338             :         bool conflictLaneOccupied(const std::string& joinVehicle = "", bool store = true, const SUMOVehicle* ego = nullptr) const;
     339             : 
     340             :         /// @brief whether any of myBidiExtended is occupied by a vehicle that targets myBidi
     341             :         bool deadlockLaneOccupied(bool store = true) const;
     342             : 
     343             :         /// @brief attempt reserve this driveway for the given vehicle
     344             :         bool reserve(const Approaching& closest, MSEdgeVector& occupied);
     345             : 
     346             :         /// @brief Whether the approaching vehicle is prevent from driving by another vehicle approaching the given link
     347             :         bool hasLinkConflict(const Approaching& closest, MSLink* foeLink) const;
     348             : 
     349             :         /// @brief Whether veh must yield to the foe train
     350             :         static bool mustYield(const Approaching& veh, const Approaching& foe);
     351             : 
     352             :         /// @brief Whether any of the conflict links have approaching vehicles
     353             :         bool conflictLinkApproached() const;
     354             : 
     355             :         /// @brief find protection for the given vehicle  starting at a switch
     356             :         bool findProtection(const Approaching& veh, MSLink* link) const;
     357             : 
     358             :         /// @brief Wether this driveway (route) overlaps with the given one
     359             :         bool overlap(const DriveWay& other) const;
     360             : 
     361             :         /// @brief Wether there is a flank conflict with the given driveway
     362             :         bool flankConflict(const DriveWay& other) const;
     363             : 
     364             :         /// @brief Write block items for this driveway
     365             :         void writeBlocks(OutputDevice& od) const;
     366             : 
     367             :         /* @brief determine route that identifies this driveway (a subset of the
     368             :          * vehicle route)
     369             :          * collects:
     370             :          *   myRoute
     371             :          *   myForward
     372             :          *   myBidi
     373             :          *   myProtectedBidi
     374             :          *
     375             :          * returns edge that is assumed to safe from oncoming-deadlock or nullptr
     376             :          */
     377             :         void buildRoute(MSLink* origin, double length, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap& visited);
     378             : 
     379             :         /* @brief find switches that threaten this driveway
     380             :          * @param[out] flankSwitches collect the switches
     381             :          */
     382             :         void checkFlanks(const MSLink* originLink, const std::vector<const MSLane*>& lanes, const LaneVisitedMap& visited, bool allFoes, std::vector<MSLink*>& flankSwitches) const;
     383             : 
     384             :         /* @brief find links that cross the driveway without entering it
     385             :          * @param[out] flankSwitches collect the switches
     386             :          */
     387             :         void checkCrossingFlanks(MSLink* dwLink, const LaneVisitedMap& visited, std::vector<MSLink*>& flankSwitches) const;
     388             : 
     389             :         /* @brief find upstream protection from the given link
     390             :          * @param[out] flank: the stored flank lanes
     391             :          */
     392             :         void findFlankProtection(MSLink* link, double length, LaneVisitedMap& visited, MSLink* origLink, std::vector<const MSLane*>& flank);
     393             :     };
     394             : 
     395             :     /* @brief retrieve driveway with the given numerical id
     396             :      * @note: throws exception if the driveway does not exist at this rail signal */
     397             :     const DriveWay& retrieveDriveWay(int numericalID) const;
     398             : 
     399             :     /// @brief get the closest vehicle approaching the given link
     400             :     static Approaching getClosest(MSLink* link);
     401             : 
     402             : protected:
     403             :     /// @brief whether the given vehicle is free to drive
     404             :     bool constraintsAllow(const SUMOVehicle* veh) const;
     405             : 
     406             : protected:
     407             : 
     408             :     /* The driveways for each link
     409             :      */
     410       13319 :     struct LinkInfo {
     411             :         /// @brief constructor
     412             :         LinkInfo(MSLink* link);
     413             : 
     414             :         MSLink* myLink;
     415             : 
     416             :         /// @brief all driveways immediately following this link
     417             :         std::vector<DriveWay> myDriveways;
     418             : 
     419             :         /// @brief return id for this railsignal-link
     420             :         std::string getID() const;
     421             : 
     422             :         /// @brief retrieve an existing Driveway or construct a new driveway based on the vehicles route
     423             :         DriveWay& getDriveWay(const SUMOVehicle*);
     424             : 
     425             :         /// @brief construct a new driveway by searching along the given route until all block structures are found
     426             :         DriveWay buildDriveWay(MSRouteIterator first, MSRouteIterator end);
     427             : 
     428             :         /// @brief try rerouting vehicle if reservation failed
     429             :         void reroute(SUMOVehicle* veh, const MSEdgeVector& occupied);
     430             : 
     431             :         /// @brief init LinkInfo
     432             :         void reset();
     433             : 
     434             :         SUMOTime myLastRerouteTime;
     435             :         SUMOVehicle* myLastRerouteVehicle;
     436             :     };
     437             : 
     438             :     /// @brief data storage for every link at this node (more than one when directly guarding a switch)
     439             :     std::vector<LinkInfo> myLinkInfos;
     440             : 
     441             :     /// @brief return logicID_linkIndex
     442             :     static std::string getTLLinkID(MSLink* link);
     443             : 
     444             :     /// @brief return junctionID_junctionLinkIndex
     445             :     static std::string getJunctionLinkID(MSLink* link);
     446             : 
     447             :     /// @brief return logicID_linkIndex in a way that allows clicking in sumo-gui
     448             :     static std::string getClickableTLLinkID(MSLink* link);
     449             : 
     450             :     /// @brief print link descriptions
     451             :     static std::string describeLinks(std::vector<MSLink*> links);
     452             : 
     453             :     /// @brief print link descriptions
     454             :     static std::string formatVisitedMap(const LaneVisitedMap& visited);
     455             : 
     456             :     /// @brief append to map by map index and avoid undefined behavior
     457             :     static void appendMapIndex(LaneVisitedMap& map, const MSLane* lane);
     458             : 
     459             : protected:
     460             : 
     461             :     /** @brief The list of phases this logic uses
     462             :     *
     463             :     *   This vector is always empty and only constructed because the superclass MSTrafficLightLogic requires it.
     464             :     */
     465             :     Phases myPhases;
     466             : 
     467             :     /// @brief The current phase
     468             :     MSPhaseDefinition myCurrentPhase;
     469             : 
     470             :     /// @brief MSTrafficLightLogic requires that the phase index changes whenever signals change their state
     471             :     int myPhaseIndex;
     472             : 
     473             :     /// @brief whether the signal is in moving block mode (only protects from oncoming and flanking trains)
     474             :     bool myMovingBlock;
     475             : 
     476             :     /// @brief map from tripId to constraint list
     477             :     std::map<std::string, std::vector<MSRailSignalConstraint*> > myConstraints;
     478             : 
     479             :     static int myNumWarnings;
     480             : 
     481             :     static int myDriveWayIndex;
     482             : 
     483             : protected:
     484             :     /// @brief update vehicle lists for traci calls
     485             :     void storeTraCIVehicles(int linkIndex);
     486             : 
     487             :     /// @name traci result storage
     488             :     //@{
     489             :     static bool myStoreVehicles;
     490             :     static VehicleVector myBlockingVehicles;
     491             :     static VehicleVector myRivalVehicles;
     492             :     static VehicleVector myPriorityVehicles;
     493             :     static std::string myConstraintInfo;
     494             :     //@}
     495             : 
     496             : 
     497             : };

Generated by: LCOV version 1.14