Eclipse SUMO - Simulation of Urban MObility
MSSwarmTrafficLightLogic.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2010-2020 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 /****************************************************************************/
19 // The class for Swarm-based logics
20 /****************************************************************************/
21 #pragma once
22 #include <config.h>
23 
24 //#define SWARM_DEBUG
27 #include "MSSOTLPhasePolicy.h"
28 #include "MSSOTLPlatoonPolicy.h"
29 #include "MSSOTLMarchingPolicy.h"
30 #include "MSSOTLCongestionPolicy.h"
31 #include "MSSOTLPolicy3DStimulus.h"
33 
34 template<class T>
36 public:
39  m_buffer = new T[m_size];
40  }
41 
42  virtual ~CircularBuffer() {
43  delete[] m_buffer;
44  }
45 
46  bool addValue(const T newValue, T& replacedValue) {
47  bool result = !m_firstTime;
48  if (result) {
49  replacedValue = m_buffer[m_currentIndex];
50  }
51  insert(newValue);
52  return result;
53  }
54 
55  void push_front(const T value) {
56  insert(value);
57  }
58 
59  T at(const int index) const {
60  int idx = (m_currentIndex - 1 - index + m_size) % m_size;
61  return m_buffer[idx];
62  }
63 
64  T front() const {
65  return at(0);
66  }
67 
68  T back() const {
69  return at(size() - 1);
70  }
71 
72  int size() const {
73  if (m_firstTime) {
74  return m_currentIndex;
75  }
76  return m_size;
77  }
78 
79  void clear() {
80  m_currentIndex = 0;
81  m_firstTime = true;
82  }
83 
84 private:
86  int m_size;
89 
90  inline void insert(const T& value) {
91  m_buffer[m_currentIndex++] = value;
92  if (m_currentIndex == m_size) {
93  m_currentIndex = 0;
94  m_firstTime = false;
95  }
96  }
97 };
98 
100 public:
101  //****************************************************
112  MSSwarmTrafficLightLogic(MSTLLogicControl& tlcontrol, const std::string& id,
113  const std::string& programID, const Phases& phases, int step,
114  SUMOTime delay,
115  const std::map<std::string, std::string>& parameters);
116 
118 
125  void init(NLDetectorBuilder& nb);
126 
128  return StringUtils::toInt(getParameter("MAX_CONGESTION_DUR", "120"));
129  }
130 
131  double getPheroMaxVal() {
132  return StringUtils::toDouble(getParameter("PHERO_MAXVAL", "10"));
133  }
134 
135  double getBetaNo() {
136  return StringUtils::toDouble(getParameter("BETA_NO", "0.99"));
137  }
138 
139  double getGammaNo() {
140  return StringUtils::toDouble(getParameter("GAMMA_NO", "1.0"));
141  }
142 
143  double getBetaSp() {
144  return StringUtils::toDouble(getParameter("BETA_SP", "0.99"));
145  }
146 
147  double getGammaSp() {
148  return StringUtils::toDouble(getParameter("GAMMA_SP", "1.0"));
149  }
150 
152  return StringUtils::toDouble(getParameter("CHANGE_PLAN_PROBABILITY", "0.003"));
153  }
154 
155  double getThetaMax() {
156  return StringUtils::toDouble(getParameter("THETA_MAX", "0.8"));
157  }
158 
159  double getThetaMin() {
160  return StringUtils::toDouble(getParameter("THETA_MIN", "0.2"));
161  }
162 
163  double getThetaInit() {
164  return StringUtils::toDouble(getParameter("THETA_INIT", "0.5"));
165  }
166 
167  double getLearningCox() {
168  return StringUtils::toDouble(getParameter("LEARNING_COX", "0.0005"));
169  }
170 
171  double getForgettingCox() {
172  return StringUtils::toDouble(getParameter("FORGETTING_COX", "0.0005"));
173  }
174 
177  }
178 
181  }
182 
186  const std::string getLogicType() const {
187  return "swarmBasedTrafficLogic";
188  }
190 
191 protected:
199 
207 
214 
215  /*
216  * This member has to contain the switching logic for SOTL policies
217  */
218 
219  int decideNextPhase();
220 
221  bool canRelease();
222 
223  /*
224  * Computes how much time will pass after decideNextPhase will be executed again
225  */
227 
228  return DELTA_T;
229 
230  }
231 
235  void resetPheromone();
236 
237  /*
238  * @return The average pheromone level regarding congestion on input lanes
239  */
240  double getPheromoneForInputLanes();
241 
242  /*
243  * @return The average pheromone level regarding congestion on output lanes
244  */
246 
247  /*
248  * @return The dispersion level regarding congestion on input lanes
249  */
250  double getDispersionForInputLanes(double average_phero_in);
251 
252  /*
253  * @return The dispersion level regarding congestion on output lanes
254  */
255  double getDispersionForOutputLanes(double average_phero_out);
256 
257  /*
258  * @return The difference between the current max phero value and the average phero of the other lanes
259  */
261 
262  /*
263  * @return The difference between the current max phero value and the average phero of the other lanes
264  */
271  void updatePheromoneLevels();
272 
276  void updatePheromoneLevels(MSLaneId_PheromoneMap&, std::string, const double, const double);
277 
283  void updateSensitivities();
284 
289  void decidePolicy();
290 
297  double calculatePhi(int factor);
298 
305  double calculateEtaDiff();
306 
307  double calculateEtaRatio();
308 
309  /*
310  * \brief Method to reset the map that stores if a lane is already been checked during the
311  * evaluation of eta.
312  */
313  void resetLaneCheck();
314  void choosePolicy(double phero_in, double phero_out, double dispersion_in, double dispersion_out);
315  void choosePolicy(double phero_in, double phero_out);
316 
317  std::string getPoliciesParam() {
318  return getParameter("POLICIES", "Platoon;Phase;Marching;Congestion");
319  }
320 
321  /*
322  * Reinforcement modes:
323  * 0-> elapsed time
324  * 1-> diff
325  * 2-> ratio
326  */
328  return StringUtils::toInt(getParameter("REIMODE", "0"));
329  }
330 
331  void initScaleFactorDispersionIn(int lanes_in) {
332  std::vector<double> phero_values;
333 
334  for (int i = 0; i < lanes_in / 2; i++) {
335  phero_values.push_back(getPheroMaxVal());
336  }
337  for (int i = lanes_in / 2; i < lanes_in; i++) {
338  phero_values.push_back(0.0);
339  }
340 
341  double sum_avg_tmp = 0;
342 
343  for (int i = 0; i < (int)phero_values.size(); i++) {
344  sum_avg_tmp += phero_values[i];
345  }
346 
347  double mean = sum_avg_tmp / phero_values.size();
348 
349  double sum_dev_tmp = 0;
350  for (int i = 0; i < (int)phero_values.size(); i++) {
351  sum_dev_tmp += pow(phero_values[i] - mean, 2);
352  }
353 
354  double deviation = sqrt(sum_dev_tmp / phero_values.size());
355 
356  scaleFactorDispersionIn = getPheroMaxVal() / deviation;
357  }
358 
359  void initScaleFactorDispersionOut(int lanes_out) {
360  std::vector<double> phero_values;
361 
362  for (int i = 0; i < lanes_out / 2; i++) {
363  phero_values.push_back(getPheroMaxVal());
364  }
365  for (int i = lanes_out / 2; i < lanes_out; i++) {
366  phero_values.push_back(0.0);
367  }
368 
369  double sum_avg_tmp = 0;
370  for (int i = 0; i < (int)phero_values.size(); i++) {
371  sum_avg_tmp += phero_values[i];
372  }
373  double mean = sum_avg_tmp / phero_values.size();
374 
375  double sum_dev_tmp = 0;
376 
377  for (int i = 0; i < (int)phero_values.size(); i++) {
378  sum_dev_tmp += pow(phero_values[i] - mean, 2);
379  }
380 
381  double deviation = sqrt(sum_dev_tmp / phero_values.size());
382 
384  }
385 
391  bool allowLine(MSLane*);
392 
393  bool logData;
394  std::ofstream swarmLogFile;
401 
414  bool skipEta;
420 
421  int carsIn;
422  int carsOut;
423  int inTarget;
430 
431 // For every lane its index. Esed to get the current lane state for the lane
432  std::map<std::string, std::vector<int> > m_laneIndexMap;
433  std::string getLaneLightState(const std::string& laneId);
434 // store the last message logged. if equal do not log it again
435  std::map<std::string, std::string> m_pheroLevelLog;
436 
437  //derivative
438  std::map<std::string, CircularBuffer<double>* > m_meanSpeedHistory;
439  std::map<std::string, CircularBuffer<double>* > m_derivativeHistory;
441  int m_losCounter;//los: loss of signal
444 
445 // double pheroBegin;
446 };
std::map< std::string, double > MSLaneId_PheromoneMap
std::map< MSLane *, bool > LaneCheckMap
std::vector< std::string > LaneIdVector
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
long long int SUMOTime
Definition: SUMOTime.h:31
bool addValue(const T newValue, T &replacedValue)
T at(const int index) const
void push_front(const T value)
void insert(const T &value)
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
A self-organizing high-level traffic light logic.
MSLaneId_PheromoneMap pheromoneOutputLanes
This pheromone is an indicator of congestion on output lanes. Its levels refer to the average speed o...
bool mustChange
When true, indicates that the current policy MUST be changed. It's used to force the exit from the co...
bool allowLine(MSLane *)
Check if a lane is allowed to be added to the maps pheromoneInputLanes and pheromoneOutputLanes Contr...
bool gotTargetLane
When true indicates that we've already acquired the target lanes for this particular phase.
void updatePheromoneLevels()
Update pheromone levels Pheromone on input lanes is costantly updated Pheromone follows a discrete-ti...
void choosePolicy(double phero_in, double phero_out, double dispersion_in, double dispersion_out)
void initScaleFactorDispersionIn(int lanes_in)
LaneIdVector targetLanes
A copy of the target lanes of this phase.
double getDispersionForOutputLanes(double average_phero_out)
bool skipEta
When true indicates that we can skip the evaluation of eta since we've a congestion policy that is la...
double calculateEtaDiff()
Method that should calculate the valor of eta a coefficient to evaluate the current policy's work....
std::map< std::string, CircularBuffer< double > * > m_meanSpeedHistory
std::map< std::string, std::string > m_pheroLevelLog
double getDispersionForInputLanes(double average_phero_in)
std::map< std::string, CircularBuffer< double > * > m_derivativeHistory
void resetPheromone()
Resets pheromone levels.
MSSwarmTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const Phases &phases, int step, SUMOTime delay, const std::map< std::string, std::string > &parameters)
Constructor without sensors passed.
MSLaneId_PheromoneMap pheromoneInputLanes
This pheronome is an indicator of congestion on input lanes. Its levels refer to the average speed of...
std::string getLaneLightState(const std::string &laneId)
void initScaleFactorDispersionOut(int lanes_out)
std::map< std::string, std::vector< int > > m_laneIndexMap
void decidePolicy()
Decide the current policy according to pheromone levels The decision reflects on currentPolicy value.
LaneCheckMap laneCheck
Map to check if a lane was already controlled during the elaboration of eta.
double calculatePhi(int factor)
Method that should calculate the valor of phi a coefficient to amplify/attenuate eta based on a facto...
void init(NLDetectorBuilder &nb)
Initialises the tls with sensors on incoming and outgoing lanes Sensors are built in the simulation a...
const std::string getLogicType() const
Returns the type of the logic as a string.
A class that stores and controls tls and switching of their programs.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
Builds detectors for microsim.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...