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