23 #include "../MSEdge.h"
26 #define ANALYSIS_DBG(X) {X}
28 #define ANALYSIS_DBG(X) DBG(X)
32 const std::string& programID,
const Phases& phases,
int step,
SUMOTime delay,
33 const std::map<std::string, std::string>& parameters) :
37 std::transform(pols.begin(), pols.end(), pols.begin(), ::tolower);
38 DBG(std::ostringstream str; str <<
"policies: " << pols;
WRITE_MESSAGE(str.str());)
40 if (pols.find(
"platoon") != std::string::npos) {
43 if (pols.find(
"phase") != std::string::npos) {
46 if (pols.find(
"marching") != std::string::npos) {
49 if (pols.find(
"congestion") != std::string::npos) {
67 std::ostringstream _str;
74 WRITE_ERROR(
"VEHICLE TYPES WEIGHT only works with phase policy, which is missing");
123 srand((
int) time(
nullptr));
126 MSLane* currentLane =
nullptr;
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();
140 currentLane = (*lane);
149 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::init Intersection " +
getID() +
" pheromoneInputLanes adding " + currentLane->
getID());)
152 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::init Intersection " +
getID() +
" pheromoneInputLanes: lane " + currentLane->
getID() +
" not allowed");)
160 for (
int i = 0; i < (int)
myLinks.size(); i++) {
162 for (
int j = 0; j < (int)oneLink.size(); j++) {
163 currentLane = oneLink[j]->getLane();
169 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::init Intersection " +
getID() +
" pheromoneOutputLanes adding " + currentLane->
getID());)
172 WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::init Intersection " +
getID() +
" pheromoneOutputLanes lane " + currentLane->
getID() +
" not allowed");)
183 WRITE_MESSAGE(
"*** Intersection " +
getID() +
" will run using MSSwarmTrafficLightLogic ***");
185 logData = logFileName.compare(
"") != 0;
187 swarmLogFile.open(logFileName.c_str(), std::ios::out | std::ios::binary);
208 std::string laneId = laneIterator->first;
214 std::string laneId = laneIterator->first;
301 const double beta,
const double gamma) {
304 std::ostringstream _str; _str << logString <<
" Lanes " << pheroMap.size() <<
" TL " <<
getID() <<
" .";
WRITE_MESSAGE(
time2string(
MSNet::getInstance()->getCurrentTimeStep()) +
" MSSwarmTrafficLightLogic::updatePheromoneLevels:: " + _str.str());)
306 for (MSLaneId_PheromoneMap::iterator laneIterator = pheroMap.begin(); laneIterator != pheroMap.end();
308 std::string laneId = laneIterator->first;
309 double oldPhero = laneIterator->second;
312 bool updatePheromone = (meanVehiclesSpeed > -1);
316 double derivative = 0;
320 if (updatePheromone) {
321 double currentDerivative = 0;
355 double pheroAdd =
MAX2((maxSpeed - meanVehiclesSpeed) * 10 / maxSpeed, 0.0);
364 if (updatePheromone) {
365 std::ostringstream oss;
367 oss <<
" der " << derivative <<
" phero " << pheroAdd <<
" maxS " << maxSpeed <<
" meanS " << meanVehiclesSpeed;
373 double phero = beta * oldPhero + gamma * pheroAdd * updatePheromone;
376 std::ostringstream i_str;
377 i_str <<
"MSSwarmTrafficLightLogic::updatePheromoneLevels " << logString <<
" > 10. Value: " << phero;
382 pheroMap[laneId] = phero;
385 std::ostringstream i_str;
393 i_str <<
" op " << oldPhero <<
" ms " << meanVehiclesSpeed <<
" p " << pheroAdd * updatePheromone <<
394 " pe " << oldPhero - oldPhero * beta <<
" pd " << gamma * pheroAdd * updatePheromone <<
" np " <<
425 for (
int i = 0; i < (int)
policies.size(); i++) {
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());)
452 for (
int i = 0; i < (int)
policies.size(); i++) {
454 double newSensitivity;
481 phero_str <<
" policy " << policy->
getName() <<
" newSensitivity " << newSensitivity <<
" ,pol.Sensitivity " << policy->
getThetaSensitivity() <<
" ,elapsedTime " << elapsedTime << lf.str() <<
" NEWERSensitivity= " << max(min(newSensitivity,
getThetaMax()),
getThetaMin()) <<
" ID " <<
getID() <<
" .";
487 }
else if (eta > 0) {
489 }
else if (eta < 0) {
508 std::string laneId = iterator->first;
509 pheroIn += iterator->second;
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());)
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;
542 std::string laneId = iterator->first;
543 sum += pow(iterator->second - average_phero_in, 2);
548 ostringstream so_str; so_str <<
" dispersionIn " << result;
WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::getDispersionForInputLanes::" + so_str.str());)
559 sum += pow(iterator->second - average_phero_out, 2);
564 ostringstream so_str; so_str <<
" dispersionOut " << result;
WRITE_MESSAGE(
"MSSwarmTrafficLightLogic::getDispersionForOutputLanes::" + so_str.str());)
571 double max_phero_val_current = 0;
572 double max_phero_val_old = 0;
573 double temp_avg_other_lanes = 0;
574 std::string laneId_max;
578 std::string laneId = iterator->first;
579 double lanePhero = iterator->second;
581 max_phero_val_current = lanePhero;
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;
590 temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + lanePhero) / counter;
596 double result = max_phero_val_current - temp_avg_other_lanes;
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());)
606 double max_phero_val_current = 0;
607 double max_phero_val_old = 0;
608 double temp_avg_other_lanes = 0;
609 std::string laneId_max;
613 std::string laneId = iterator->first;
614 double lanePhero = iterator->second;
616 max_phero_val_current = lanePhero;
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;
625 temp_avg_other_lanes = (temp_avg_other_lanes * (counter - 1) + lanePhero) / counter;
631 double result = max_phero_val_current - temp_avg_other_lanes;
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());)
653 choosePolicy(pheroIn, pheroOut, distancePheroIn, distancePheroOut);
656 if (newPolicy != oldPolicy) {
659 if (oldPolicy->
getName().compare(
"Congestion") == 0) {
679 return 1 - (1 / ((double) factor));
685 MSLane* currentLane =
nullptr;
686 int count = 0, minIn = 0, minOut = 0, toSub, tmp;
687 bool inInit =
true, outInit =
true;
688 double eta, normalized, diff, phi, delta;
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();
703 currentLane = (*lane);
711 std::ostringstream cars_str; cars_str <<
"Lane " << currentLane->
getID() <<
": vehicles entered - " << count;
WRITE_MESSAGE(
time2string(
MSNet::getInstance()->getCurrentTimeStep()) +
" MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
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();
727 currentLane = (*link)->getLane();
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());)
745 toReset.push_back(currentLane->
getID());
749 }
else if (count <= minOut) {
763 std::string lane = (*laneId);
766 if (inInit && tmp != 0) {
770 if (tmp < minIn && tmp != 0) {
774 toReset.push_back(lane);
777 std::ostringstream cars_str; cars_str <<
"Lane " << lane <<
" passed: " << tmp;
WRITE_MESSAGE(
time2string(
MSNet::getInstance()->getCurrentTimeStep()) +
" MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
785 toSub = std::min(minIn, minOut);
788 while (!toReset.empty()) {
789 std::string laneId = toReset.back();
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());)
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());)
823 eta = (-normalized * (1 / phi));
861 eta = normalized * phi;
874 MSLane* currentLane =
nullptr;
875 int count = 0, minIn = 0, minOut = 0, toSub, tmp;
876 bool inInit =
true, outInit =
true;
877 double eta, ratio, phi, normalized, delta;
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();
892 currentLane = (*lane);
900 std::ostringstream cars_str; cars_str <<
"Lane " << currentLane->
getID() <<
": vehicles entered - " << count;
WRITE_MESSAGE(
time2string(
MSNet::getInstance()->getCurrentTimeStep()) +
" MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
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();
916 currentLane = (*link)->getLane();
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());)
934 toReset.push_back(currentLane->
getID());
938 }
else if (count <= minOut) {
953 std::string lane = (*laneId);
956 if (inInit && tmp != 0) {
960 if (tmp < minIn && tmp != 0) {
964 toReset.push_back(lane);
967 std::ostringstream cars_str; cars_str <<
"Lane " << lane <<
" passed: " << tmp;
WRITE_MESSAGE(
time2string(
MSNet::getInstance()->getCurrentTimeStep()) +
" MSSwarmTrafficLightLogic::calculateEta::" + cars_str.str());)
975 toSub = std::min(minIn, minOut);
978 while (!toReset.empty()) {
979 std::string laneId = toReset.back();
989 ratio = std::numeric_limits<double>::infinity();
990 normalized = std::numeric_limits<double>::infinity();
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());)
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());)
1017 eta = (-(normalized) * (1 / phi));
1053 eta = (normalized) * phi;
1061 std::ostringstream eta_str; eta_str <<
"Eta Normalized: " << eta <<
".";
WRITE_MESSAGE(
time2string(
MSNet::getInstance()->getCurrentTimeStep()) +
" MSSwarmTrafficLightLogic::calculateEta::" + eta_str.str());)
1068 MSLane* currentLane =
nullptr;
1071 for (MSTrafficLightLogic::LaneVectorVector::const_iterator laneVector =
myLanes.begin();
1072 laneVector !=
myLanes.end(); laneVector++) {
1074 for (MSTrafficLightLogic::LaneVector::const_iterator lane = laneVector->begin(); lane != laneVector->end();
1076 currentLane = (*lane);
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();
1085 currentLane = (*link)->getLane();
1092 double dispersion_out) {
1095 if (it.operator * ()->getName() ==
"Phase") {
1101 std::vector<double> thetaStimuli;
1102 double thetaSum = 0.0;
1104 for (
int i = 0; i < (int)
getPolicies().size(); i++) {
1105 double stimulus =
getPolicies()[i]->computeDesirability(phero_in, phero_out, dispersion_in, dispersion_out);
1106 double thetaStimulus = pow(stimulus, 2) / (pow(stimulus, 2) + pow(
getPolicies()[i]->getThetaSensitivity(), 2));
1108 thetaStimuli.push_back(thetaStimulus);
1109 thetaSum += thetaStimulus;
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());)
1122 double partialSum = 0;
1123 for (
int i = 0; i < (int)
getPolicies().size(); i++) {
1124 partialSum += thetaStimuli[i];
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());)
1130 if (partialSum >= r) {
1150 std::string laneState =
"";
1154 laneState += state[*it];
std::map< std::string, double > MSLaneId_PheromoneMap
std::pair< std::string, double > MSLaneId_Pheromone
std::vector< std::string > LaneIdVector
#define WRITE_MESSAGE(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
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 LaneIdVector & getTargetLaneSet() const
int getCurrentPhaseIndex() const
Returns the current index within the program.
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
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 * > policies
MSSOTLPolicy * getCurrentPolicy()
Returns the low-level policy currently selected by this high-level tll.
void addPolicy(MSSOTLPolicy *policy)
void activate(MSSOTLPolicy *policy)
std::vector< MSSOTLPolicy * > & getPolicies()
Returns the vector of the low-level policies used by this high-level tll.
MSSOTLPolicy * currentPolicy
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 void setThetaSensitivity(double val)
MSSOTLPolicyDesirability * getDesirabilityAlgorithm()
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()
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)
MSSOTLSensors * getSensors()
SUMOTime getCurrentPhaseElapsed()
bool isPushButtonPressed()
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.
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()
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
std::map< std::string, std::string > m_pheroLevelLog
double getDispersionForInputLanes(double average_phero_in)
std::map< std::string, CircularBuffer< double > * > m_derivativeHistory
void resetPheromone()
Resets pheromone levels.
MSSwarmTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const Phases &phases, int step, SUMOTime delay, const std::map< std::string, std::string > ¶meters)
Constructor without sensors passed.
MSLaneId_PheromoneMap pheromoneInputLanes
This pheronome is an indicator of congestion on input lanes. Its levels refer to the average speed of...
std::string getLaneLightState(const std::string &laneId)
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 LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
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.
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.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
static double rand(std::mt19937 *rng=nullptr)
Returns a random real number in [0, 1)
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,...