diff --git a/include/rosa/agent/SignalState.hpp b/include/rosa/agent/SignalState.hpp index a65ca9c..4b001a5 100644 --- a/include/rosa/agent/SignalState.hpp +++ b/include/rosa/agent/SignalState.hpp @@ -1,609 +1,606 @@ //===-- 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 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; } 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 FuzzyFunctionSignalIsDrifting is the fuzzy function that gives the /// confidence how likely it is that the signal (resp. the state of a signal) /// is drifting. PartFuncReference FuzzyFunctionSignalIsDrifting; /// 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. std::vector> DABs; /// DABHistory is a history in that the last DABs (to be exact, the averages /// of the last DABs) are stored. std::vector> DABHistories; /// 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; #pragma GCC diagnostic ignored "-Wunused-parameter" 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 FuzzyFunctionSignalIsDrifting The FuzzyFunctionSignalIsDrifting is /// the fuzzy function that gives the confidence how likely it is that the /// signal (resp. the state of a signal) is drifting. /// /// \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. /// /// \param DABSize Size of DAB \c DynamicLengthHistory . DAB is a (usually) /// small history of the last sample values of which a average is calculated /// if the DAB is full. /// /// \param DABHistorySize Size of the DABHistory \c DynamicLengthHistory . /// DABHistory is a history in that the last DABs (to be exact, the averages /// of the last DABs) are stored. /// SignalState( uint32_t SignalStateID, SignalProperties SignalProperty, uint32_t SampleHistorySize, uint32_t DABSize, uint32_t DABHistorySize, DistanceMetricAbstraction DistanceMetric, PartFuncReference FuzzyFunctionSampleMatches, PartFuncReference FuzzyFunctionSampleMismatches, StepFuncReference FuzzyFunctionNumOfSamplesMatches, StepFuncReference FuzzyFunctionNumOfSamplesMismatches, PartFuncReference FuzzyFunctionSampleValid, PartFuncReference FuzzyFunctionSampleInvalid, StepFuncReference FuzzyFunctionNumOfSamplesValid, StepFuncReference FuzzyFunctionNumOfSamplesInvalid, // SAVE CHANGES PartFuncReference FuzzyFunctionSignalIsDrifting, PartFuncReference FuzzyFunctionSignalIsStable, PartialFunction &FuzzyFunctionSignalConditionLookBack, // - SAVE CHANGES 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), FuzzyFunctionSignalIsDrifting(FuzzyFunctionSignalIsDrifting), FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable), // SAVE CHANGES FuzzyFunctionSignalConditionLookBack( FuzzyFunctionSignalConditionLookBack), FuzzyFunctionSignalConditionHistoryDesicion( FuzzyFunctionSignalConditionHistoryDesicion), DriftLookbackRange(DriftLookbackRange), // - SAVE CHANGES SampleHistory(SampleHistorySize), LowestConfidenceMatchingHistory(SampleHistorySize), HighestConfidenceMismatchingHistory(SampleHistorySize) { //DAB(DABSize); DABs.push_back(3); DABHistories.push_back(DynamicLengthHistory(DABHistorySize)); DABs.push_back(DynamicLengthHistory(5)); DABHistories.push_back(DynamicLengthHistory(DABHistorySize)); DABs.push_back(DynamicLengthHistory(10)); DABHistories.push_back(DynamicLengthHistory(DABHistorySize)); DABs.push_back(DynamicLengthHistory(20)); DABHistories.push_back(DynamicLengthHistory(DABHistorySize)); } /// Destroys \p this object. ~SignalState(void) = default; void leaveSignalState(void) noexcept { for(auto& dab: DABs) { dab.clear(); } SignalStateInfo.NumberOfInsertedSamplesAfterEntrance = 0; SignalStateInfo.StateIsValidAfterReentrance = false; } SignalStateInformation insertSample(INDATATYPE Sample) noexcept { SignalStateInfo.NumberOfInsertedSamplesAfterEntrance++; validateSignalState(Sample); SampleHistory.addEntry(Sample); unsigned int index = 0; for(auto& DAB: DABs) { DAB.addEntry(Sample); if (DAB.full()) { PROCDATATYPE AvgOfDAB = DAB.template median(); DABHistories[index].addEntry(AvgOfDAB); DAB.clear(); } index++; } 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) { SignalStateInfo.ConfidenceStateIsStable = 0; - SignalStateInfo.ConfidenceStateIsDrifting = 0; + SignalStateInfo.ConfidenceStateIsDriftingDown = 0; + SignalStateInfo.ConfidenceStateIsDriftingUp = 0; - bool DriftDirectionIsUp = true; + unsigned int Divider = 0; for(auto& DABHistory: DABHistories) { if (DABHistory.numberOfEntries() >= 2) { - // SAVE CHANGES INDATATYPE CurrentDAB = DABHistory[DABHistory.numberOfEntries() - 1]; INDATATYPE DAB2Compare; - // ########### TODO HERE: calculating up_down - - uint32_t DriftDnCounter = 0; - uint32_t DriftUpCounter = 0; - - // EXPERIMENTING for (unsigned int t = 1; t <= DriftLookbackRange && t < DABHistory.numberOfEntries(); t++) { DAB2Compare = DABHistory[DABHistory.numberOfEntries() - (t + 1)]; INDATATYPE dist = DistanceMetric(std::make_pair(CurrentDAB, DAB2Compare)); // AVG SignalStateInfo.ConfidenceStateIsStable += FuzzyFunctionSignalIsStable(dist); - SignalStateInfo.ConfidenceStateIsDrifting += - FuzzyFunctionSignalIsDrifting(dist); - if (CurrentDAB > DAB2Compare) - DriftUpCounter++; + SignalStateInfo.ConfidenceStateIsDriftingUp += + FuzzyFunctionSignalIsDrifting(dist); else if (CurrentDAB < DAB2Compare) - DriftDnCounter++; + SignalStateInfo.ConfidenceStateIsDriftingDown += + FuzzyFunctionSignalIsDrifting(dist); } - CONFDATATYPE Divider; + if(DriftLookbackRange<=DABHistory.numberOfEntries()) - Divider = DriftLookbackRange; + Divider += DriftLookbackRange; else - Divider = DABHistory.numberOfEntries(); - - SignalStateInfo.ConfidenceStateIsStable /= Divider; - SignalStateInfo.ConfidenceStateIsDrifting /= Divider; - - // TODO: change something because it is biased if the are equal - DriftDirectionIsUp = DriftUpCounter > DriftDnCounter; + Divider += DABHistory.numberOfEntries(); } } + SignalStateInfo.ConfidenceStateIsStable /= Divider; + SignalStateInfo.ConfidenceStateIsDriftingDown /= Divider; + SignalStateInfo.ConfidenceStateIsDriftingUp /= Divider; + + if (SignalStateInfo.ConfidenceStateIsDriftingDown > + SignalStateInfo.ConfidenceStateIsDriftingUp) { + SignalStateInfo.ConfidenceStateIsDrifting = SignalStateInfo.ConfidenceStateIsDriftingDown; + SignalStateInfo.StateCondition = StateConditions::DRIFTING_DN; + } + else if (SignalStateInfo.ConfidenceStateIsDriftingUp > + SignalStateInfo.ConfidenceStateIsDriftingDown) { + SignalStateInfo.ConfidenceStateIsDrifting = SignalStateInfo.ConfidenceStateIsDriftingUp; + SignalStateInfo.StateCondition = StateConditions::DRIFTING_UP; + } + else + SignalStateInfo.StateCondition = StateConditions::STABLE; + if (SignalStateInfo.ConfidenceStateIsStable > SignalStateInfo.ConfidenceStateIsDrifting) { SignalStateInfo.StateCondition = StateConditions::STABLE; - } else if (SignalStateInfo.ConfidenceStateIsStable < - SignalStateInfo.ConfidenceStateIsDrifting) { - - if (DriftDirectionIsUp) { - SignalStateInfo.StateCondition = StateConditions::DRIFTING_UP; - } else { - SignalStateInfo.StateCondition = StateConditions::DRIFTING_DN; - } - } else { + } + else if (SignalStateInfo.ConfidenceStateIsStable == + SignalStateInfo.ConfidenceStateIsDrifting) SignalStateInfo.StateCondition = StateConditions::UNKNOWN; - } } }; // namespace agent } // namespace agent } // End namespace rosa #endif // ROSA_AGENT_SIGNALSTATE_HPP diff --git a/include/rosa/agent/State.hpp b/include/rosa/agent/State.hpp index ca267b5..6dc2481 100644 --- a/include/rosa/agent/State.hpp +++ b/include/rosa/agent/State.hpp @@ -1,97 +1,99 @@ //===-- rosa/agent/State.hpp ------------------------------------*- C++ -*-===// // // The RoSA Framework // // Distributed under the terms and conditions of the Boost Software License 1.0. // See accompanying file LICENSE. // // If you did not receive a copy of the license file, see // http://www.boost.org/LICENSE_1_0.txt. // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/State.hpp /// /// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *state* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_STATE_HPP #define ROSA_AGENT_STATE_HPP #include "rosa/agent/Functionality.h" //#include "rosa/agent/FunctionAbstractions.hpp" //#include "rosa/agent/History.hpp" #include "rosa/support/debug.hpp" #include //#include namespace rosa { namespace agent { /// State conditions defining how the condition of a \c rosa::agent::State is /// saved in \c rosa::agent::StateInformation. enum StateConditions : uint8_t { UNKNOWN = '0', ///< The state is unknown STABLE = '1', ///< The state is stable DRIFTING_DN = '2', ///< The state is drifting down DRIFTING = '3', ///< The state is drifting down or up DRIFTING_UP = '4', ///< The state is drifting up MALFUNCTIONING = '5' ///< Malfunction }; template struct StateInformation { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "confidence type is not to arithmetic"); /// The StateID stores the ID of the state. unsigned int StateID; /// The StateCondition shows the condition of a state (stable, drifting, or /// unknown) StateConditions StateCondition; /// The StateIsValid shows whether a state is valid or invalid. In this /// context, valid means that enough samples which are in close proximitry /// have been inserted into the state. bool StateIsValid; /// The StateJustGotValid shows whether a state got valid (toggled from /// invalid to valid) during the current inserted sample. bool StateJustGotValid; /// The StateIsValidAfterReentrance shows whether a state is valid after the /// variable changed back to it again. bool StateIsValidAfterReentrance; /// TODO: describe CONFDATATYPE ConfidenceStateIsValid; CONFDATATYPE ConfidenceStateIsInvalid; CONFDATATYPE ConfidenceStateIsStable; CONFDATATYPE ConfidenceStateIsDrifting; + CONFDATATYPE ConfidenceStateIsDriftingUp; + CONFDATATYPE ConfidenceStateIsDriftingDown; }; template class State : 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 abstraction type is not to arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "process type is not to arithmetic"); protected: }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_SIGNALSTATEDETECTOR_HPP