SUMO - Simulation of Urban MObility
MSSwarmTrafficLightLogic.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2010-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
18 // The class for Swarm-based logics
19 /****************************************************************************/
20 
22 #include "../MSEdge.h"
23 
24 #if 1
25 #define ANALYSIS_DBG(X) {X}
26 #else
27 #define ANALYSIS_DBG(X) DBG(X)
28 #endif
29 
31  const std::string& subid, const Phases& phases, int step, SUMOTime delay,
32  const std::map<std::string, std::string>& parameters) :
33  MSSOTLHiLevelTrafficLightLogic(tlcontrol, id, subid, phases, step, delay, parameters) {
34 
35  std::string pols = getPoliciesParam();
36  std::transform(pols.begin(), pols.end(), pols.begin(), ::tolower);
37  DBG(std::ostringstream str; str << "policies: " << pols; WRITE_MESSAGE(str.str());)
38 
39  if (pols.find("platoon") != std::string::npos) {
40  addPolicy(new MSSOTLPlatoonPolicy(new MSSOTLPolicy5DFamilyStimulus("PLATOON", parameters), parameters));
41  }
42  if (pols.find("phase") != std::string::npos) {
43  addPolicy(new MSSOTLPhasePolicy(new MSSOTLPolicy5DFamilyStimulus("PHASE", parameters), parameters));
44  }
45  if (pols.find("marching") != std::string::npos) {
46  addPolicy(new MSSOTLMarchingPolicy(new MSSOTLPolicy5DFamilyStimulus("MARCHING", parameters), parameters));
47  }
48  if (pols.find("congestion") != std::string::npos) {
49  addPolicy(new MSSOTLCongestionPolicy(new MSSOTLPolicy5DFamilyStimulus("CONGESTION", parameters), parameters));
50  }
51 
52  if (getPolicies().empty()) {
53  WRITE_ERROR("NO VALID POLICY LIST READ");
54  }
55 
56  mustChange = false;
57  skipEta = false;
58  gotTargetLane = false;
59 
60  DBG(
61  std::ostringstream d_str; d_str << getMaxCongestionDuration(); vector<MSSOTLPolicy*> policies = getPolicies();
62 
63  WRITE_MESSAGE("getMaxCongestionDuration " + d_str.str()); for (int i = 0; i < policies.size(); i++) {
64  MSSOTLPolicy* policy = policies[i];
66  std::ostringstream _str;
67  _str << policy->getName() << stim->getMessage() << " getThetaSensitivity " << policy->getThetaSensitivity() << " .";
68  WRITE_MESSAGE(_str.str());
69  })
70  congestion_steps = 0;
71  m_useVehicleTypesWeights = getParameter("USE_VEHICLE_TYPES_WEIGHTS", "0") == "1";
72  if (m_useVehicleTypesWeights && pols.find("phase") == std::string::npos) {
73  WRITE_ERROR("VEHICLE TYPES WEIGHT only works with phase policy, which is missing");
74  }
75 }
76 
78  if (logData && swarmLogFile.is_open()) {
79  swarmLogFile.close();
80  }
81  for (std::map<std::string, CircularBuffer<double>*>::iterator it = m_meanSpeedHistory.begin();
82  it != m_meanSpeedHistory.end(); ++it) {
83  delete it->second;
84  }
85  m_meanSpeedHistory.clear();
86  for (std::map<std::string, CircularBuffer<double>*>::iterator it = m_derivativeHistory.begin();
87  it != m_derivativeHistory.end(); ++it) {
88  delete it->second;
89  }
90  m_derivativeHistory.clear();
91 }
92 
94  //No walking areas
95  if (lane->getEdge().isWalkingArea()) {
96  return false;
97  }
98  //No pedestrian crossing
99  if (lane->getEdge().isCrossing()) {
100  return false;
101  }
102  //No pedestrian only lanes
103  if (lane->getPermissions() == SVC_PEDESTRIAN) {
104  return false;
105  }
106  //No bicycle only lanes
107  if (lane->getPermissions() == SVC_BICYCLE) {
108  return false;
109  }
110  //No pedestrian and bicycle only lanes
111  if (lane->getPermissions() == (SVC_PEDESTRIAN | SVC_BICYCLE)) {
112  return false;
113  }
114  return true;
115 }
116 
119  //Setting the startup policy
120  choosePolicy(0, 0, 0, 0);
121  //Initializing the random number generator to a time-dependent seed
122  srand((int) time(NULL));
123  //Initializing pheromone maps according to input lanes
124  //For each lane insert a pair into maps
125  MSLane* currentLane = NULL;
126 
127 // Derivative
128  const int derivativeHistorySize = TplConvert::_2int(getParameter("PHERO_DERIVATIVE_HISTORY_SIZE", "3").c_str());
129  const int meanSpeedHistorySize = TplConvert::_2int(getParameter("PHERO_MEAN_SPEED_HISTORY_SIZE", "3").c_str());
130  m_derivativeAlpha = TplConvert::_2double(getParameter("PHERO_DERIVATIVE_ALPHA", "1").c_str());
131  m_losCounter = 0;
132  m_losMaxLimit = TplConvert::_2int(getParameter("LOSS_OF_SIGNAL_LIMIT", "10").c_str());
133 
134  int index = 0;
135  for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector = myLanes.begin();
136  laneVector != myLanes.end(); laneVector++) {
137  for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
138  lane++) {
139  currentLane = (*lane);
140  if (pheromoneInputLanes.find(currentLane->getID()) == pheromoneInputLanes.end()) {
141  laneCheck[currentLane] = false;
142  if (allowLine(currentLane)) {
143  pheromoneInputLanes.insert(MSLaneId_Pheromone(currentLane->getID(), 0.0));
144 // Consider the derivative only for the input lane
145  m_meanSpeedHistory.insert(std::make_pair(currentLane->getID(), new CircularBuffer<double>(meanSpeedHistorySize)));
146  m_derivativeHistory.insert(std::make_pair(currentLane->getID(), new CircularBuffer<double>(derivativeHistorySize)));
147  ANALYSIS_DBG(
148  WRITE_MESSAGE("MSSwarmTrafficLightLogic::init Intersection " + getID() + " pheromoneInputLanes adding " + currentLane->getID());)
149  } else {
150  ANALYSIS_DBG(
151  WRITE_MESSAGE("MSSwarmTrafficLightLogic::init Intersection " + getID() + " pheromoneInputLanes: lane " + currentLane->getID() + " not allowed");)
152  }
153  }
154  m_laneIndexMap[currentLane->getID()].push_back(index++);
155  }
156  }
157 
159  for (int i = 0; i < (int)myLinks.size(); i++) {
160  LinkVector oneLink = getLinksAt(i);
161  for (int j = 0; j < (int)oneLink.size(); j++) {
162  currentLane = oneLink[j]->getLane();
163  if (pheromoneOutputLanes.find(currentLane->getID()) == pheromoneOutputLanes.end()) {
164  laneCheck[currentLane] = false;
165  if (allowLine(currentLane)) {
166  pheromoneOutputLanes.insert(MSLaneId_Pheromone(currentLane->getID(), 0.0));
167  ANALYSIS_DBG(
168  WRITE_MESSAGE("MSSwarmTrafficLightLogic::init Intersection " + getID() + " pheromoneOutputLanes adding " + currentLane->getID());)
169  } else {
170  ANALYSIS_DBG(
171  WRITE_MESSAGE("MSSwarmTrafficLightLogic::init Intersection " + getID() + " pheromoneOutputLanes lane " + currentLane->getID() + " not allowed");)
172  }
173  }
174  }
175  }
176 
179  //Initializing thresholds for theta evaluations
181 
182  WRITE_MESSAGE("*** Intersection " + getID() + " will run using MSSwarmTrafficLightLogic ***");
183  std::string logFileName = getParameter("SWARMLOG", "");
184  logData = logFileName.compare("") != 0;
185  if (logData) {
186  swarmLogFile.open(logFileName.c_str(), std::ios::out | std::ios::binary);
187  }
188 // Log the initial state
189  ANALYSIS_DBG(
190  WRITE_MESSAGE("TL " + getID() + " time 0 Policy: " + getCurrentPolicy()->getName() + " (pheroIn= 0 ,pheroOut= 0 ) OldPolicy: " + getCurrentPolicy()->getName() + " .");
191 // ostringstream maplog;
192 // for(map<string, vector<int> >::const_iterator mIt = m_laneIndexMap.begin();mIt != m_laneIndexMap.end();++mIt)
193 // {
194 // maplog << mIt->first <<'[';
195 // for(vector<int>::const_iterator vIt = mIt->second.begin();vIt != mIt->second.end();++vIt)
196 // maplog<<*vIt<<", ";
197 // maplog << "] ";
198 // }
199 // WRITE_MESSAGE("Map content " + maplog.str());
200  );
201 }
202 
204  //input
205  for (MSLaneId_PheromoneMap::iterator laneIterator = pheromoneInputLanes.begin();
206  laneIterator != pheromoneInputLanes.end(); laneIterator++) {
207  std::string laneId = laneIterator->first;
208  pheromoneInputLanes[laneId] = 0;
209  }
210  //output
211  for (MSLaneId_PheromoneMap::iterator laneIterator = pheromoneOutputLanes.begin();
212  laneIterator != pheromoneOutputLanes.end(); laneIterator++) {
213  std::string laneId = laneIterator->first;
214  pheromoneOutputLanes[laneId] = 0;
215  }
216 }
217 
219 
220  DBG(
221  MsgHandler::getMessageInstance()->inform("\n" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic decideNextPhase()"); std::ostringstream dnp; dnp << (MSNet::getInstance()->getCurrentTimeStep()) << " MSSwarmTrafficLightLogic::decideNextPhase:: " << "tlsid=" << getID() << " getCurrentPhaseDef().getState()=" << getCurrentPhaseDef().getState() << " is commit?" << getCurrentPhaseDef().isCommit(); MsgHandler::getMessageInstance()->inform(dnp.str());)
222  // if we're congested, it should be wise to reset and recalculate the pheromone levels after X steps
223 
224  if (getCurrentPhaseDef().isTarget()) {
226  }
227 
228  if (getCurrentPolicy()->getName().compare("Congestion") == 0 && getCurrentPhaseDef().isCommit()) {
229  congestion_steps += 1; //STEPS2TIME(getCurrentPhaseDef().duration);
230  DBG(
231  WRITE_MESSAGE("\n" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic decideNextPhase()"); std: ostringstream dnp; dnp << (MSNet::getInstance()->getCurrentTimeStep()) << " MSSwarmTrafficLightLogic::decideNextPhase:: " << "tlsid=" << getID() << " congestion_steps=" << congestion_steps; WRITE_MESSAGE(dnp.str());)
233  resetPheromone();
234  congestion_steps = 0;
235  mustChange = true;
236  if (getReinforcementMode() != 0) {
237  skipEta = true;
238  }
239  DBG(
240  WRITE_MESSAGE("\n" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic decideNextPhase()"); std::ostringstream dnp; dnp << (MSNet::getInstance()->getCurrentTimeStep()) << " MSSwarmTrafficLightLogic::decideNextPhase:: " << "tlsid=" << getID() << " max congestion reached, congestion_steps=" << congestion_steps; WRITE_MESSAGE(dnp.str());)
241  }
242  }
243 
244  //Update pheromone levels
246 
247  /* Since we changed the behaviour of computeReturnTime() in order to update pheromone levels every step
248  * it is now mandatory to check if the duration of a transient phase is elapsed or not*/
249  if (getCurrentPhaseDef().isTransient() && getCurrentPhaseElapsed() < getCurrentPhaseDef().duration) {
250  return getCurrentPhaseIndex();
251  }
252 
253  //Decide the current policy according to pheromone levels. this should be done only at the end of a chain, before selecting the new one
254  if (getCurrentPhaseDef().isCommit()) {
255  //Update learning and forgetting thresholds
257  decidePolicy();
258  gotTargetLane = false;
259  }
260 
261 // double phero =0;
262 // if(getCurrentPhaseDef().isDecisional())
263 // {
264 // for(LaneIdVector::const_iterator it = targetLanes.begin(); it != targetLanes.end(); ++it)
265 // {
266 // string name = (*it);
267 // phero +=pheromoneInputLanes[name];
268 // }
269 // phero /= targetLanes.size() == 0 ? 1 : targetLanes.size();
270 // if(getCurrentPhaseElapsed() >= getCurrentPhaseDef().minDuration)
271 // if(abs(phero-pheroBegin) <= 2)
272 // return getCurrentPhaseIndex() + 1;
273 // }
274  DBG(
275  std::ostringstream str; str << "tlsID=" << getID() << " currentPolicyname=" + getCurrentPolicy()->getName(); WRITE_MESSAGE(str.str());)
276 
277  //Execute current policy. congestion "policy" must maintain the commit phase, and that must be an all-red one
280 // int newStep =getCurrentPolicy()->decideNextPhase(getCurrentPhaseElapsed(), &getCurrentPhaseDef(), getCurrentPhaseIndex(),
281 // getPhaseIndexWithMaxCTS(), isThresholdPassed(), isPushButtonPressed(), countVehicles(getCurrentPhaseDef()));
282 // if(newStep != myStep)
283 // pheroBegin = phero;
284 // return newStep;
285 }
286 
288  //Updating input lanes pheromone: all input lanes without distinction
289  //BETA_NO, GAMMA_NO
291 
292  //BETA_SP, GAMMA_SP
293  //Updating output lanes pheromone: only input lanes currently having green light. Pheromone for non green lanes is "freezed"
294 // if (getCurrentPhaseDef().isDecisional()) {
296 // }
297 }
298 
300  const double beta, const double gamma) {
301  // ANALYSIS_DBG(
302  DBG(
303  std::ostringstream _str; _str << logString << " Lanes " << pheroMap.size() << " TL " << getID() << " ."; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::updatePheromoneLevels:: " + _str.str());)
304 
305  for (MSLaneId_PheromoneMap::iterator laneIterator = pheroMap.begin(); laneIterator != pheroMap.end();
306  ++laneIterator) {
307  std::string laneId = laneIterator->first;
308  double oldPhero = laneIterator->second;
309  double maxSpeed = getSensors()->getMaxSpeed(laneId);
310  double meanVehiclesSpeed = getSensors()->meanVehiclesSpeed(laneId);
311  bool updatePheromone = (meanVehiclesSpeed > -1);
312  // double pheroAdd = getSensors()->countVehicles(laneId);
313 
314  //derivative
315  double derivative = 0;
316  //If i need to use the derivative for the lane
317  if (m_meanSpeedHistory.find(laneId) != m_meanSpeedHistory.end()) {
318  //Update the derivative
319  if (updatePheromone) {
320  double currentDerivative = 0;
321  m_losCounter = 0;
322  if (m_meanSpeedHistory[laneId]->size() > 0) {
323  //Calculate the current derivative mean with the old speed points
324  for (int i = 0; i < m_meanSpeedHistory[laneId]->size(); ++i)
325  if (i == 0) {
326  currentDerivative += fabs(meanVehiclesSpeed - m_meanSpeedHistory[laneId]->at(i));
327  } else {
328  currentDerivative += fabs(m_meanSpeedHistory[laneId]->at(i - 1) - m_meanSpeedHistory[laneId]->at(i));
329  }
330  currentDerivative /= m_meanSpeedHistory[laneId]->size(); //Non weighted mean
331  }
332  m_meanSpeedHistory[laneId]->push_front(meanVehiclesSpeed);
333  //Check if the current value of the derivative is above the set alpha
334  if (currentDerivative >= m_derivativeAlpha) {
335  m_derivativeHistory[laneId]->push_front(currentDerivative);
336  }
337  if (m_derivativeHistory[laneId]->size() > 0) {
338  //Calculate the mean derivative with the old derivative
339  for (int i = 0; i < m_derivativeHistory[laneId]->size(); ++i) {
340  derivative += m_derivativeHistory[laneId]->at(i);
341  }
342  derivative /= m_derivativeHistory[laneId]->size();
343  }
344  } else {
345  //Reset the values if no information is received after a timeout
346  ++m_losCounter;
347  if (m_losCounter >= m_losMaxLimit) {
348  m_derivativeHistory[laneId]->clear();
349  m_meanSpeedHistory[laneId]->clear();
350  m_meanSpeedHistory[laneId]->push_front(maxSpeed);
351  }
352  }
353  }
354  double pheroAdd = MAX2((maxSpeed - meanVehiclesSpeed) * 10 / maxSpeed, 0.0);
355 // Use the derivative only if it has a value
356  if (derivative > 0)
357 // Correct the pheromone value by dividing it for the derivative.
358  {
359  pheroAdd /= MAX2(derivative, m_derivativeAlpha);
360  }
361 // pheroAdd /= max(derivative, 1.0);
362  ANALYSIS_DBG(
363  if (updatePheromone) {
364  std::ostringstream oss;
365  oss << time2string(MSNet::getInstance()->getCurrentTimeStep()) << " l " << laneId;
366  oss << " der " << derivative << " phero " << pheroAdd << " maxS " << maxSpeed << " meanS " << meanVehiclesSpeed;
367  WRITE_MESSAGE(oss.str())
368  }
369  )
370 
371  // Evaporation + current contribute
372  double phero = beta * oldPhero + gamma * pheroAdd * updatePheromone;
373  ANALYSIS_DBG(
374  if (phero > 10) {
375  std::ostringstream i_str;
376  i_str << "MSSwarmTrafficLightLogic::updatePheromoneLevels " << logString << " > 10. Value: " << phero;
377  WRITE_MESSAGE(i_str.str())
378  });
379 
380  phero = MIN2(MAX2(phero, 0.0), getPheroMaxVal());
381  pheroMap[laneId] = phero;
382  ANALYSIS_DBG(
383  // DBG(
384  std::ostringstream i_str;
385  // i_str << " oldPheroIn " << oldPheroIn
386  // << " inMeanVehiclesSpeed " << meanVehiclesSpeed
387  // << " pheroInAdd " << pheroAdd * updatePheromoneIn
388  // << " pheroInEvaporated " << oldPheroIn-oldPheroIn*getBetaNo()
389  // << " pheroInDeposited " << getGammaNo() * pheroAdd * updatePheromoneIn
390  // <<" newPheroIn "<<pheromoneInputLanes[laneId]
391  // << " inLane "<< laneId<<" ID "<< getID() <<" .";
392  i_str << " op " << oldPhero << " ms " << meanVehiclesSpeed << " p " << pheroAdd * updatePheromone <<
393  " pe " << oldPhero - oldPhero * beta << " pd " << gamma * pheroAdd * updatePheromone << " np " <<
394  pheroMap[laneId] << " l " << laneId << " ID " << getID() << " c " << getSensors()->countVehicles(laneId) << " s " << getLaneLightState(laneId) << " ."; if (m_pheroLevelLog[laneId] != i_str.str()) {
395  m_pheroLevelLog[laneId] = i_str.str();
396  WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::updatePheromoneLevels:: " + logString + i_str.str());
397  })
398 
399  DBG(
400  std::ostringstream str; str << time2string(MSNet::getInstance()->getCurrentTimeStep()) << " MSSwarmTrafficLightLogic::countSensors:: lane " << laneId << " passedVeh " << getCountSensors()->getPassedVeh(laneId, false); WRITE_MESSAGE(str.str());)
401 
402 // int vehicles = getSensors()->countVehicles(laneId);
403 // double pheroIn = getBetaNo() * oldPheroIn + // Evaporation
404 // getGammaNo() * vehicles;
405 // DBG(
406 // std::ostringstream i_str;
407 // i_str << " vehicles " << getSensors()->countVehicles(laneId)<<" pheromoneInputLanes "<<pheromoneInputLanes[laneId] << " lane "<< laneId<<" ID "<< getID() <<" .";
408 // MsgHandler::getMessageInstance()->inform(time2string(MSNet::getInstance()->getCurrentTimeStep()) +" MSSwarmTrafficLightLogic::updatePheromoneLevels:: PheroIn"+i_str.str());
409 // )
410 //
411 // pheroIn = MIN2(MAX2(pheroIn, 0.0), getPheroMaxVal());
412 // pheromoneInputLanes[laneId] = pheroIn;
413  }
414 }
416  double elapsedTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - lastThetaSensitivityUpdate);
418 
420  std::vector<MSSOTLPolicy*> policies = getPolicies();
421 
422  //reset of the sensitivity thresholds in case of 0 pheromone on the input lanes
423  if (getPheromoneForInputLanes() == 0) {
424  for (int i = 0; i < (int)policies.size(); i++) {
425  policies[i]->setThetaSensitivity(getThetaInit());
426 // ANALYSIS_DBG(
427  DBG(
428  std::ostringstream phero_str; phero_str << "Policy " << policies[i]->getName() << " sensitivity reset to " << policies[i]->getThetaSensitivity() << " due to evaporated input pheromone."; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::updateSensitivities::" + phero_str.str());)
429  }
430  return;
431  }
432 
433  double eta = -1.;
434  // If skipEta it means that we've had Congestion for too much time. Forcing forgetting.
435  if (!skipEta || currentPolicy->getName().compare("Congestion") != 0) {
436  switch (getReinforcementMode()) {
437  case 0:
438  if (elapsedTime == STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())) {
439  return; //we don't want to reinforce the policy selected at the beginning of the simulation since it's time-based
440  }
441  eta = elapsedTime;
442  break;
443  case 1:
444  eta = calculateEtaDiff();
445  break;
446  case 2:
447  eta = calculateEtaRatio();
448  break;
449  }
450  }
451  for (int i = 0; i < (int)policies.size(); i++) {
452  MSSOTLPolicy* policy = policies[i];
453  double newSensitivity;
454  if (eta < 0) { //bad performance
455  if (policy == currentPolicy) { // punish the current policy
456  newSensitivity = policy->getThetaSensitivity() + getForgettingCox() * (-eta);
457  } else
458  // reward the other ones
459  {
460  newSensitivity = policy->getThetaSensitivity() - getLearningCox() * (-eta);
461  }
462  } else { //good performance
463  if (policy == currentPolicy) { //reward the current policy
464  newSensitivity = policy->getThetaSensitivity() - getLearningCox() * eta;
465  } else
466  // punish the other ones
467  {
468  newSensitivity = policy->getThetaSensitivity() + getForgettingCox() * eta;
469  }
470  }
471 // ANALYSIS_DBG(
472  DBG(
473  std::ostringstream lf; std::ostringstream phero_str; if (getReinforcementMode() == 0) {
474  if (policy == currentPolicy) {
475  lf << " ,LearningCox " << getLearningCox() << " ,LCox*Time " << getLearningCox() * elapsedTime;
476  } else {
477  lf << " ,ForgettingCox " << getForgettingCox() << " ,FCox*Time " << getForgettingCox() * elapsedTime;
478  }
479 
480  phero_str << " policy " << policy->getName() << " newSensitivity " << newSensitivity << " ,pol.Sensitivity " << policy->getThetaSensitivity() << " ,elapsedTime " << elapsedTime << lf.str() << " NEWERSensitivity= " << max(min(newSensitivity, getThetaMax()), getThetaMin()) << " ID " << getID() << " .";
481  } else {
482  if (policy == currentPolicy && eta > 0) {
483  lf << " ,LearningCox " << getLearningCox() << " ,LCox*Eta " << getLearningCox() * eta;
484  } else if (policy == currentPolicy && eta < 0) {
485  lf << " ,ForgettingCox " << getForgettingCox() << " ,FCox*Eta " << getForgettingCox() * eta;
486  } else if (eta > 0) {
487  lf << " ,ForgettingCox " << getForgettingCox() << " ,FCox*Eta " << getForgettingCox() * eta;
488  } else if (eta < 0) {
489  lf << " ,LearningCox " << getLearningCox() << " ,LCox*Eta " << getLearningCox() * eta;
490  }
491  phero_str << " policy " << policy->getName() << " newSensitivity " << newSensitivity << " ,pol.Sensitivity " << policy->getThetaSensitivity() << " ,eta " << eta << " ,carsIn " << carsIn << " ,inTarget " << inTarget << " ,notTarget " << notTarget << " ,carsOut " << carsOut << lf.str() << " NEWERSensitivity= " << max(min(newSensitivity, getThetaMax()), getThetaMin()) << " ID " << getID() << " .";
492  }
493  WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::updateSensitivities::" + phero_str.str());)
494 
495  newSensitivity = MAX2(MIN2(newSensitivity, getThetaMax()), getThetaMin());
496  policy->setThetaSensitivity(newSensitivity);
497  }
498 }
499 
501  if (pheromoneInputLanes.size() == 0) {
502  return 0;
503  }
504  double pheroIn = 0;
505  for (MSLaneId_PheromoneMap::const_iterator iterator = pheromoneInputLanes.begin();
506  iterator != pheromoneInputLanes.end(); iterator++) {
507  std::string laneId = iterator->first;
508  pheroIn += iterator->second;
509  DBG(
510  std::ostringstream phero_str; phero_str << " lane " << iterator->first << " pheromoneIN " << iterator->second << " id " << getID() << " ."; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::getPheromoneForInputLanes::" + phero_str.str());)
511  }
512 
513  DBG(
514  std::ostringstream o_str; o_str << " TOTpheromoneIN " << pheroIn << " return " << pheroIn / pheromoneInputLanes.size() << getID() << " ."; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::getPheromoneForInputLanes::" + o_str.str());)
515  return pheroIn / pheromoneInputLanes.size();
516 }
517 
519  if (pheromoneOutputLanes.size() == 0) {
520  return 0;
521  }
522  double pheroOut = 0;
523  for (MSLaneId_PheromoneMap::const_iterator iterator = pheromoneOutputLanes.begin();
524  iterator != pheromoneOutputLanes.end(); iterator++) {
525  DBG(
526  std::ostringstream phero_str; phero_str << " lane " << iterator->first << " pheromoneOUT " << iterator->second << " id " << getID() << " ."; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::getPheromoneForOutputLanes::" + phero_str.str());)
527  pheroOut += iterator->second;
528  }
529  DBG(
530  std::ostringstream o_str; o_str << " TOTpheromoneOUT " << pheroOut << " return " << pheroOut / pheromoneOutputLanes.size() << " id " << getID() << " ."; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::getPheromoneForOutputLanes::" + o_str.str());)
531  return pheroOut / pheromoneOutputLanes.size();
532 }
533 
535  if (pheromoneInputLanes.size() == 0) {
536  return 0;
537  }
538  double sum = 0;
539  for (MSLaneId_PheromoneMap::const_iterator iterator = pheromoneInputLanes.begin();
540  iterator != pheromoneInputLanes.end(); iterator++) {
541  std::string laneId = iterator->first;
542  sum += pow(iterator->second - average_phero_in, 2);
543  }
544 
545  double result = sqrt(sum / pheromoneInputLanes.size()) * getScaleFactorDispersionIn();
546  DBG(
547  ostringstream so_str; so_str << " dispersionIn " << result; WRITE_MESSAGE("MSSwarmTrafficLightLogic::getDispersionForInputLanes::" + so_str.str());)
548  return result;
549 }
550 
552  if (pheromoneOutputLanes.size() == 0) {
553  return 0;
554  }
555  double sum = 0;
556  for (MSLaneId_PheromoneMap::const_iterator iterator = pheromoneOutputLanes.begin();
557  iterator != pheromoneOutputLanes.end(); iterator++) {
558  sum += pow(iterator->second - average_phero_out, 2);
559  }
560 
561  double result = sqrt(sum / pheromoneOutputLanes.size()) * getScaleFactorDispersionOut();
562  DBG(
563  ostringstream so_str; so_str << " dispersionOut " << result; WRITE_MESSAGE("MSSwarmTrafficLightLogic::getDispersionForOutputLanes::" + so_str.str());)
564  return result;
565 }
567  if (pheromoneInputLanes.size() == 0) {
568  return 0;
569  }
570  double max_phero_val_current = 0;
571  double max_phero_val_old = 0;
572  double temp_avg_other_lanes = 0;
573  std::string laneId_max;
574  int counter = 0;
575  for (MSLaneId_PheromoneMap::const_iterator iterator = pheromoneInputLanes.begin();
576  iterator != pheromoneInputLanes.end(); iterator++) {
577  std::string laneId = iterator->first;
578  double lanePhero = iterator->second;
579  if (counter == 0) {
580  max_phero_val_current = lanePhero;
581  counter++;
582  continue;
583  }
584  if (lanePhero > max_phero_val_current) {
585  max_phero_val_old = max_phero_val_current;
586  max_phero_val_current = lanePhero;
587  temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + max_phero_val_old) / counter;
588  } else {
589  temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + lanePhero) / counter;
590  }
591 
592  counter++;
593  }
594 
595  double result = max_phero_val_current - temp_avg_other_lanes;
596  DBG(
597  ostringstream so_str; so_str << " currentMaxPhero " << max_phero_val_current << " lane " << laneId_max << " avgOtherLanes " << temp_avg_other_lanes << " distance " << result; WRITE_MESSAGE("MSSwarmTrafficLightLogic::getDistanceOfMaxPheroForInputLanes::" + so_str.str());)
598  return result;
599 }
600 
602  if (pheromoneOutputLanes.size() == 0) {
603  return 0;
604  }
605  double max_phero_val_current = 0;
606  double max_phero_val_old = 0;
607  double temp_avg_other_lanes = 0;
608  std::string laneId_max;
609  int counter = 0;
610  for (MSLaneId_PheromoneMap::const_iterator iterator = pheromoneOutputLanes.begin();
611  iterator != pheromoneOutputLanes.end(); iterator++) {
612  std::string laneId = iterator->first;
613  double lanePhero = iterator->second;
614  if (counter == 0) {
615  max_phero_val_current = lanePhero;
616  counter++;
617  continue;
618  }
619  if (lanePhero > max_phero_val_current) {
620  max_phero_val_old = max_phero_val_current;
621  max_phero_val_current = lanePhero;
622  temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + max_phero_val_old) / counter;
623  } else {
624  temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + lanePhero) / counter;
625  }
626 
627  counter++;
628  }
629 
630  double result = max_phero_val_current - temp_avg_other_lanes;
631  DBG(
632  ostringstream so_str; so_str << " currentMaxPhero " << max_phero_val_current << " lane " << laneId_max << " avgOtherLanes " << temp_avg_other_lanes << " distance " << result; WRITE_MESSAGE("MSSwarmTrafficLightLogic::getDistanceOfMaxPheroForOutputLanes::" + so_str.str());)
633  return result;
634 }
636 // MSSOTLPolicy* currentPolicy = getCurrentPolicy();
637  // Decide if it is the case to check for another plan
638 // double sampled = (double) RandHelper::rand(RAND_MAX);
639  double sampled = RandHelper::rand();
640  double changeProb = getChangePlanProbability();
641 // changeProb = changeProb * RAND_MAX;
642 
643  if (sampled <= changeProb || mustChange) { // Check for another plan
644 
645  double pheroIn = getPheromoneForInputLanes();
646  double pheroOut = getPheromoneForOutputLanes();
647  //double dispersionIn = getDispersionForInputLanes(pheroIn);
648  //double dispersionOut = getDispersionForOutputLanes(pheroOut);
649  double distancePheroIn = getDistanceOfMaxPheroForInputLanes();
650  double distancePheroOut = getDistanceOfMaxPheroForOutputLanes();
651  MSSOTLPolicy* oldPolicy = getCurrentPolicy();
652  choosePolicy(pheroIn, pheroOut, distancePheroIn, distancePheroOut);
653  MSSOTLPolicy* newPolicy = getCurrentPolicy();
654 
655  if (newPolicy != oldPolicy) {
656  ANALYSIS_DBG(
657  SUMOTime step = MSNet::getInstance()->getCurrentTimeStep(); std::ostringstream phero_str; phero_str << " (pheroIn= " << pheroIn << " ,pheroOut= " << pheroOut << " )"; WRITE_MESSAGE("TL " + getID() + " time " + time2string(step) + " Policy: " + newPolicy->getName() + phero_str.str() + " OldPolicy: " + oldPolicy->getName() + " id " + getID() + " .");)
658  if (oldPolicy->getName().compare("Congestion") == 0) {
659  congestion_steps = 0;
660  }
661  } else { //debug purpose only
662  ANALYSIS_DBG(
663  std::ostringstream phero_str; phero_str << " (pheroIn= " << pheroIn << " ,pheroOut= " << pheroOut << " )"; SUMOTime step = MSNet::getInstance()->getCurrentTimeStep(); WRITE_MESSAGE("TL " + getID() + " time " + time2string(step) + " Policy: Nochanges" + phero_str.str() + " OldPolicy: " + oldPolicy->getName() + " id " + getID() + " .");)
664  }
665 
666  mustChange = false;
667  skipEta = false;
668  }
669 }
670 
672  if (factor == 0) {
673  return 1;
674  }
675  if (factor == 1) {
676  return 0.2;
677  } else {
678  return 1 - (1 / ((double) factor));
679  }
680 }
681 
683 
684  MSLane* currentLane = NULL;
685  int count = 0, minIn = 0, minOut = 0, toSub, tmp;
686  bool inInit = true, outInit = true;
687  double eta, normalized, diff, phi, delta;
688  LaneIdVector toReset;
689 
690  carsIn = 0;
691  carsOut = 0;
692  inTarget = 0;
693  notTarget = 0;
694 
696 
697  // Search the incoming lane to get the count of the vehicles passed. [IN]
698  for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector = myLanes.begin();
699  laneVector != myLanes.end(); laneVector++) {
700  for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
701  lane++) {
702  currentLane = (*lane);
703 
704  // Map to avoid check the lane for every possible direction
705  if (laneCheck[currentLane] == false) {
706  // Get the vehicles passed from this lane.
707  count = sensors->getPassedVeh(currentLane->getID(), false);
708 
709  DBG(
710  std::ostringstream cars_str; cars_str << "Lane " << currentLane->getID() << ": vehicles entered - " << count; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
711 
712  // Increment the global count of the cars passed through the tl
713  carsIn += count;
714  // Set to true to skip similar lane since there's just one sensor
715  laneCheck[currentLane] = true;
716  }
717  }
718  }
719 
720  // Search the outgoing lane to get the count of the vehicles passed. [OUT]
721  // We use the links to get the respective lane id.
722  for (MSTrafficLightLogic::LinkVectorVector::const_iterator linkVector = myLinks.begin();
723  linkVector != myLinks.end(); linkVector++) {
724  for (MSTrafficLightLogic::LinkVector::const_iterator link = linkVector->begin(); link != linkVector->end();
725  link++) {
726  currentLane = (*link)->getLane();
727 
728  // Map to avoid check the lane for every possible direction
729  if (laneCheck[currentLane] == false) {
730  // Get the vehicles passed from this lane.
731  count = sensors->getPassedVeh(currentLane->getID(), true);
732 
733  DBG(
734  std::ostringstream cars_str; cars_str << "Lane " << currentLane->getID() << ": vehicles gone out- " << count; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
735 
736  // Increment the global count of the cars passed through the tl
737  carsOut += count;
738 
739  // Since there's no output target lanes we check here the minimum number of
740  // cars passed though the tl. This ahs to be done to all the output lanes since cars can go
741  // in any direction from a target lane. If a direction isn't reachable the sensor count will be 0.
742  // This is done to update the sensorCount value in order to don't make it grow too much.
743  if (count != 0) {
744  toReset.push_back(currentLane->getID());
745  if (outInit) {
746  minOut = count;
747  outInit = false;
748  } else if (count <= minOut) {
749  minOut = count;
750  }
751  }
752  // Set to true to skip similar lane since there's just one sensor
753  laneCheck[currentLane] = true;
754  }
755  }
756  }
757  // Reset the map to check again all the lane on the next commit.
758  resetLaneCheck();
759 
760  // We retrieve the minimum number of cars passed from the target lanes.
761  for (LaneIdVector::const_iterator laneId = targetLanes.begin(); laneId < targetLanes.end(); laneId++) {
762  std::string lane = (*laneId);
763  tmp = sensors->getPassedVeh(lane, false);
764  inTarget += tmp;
765  if (inInit && tmp != 0) {
766  minIn = tmp;
767  inInit = false;
768  }
769  if (tmp < minIn && tmp != 0) {
770  minIn = tmp;
771  }
772  if (tmp != 0) {
773  toReset.push_back(lane);
774  }
775  DBG(
776  std::ostringstream cars_str; cars_str << "Lane " << lane << " passed: " << tmp; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
777  }
778 
779  // The cars not on a target lane counted as in.
781 
782  // Calculate the min beetween the min number of cars entered the tl (minIn) and the
783  // ones that have exit the tl (minOut)
784  toSub = std::min(minIn, minOut);
785 
786  // Subtract the value to all the sensor on the target lanes.
787  while (!toReset.empty()) {
788  std::string laneId = toReset.back();
789  toReset.pop_back();
790  sensors->subtractPassedVeh(laneId, toSub);
791  }
792 
793  //Normalized to 1
794  diff = inTarget - carsOut;
795  normalized = diff / inTarget;
796 
797  // Analize difference to return an appropriate eta to reinforce/forget the policies.
798 
799  DBG(
800  std::ostringstream final_str; final_str << "Total cars in lanes: " << carsIn << " Total cars out: " << carsOut << " Difference: " << diff << " Pure eta: " << normalized; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + final_str.str());)
801  DBG(
802  std::ostringstream eta_str; eta_str << "IN:" << inTarget << " OUT:" << carsOut << " R:" << notTarget; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + eta_str.str());)
803  DBG(
804  std::ostringstream eta_str; eta_str << "Min found:" << toSub << " MinIn:" << minIn << " MinOut:" << minOut; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + eta_str.str());)
805 
806  // IN > OUT
807  if (inTarget > carsOut) {
808  if (carsOut == 0) {
809  // We're in Congestion but not for long so we don't do nothing. When we reach max steps for
810  // Congestion the evaluation of eta is skipped and we force a forget of the policy
811  if (getCurrentPolicy()->getName().compare("Congestion") == 0) {
812  eta = 0;
813  }
814  // vehicles aren't going out and we've additional vehicle on a red lane. We set
815  // eta to -1 to forget
816  else {
817  eta = -1;
818  }
819  } else {
820  // Forget - Amplify to R
821  phi = calculatePhi(notTarget);
822  eta = (-normalized * (1 / phi));
823  if (eta < -1.0) {
824  eta = -1.0;
825  }
826  }
827  }
828 
829  // IN = OUT
830  else if (inTarget == carsOut) {
831  // Can't say nothing
832  if (inTarget == 0) {
833  eta = 0;
834  }
835 
836  // Reinforce - Attenuate to R
837  // Normalized = 0 --> use delta = 1-1/IN
838  else {
839  delta = calculatePhi(inTarget);
840  phi = calculatePhi(notTarget);
841  eta = delta * phi;
842  if (eta > 1.0) {
843  eta = 1.0;
844  }
845  }
846  }
847 
848  // IN < OUT
849  else {
850  // Can't say nothing
851  if (inTarget == 0) {
852  eta = 0;
853  }
854 
855  // Reinforce - Attenuate to R
856  else {
857  phi = calculatePhi(notTarget);
858  diff = inTarget - carsOut;
859  normalized = diff / carsOut;
860  eta = normalized * phi;
861  if (eta > 1.0) {
862  eta = 1.0;
863  }
864  }
865  }
866 
867  DBG(
868  std::ostringstream eta_str; eta_str << "Eta Normalized: " << eta; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + eta_str.str());)
869  return eta;
870 }
871 
873  MSLane* currentLane = NULL;
874  int count = 0, minIn = 0, minOut = 0, toSub, tmp;
875  bool inInit = true, outInit = true;
876  double eta, ratio, phi, normalized, delta;
877  LaneIdVector toReset;
878 
879  carsIn = 0;
880  carsOut = 0;
881  inTarget = 0;
882  notTarget = 0;
883 
885 
886  // Search the incoming lane to get the count of the vehicles passed. [IN]
887  for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector = myLanes.begin();
888  laneVector != myLanes.end(); laneVector++) {
889  for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
890  lane++) {
891  currentLane = (*lane);
892 
893  // Map to avoid check the lane for every possible direction
894  if (laneCheck[currentLane] == false) {
895  // Get the vehicles passed from this lane.
896  count = sensors->getPassedVeh(currentLane->getID(), false);
897 
898  DBG(
899  std::ostringstream cars_str; cars_str << "Lane " << currentLane->getID() << ": vehicles entered - " << count; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
900 
901  // Increment the global count of the cars passed through the tl
902  carsIn += count;
903  // Set to true to skip similar lane since there's just one sensor
904  laneCheck[currentLane] = true;
905  }
906  }
907  }
908 
909  // Search the outgoing lane to get the count of the vehicles passed. [OUT]
910  // We use the links to get the respective lane id.
911  for (MSTrafficLightLogic::LinkVectorVector::const_iterator linkVector = myLinks.begin();
912  linkVector != myLinks.end(); linkVector++) {
913  for (MSTrafficLightLogic::LinkVector::const_iterator link = linkVector->begin(); link != linkVector->end();
914  link++) {
915  currentLane = (*link)->getLane();
916 
917  // Map to avoid check the lane for every possible direction
918  if (laneCheck[currentLane] == false) {
919  // Get the vehicles passed from this lane.
920  count = sensors->getPassedVeh(currentLane->getID(), true);
921 
922  DBG(
923  std::ostringstream cars_str; cars_str << "Lane " << currentLane->getID() << ": vehicles gone out- " << count; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
924 
925  // Increment the global count of the cars passed through the tl
926  carsOut += count;
927 
928  // Since there's no output target lanes we check here the minimum number of
929  // cars passed though the tl. This has to be done to all the output lanes since cars can go
930  // in any direction from a target lane. If a direction isn't reachable the sensor count will be 0.
931  // This is done to update the sensorCount value in order to don't make it grow too much.
932  if (count != 0) {
933  toReset.push_back(currentLane->getID());
934  if (outInit) {
935  minOut = count;
936  outInit = false;
937  } else if (count <= minOut) {
938  minOut = count;
939  }
940  }
941 
942  // Set to true to skip similar lane since there's just one sensor
943  laneCheck[currentLane] = true;
944  }
945  }
946  }
947  // Reset the map to check again all the lane on the next commit.
948  resetLaneCheck();
949 
950  // We retrieve the minimum number of cars passed from the target lanes.
951  for (LaneIdVector::const_iterator laneId = targetLanes.begin(); laneId < targetLanes.end(); laneId++) {
952  std::string lane = (*laneId);
953  tmp = sensors->getPassedVeh(lane, false);
954  inTarget += tmp;
955  if (inInit && tmp != 0) {
956  minIn = tmp;
957  inInit = false;
958  }
959  if (tmp < minIn && tmp != 0) {
960  minIn = tmp;
961  }
962  if (tmp != 0) {
963  toReset.push_back(lane);
964  }
965  DBG(
966  std::ostringstream cars_str; cars_str << "Lane " << lane << " passed: " << tmp; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
967  }
968 
969  // The cars not on a target lane counted as in.
971 
972  // Calculate the min beetween the min number of cars entered the tl (minIn) and the
973  // ones that have exit the tl (minOut)
974  toSub = std::min(minIn, minOut);
975 
976  // Subtract the value to all the sensor on the target lanes.
977  while (!toReset.empty()) {
978  std::string laneId = toReset.back();
979  toReset.pop_back();
980  sensors->subtractPassedVeh(laneId, toSub);
981  }
982 
983  //Normalized to 1
984  if (carsOut != 0) {
985  ratio = ((double) inTarget) / carsOut;
986  normalized = ratio / (inTarget + carsOut);
987  } else {
988  ratio = std::numeric_limits<double>::infinity();
989  normalized = std::numeric_limits<double>::infinity();
990  }
991 
992  DBG(
993  std::ostringstream final_str; final_str << "Total cars in lanes: " << carsIn << " Total cars out: " << carsOut << " Ratio: " << ratio << " Pure eta: " << normalized; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + final_str.str());)
994  DBG(
995  std::ostringstream eta_str; eta_str << "IN:" << inTarget << ". OUT:" << carsOut << " R:" << notTarget; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + eta_str.str());)
996  DBG(
997  std::ostringstream eta_str; eta_str << "Min found:" << toSub << ". MinIn:" << minIn << " MinOut:" << minOut; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + eta_str.str());)
998  // Analize ratio to return an appropriate eta to reinforce/forget the policies.
999 
1000  // IN > OUT
1001  if (inTarget > carsOut) {
1002  if (carsOut == 0) {
1003  // we're in Congestion but not for long so we don't do nothing. When we reach max steps for
1004  // Congestion the evaluation of eta is skipped and we force a forget of the policy
1005  if (getCurrentPolicy()->getName().compare("Congestion") == 0) {
1006  eta = 0;
1007  }
1008  // vehicles aren't going out and we've additional vehicle on a red lane. We set
1009  // eta to -1 to forget
1010  else {
1011  eta = -1;
1012  }
1013  } else {
1014  // Forget according to the ratio. Amplify due to the cars in the red lanes
1015  phi = calculatePhi(notTarget);
1016  eta = (-(normalized) * (1 / phi));
1017  if (eta < -1.0) {
1018  eta = -1.0;
1019  }
1020  }
1021  }
1022  // IN = OUT
1023  else if (inTarget == carsOut) {
1024  // We can't say nothing.
1025  if (inTarget == 0) {
1026  eta = 0;
1027  }
1028  // Reinforce - Attenuate to R
1029  // same number of vehicles that are getting IN is getting OUT
1030  // Normalized = 1/TOT ---> change to delta = 1-1/IN
1031  else {
1032  delta = calculatePhi(inTarget);
1033  phi = calculatePhi(notTarget);
1034  eta = delta * phi;
1035  if (eta > 1.0) {
1036  eta = 1.0;
1037  }
1038  }
1039  }
1040  // IN < OUT
1041  else {
1042  // We can't say nothing.
1043  if (inTarget == 0) {
1044  eta = 0;
1045  }
1046 
1047  // There was a queue and now cars are getting over it
1048  // There're vehicles on the red lanes (R)
1049  // We reinforce and attenuate according to R
1050  else {
1051  phi = calculatePhi(notTarget);
1052  eta = (normalized) * phi;
1053  if (eta > 1.0) {
1054  eta = 1.0;
1055  }
1056  }
1057  }
1058 
1059  DBG(
1060  std::ostringstream eta_str; eta_str << "Eta Normalized: " << eta << "."; WRITE_MESSAGE(time2string(MSNet::getInstance()->getCurrentTimeStep()) + " MSSwarmTrafficLightLogic::calculateEta::" + eta_str.str());)
1061  return eta;
1062 
1063 }
1064 
1066 
1067  MSLane* currentLane = NULL;
1068 
1069  // reset both the input and the output lanes.
1070  for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector = myLanes.begin();
1071  laneVector != myLanes.end(); laneVector++) {
1072 
1073  for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
1074  lane++) {
1075  currentLane = (*lane);
1076  laneCheck[currentLane] = false;
1077  }
1078  }
1079 
1080  for (MSTrafficLightLogic::LinkVectorVector::const_iterator linkVector = myLinks.begin();
1081  linkVector != myLinks.end(); linkVector++) {
1082  for (MSTrafficLightLogic::LinkVector::const_iterator link = linkVector->begin(); link != linkVector->end();
1083  link++) {
1084  currentLane = (*link)->getLane();
1085  laneCheck[currentLane] = false;
1086  }
1087  }
1088 }
1089 
1090 void MSSwarmTrafficLightLogic::choosePolicy(double phero_in, double phero_out, double dispersion_in,
1091  double dispersion_out) {
1093  for (std::vector<MSSOTLPolicy*>::iterator it = getPolicies().begin(); it != getPolicies().end(); ++it) {
1094  if (it.operator * ()->getName() == "Phase") {
1095  activate(*it);
1096  return;
1097  }
1098  }
1099  }
1100  std::vector<double> thetaStimuli;
1101  double thetaSum = 0.0;
1102  // Compute stimulus for each policy
1103  for (int i = 0; i < (int)getPolicies().size(); i++) {
1104  double stimulus = getPolicies()[i]->computeDesirability(phero_in, phero_out, dispersion_in, dispersion_out);
1105  double thetaStimulus = pow(stimulus, 2) / (pow(stimulus, 2) + pow(getPolicies()[i]->getThetaSensitivity(), 2));
1106 
1107  thetaStimuli.push_back(thetaStimulus);
1108  thetaSum += thetaStimulus;
1109 
1110 // ANALYSIS_DBG(
1111  DBG(
1112  ostringstream so_str; so_str << " policy " << getPolicies()[i]->getName() << " stimulus " << stimulus << " pow(stimulus,2) " << pow(stimulus, 2) << " pow(Threshold,2) " << pow(getPolicies()[i]->getThetaSensitivity(), 2) << " thetaStimulus " << thetaStimulus << " thetaSum " << thetaSum << " TL " << getID(); WRITE_MESSAGE("MSSwarmTrafficLightLogic::choosePolicy::" + so_str.str());)
1113 
1114  }
1115 
1116  // Compute a random value between 0 and the sum of the thetaSum
1117 // double r = RandHelper::rand(RAND_MAX);
1118 // r = r / RAND_MAX * thetaSum;
1119  double r = RandHelper::rand((double)thetaSum);
1120 
1121  double partialSum = 0;
1122  for (int i = 0; i < (int)getPolicies().size(); i++) {
1123  partialSum += thetaStimuli[i];
1124 
1125 // ANALYSIS_DBG(
1126  DBG(
1127  ostringstream aao_str; aao_str << " policy " << getPolicies()[i]->getName() << " partialSum " << partialSum << " thetaStimuls " << thetaStimuli[i] << " r " << r << " TL " << getID(); WRITE_MESSAGE("MSSwarmTrafficLightLogic::choosePolicy::" + aao_str.str());)
1128 
1129  if (partialSum >= r) {
1130  activate(getPolicies()[i]);
1131  break;
1132  }
1133  }
1134 }
1135 
1136 void MSSwarmTrafficLightLogic::choosePolicy(double phero_in, double phero_out) {
1137  choosePolicy(phero_in, phero_out, 0, 0);
1138 }
1139 
1140 //never called...
1142  DBG(
1143  std::ostringstream phero_str; phero_str << "getCurrentPhaseElapsed()=" << time2string(getCurrentPhaseElapsed()) << " isThresholdPassed()=" << isThresholdPassed() << " currentPhase=" << (&getCurrentPhaseDef())->getState() << " countVehicles()=" << countVehicles(getCurrentPhaseDef()); WRITE_MESSAGE("MSSwamTrafficLightLogic::canRelease(): " + phero_str.str());)
1146 }
1147 
1148 std::string MSSwarmTrafficLightLogic::getLaneLightState(const std::string& laneId) {
1149  std::string laneState = "";
1150  if (m_laneIndexMap.find(laneId) != m_laneIndexMap.end()) {
1151  std::string state = getCurrentPhaseDef().getState();
1152  for (std::vector<int>::const_iterator it = m_laneIndexMap[laneId].begin(); it != m_laneIndexMap[laneId].end(); ++it) {
1153  laneState += state[*it];
1154  }
1155  }
1156  return laneState;
1157 }
std::map< std::string, double > MSLaneId_PheromoneMap
void initScaleFactorDispersionOut(int lanes_out)
virtual std::string getMessage()=0
const std::string & getState() const
Returns the state within this phase.
Builds detectors for microsim.
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:607
is a pedestrian
Class for low-level platoon policy.
MSSwarmTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &subid, const Phases &phases, int step, SUMOTime delay, const std::map< std::string, std::string > &parameters)
Constructor without sensors passed.
vehicle is a bicycle
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:64
#define ANALYSIS_DBG(X)
bool allowLine(MSLane *)
Check if a lane is allowed to be added to the maps pheromoneInputLanes and pheromoneOutputLanes Contr...
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
Class for low-level marching policy.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
T MAX2(T a, T b)
Definition: StdDefs.h:73
void init(NLDetectorBuilder &nb)
Initialises the tls.
virtual int decideNextPhase(SUMOTime elapsed, const MSPhaseDefinition *stage, int currentPhaseIndex, int phaseMaxCTS, bool thresholdPassed, bool pushButtonPressed, int vehicleCount)
void updatePheromoneLevels()
Update pheromone levels Pheromone on input lanes is costantly updated Pheromone follows a discrete-ti...
const std::string & getID() const
Returns the id.
Definition: Named.h:65
LaneIdVector targetLanes
A copy of the target lanes of this phase.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
virtual bool canRelease(SUMOTime elapsed, bool thresholdPassed, bool pushButtonPressed, const MSPhaseDefinition *stage, int vehicleCount)=0
A self-organizing high-level traffic light logic.
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index...
double calculatePhi(int factor)
Method that should calculate the valor of phi a coefficient to amplify/attenuate eta based on a facto...
A class that stores and controls tls and switching of their programs.
bool mustChange
When true, indicates that the current policy MUST be changed. It&#39;s used to force the exit from the co...
MSSOTLPolicyDesirability * getDesirabilityAlgorithm()
Definition: MSSOTLPolicy.h:127
std::vector< LinkVector > LinkVectorVector
Definition of a list that holds lists of links that do have the same attribute.
std::string getLaneLightState(const std::string &laneId)
MSSOTLE2Sensors * getCountSensors()
Return the sensors that count the passage of vehicles in and out of the tl.
std::pair< std::string, double > MSLaneId_Pheromone
double getDispersionForOutputLanes(double average_phero_out)
std::map< std::string, std::string > m_pheroLevelLog
int getPassedVeh(std::string laneId, bool out)
std::vector< MSSOTLPolicy * > & getPolicies()
Returns the vector of the low-level policies used by this high-level tll.
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
Definition: MSLane.h:505
#define STEPS2TIME(x)
Definition: SUMOTime.h:64
bool skipEta
When true indicates that we can skip the evaluation of eta since we&#39;ve a congestion policy that is la...
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
void decidePolicy()
Decide the current policy according to pheromone levels The decision reflects on currentPolicy value...
T MIN2(T a, T b)
Definition: StdDefs.h:67
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Definition: MsgHandler.cpp:57
std::map< std::string, CircularBuffer< double > *> m_meanSpeedHistory
#define DBG(X)
Definition: SwarmDebug.h:29
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:234
std::string getName()
Definition: MSSOTLPolicy.h:124
bool gotTargetLane
When true indicates that we&#39;ve already acquired the target lanes for this particular phase...
virtual void setThetaSensitivity(double val)
Definition: MSSOTLPolicy.h:121
MSLaneId_PheromoneMap pheromoneOutputLanes
This pheromone is an indicator of congestion on output lanes. Its levels refer to the average speed o...
virtual int countVehicles(MSLane *lane)=0
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
MSSOTLPolicy * getCurrentPolicy()
Returns the low-level policy currently selected by this high-level tll.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
virtual double meanVehiclesSpeed(MSLane *lane)=0
This class determines the desirability algorithm of a MSSOTLPolicy when used in combination with a hi...
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index...
virtual double getMaxSpeed(std::string laneId)=0
virtual double getThetaSensitivity()
Definition: MSSOTLPolicy.h:118
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:155
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
void init(NLDetectorBuilder &nb)
Initialises the tls with sensors on incoming and outgoing lanes Sensors are built in the simulation a...
int getCurrentPhaseIndex() const
Returns the current index within the program.
Class for low-level phase policy.
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:84
void choosePolicy(double phero_in, double phero_out, double dispersion_in, double dispersion_out)
static double _2double(const E *const data)
converts a char-type array into the double value described by it
Definition: TplConvert.h:311
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
MSLaneId_PheromoneMap pheromoneInputLanes
This pheronome is an indicator of congestion on input lanes. Its levels refer to the average speed of...
Class for a low-level policy.
Definition: MSSOTLPolicy.h:71
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:248
Class for low-level congestion policy.
long long int SUMOTime
Definition: TraCIDefs.h:51
const LaneIdVector & getTargetLaneSet() const
void subtractPassedVeh(std::string laneId, int passed)
void initScaleFactorDispersionIn(int lanes_in)
LaneCheckMap laneCheck
Map to check if a lane was already controlled during the elaboration of eta.
std::vector< std::string > LaneIdVector
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:200
double calculateEtaDiff()
Method that should calculate the valor of eta a coefficient to evaluate the current policy&#39;s work...
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
std::map< std::string, std::vector< int > > m_laneIndexMap
double getDispersionForInputLanes(double average_phero_in)
void resetPheromone()
Resets pheromone levels.
int countVehicles(MSPhaseDefinition phase)
std::map< std::string, CircularBuffer< double > *> m_derivativeHistory