diff --git a/include/rosa/agent/SignalState.hpp b/include/rosa/agent/SignalState.hpp index ec1e493..2b2595e 100644 --- a/include/rosa/agent/SignalState.hpp +++ b/include/rosa/agent/SignalState.hpp @@ -1,712 +1,688 @@ //===-- rosa/agent/SignalState.hpp ------------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/SignalState.hpp /// /// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *signal state* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_SIGNALSTATE_HPP #define ROSA_AGENT_SIGNALSTATE_HPP #include "rosa/agent/DistanceMetrics.hpp" #include "rosa/agent/FunctionAbstractions.hpp" #include "rosa/agent/Functionality.h" #include "rosa/agent/History.hpp" #include "rosa/agent/State.hpp" #include "rosa/support/math.hpp" namespace rosa { namespace agent { /// Signal properties defining the properties of the signal which is monitored /// by \c rosa::agent::SignalStateDetector and is saved in \c /// rosa::agent::SignalStateInformation. enum SignalProperties : uint8_t { INPUT = 0, ///< The signal is an input signal OUTPUT = 1 ///< The signal is an output signal }; /// TODO: write description template struct DABHistoryEntry { /// TODO: write description PROCDATATYPE AvgValue; /// TODO: write description CONFDATATYPE DecisionDABIsStable; /// TODO: write description CONFDATATYPE DecisionDABIsDriftingDown; /// TODO: write description CONFDATATYPE DecisionDABIsDriftingUp; /// TODO: write description - bool DABWasCurrent; + bool DABIsCurrent; public: DABHistoryEntry(PROCDATATYPE AvgValue) { this->AvgValue = AvgValue; - this->DecisionDABIsStable = 0; + this->DecisionDABIsStable = 1; this->DecisionDABIsDriftingDown = 0; this->DecisionDABIsDriftingUp = 0; - this->DABWasCurrent = false; + this->DABIsCurrent = true; } - - DABHistoryEntry() = default; }; /// TODO: write description template struct SignalStateInformation : StateInformation { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "confidence type is not to arithmetic"); /// ConfidenceOfMatchingState is the confidence how good the new sample /// matches the state. CONFDATATYPE ConfidenceOfMatchingState; /// ConfidenceOfMatchingState is the confidence how bad the new sample /// matches the state. CONFDATATYPE ConfidenceOfMismatchingState; /// The SignalProperty saves whether the monitored signal is an input our /// output signal. SignalProperties SignalProperty; /// The SignalStateIsValid saves the number of samples which have been /// inserted into the state after entering it. uint32_t NumberOfInsertedSamplesAfterEntrance; public: SignalStateInformation(unsigned int SignalStateID, SignalProperties _SignalProperty) { this->StateID = SignalStateID; this->SignalProperty = _SignalProperty; this->StateCondition = StateConditions::UNKNOWN; this->NumberOfInsertedSamplesAfterEntrance = 0; this->StateIsValid = false; this->StateJustGotValid = false; this->StateIsValidAfterReentrance = false; this->ConfidenceStateIsValid = 0; this->ConfidenceStateIsInvalid = 0; this->ConfidenceStateIsStable = 0; this->ConfidenceStateIsDrifting = 0; this->ConfidenceStateIsDriftingDown = 0; this->ConfidenceStateIsDriftingUp = 0; } SignalStateInformation() = default; }; /// \tparam INDATATYPE type of input data, \tparam CONFDATATYPE type of /// data in that the confidence values are given, \tparam PROCDATATYPE type of /// the relative distance and the type of data in which DABs are saved. template class SignalState : public Functionality { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "input data type not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "confidence data type is not to arithmetic"); STATIC_ASSERT( (std::is_arithmetic::value), "process data type (DAB and Relative Distance) is not to arithmetic"); public: // The metric to calculate the distance between two points using DistanceMetricAbstraction = Abstraction, PROCDATATYPE> &; // For the convinience to write a shorter data type name using PartFuncReference = PartialFunction &; // using PartFuncReference2 = ; using StepFuncReference = StepFunction &; private: /// SignalStateInfo is a struct of SignalStateInformation that contains /// information about the current signal state. SignalStateInformation SignalStateInfo; /// The metric to calculate the distance between two points DistanceMetricAbstraction DistanceMetric; /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the /// confidence how good the new sample matches another sample in the sample /// history. PartFuncReference FuzzyFunctionSampleMatches; /// The FuzzyFunctionSampleMismatches is the fuzzy function that gives the /// confidence how bad the new sample matches another sample in the sample /// history. PartFuncReference FuzzyFunctionSampleMismatches; /// The FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the /// confidence how many samples from the sampe history match the new sample. StepFuncReference FuzzyFunctionNumOfSamplesMatches; /// The FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives /// the confidence how many samples from the sampe history mismatch the new /// sample. StepFuncReference FuzzyFunctionNumOfSamplesMismatches; /// The FuzzyFunctionSampleValid is the fuzzy function that gives the /// confidence how good one matches another sample in the sample /// history. This is done to evaluate whether a state is valid. PartFuncReference FuzzyFunctionSampleValid; /// The FuzzyFunctionSampleInvalid is the fuzzy function that gives the /// confidence how bad one sample matches another sample in the sample /// history. This is done to evaluate whether a state is invalid. PartFuncReference FuzzyFunctionSampleInvalid; /// The FuzzyFunctionNumOfSamplesValid is the fuzzy function that gives the /// confidence how many samples from the sample history match another sample. /// This is done to evaluate whether a state is valid. StepFuncReference FuzzyFunctionNumOfSamplesValid; /// The FuzzyFunctionNumOfSamplesInvalid is the fuzzy function that gives /// the confidence how many samples from the sample history mismatch another /// sample. This is done to evaluate whether a state is invalid. StepFuncReference FuzzyFunctionNumOfSamplesInvalid; /// The FuzzyFunctionSignalIsDriftingDown is the fuzzy function that gives the /// confidence how likely it is that the signal (resp. the state of a signal) /// is drifting down. PartFuncReference FuzzyFunctionSignalIsDriftingDown; /// The FuzzyFunctionSignalIsDriftingUp is the fuzzy function that gives the /// confidence how likely it is that the signal (resp. the state of a signal) /// is drifting up. PartFuncReference FuzzyFunctionSignalIsDriftingUp; /// The FuzzyFunctionSignalIsStable is the fuzzy function that gives the /// confidence how likely it is that the signal (resp. the state of a signal) /// is stable (not drifting). PartFuncReference FuzzyFunctionSignalIsStable; /// TODO: description PartialFunction &FuzzyFunctionSignalConditionLookBack; /// TODO: description PartialFunction &FuzzyFunctionSignalConditionHistoryDesicion; /// TODO: description uint32_t DriftLookbackRange; /// SampleHistory is a history in that the last sample values are stored. DynamicLengthHistory SampleHistory; /// DAB is a (usually) small history of the last sample values of which a /// average is calculated if the DAB is full. DynamicLengthHistory DAB; /// DABHistory is a history in that the last DABs (to be exact, the averages /// of the last DABs) are stored. - DynamicLengthHistory, + DynamicLengthHistory, HistoryPolicy::FIFO> DABHistory; /// LowestConfidenceMatchingHistory is a history in that the lowest confidence /// for the current sample matches all history samples are saved. DynamicLengthHistory LowestConfidenceMatchingHistory; /// HighestConfidenceMatchingHistory is a history in that the highest /// confidence for the current sample matches all history samples are saved. DynamicLengthHistory HighestConfidenceMismatchingHistory; /// TempConfidenceMatching is the confidence how good a sample matches the /// state. However, the value of this variable is only needed temporarly. CONFDATATYPE TempConfidenceMatching = 0; /// TempConfidenceMatching is the confidence how bad a sample matches the /// state. However, the value of this variable is only needed temporarly. CONFDATATYPE TempConfidenceMismatching = 0; public: /// Creates an instance by setting all parameters /// \param SignalStateID The Id of the SignalStateinfo \c /// SignalStateInformation. /// /// \param DistanceMetric the distance metric to calculate the distance /// between two points /// /// \param FuzzyFunctionSampleMatches The FuzzyFunctionSampleMatches is the /// fuzzy function that gives the confidence how good the new sample matches /// another sample in the sample history. /// /// \param FuzzyFunctionSampleMismatches The FuzzyFunctionSampleMismatches is /// the fuzzy function that gives the confidence how bad the new sample /// matches another sample in the sample history. /// /// \param FuzzyFunctionNumOfSamplesMatches The /// FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the /// confidence how many samples from the sampe history match the new sample. /// /// \param FuzzyFunctionNumOfSamplesMismatches The /// FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives the /// confidence how many samples from the sampe history mismatch the new /// sample. /// /// \param FuzzyFunctionSignalIsDriftingDown The /// FuzzyFunctionSignalIsDriftingDown is the fuzzy function that gives the /// confidence how likely it is that the signal (resp. the state of a signal) /// is drifting down. /// /// /// \param FuzzyFunctionSignalIsDriftingUp The FuzzyFunctionSignalIsDriftingUp /// is the fuzzy function that gives the confidence how likely it is that the /// signal (resp. the state of a signal) is drifting down. /// /// \param FuzzyFunctionSignalIsStable The FuzzyFunctionSignalIsStable is the /// fuzzy function that gives the confidence how likely it is that the signal /// (resp. the state of a signal) is stable (not drifting). /// /// \param SampleHistorySize Size of the Sample History \c /// DynamicLengthHistory . SampleHistory is a history in that the last sample /// values are stored. /// SignalState( uint32_t SignalStateID, SignalProperties SignalProperty, uint32_t SampleHistorySize, uint32_t DABSize, DistanceMetricAbstraction DistanceMetric, PartFuncReference FuzzyFunctionSampleMatches, PartFuncReference FuzzyFunctionSampleMismatches, StepFuncReference FuzzyFunctionNumOfSamplesMatches, StepFuncReference FuzzyFunctionNumOfSamplesMismatches, PartFuncReference FuzzyFunctionSampleValid, PartFuncReference FuzzyFunctionSampleInvalid, StepFuncReference FuzzyFunctionNumOfSamplesValid, StepFuncReference FuzzyFunctionNumOfSamplesInvalid, PartFuncReference FuzzyFunctionSignalIsDriftingDown, PartFuncReference FuzzyFunctionSignalIsDriftingUp, PartFuncReference FuzzyFunctionSignalIsStable, PartialFunction &FuzzyFunctionSignalConditionLookBack, PartialFunction &FuzzyFunctionSignalConditionHistoryDesicion, uint32_t DriftLookbackRange) noexcept : SignalStateInfo{SignalStateID, SignalProperty}, DistanceMetric(DistanceMetric), FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches), FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches), FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches), FuzzyFunctionNumOfSamplesMismatches( FuzzyFunctionNumOfSamplesMismatches), FuzzyFunctionSampleValid(FuzzyFunctionSampleValid), FuzzyFunctionSampleInvalid(FuzzyFunctionSampleInvalid), FuzzyFunctionNumOfSamplesValid(FuzzyFunctionNumOfSamplesValid), FuzzyFunctionNumOfSamplesInvalid(FuzzyFunctionNumOfSamplesInvalid), FuzzyFunctionSignalIsDriftingDown(FuzzyFunctionSignalIsDriftingDown), FuzzyFunctionSignalIsDriftingUp(FuzzyFunctionSignalIsDriftingUp), FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable), FuzzyFunctionSignalConditionLookBack( FuzzyFunctionSignalConditionLookBack), FuzzyFunctionSignalConditionHistoryDesicion( FuzzyFunctionSignalConditionHistoryDesicion), DriftLookbackRange(DriftLookbackRange), SampleHistory(SampleHistorySize), DAB(DABSize), DABHistory(DriftLookbackRange + 1), LowestConfidenceMatchingHistory(SampleHistorySize), - HighestConfidenceMismatchingHistory(SampleHistorySize) { - - // std::cout << "BEIM ERSTELLEN: " << DABSize << std::endl; - } + HighestConfidenceMismatchingHistory(SampleHistorySize) {} /// Destroys \p this object. ~SignalState(void) = default; void leaveSignalState(void) noexcept { DAB.clear(); SignalStateInfo.NumberOfInsertedSamplesAfterEntrance = 0; SignalStateInfo.StateIsValidAfterReentrance = false; } SignalStateInformation insertSample(INDATATYPE Sample) noexcept { SignalStateInfo.NumberOfInsertedSamplesAfterEntrance++; validateSignalState(Sample); SampleHistory.addEntry(Sample); - // std::cout << "DAB size vorher: " << DAB.numberOfEntries() << std::endl; - DAB.addEntry(Sample); - // std::cout << "DAB size nachher: " << DAB.numberOfEntries() << std::endl; - if (DAB.full()) { // TODO: try median instead of avg PROCDATATYPE AvgOfDAB = DAB.template average(); - - // std::cout << "vorher size: " << DABHistory.numberOfEntries() << - // std::endl; - - // DABHistory.addEntry(AvgOfDAB); DABHistory.addEntry( DABHistoryEntry(AvgOfDAB)); DAB.clear(); - - // std::cout << "nachher size: " << DABHistory.numberOfEntries() - // << std::endl; } - // getchar(); - FuzzyFunctionNumOfSamplesMatches.setRightLimit( static_cast(SampleHistory.numberOfEntries())); FuzzyFunctionNumOfSamplesMismatches.setRightLimit( static_cast(SampleHistory.numberOfEntries())); checkSignalStability(); SignalStateInfo.ConfidenceOfMatchingState = TempConfidenceMatching; SignalStateInfo.ConfidenceOfMismatchingState = TempConfidenceMismatching; return SignalStateInfo; } /// Gives the confidence how likely the new sample matches the signal state. /// /// \param Sample is the actual sample of the observed signal. /// /// \return the confidence of the new sample is matching the signal state. CONFDATATYPE confidenceSampleMatchesSignalState(INDATATYPE Sample) noexcept { CONFDATATYPE ConfidenceOfBestCase = 0; DynamicLengthHistory RelativeDistanceHistory(SampleHistory.maxLength()); // Calculate distances to all history samples. for (auto &HistorySample : SampleHistory) { PROCDATATYPE RelativeDistance = DistanceMetric(std::make_pair(Sample, HistorySample)); RelativeDistanceHistory.addEntry(RelativeDistance); } // Sort all calculated distances so that the lowest distance (will get the // highest confidence) is at the beginning. RelativeDistanceHistory.sortAscending(); CONFDATATYPE ConfidenceOfWorstFittingSample = 1; // Case 1 means that one (the best fitting) sample of the history is // compared with the new sample. Case 2 means the two best history samples // are compared with the new sample. And so on. // TODO (future): to accelerate . don't start with 1 start with some higher // number because a low number (i guess lower than 5) will definetely lead // to a low confidence. except the history is not full. // Case 1 means that one (the best fitting) sample of the history is // compared with the new sample. Case 2 means the two best history samples // are compared with the new sample. And so on. for (uint32_t Case = 0; Case < RelativeDistanceHistory.numberOfEntries(); Case++) { CONFDATATYPE ConfidenceFromRelativeDistance; if (std::isinf(RelativeDistanceHistory[Case])) { // TODO (future): if fuzzy is defined in a way that infinity is not 0 it // would be a problem. ConfidenceFromRelativeDistance = 0; } else { ConfidenceFromRelativeDistance = FuzzyFunctionSampleMatches(RelativeDistanceHistory[Case]); } ConfidenceOfWorstFittingSample = fuzzyAND(ConfidenceOfWorstFittingSample, ConfidenceFromRelativeDistance); ConfidenceOfBestCase = fuzzyOR(ConfidenceOfBestCase, fuzzyAND(ConfidenceOfWorstFittingSample, FuzzyFunctionNumOfSamplesMatches( static_cast(Case) + 1))); } TempConfidenceMatching = ConfidenceOfBestCase; return ConfidenceOfBestCase; } /// Gives the confidence how likely the new sample mismatches the signal /// state. /// /// \param Sample is the actual sample of the observed signal. /// /// \return the confidence of the new sample is mismatching the signal state. CONFDATATYPE confidenceSampleMismatchesSignalState(INDATATYPE Sample) noexcept { float ConfidenceOfWorstCase = 1; DynamicLengthHistory RelativeDistanceHistory(SampleHistory.maxLength()); // Calculate distances to all history samples. for (auto &HistorySample : SampleHistory) { RelativeDistanceHistory.addEntry( DistanceMetric(std::make_pair(Sample, HistorySample))); } // Sort all calculated distances so that the highest distance (will get the // lowest confidence) is at the beginning. RelativeDistanceHistory.sortDescending(); CONFDATATYPE ConfidenceOfBestFittingSample = 0; // TODO (future): to accelerate -> don't go until end. Confidences will only // get higher. See comment in "CONFDATATYPE // confidenceSampleMatchesSignalState(INDATATYPE Sample)". // Case 1 means that one (the worst fitting) sample of the history is // compared with the new sample. Case 2 means the two worst history samples // are compared with the new sample. And so on. for (uint32_t Case = 0; Case < RelativeDistanceHistory.numberOfEntries(); Case++) { CONFDATATYPE ConfidenceFromRelativeDistance; if (std::isinf(RelativeDistanceHistory[Case])) { ConfidenceFromRelativeDistance = 1; } else { ConfidenceFromRelativeDistance = FuzzyFunctionSampleMismatches(RelativeDistanceHistory[Case]); } ConfidenceOfBestFittingSample = fuzzyOR(ConfidenceOfBestFittingSample, ConfidenceFromRelativeDistance); ConfidenceOfWorstCase = fuzzyAND(ConfidenceOfWorstCase, fuzzyOR(ConfidenceOfBestFittingSample, FuzzyFunctionNumOfSamplesMismatches( static_cast(Case) + 1))); } TempConfidenceMismatching = ConfidenceOfWorstCase; return ConfidenceOfWorstCase; } /// Gives information about the current signal state. /// /// \return a struct SignalStateInformation that contains information about /// the current signal state. SignalStateInformation signalStateInformation(void) noexcept { return SignalStateInfo; } private: void validateSignalState(INDATATYPE Sample) { // TODO (future): WorstConfidenceDistance and BestConfidenceDistance could // be set already in "CONFDATATYPE // confidenceSampleMatchesSignalState(INDATATYPE Sample)" and "CONFDATATYPE // confidenceSampleMismatchesSignalState(INDATATYPE Sample)" when the new // sample is compared to all history samples. This would save a lot time // because the comparisons are done only once. However, it has to be asured // that the these two functions are called before the insertation, and the // FuzzyFunctions for validation and matching have to be the same! CONFDATATYPE LowestConfidenceMatching = 1; CONFDATATYPE HighestConfidenceMismatching = 0; for (auto &HistorySample : SampleHistory) { // TODO (future): think about using different fuzzy functions for // validation and matching. LowestConfidenceMatching = fuzzyAND(LowestConfidenceMatching, FuzzyFunctionSampleMatches( DistanceMetric(std::make_pair(Sample, HistorySample)))); HighestConfidenceMismatching = fuzzyOR(HighestConfidenceMismatching, FuzzyFunctionSampleMismatches( DistanceMetric(std::make_pair(Sample, HistorySample)))); } LowestConfidenceMatchingHistory.addEntry(LowestConfidenceMatching); HighestConfidenceMismatchingHistory.addEntry(HighestConfidenceMismatching); LowestConfidenceMatching = LowestConfidenceMatchingHistory.lowestEntry(); HighestConfidenceMismatching = HighestConfidenceMismatchingHistory.highestEntry(); SignalStateInfo.ConfidenceStateIsValid = fuzzyAND(LowestConfidenceMatching, FuzzyFunctionNumOfSamplesValid(static_cast( SignalStateInfo.NumberOfInsertedSamplesAfterEntrance))); SignalStateInfo.ConfidenceStateIsInvalid = fuzzyOR(HighestConfidenceMismatching, FuzzyFunctionNumOfSamplesInvalid(static_cast( SignalStateInfo.NumberOfInsertedSamplesAfterEntrance))); if (SignalStateInfo.ConfidenceStateIsValid > SignalStateInfo.ConfidenceStateIsInvalid) { if (SignalStateInfo.StateIsValid) { SignalStateInfo.StateJustGotValid = false; } else { SignalStateInfo.StateJustGotValid = true; } SignalStateInfo.StateIsValid = true; SignalStateInfo.StateIsValidAfterReentrance = true; } } void checkSignalStability(void) { CONFDATATYPE CurrentConfidenceStable = 0; CONFDATATYPE CurrentConfidenceStateDriftingDown = 0; CONFDATATYPE CurrentConfidenceStateDriftingUp = 0; CONFDATATYPE HistoryConfidenceStable = 0; CONFDATATYPE HistoryConfidenceStateDriftingDown = 0; CONFDATATYPE HistoryConfidenceStateDriftingUp = 0; - // std::cout << "1" << std::endl; - if (DABHistory.numberOfEntries() >= 2) { - // std::cout << "2" << std::endl; - DABHistoryEntry CurrentDAB = DABHistory[DABHistory.numberOfEntries() - 1]; - if (CurrentDAB.DABWasCurrent == false) { - - DABHistoryEntry DAB2Compare; + if (CurrentDAB.DABIsCurrent == true) { // THIS WOULD BE FOR EQUATION NORMALIZATION // TODO: make the following also for distance measurement when comparing // sample with state and validate state /* // sigma correction if (NormalizedDistanceMetric *NormalizableDistanceMetric = dynamic_cast< NormalizedDistanceMetric *>( DistanceMetric)) { // old was safely casted to NewType NormalizableDistanceMetric->setNorm( // TODO: (1) Sigma von Sample // History(!) abholen, (2) irgendwas mit Sigma hier reinschreiben, // und (3) überlegen wegen zweiter History (länger) für // Sigmaberechnung ); } */ // Iterate through all history DABs for (unsigned int t = 1; t <= DriftLookbackRange && t < DABHistory.numberOfEntries(); t++) { // Pick one history DAB - DAB2Compare = DABHistory[DABHistory.numberOfEntries() - (t + 1)]; + DABHistoryEntry DAB2Compare = + DABHistory[DABHistory.numberOfEntries() - (t + 1)]; // Calculate distance between most recent (completed) DAB and the // chosen history DAB PROCDATATYPE dist = DistanceMetric( std::make_pair(CurrentDAB.AvgValue, DAB2Compare.AvgValue)); // Add current confidences for Stable, drift down and drift up // together CurrentConfidenceStable += FuzzyFunctionSignalIsStable(dist); CurrentConfidenceStateDriftingDown += FuzzyFunctionSignalIsDriftingDown(dist); CurrentConfidenceStateDriftingUp += FuzzyFunctionSignalIsDriftingUp(dist); // Add history confidences for Stable, drift down and drift up // together HistoryConfidenceStable += DAB2Compare.DecisionDABIsStable; HistoryConfidenceStateDriftingDown += DAB2Compare.DecisionDABIsDriftingDown; HistoryConfidenceStateDriftingUp += DAB2Compare.DecisionDABIsDriftingUp; } // chose right divisor for average calculation unsigned int numOfCompares; if (DriftLookbackRange <= DABHistory.numberOfEntries()) numOfCompares = DriftLookbackRange; else numOfCompares = - static_cast(DABHistory.numberOfEntries()); + static_cast(DABHistory.numberOfEntries() - 1); // calculate the average of the current confidence decision CurrentConfidenceStable /= numOfCompares; CurrentConfidenceStateDriftingDown /= numOfCompares; CurrentConfidenceStateDriftingUp /= numOfCompares; // store the current confidence decision in current DAB CurrentDAB.DecisionDABIsStable = CurrentConfidenceStable; CurrentDAB.DecisionDABIsDriftingDown = CurrentConfidenceStateDriftingDown; CurrentDAB.DecisionDABIsDriftingUp = CurrentConfidenceStateDriftingUp; - CurrentDAB.DABWasCurrent = true; + CurrentDAB.DABIsCurrent = false; // calculate the confidences for SignalStateInfo (current output) HistoryConfidenceStable = (HistoryConfidenceStable + CurrentConfidenceStable) / (numOfCompares + 1); HistoryConfidenceStateDriftingDown = (HistoryConfidenceStateDriftingDown + CurrentConfidenceStateDriftingDown) / (numOfCompares + 1); HistoryConfidenceStateDriftingUp = (HistoryConfidenceStateDriftingUp + CurrentConfidenceStateDriftingUp) / (numOfCompares + 1); // set SignalStateInfo Confidences SignalStateInfo.ConfidenceStateIsStable = HistoryConfidenceStable; SignalStateInfo.ConfidenceStateIsDrifting = HistoryConfidenceStateDriftingDown > HistoryConfidenceStateDriftingUp ? HistoryConfidenceStateDriftingDown : HistoryConfidenceStateDriftingUp; SignalStateInfo.ConfidenceStateIsDriftingDown = HistoryConfidenceStateDriftingDown; SignalStateInfo.ConfidenceStateIsDriftingUp = HistoryConfidenceStateDriftingUp; // set SignalStateInfo StateCondition if (SignalStateInfo.ConfidenceStateIsStable > SignalStateInfo.ConfidenceStateIsDrifting) SignalStateInfo.StateCondition = StateConditions::STABLE; else if (SignalStateInfo.ConfidenceStateIsStable < SignalStateInfo.ConfidenceStateIsDrifting) if (SignalStateInfo.ConfidenceStateIsDriftingDown > SignalStateInfo.ConfidenceStateIsDriftingUp) SignalStateInfo.StateCondition = StateConditions::DRIFTING_DN; else if (SignalStateInfo.ConfidenceStateIsDriftingDown < SignalStateInfo.ConfidenceStateIsDriftingUp) SignalStateInfo.StateCondition = StateConditions::DRIFTING_UP; else SignalStateInfo.StateCondition = StateConditions::UNKNOWN; else SignalStateInfo.StateCondition = StateConditions::UNKNOWN; } } else { SignalStateInfo.ConfidenceStateIsStable = 0; SignalStateInfo.ConfidenceStateIsDrifting = 0; SignalStateInfo.ConfidenceStateIsDriftingDown = 0; SignalStateInfo.ConfidenceStateIsDriftingUp = 0; SignalStateInfo.StateCondition = StateConditions::UNKNOWN; } } }; // namespace agent } // namespace agent } // End namespace rosa #endif // ROSA_AGENT_SIGNALSTATE_HPP