31 const std::string& programID,
const Phases& phases,
int step,
SUMOTime delay,
38 std::ostringstream str;
39 str <<
"policies: " << pols;
43 if (pols.find(
"platoon") != std::string::npos) {
46 if (pols.find(
"phase") != std::string::npos) {
49 if (pols.find(
"marching") != std::string::npos) {
52 if (pols.find(
"congestion") != std::string::npos) {
65 std::ostringstream d_str;
70 for (
int i = 0; i < policies.size(); i++) {
73 std::ostringstream _str;
81 WRITE_ERROR(
TL(
"VEHICLE TYPES WEIGHT only works with phase policy, which is missing"));
130 srand((
int) time(
nullptr));
133 MSLane* currentLane =
nullptr;
143 for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector =
myLanes.begin();
144 laneVector !=
myLanes.end(); laneVector++) {
145 for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
147 currentLane = (*lane);
156 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::init Intersection " +
getID() +
" pheromoneInputLanes adding " + currentLane->
getID());
160 WRITE_MESSAGEF(
TL(
"MSSwarmTrafficLightLogic::init Intersection % pheromoneInputLanes: lane % not allowed"),
getID(), currentLane->
getID());
169 for (
int i = 0; i < (int)links.size(); i++) {
171 for (
int j = 0; j < (int)oneLink.size(); j++) {
172 currentLane = oneLink[j]->getLane();
178 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::init Intersection " +
getID() +
" pheromoneOutputLanes adding " + currentLane->
getID());
182 WRITE_MESSAGEF(
TL(
"MSSwarmTrafficLightLogic::init Intersection % pheromoneOutputLanes lane % not allowed"),
getID(), currentLane->
getID());
196 logData = logFileName.compare(
"") != 0;
198 swarmLogFile.open(logFileName.c_str(), std::ios::out | std::ios::binary);
219 std::string laneId = laneIterator->first;
225 std::string laneId = laneIterator->first;
234 std::ostringstream dnp;
262 std::ostringstream dnp;
300 std::ostringstream str;
328 const double beta,
const double gamma) {
331 std::ostringstream _str;
332 _str << logString <<
" Lanes " << pheroMap.size() <<
" TL " <<
getID() <<
" .";
337 for (MSLaneId_PheromoneMap::iterator laneIterator = pheroMap.begin(); laneIterator != pheroMap.end();
339 std::string laneId = laneIterator->first;
340 double oldPhero = laneIterator->second;
343 bool updatePheromone = (meanVehiclesSpeed > -1);
347 double derivative = 0;
351 if (updatePheromone) {
352 double currentDerivative = 0;
386 double pheroAdd =
MAX2((maxSpeed - meanVehiclesSpeed) * 10 / maxSpeed, 0.0);
395 if (updatePheromone) {
396 std::ostringstream oss;
398 oss <<
" der " << derivative <<
" phero " << pheroAdd <<
" maxS " << maxSpeed <<
" meanS " << meanVehiclesSpeed;
404 double phero = beta * oldPhero + gamma * pheroAdd * updatePheromone;
407 std::ostringstream i_str;
408 i_str <<
"MSSwarmTrafficLightLogic::updatePheromoneLevels " << logString <<
" > 10. Value: " << phero;
413 pheroMap[laneId] = phero;
416 std::ostringstream i_str;
424 i_str <<
" op " << oldPhero <<
" ms " << meanVehiclesSpeed <<
" p " << pheroAdd* updatePheromone <<
425 " pe " << oldPhero - oldPhero* beta <<
" pd " << gamma* pheroAdd* updatePheromone <<
" np " <<
433 std::ostringstream str;
460 std::ostringstream phero_str;
461 phero_str <<
"Policy " << policy->getName() <<
" sensitivity reset to " << policy->getThetaSensitivity() <<
" due to evaporated input pheromone.";
487 double newSensitivity;
490 newSensitivity = policy->getThetaSensitivity() +
getForgettingCox() * (-eta);
494 newSensitivity = policy->getThetaSensitivity() -
getLearningCox() * (-eta);
498 newSensitivity = policy->getThetaSensitivity() -
getLearningCox() * eta;
507 std::ostringstream lf;
508 std::ostringstream phero_str;
510 if (policy == currentPolicy) {
516 phero_str <<
" policy " << policy->getName() <<
" newSensitivity " << newSensitivity <<
" ,pol.Sensitivity " << policy->getThetaSensitivity() <<
" ,elapsedTime " << elapsedTime << lf.str() <<
" NEWERSensitivity= " << max(min(newSensitivity,
getThetaMax()),
getThetaMin()) <<
" ID " <<
getID() <<
" .";
518 if (policy == currentPolicy && eta > 0) {
520 }
else if (policy == currentPolicy && eta < 0) {
522 }
else if (eta > 0) {
524 }
else if (eta < 0) {
527 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() <<
" .";
532 policy->setThetaSensitivity(newSensitivity);
543 std::string laneId = iterator->first;
544 pheroIn += iterator->second;
546 std::ostringstream phero_str;
547 phero_str <<
" lane " << iterator->first <<
" pheromoneIN " << iterator->second <<
" id " <<
getID() <<
" .";
553 std::ostringstream o_str;
568 std::ostringstream phero_str;
569 phero_str <<
" lane " << iterator->first <<
" pheromoneOUT " << iterator->second <<
" id " <<
getID() <<
" .";
572 pheroOut += iterator->second;
575 std::ostringstream o_str;
576 o_str <<
" TOTpheromoneOUT " << pheroOut <<
" return " << pheroOut /
pheromoneOutputLanes.size() <<
" id " <<
getID() <<
" .";
589 std::string laneId = iterator->first;
590 sum += pow(iterator->second - average_phero_in, 2);
595 ostringstream so_str;
596 so_str <<
" dispersionIn " << result;
597 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::getDispersionForInputLanes::" + so_str.str());
609 sum += pow(iterator->second - average_phero_out, 2);
614 ostringstream so_str;
615 so_str <<
" dispersionOut " << result;
616 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::getDispersionForOutputLanes::" + so_str.str());
624 double max_phero_val_current = 0;
625 double max_phero_val_old = 0;
626 double temp_avg_other_lanes = 0;
627 std::string laneId_max;
631 std::string laneId = iterator->first;
632 double lanePhero = iterator->second;
634 max_phero_val_current = lanePhero;
638 if (lanePhero > max_phero_val_current) {
639 max_phero_val_old = max_phero_val_current;
640 max_phero_val_current = lanePhero;
641 temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + max_phero_val_old) / counter;
643 temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + lanePhero) / counter;
649 double result = max_phero_val_current - temp_avg_other_lanes;
651 ostringstream so_str;
652 so_str <<
" currentMaxPhero " << max_phero_val_current <<
" lane " << laneId_max <<
" avgOtherLanes " << temp_avg_other_lanes <<
" distance " << result;
653 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::getDistanceOfMaxPheroForInputLanes::" + so_str.str());
662 double max_phero_val_current = 0;
663 double max_phero_val_old = 0;
664 double temp_avg_other_lanes = 0;
665 std::string laneId_max;
669 std::string laneId = iterator->first;
670 double lanePhero = iterator->second;
672 max_phero_val_current = lanePhero;
676 if (lanePhero > max_phero_val_current) {
677 max_phero_val_old = max_phero_val_current;
678 max_phero_val_current = lanePhero;
679 temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + max_phero_val_old) / counter;
681 temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + lanePhero) / counter;
687 double result = max_phero_val_current - temp_avg_other_lanes;
689 ostringstream so_str;
690 so_str <<
" currentMaxPhero " << max_phero_val_current <<
" lane " << laneId_max <<
" avgOtherLanes " << temp_avg_other_lanes <<
" distance " << result;
691 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::getDistanceOfMaxPheroForOutputLanes::" + so_str.str());
712 choosePolicy(pheroIn, pheroOut, distancePheroIn, distancePheroOut);
715 if (newPolicy != oldPolicy) {
718 std::ostringstream phero_str;
719 phero_str <<
" (pheroIn= " << pheroIn <<
" ,pheroOut= " << pheroOut <<
" )";
722 if (oldPolicy->
getName().compare(
"Congestion") == 0) {
727 std::ostringstream phero_str;
728 phero_str <<
" (pheroIn= " << pheroIn <<
" ,pheroOut= " << pheroOut <<
" )";
746 return 1 - (1 / ((double) factor));
752 MSLane* currentLane =
nullptr;
753 int count = 0, minIn = 0, minOut = 0, toSub, tmp;
754 bool inInit =
true, outInit =
true;
755 double eta, normalized, diff, phi, delta;
766 for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector =
myLanes.begin();
767 laneVector !=
myLanes.end(); laneVector++) {
768 for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
770 currentLane = (*lane);
778 std::ostringstream cars_str;
779 cars_str <<
"Lane " << currentLane->
getID() <<
": vehicles entered - " << count;
793 for (MSTrafficLightLogic::LinkVectorVector::const_iterator linkVector =
myLinks.begin();
794 linkVector !=
myLinks.end(); linkVector++) {
795 for (MSTrafficLightLogic::LinkVector::const_iterator link = linkVector->begin(); link != linkVector->end();
797 currentLane = (*link)->getLane();
805 std::ostringstream cars_str;
806 cars_str <<
"Lane " << currentLane->
getID() <<
": vehicles gone out- " << count;
818 toReset.push_back(currentLane->
getID());
822 }
else if (count <= minOut) {
836 std::string lane = (*laneId);
839 if (inInit && tmp != 0) {
843 if (tmp < minIn && tmp != 0) {
847 toReset.push_back(lane);
850 std::ostringstream cars_str;
851 cars_str <<
"Lane " << lane <<
" passed: " << tmp;
861 toSub = std::min(minIn, minOut);
864 while (!toReset.empty()) {
865 std::string laneId = toReset.back();
877 std::ostringstream final_str;
878 final_str <<
"Total cars in lanes: " <<
carsIn <<
" Total cars out: " <<
carsOut <<
" Difference: " << diff <<
" Pure eta: " << normalized;
880 std::ostringstream eta_str;
883 std::ostringstream eta_str;
884 eta_str <<
"Min found:" << toSub <<
" MinIn:" << minIn <<
" MinOut:" << minOut;
903 eta = (-normalized * (1 / phi));
941 eta = normalized * phi;
949 std::ostringstream eta_str;
950 eta_str <<
"Eta Normalized: " << eta;
957 MSLane* currentLane =
nullptr;
958 int count = 0, minIn = 0, minOut = 0, toSub, tmp;
959 bool inInit =
true, outInit =
true;
960 double eta, ratio, phi, normalized, delta;
971 for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector =
myLanes.begin();
972 laneVector !=
myLanes.end(); laneVector++) {
973 for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
975 currentLane = (*lane);
983 std::ostringstream cars_str;
984 cars_str <<
"Lane " << currentLane->
getID() <<
": vehicles entered - " << count;
998 for (MSTrafficLightLogic::LinkVectorVector::const_iterator linkVector =
myLinks.begin();
999 linkVector !=
myLinks.end(); linkVector++) {
1000 for (MSTrafficLightLogic::LinkVector::const_iterator link = linkVector->begin(); link != linkVector->end();
1002 currentLane = (*link)->getLane();
1010 std::ostringstream cars_str;
1011 cars_str <<
"Lane " << currentLane->
getID() <<
": vehicles gone out- " << count;
1022 toReset.push_back(currentLane->
getID());
1026 }
else if (count <= minOut) {
1041 std::string lane = (*laneId);
1044 if (inInit && tmp != 0) {
1048 if (tmp < minIn && tmp != 0) {
1052 toReset.push_back(lane);
1055 std::ostringstream cars_str;
1056 cars_str <<
"Lane " << lane <<
" passed: " << tmp;
1066 toSub = std::min(minIn, minOut);
1069 while (!toReset.empty()) {
1070 std::string laneId = toReset.back();
1080 ratio = std::numeric_limits<double>::infinity();
1081 normalized = std::numeric_limits<double>::infinity();
1085 std::ostringstream final_str;
1086 final_str <<
"Total cars in lanes: " <<
carsIn <<
" Total cars out: " <<
carsOut <<
" Ratio: " << ratio <<
" Pure eta: " << normalized;
1088 std::ostringstream eta_str;
1091 std::ostringstream eta_str;
1092 eta_str <<
"Min found:" << toSub <<
". MinIn:" << minIn <<
" MinOut:" << minOut;
1113 eta = (-(normalized) * (1 / phi));
1149 eta = (normalized) * phi;
1157 std::ostringstream eta_str;
1158 eta_str <<
"Eta Normalized: " << eta <<
".";
1167 MSLane* currentLane =
nullptr;
1170 for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector =
myLanes.begin();
1171 laneVector !=
myLanes.end(); laneVector++) {
1173 for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
1175 currentLane = (*lane);
1180 for (MSTrafficLightLogic::LinkVectorVector::const_iterator linkVector =
myLinks.begin();
1181 linkVector !=
myLinks.end(); linkVector++) {
1182 for (MSTrafficLightLogic::LinkVector::const_iterator link = linkVector->begin(); link != linkVector->end();
1184 currentLane = (*link)->getLane();
1191 double dispersion_out) {
1193 for (std::vector<MSSOTLPolicy*>::iterator it =
myPolicies.begin(); it !=
myPolicies.end(); ++it) {
1194 if (it.operator * ()->getName() ==
"Phase") {
1200 std::vector<double> thetaStimuli;
1201 double thetaSum = 0.0;
1203 for (
int i = 0; i < (int)
myPolicies.size(); i++) {
1204 double stimulus =
myPolicies[i]->computeDesirability(phero_in, phero_out, dispersion_in, dispersion_out);
1205 double thetaStimulus = pow(stimulus, 2) / (pow(stimulus, 2) + pow(
myPolicies[i]->getThetaSensitivity(), 2));
1207 thetaStimuli.push_back(thetaStimulus);
1208 thetaSum += thetaStimulus;
1212 ostringstream so_str;
1213 so_str <<
" policy " <<
myPolicies[i]->getName() <<
" stimulus " << stimulus <<
" pow(stimulus,2) " << pow(stimulus, 2) <<
" pow(Threshold,2) " << pow(
myPolicies[i]->getThetaSensitivity(), 2) <<
" thetaStimulus " << thetaStimulus <<
" thetaSum " << thetaSum <<
" TL " <<
getID();
1214 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::choosePolicy::" + so_str.str());
1223 double partialSum = 0;
1224 for (
int i = 0; i < (int)
myPolicies.size(); i++) {
1225 partialSum += thetaStimuli[i];
1229 ostringstream aao_str;
1230 aao_str <<
" policy " <<
myPolicies[i]->getName() <<
" partialSum " << partialSum <<
" thetaStimuls " << thetaStimuli[i] <<
" r " << r <<
" TL " <<
getID();
1231 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::choosePolicy::" + aao_str.str());
1233 if (partialSum >= r) {
1247 std::ostringstream phero_str;
1249 WRITE_MESSAGE(
"MSSwamTrafficLightLogic::canRelease(): " + phero_str.str());
1256 std::string laneState =
"";
1260 laneState += state[*it];
std::map< std::string, double > MSLaneId_PheromoneMap
std::pair< std::string, double > MSLaneId_Pheromone
std::vector< std::string > LaneIdVector
#define WRITE_MESSAGEF(...)
#define WRITE_MESSAGE(msg)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
#define UNUSED_PARAMETER(x)
bool isCrossing() const
return whether this edge is a pedestrian crossing
bool isWalkingArea() const
return whether this edge is walking area
Representation of a lane in the micro simulation.
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
MSEdge & getEdge() const
Returns the lane's edge.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
const std::string & getState() const
Returns the state within this phase.
const std::vector< std::string > & getTargetLaneSet() const
Class for low-level congestion policy.
void subtractPassedVeh(std::string laneId, int passed)
int getPassedVeh(std::string laneId, bool out)
A self-organizing high-level traffic light logic.
std::vector< MSSOTLPolicy * > myPolicies
void addPolicy(MSSOTLPolicy *policy)
MSSOTLPolicy * myCurrentPolicy
void activate(MSSOTLPolicy *policy)
void init(NLDetectorBuilder &nb)
Initialises the tls.
Class for low-level marching policy.
Class for low-level phase policy.
Class for low-level platoon policy.
This class determines the desirability algorithm of a MSSOTLPolicy when used in combination with a hi...
virtual std::string getMessage()=0
Class for a low-level policy.
virtual bool canRelease(SUMOTime elapsed, bool thresholdPassed, bool pushButtonPressed, const MSPhaseDefinition *stage, int vehicleCount)=0
virtual int decideNextPhase(SUMOTime elapsed, const MSPhaseDefinition *stage, int currentPhaseIndex, int phaseMaxCTS, bool thresholdPassed, bool pushButtonPressed, int vehicleCount)
virtual double getThetaSensitivity()
MSSOTLPolicyDesirability * getDesirabilityAlgorithm()
virtual double meanVehiclesSpeed(MSLane *lane)=0
virtual double getMaxSpeed(std::string laneId)=0
virtual int countVehicles(MSLane *lane)=0
int getPhaseIndexWithMaxCTS()
MSSOTLE2Sensors * getCountSensors()
Return the sensors that count the passage of vehicles in and out of the tl.
int countVehicles(MSPhaseDefinition phase)
SUMOTime getCurrentPhaseElapsed()
bool isPushButtonPressed()
MSSOTLSensors * getSensors()
int getCurrentPhaseIndex() const override
Returns the current index within the program.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const override
gets a parameter
const MSPhaseDefinition & getCurrentPhaseDef() const override
Returns the definition of the current phase.
std::string getPoliciesParam()
double getPheromoneForInputLanes()
MSLaneId_PheromoneMap pheromoneOutputLanes
This pheromone is an indicator of congestion on output lanes. Its levels refer to the average speed o...
bool mustChange
When true, indicates that the current policy MUST be changed. It's used to force the exit from the co...
bool allowLine(MSLane *)
Check if a lane is allowed to be added to the maps pheromoneInputLanes and pheromoneOutputLanes Contr...
bool gotTargetLane
When true indicates that we've already acquired the target lanes for this particular phase.
MSSwarmTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const Phases &phases, int step, SUMOTime delay, const Parameterised::Map ¶meters)
Constructor without sensors passed.
int getReinforcementMode()
void updatePheromoneLevels()
Update pheromone levels Pheromone on input lanes is costantly updated Pheromone follows a discrete-ti...
void choosePolicy(double phero_in, double phero_out, double dispersion_in, double dispersion_out)
void initScaleFactorDispersionIn(int lanes_in)
double getForgettingCox()
double calculateEtaRatio()
LaneIdVector targetLanes
A copy of the target lanes of this phase.
~MSSwarmTrafficLightLogic()
double getDispersionForOutputLanes(double average_phero_out)
bool skipEta
When true indicates that we can skip the evaluation of eta since we've a congestion policy that is la...
void updateSensitivities()
Parameterised::Map m_pheroLevelLog
double getDistanceOfMaxPheroForInputLanes()
SUMOTime getMaxCongestionDuration()
double calculateEtaDiff()
Method that should calculate the valor of eta a coefficient to evaluate the current policy's work....
double getChangePlanProbability()
std::map< std::string, CircularBuffer< double > * > m_meanSpeedHistory
double getDispersionForInputLanes(double average_phero_in)
std::map< std::string, CircularBuffer< double > * > m_derivativeHistory
void resetPheromone()
Resets pheromone levels.
MSLaneId_PheromoneMap pheromoneInputLanes
This pheronome is an indicator of congestion on input lanes. Its levels refer to the average speed of...
std::string getLaneLightState(const std::string &laneId)
double getScaleFactorDispersionOut()
double getDistanceOfMaxPheroForOutputLanes()
double getScaleFactorDispersionIn()
bool m_useVehicleTypesWeights
void initScaleFactorDispersionOut(int lanes_out)
std::ofstream swarmLogFile
std::map< std::string, std::vector< int > > m_laneIndexMap
SUMOTime lastThetaSensitivityUpdate
void decidePolicy()
Decide the current policy according to pheromone levels The decision reflects on currentPolicy value.
LaneCheckMap laneCheck
Map to check if a lane was already controlled during the elaboration of eta.
double calculatePhi(int factor)
Method that should calculate the valor of phi a coefficient to amplify/attenuate eta based on a facto...
void init(NLDetectorBuilder &nb)
Initialises the tls with sensors on incoming and outgoing lanes Sensors are built in the simulation a...
SUMOTime congestion_steps
double getPheromoneForOutputLanes()
A class that stores and controls tls and switching of their programs.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
std::vector< LinkVector > LinkVectorVector
Definition of a list that holds lists of links that do have the same attribute.
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index.
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Builds detectors for microsim.
const std::string & getID() const
Returns the id.
std::map< std::string, std::string > Map
parameters map
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...