1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    MSPhaseDefinition.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Julia Ringel
13 /// @author  Jakob Erdmann
14 /// @author  Sascha Krieg
15 /// @author  Michael Behrisch
16 /// @date    Jan 2004
17 /// @version $Id$
18 ///
19 // The definition of a single phase of a tls logic
20 /****************************************************************************/
21 #ifndef MSPhaseDefinition_h
22 #define MSPhaseDefinition_h
23 
24 #define TARGET_BIT 0
25 #define TRANSIENT_NOTDECISIONAL_BIT 1
26 #define COMMIT_BIT 2
27 #define UNDEFINED_BIT 3
28 
29 
30 
31 // ===========================================================================
32 // included modules
33 // ===========================================================================
34 #include <config.h>
35 
36 #include <bitset>
37 #include <string>
38 #include <vector>
39 #include <utils/common/MsgHandler.h>
40 #include <utils/common/SUMOTime.h>
41 #include <utils/options/OptionsCont.h>
42 #include <utils/xml/SUMOXMLDefinitions.h>
43 
44 
45 // ===========================================================================
46 // class definitions
47 // ===========================================================================
48 /**
49  * @class MSPhaseDefinition
50  * @brief The definition of a single phase of a tls logic
51  */
52 class MSPhaseDefinition {
53 public:
54     /*
55      * @brief The definition of phase types
56      * Phase types are compulsory directives for SOTL policies.
57      * Knowing the phase type a policy can drive complex junction that need higly customized phases.
58      * Leaving the phase type as "undefined" makes SOTL policies to malfunction.
59      * Four bits:
60      * TARGET_BIT 0 -> the phase is a target one
61      * TRANSIENT_NOTDECISIONAL_BIT 1 -> the phase is a transient one or a decisional one
62      * COMMIT_BIT 2 -> the phase is a commit one
63      * UNDEFINED_BIT 3 -> the phase type is undefined
64      */
65     typedef std::bitset<4> PhaseType;
66 
67     typedef std::vector<std::string> LaneIdVector;
68 
69 public:
70     /// @brief The duration of the phase
71     SUMOTime duration;
72 
73     /// @brief The previous duration of the phase
74     SUMOTime lastDuration;
75 
76     /// @brief The minimum duration of the phase
77     SUMOTime minDuration;
78 
79     /// @brief The maximum duration of the phase
80     SUMOTime maxDuration;
81 
82     /// @brief Stores the timestep of the last on-switched of the phase
83     SUMOTime myLastSwitch;
84 
85     /// @brief The index of the phase that suceeds this one (or -1)
86     std::vector<int> nextPhases;
87 
88     /// @brief Optional name or description for the current phase
89     std::string name;
90 
91 private:
92     /// @brief The phase definition
93     std::string state;
94 
95     /*
96     * The type of this phase
97     */
98     PhaseType phaseType;
99 
100     /*
101      * @brief The lanes-set
102      * This array can be null if this phase is not a target step,
103      * otherwise, a bit is true if the corresponding lane belongs to a
104      * set of input lanes.
105      * SOTL traffic light logics choose the target step according to sensors
106      * belonging to the lane-set.
107      */
108     LaneIdVector targetLaneSet;
109 
init(SUMOTime durationArg,const std::string & stateArg,SUMOTime minDurationArg,SUMOTime maxDurationArg,const std::vector<int> nextPhases,const std::string & name)110     void init(SUMOTime durationArg, const std::string& stateArg, SUMOTime minDurationArg, SUMOTime maxDurationArg,
111               const std::vector<int> nextPhases, const std::string& name) {
112         this->duration = durationArg;
113         this->state = stateArg;
114         this->minDuration = minDurationArg < 0 ? durationArg : minDurationArg;
115         this->maxDuration = (maxDurationArg < 0 || maxDurationArg < minDurationArg) ? durationArg : maxDurationArg;
116         // assert(this->minDuration <= this->maxDuration); // not ensured by the previous lines
117         this->myLastSwitch = string2time(OptionsCont::getOptions().getString("begin")); // SUMOTime-option
118         //For SOTL phases
119         //this->phaseType = phaseTypeArg;
120         this->nextPhases = nextPhases;
121         this->name = name;
122     }
123 
init(SUMOTime durationArg,SUMOTime minDurationArg,SUMOTime maxDurationArg,const std::string & stateArg,const std::vector<int> & nextPhases,const std::string & name,LaneIdVector * targetLaneSetArg)124     void init(SUMOTime durationArg, SUMOTime minDurationArg, SUMOTime maxDurationArg, const std::string& stateArg,
125               const std::vector<int>& nextPhases, const std::string& name, LaneIdVector* targetLaneSetArg) {
126         init(durationArg, stateArg, minDurationArg, maxDurationArg, nextPhases, name);
127         //For SOTL target phases
128         if (targetLaneSetArg != nullptr) {
129             this->targetLaneSet = *targetLaneSetArg;
130         }
131     }
132 
133 
134 public:
135     /** @brief Constructor
136      *
137      * minDuration and maxDuration are set to duration.
138      *
139      * @param[in] durationArg The duration of the phase
140      * @param[in] stateArg The state in the phase
141      */
142     MSPhaseDefinition(SUMOTime durationArg, const std::string& stateArg, const std::vector<int>& nextPhases, const std::string& name = "") {
143         //PhaseType phaseType;
144         phaseType = PhaseType();
145         phaseType[UNDEFINED_BIT] = 1;
146         phaseType[TRANSIENT_NOTDECISIONAL_BIT] = 0;
147         phaseType[TARGET_BIT] = 0;
148         phaseType[COMMIT_BIT] = 0;
149         init(durationArg, stateArg, durationArg, durationArg, nextPhases, name);
150     }
151 
152 
153     /** @brief Constructor
154      * In this phase the duration is constrained between min and max duration
155      * @param[in] durationArg The duration of the phase
156      * @param[in] stateArg The state in the phase
157      * @param[in] minDurationArg The minimum duration of the phase
158      * @param[in] maxDurationArg The maximum duration of the phase
159      */
160     MSPhaseDefinition(SUMOTime durationArg, const std::string& stateArg, SUMOTime minDurationArg = -1, SUMOTime maxDurationArg = -1,
161                       const std::vector<int>& nextPhases = std::vector<int>(), const std::string& name = "") {
162         //PhaseType phaseType;
163         phaseType = PhaseType();
164         phaseType[UNDEFINED_BIT] = 1;
165         phaseType[TRANSIENT_NOTDECISIONAL_BIT] = 0;
166         phaseType[TARGET_BIT] = 0;
167         phaseType[COMMIT_BIT] = 0;
168         init(durationArg, stateArg, minDurationArg, maxDurationArg, nextPhases, name);
169     }
170 
171     /*
172      * @brief Constructor for definitions for SOTL target step
173      * In this phase the duration is constrained between min and max duration
174      * @param[in] phaseType Indicates the type of the step
175      * @param[in] targetLaneSet If not null, specifies this MSPhaseDefinition is a target step
176      * @see MSPhaseDefinition::PhaseType
177      */
178     MSPhaseDefinition(SUMOTime durationArg, const std::string& stateArg, SUMOTime minDurationArg, SUMOTime maxDurationArg,
179                       const std::vector<int>& nextPhases, const std::string& name, bool transient_notdecisional, bool commit, LaneIdVector* targetLaneSetArg = nullptr) {
180         if (targetLaneSetArg != nullptr && targetLaneSetArg->size() == 0) {
181             MsgHandler::getErrorInstance()->inform("MSPhaseDefinition::MSPhaseDefinition -> targetLaneSetArg cannot be empty for a target phase");
182         }
183         //PhaseType phaseType;
184         //phaseType = PhaseType::bitset();
185         phaseType = PhaseType();
186         phaseType[UNDEFINED_BIT] = 0;
187         phaseType[TRANSIENT_NOTDECISIONAL_BIT] = transient_notdecisional;
188         phaseType[TARGET_BIT] = targetLaneSetArg == nullptr ? 0 : 1;
189         phaseType[COMMIT_BIT] = commit;
190         init(durationArg, minDurationArg, maxDurationArg, stateArg, nextPhases, name, targetLaneSetArg);
191     }
192 
193     /// @brief Destructor
~MSPhaseDefinition()194     virtual ~MSPhaseDefinition() { }
195 
196 
197     /** @brief Returns the state within this phase
198      * @return The state in this phase
199      */
getState()200     const std::string& getState() const {
201         return state;
202     }
203 
setState(const std::string & _state)204     void setState(const std::string& _state) {
205         state = _state;
206     }
207 
getTargetLaneSet()208     const LaneIdVector& getTargetLaneSet() const {
209         return targetLaneSet;
210     }
211 
getNextPhases()212     const std::vector<int>& getNextPhases() const {
213         return nextPhases;
214     }
215 
getName()216     const std::string& getName() const {
217         return name;
218     }
219 
setName(const std::string & _name)220     void setName(const std::string& _name) {
221         name = _name;
222     }
223 
224     /** @brief Returns whether this phase is a pure "green" phase
225      *
226      * "pure green" means in this case that at least one stream has green
227      *  and no stream has yellow. Such phases are meant to be candidates
228      *  for being stretched by actuated or agentbased traffic light logics.
229      * @return Whether this phase is a "pure green" phase
230      */
isGreenPhase()231     bool isGreenPhase() const {
232         if (state.find_first_of("gG") == std::string::npos) {
233             return false;
234         }
235         if (state.find_first_of("yY") != std::string::npos) {
236             return false;
237         }
238         return true;
239     }
240 
241 
242     /** @brief Returns the state of the tls signal at the given position
243      * @param[in] pos The position of the signal to return the state for
244      * @return The state of the signal at the given position
245      */
getSignalState(int pos)246     LinkState getSignalState(int pos) const {
247         return (LinkState) state[pos];
248     }
249 
250 
251     /** @brief Comparison operator
252      *
253      * Note that only the state must differ, not the duration!
254      * @param[in] pd The phase definition to compare against
255      * @return Whether the given phase definition differs
256      */
257     bool operator!=(const MSPhaseDefinition& pd) {
258         return state != pd.state;
259     }
260 
261 
262     /*
263     * @return true if the phase type is undefined
264     */
isUndefined()265     bool isUndefined() const {
266         return phaseType[UNDEFINED_BIT];
267     }
268 
269     /*
270     * @return true if this is a target phase
271     */
isTarget()272     bool isTarget() const {
273         return phaseType[TARGET_BIT];
274     }
275 
276     /*
277     * @return true if this is a transient phase
278     */
isTransient()279     bool isTransient() const {
280         return phaseType[TRANSIENT_NOTDECISIONAL_BIT];
281     }
282 
283     /*
284     * @return true if this is a decisional phase
285     */
isDecisional()286     bool isDecisional() const {
287         return !phaseType[TRANSIENT_NOTDECISIONAL_BIT];
288     }
289 
290     /*
291     * @return true if this is a commit phase
292     */
isCommit()293     bool isCommit() const {
294         return phaseType[COMMIT_BIT];
295     }
296 
297 };
298 
299 #endif
300 
301 /****************************************************************************/
302 
303