SUMO - Simulation of Urban MObility
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 
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 
180  //Initializing thresholds for theta evaluations
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 }
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:571
long long int SUMOTime
Definition: SUMOTime.h:43
is a pedestrian
std::map< std::string, CircularBuffer< SUMOReal > *> m_derivativeHistory
#define min(a, b)
Definition: polyfonts.c:66
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
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
#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)
const std::string & getID() const
Returns the id.
Definition: Named.h:66
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...
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...
virtual void setThetaSensitivity(SUMOReal val)
Definition: MSSOTLPolicy.h:122
MSSOTLPolicyDesirability * getDesirabilityAlgorithm()
Definition: MSSOTLPolicy.h:128
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.
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.
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
Definition: MSLane.h:488
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
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:254
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
#define DBG(X)
Definition: SwarmDebug.h:30
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:259
std::string getName()
Definition: MSSOTLPolicy.h:125
bool gotTargetLane
When true indicates that we&#39;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 std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index...
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:149
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: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
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:264
Class for low-level congestion policy.
#define SUMOReal
Definition: config.h:213
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:201
SUMOReal calculateEtaDiff()
Method that should calculate the valor of eta a coefficient to evaluate the current policy&#39;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
void resetPheromone()
Resets pheromone levels.
int countVehicles(MSPhaseDefinition phase)