1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2013-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    MSSOTLTrafficLightLogic.h
11 /// @author  Gianfilippo Slager
12 /// @author	 Anna Chiara Bellini
13 /// @author  Federico Caselli
14 /// @date    Apr 2013
15 /// @version $Id$
16 ///
17 // The base abstract class for SOTL logics
18 /****************************************************************************/
19 #ifndef MSSOTLTrafficLightLogic_h
20 #define MSSOTLTrafficLightLogic_h
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <utils/common/SwarmDebug.h>
28 
29 #include <utils/common/SUMOTime.h>
30 #include "MSSOTLDefinitions.h"
31 #include "MSPhasedTrafficLightLogic.h"
32 #include "MSSOTLE2Sensors.h"
33 #include <utils/common/RandHelper.h>
34 #include <utils/common/StringUtils.h>
35 
36 
37 // ===========================================================================
38 // class declarations
39 // ===========================================================================
40 class MSPushButton;
41 
42 
43 // ===========================================================================
44 // class definitions
45 // ===========================================================================
46 
47 /**
48  * @class MSSOTLTrafficLightLogic
49  * @brief A self-organizing traffic light logic
50  *
51  * The base class for SOTL traffic light which switches between
52  * its phases and sets the lights to red in between.
53  * Some functions are called with an information about the current step. This
54  * is needed as a single logic may be used by many junctions and so the current
55  * step is stored within them, not within methods.
56  * Basically a SOTL logic overrides the natural flow of steps in order and length
57  * according to sensors on input (and output) lanes
58  */
59 class MSSOTLTrafficLightLogic: public MSPhasedTrafficLightLogic {
60 public:
61     // typedef int CTS;
62 
63     /**
64      * @brief Constructor without sensors passed
65      * @param[in] tlcontrol The tls control responsible for this tls
66      * @param[in] id This traffic light id
67      * @param[in] programID This tls' sub-id (program id)
68      * @param[in] logicType This tls' type (static, actuated etc.)
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] parameters Parameters defined for the tll
73      */
74     MSSOTLTrafficLightLogic(MSTLLogicControl& tlcontrol, const std::string& id,
75                             const std::string& programID, const TrafficLightType logicType, const Phases& phases, int step,
76                             SUMOTime delay,
77                             const std::map<std::string, std::string>& parameters);
78 
79     /**
80      * @brief Constructor with sensors passed
81      * @param[in] tlcontrol The tls control responsible for this tls
82      * @param[in] id This tls' id
83      * @param[in] programID This tls' sub-id (program id)
84      * @param[in] logicType This tls' type (static, actuated etc.)
85      * @param[in] phases Definitions of the phases
86      * @param[in] step The initial phase index
87      * @param[in] delay The time to wait before the first switch
88      * @param[in] parameters Parameters defined for the tll
89      * @param[in] sensors The already defined sensor logic
90      */
91     MSSOTLTrafficLightLogic(MSTLLogicControl& tlcontrol, const std::string& id,
92                             const std::string& programID, const TrafficLightType logicType, const Phases& phases, int step,
93                             SUMOTime delay,
94                             const std::map<std::string, std::string>& parameters,
95                             MSSOTLSensors* sensors);
96 
97     /// @brief Destructor
98     ~MSSOTLTrafficLightLogic();
99 
100     /**
101      * @brief Initialises the tls with sensors on incoming and outgoing lanes
102      * Sensors are built in the simulation according to the type of sensor specified in the simulation parameter
103      * @param[in] nb The detector builder
104      * @exception ProcessError If something fails on initialisation
105      */
106     void init(NLDetectorBuilder& nb);
107 
108     /*
109      * This member implements the base operations for all SOTL logics.
110      * SOTL politics are implementated through decidePhase() member
111      * @see MSTrafficLightLogic::trySwitch
112      */
113     SUMOTime trySwitch();
114 
115 protected:
116 
117     typedef std::map<const std::string, std::vector<MSPushButton*> > PhasePushButtons;
118     PhasePushButtons m_pushButtons;
119 
120     void logStatus();
121     /*
122      * This member has to contain the switching logic for SOTL policies
123      */
124 
125     virtual int decideNextPhase();
126 
127     virtual bool canRelease() = 0;
128 
129     SUMOTime getCurrentPhaseElapsed();
130 
131     /*
132      * Count the number of vehicles approaching the target lanes for the given phase.
133      * If the phase in not a target phase the function member will return 0.
134      * @param[in] The target phase index
135      */
136     int countVehicles(MSPhaseDefinition phase);
137 
138     /*
139      * Every target step except the one from the current chain is checked.
140      * This is because the current chain is not eligible to be directly
141      * targeted again, it would be unfair.
142      * @return True if at least a target phase has passed the threshold for input cars-timesteps
143      */
144     bool isThresholdPassed();
145 
146     /**
147      * @breef Checks the if the pushbutton was activated for the current stage
148      * @return True if at least a push button was pressed
149      */
150     bool isPushButtonPressed();
151 
getThreshold()152     int getThreshold() {
153         return StringUtils::toInt(getParameter("THRESHOLD", "10"));
154     }
155 
getSpeedThreshold()156     double getSpeedThreshold() {
157         return StringUtils::toDouble(getParameter("THRESHOLDSPEED", "2"));
158     }
159 
getInputSensorsLength()160     double getInputSensorsLength() {
161         return StringUtils::toDouble(getParameter("INSENSORSLENGTH", "100"));
162     }
163 
getOutputSensorsLength()164     double getOutputSensorsLength() {
165         return StringUtils::toDouble(getParameter("OUTSENSORSLENGTH", "80"));
166     }
167 
168     /*
169      * Every target step except the one from the current chain is checked.
170      * This is because the current chain is not eligible to be directly
171      * targeted again, it would be unfair.
172      * @return The index of the phase with the maximum value of cars-timesteps
173      */
174     int getPhaseIndexWithMaxCTS();
175 
getSensors()176     MSSOTLSensors* getSensors() {
177         return mySensors;
178     }
179 
180     /**
181      *\brief Return the sensors that count the passage of vehicles in and out of the tl.
182      */
getCountSensors()183     MSSOTLE2Sensors* getCountSensors() {
184         return myCountSensors;
185     }
186     /*
187      * Computes how much time will pass after decideNextPhase will be executed again
188      */
computeReturnTime()189     virtual SUMOTime computeReturnTime() {
190         if (getCurrentPhaseDef().isTransient()) {
191             return getCurrentPhaseDef().duration;
192 
193         }
194         return DELTA_T;
195 
196     }
197 
198 
199 private:
200     /*
201      * Pointer to the sensor logic regarding the junction controlled by this SOTLTrafficLightLogic
202      */
203     MSSOTLSensors* mySensors;
204 
205     /*
206      * Pointer to the sensor logic regarding the count of the vehicles that pass into a tl.
207      */
208     MSSOTLE2Sensors* myCountSensors;
209 
210     /*
211      * When true means the class has responsibilities to intantiate and delete the SOTLSensors instance,
212      * otherwise MSSOTLTrafficLightLogic::init and MSSOTLTrafficLightLogic::~MSSOTLTrafficLightLogic have not to affect SOTLSensors instance lifecycle
213      */
214     bool sensorsSelfBuilt;
215 
216     // The map to store the cars*timesteps for each target phase
217     std::map<int, SUMOTime> targetPhasesCTS;
218 
219     //The map to store the time each target phase have been checked last
220     //This helps to compute the timesteps to get the cars*timesteps value
221     std::map<int, SUMOTime> lastCheckForTargetPhase;
222 
223     //Map to store how many selection rounds have been done from the last selection of the phase
224     std::map<int, int> targetPhasesLastSelection;
225 
getTargetPhaseMaxLastSelection()226     int getTargetPhaseMaxLastSelection() {
227         //return 2 * targetPhasesCTS.size() - 1;
228         return (int)targetPhasesCTS.size() - 1;
229     }
230 
231     /*
232      * This member keeps track which is the current steps chain, i.e.
233      * which is the last target phase executed (even if it is currently executed)
234      * (a steps chain starts always with a target phase)
235      */
236     int lastChain;
237 
238     double decayThreshold;
239     /*
240      * @brief Check for phases compliancy
241      */
242     void checkPhases();
243 
244     /*
245      * Find the first target phase and set the current step on it
246      */
247     void setToATargetPhase();
248 
249     /*
250      * This function member helps to set up the map keeping track of target phases and associated timesteps
251      */
252     void setupCTS();
253 
254     /*
255      * Updates the cars-timesteps counters for each target phase except the one belonging to the current steps chain
256      */
257     void updateCTS();
258 
259     /*
260      * To reset the cars-timesteps counter when a target phase is newly selected
261      * If phaseStep is not a target phase nothing happens
262      */
263     void resetCTS(int phaseStep);
264     /*
265      * TEST
266      */
267     void updateDecayThreshold();
268 
269     /*
270      * Traffic threshold calculation mode:
271      * 0-> cars times seconds
272      * 1-> estimated cars times seconds
273      * 2-> queue length
274      */
getMode()275     int getMode() {
276         return StringUtils::toInt(getParameter("MODE", "0"));
277     }
278     /*
279      * Decay threshold that should be used in case of penetration rate != 100%
280      * 0-> not active
281      * 1-> active
282      */
isDecayThresholdActivated()283     bool isDecayThresholdActivated() {
284         return StringUtils::toBool(getParameter("DECAY_THRESHOLD", "0"));
285     }
286 
getDecayConstant()287     double getDecayConstant() {
288         return StringUtils::toDouble(getParameter("DECAY_CONSTANT", "-0.001"));
289     }
290 
291 };
292 
293 #endif
294 /****************************************************************************/
295