Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-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 MSRailSignalControl.h
15 : /// @author Jakob Erdmann
16 : /// @date Sept 2020
17 : ///
18 : // Centralized services for rail signal control (Singleton)
19 : // - monitors track usage for long-range deadlock prevention
20 : /****************************************************************************/
21 : #pragma once
22 : #include <config.h>
23 : #include <microsim/MSNet.h>
24 :
25 : // ===========================================================================
26 : // class declarations
27 : // ===========================================================================
28 : class MSRailSignal;
29 : class MSRailSignalConstraint;
30 : class MSEdge;
31 : class MSDriveWay;
32 :
33 : // ===========================================================================
34 : // class definitions
35 : // ===========================================================================
36 : /**
37 : * @class MSRailSignalControl
38 : * @brief A signal for rails
39 : */
40 : class MSRailSignalControl : public MSNet::VehicleStateListener {
41 : public:
42 : ~MSRailSignalControl();
43 :
44 : static MSRailSignalControl& getInstance();
45 :
46 : static bool hasInstance() {
47 127724457 : return myInstance != nullptr;
48 : }
49 :
50 : static void cleanup();
51 :
52 : /** @brief Perform resets events when quick-loading state */
53 : static void clearState();
54 :
55 : /// @brief reset all waiting-for relationships at the start of the simulation step
56 3644961 : void resetWaitRelations() {
57 : myWaitRelations.clear();
58 : myWrittenDeadlocks.clear();
59 3644961 : }
60 :
61 : void addWaitRelation(const SUMOVehicle* waits, const MSRailSignal* rs, const SUMOVehicle* reason, MSRailSignalConstraint* constraint = nullptr);
62 :
63 : void addDrivewayFollower(const MSDriveWay* dw, const MSDriveWay* dw2);
64 :
65 : /// @brief check whether the given signal and driveway are part of a deadlock circle
66 : void addDWDeadlockChecks(const MSRailSignal* rs, MSDriveWay* dw);
67 :
68 : /// @brief whether there is a circle in the waiting-for relationships that contains the given vehicle
69 : bool haveDeadlock(const SUMOVehicle* veh) const;
70 :
71 : void addDeadlockCheck(std::vector<const MSRailSignal*> signals);
72 :
73 : /** @brief Called if a vehicle changes its state
74 : * @param[in] vehicle The vehicle which changed its state
75 : * @param[in] to The state the vehicle has changed to
76 : * @param[in] info Additional information on the state change
77 : */
78 : void vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& info = "");
79 :
80 : void addSignal(MSRailSignal* signal);
81 :
82 : const std::vector<MSRailSignal*>& getSignals() const {
83 : return mySignals;
84 : }
85 :
86 : const std::map<const MSRailSignal*, std::vector<const MSRailSignal*> >& getDeadlockChecks() const {
87 : return myDeadlockChecks;
88 : }
89 :
90 : /// switch rail signal to active
91 : void notifyApproach(const MSLink* link);
92 :
93 : /// @brief update active rail signals
94 : void updateSignals(SUMOTime t);
95 :
96 :
97 : static bool isSignalized(SUMOVehicleClass svc) {
98 51689 : return (mySignalizedClasses & svc) == svc;
99 : }
100 :
101 : static void initSignalized(SVCPermissions svc) {
102 39025 : mySignalizedClasses = svc;
103 : }
104 :
105 : protected:
106 :
107 : void findDeadlockFoes(const MSDriveWay* dw, const std::vector<const MSRailSignal*>& others, std::vector<const MSDriveWay*> deadlockFoes);
108 :
109 :
110 : private:
111 : /** @brief Constructor */
112 : MSRailSignalControl();
113 :
114 : /// @brief compute additioanl deadlock-check requirements for registered driveways
115 : void updateDriveways(const MSEdge* used);
116 :
117 : /// @brief all rail edges that are part of a known route
118 : std::set<const MSEdge*> myUsedEdges;
119 :
120 : struct WaitRelation {
121 143185 : WaitRelation(const MSRailSignal* _railSignal = nullptr, const SUMOVehicle* _foe = nullptr, MSRailSignalConstraint* _constraint = nullptr) :
122 143185 : railSignal(_railSignal), foe(_foe), constraint(_constraint) {}
123 : // indices along route
124 : const MSRailSignal* railSignal;
125 : const SUMOVehicle* foe;
126 : MSRailSignalConstraint* constraint;
127 : };
128 : std::map<const SUMOVehicle*, WaitRelation> myWaitRelations;
129 :
130 : mutable std::set<std::set<const SUMOVehicle*> > myWrittenDeadlocks;
131 :
132 : std::map<const MSRailSignal*, std::vector<const MSRailSignal*> > myDeadlockChecks;
133 : std::map<const MSDriveWay*, std::set<const MSDriveWay*>> myDriveWaySucc;
134 : std::map<const MSDriveWay*, std::set<const MSDriveWay*>> myDriveWayPred;
135 :
136 : /// @brief list of all rail signals
137 : std::vector<MSRailSignal*> mySignals;
138 :
139 : /// @brief list of signals that switched green along with driveway index
140 : std::vector<std::pair<MSLink*, int> > mySwitchedGreenFlanks;
141 : std::map<std::pair<int, int>, bool> myDriveWayCompatibility;
142 : std::set<MSRailSignal*, ComparatorNumericalIdLess> myActiveSignals;
143 :
144 : /// @brief signalized classes
145 : static SVCPermissions mySignalizedClasses;
146 :
147 : static MSRailSignalControl* myInstance;
148 :
149 :
150 : };
|