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