diff --git a/include/rosa/agent/SignalStateDetector.hpp b/include/rosa/agent/SignalStateDetector.hpp index 8c77758..288cf74 100644 --- a/include/rosa/agent/SignalStateDetector.hpp +++ b/include/rosa/agent/SignalStateDetector.hpp @@ -1,402 +1,356 @@ //===-- rosa/agent/StateDetector.hpp ----------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/StateDetector.hpp /// /// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *state detector* *functionality*. /// //===----------------------------------------------------------------------===// -<<<<<<< HEAD -======= -// TODO: noexcept ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 #ifndef ROSA_AGENT_STATEDETECTOR_HPP #define ROSA_AGENT_STATEDETECTOR_HPP #include "rosa/agent/FunctionAbstractions.hpp" #include "rosa/agent/Functionality.h" #include "rosa/agent/SignalState.hpp" #include // TODO: change everything from state to signal state namespace rosa { namespace agent { /// Implements \c rosa::agent::StateDetector as a functionality that detects /// states given on input samples. /// /// \note This implementation is supposed to be used for samples of an /// arithmetic type. /// /// \tparam INDATATYPE is the type of input data, \tparam CONFDATATYPE is type /// of /// data in that the confidence values are given template class SignalStateDetector : 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"); private: // For the convinience to write a shorter data type name using PartFuncPointer = std::shared_ptr>; using StepFuncPointer = std::shared_ptr>; using StatePtr = std::shared_ptr>; using StateInfoPtr = std::shared_ptr>; /// The NextStateID is a counter variable which stores the ID which the next /// state shall have. unsigned int NextStateID; /// The SignalStateHasChanged is a flag that show whether a state change has /// happened. bool SignalStateHasChanged; /// The CurrentState is a pointer to the (saved) state in which the actual /// variable (signal) of the observed system is. StatePtr CurrentState; /// The DetectedStates is vector in that all detected states are saved. // TODO: make it to history std::vector DetectedStates; /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the /// confidence how good the new sample matches another sample in the sample /// history. PartFuncPointer FuzzyFunctionSampleMatches; /// The FuzzyFunctionSampleMismatches is the fuzzy function that gives the /// confidence how bad the new sample matches another sample in the sample /// history. PartFuncPointer FuzzyFunctionSampleMismatches; /// The FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the /// confidence how many samples from the sampe history match the new sample. StepFuncPointer FuzzyFunctionNumOfSamplesMatches; /// The FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives /// the confidence how many samples from the sampe history mismatch the new /// sample. StepFuncPointer FuzzyFunctionNumOfSamplesMismatches; /// The FuzzyFunctionSignalIsDrifting is the fuzzy function that gives the /// confidence how likely it is that the signal is drifting. PartFuncPointer FuzzyFunctionSignalIsDrifting; /// The FuzzyFunctionSignalIsStable is the fuzzy function that gives the /// confidence how likely it is that the signal is stable (not drifting). PartFuncPointer FuzzyFunctionSignalIsStable; /// SampleHistorySize is the (maximum) size of the sample history. unsigned int SampleHistorySize; /// DABSize the size of a DAB (Discrete Average Block). unsigned int DABSize; /// DABHistorySize is the (maximum) size of the DAB history. unsigned int DABHistorySize; public: /// Creates an instance by setting all parameters -<<<<<<< HEAD - SignalStateDetector(PartFuncPointer FuzzyFunctionSampleMatches, - PartFuncPointer FuzzyFunctionSampleMismatches, - StepFuncPointer FuzzyFunctionNumOfSamplesMatches, - StepFuncPointer FuzzyFunctionNumOfSamplesMismatches, - PartFuncPointer FuzzyFunctionSignalIsDrifting, - PartFuncPointer FuzzyFunctionSignalIsStable, - unsigned int SampleHistorySize, unsigned int DABSize, - unsigned int DABHistorySize) noexcept - : NextStateID(1), SignalStateHasChanged(false), CurrentState(NULL), -======= /// \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 Sets the History size which will be used by \c /// State . /// /// \param DABSize Sets the DAB size which will be used by \c State . /// /// \param DABHistorySize Sets the size which will be used by \c State . /// StateDetector(PartFuncPointer FuzzyFunctionSampleMatches, PartFuncPointer FuzzyFunctionSampleMismatches, StepFuncPointer FuzzyFunctionNumOfSamplesMatches, StepFuncPointer FuzzyFunctionNumOfSamplesMismatches, PartFuncPointer FuzzyFunctionSignalIsDrifting, PartFuncPointer FuzzyFunctionSignalIsStable, unsigned int SampleHistorySize, unsigned int DABSize, unsigned int DABHistorySize) noexcept : NextStateID(1), StateHasChanged(false), CurrentState(NULL), ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches), FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches), FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches), FuzzyFunctionNumOfSamplesMismatches( FuzzyFunctionNumOfSamplesMismatches), FuzzyFunctionSignalIsDrifting(FuzzyFunctionSignalIsDrifting), FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable), SampleHistorySize(SampleHistorySize), DABSize(DABSize), DABHistorySize(DABHistorySize) {} /// Destroys \p this object. ~SignalStateDetector(void) = default; /// Detects a signal state to which the new sample belongs or create a new /// state if /// the new sample does not match to any of the saved states. /// /// \param Sample is the actual sample of the observed signal. /// -<<<<<<< HEAD /// \return the signal state ID as unsigend integer type. State IDs start with /// number -======= - /// \return the state ID as unsigned integer type. State IDs start with number ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 /// 1; that means if there is no current state, the return value is 0. unsigned int detectSignalState(INDATATYPE Sample) noexcept { StateInfoPtr StateInfo = detectState__debug(Sample); return StateInfo->StateID; } /// Gives information about the current state. /// /// \return a the Signal State ID (as unsigned integer type) of the current /// state. /// State IDs start with number 1; that means if there is no current state, /// the return value is 0. unsigned int currentSignalStateInformation(void) noexcept { StateInfoPtr StateInfo = currentStateInformation__debug(); if (StateInfo) { return StateInfo->StateID; } else { return 0; } } /// Gives information whether a state change has happened or not. /// /// \return true if a state change has happened, and false if not. bool SignallStateHasChanged(void) noexcept { return SignallStateHasChanged; } private: -<<<<<<< HEAD // TODO: change exlaination! it is not totally right -======= //@maxi \param is there to Document a specific parameter of a method/function // this method doesn't have any parameters. ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 /// Creates a new state and adds this state to the state vector in which all /// known states are saved. /// /// \param SampleHistorySize the (maximum) size of the sample history. /// \param DABSize the size of a DAB. /// \param DABHistorySize the (maximum) size of the DAB history. /// \param FuzzyFunctionSampleMatches the /// \param FuzzyFunctionSampleMismatches /// \param FuzzyFunctionNumOfSamplesMatches /// \param FuzzyFunctionNumOfSamplesMismatches /// -<<<<<<< HEAD - /// \return the new created state or NULL if no state could be created. - StatePtr createNewState(void) noexcept { -======= /// \return a pointer to the newly created state or NULL if no state could be /// created. - StatePtr createNewState(void) { ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 - + StatePtr createNewState(void) noexcept { StatePtr S = new (std::nothrow) State( NextStateID, SampleHistorySize, DABSize, DABHistorySize, FuzzyFunctionSampleMatches, FuzzyFunctionSampleMismatches, FuzzyFunctionNumOfSamplesMatches, FuzzyFunctionNumOfSamplesMismatches); // @benedikt: todo: assert in history, which checks if push_back worked DetectedStates.push_back(S); return S; } #ifdef STATEDETECTORDEBUGMODE public: #else private: #endif // STATEDETECTORDEBUGMODE // @maxi is this a debug method or is it a method that will be used and // you simply want to have access to it in debug mode? // debug -> extend the preprocessor around the function // access -> remove the __debug from the name ( it is confusing) // if you want to have it marked as a debug method for auto // complete you can do something like this : // //#ifdef STATEDETECTORDEBUGMODE // public: // StateInfoPtr debug_detectState(INDATATYPE Sample) { // return detectState(Sample); // } //#endif // STATEDETECTORDEBUGMODE // private : // StateInfoPtr detectState(INDATATYPE Sample) { ... // - /// Detects the state to which the new sample belongs or create a new state if /// the new sample does not match to any of the saved states. /// /// \param Sample is the actual sample of the observed signal. /// /// \return the information of the actual state (state ID and other /// parameters). -<<<<<<< HEAD - StateInfoPtr detectState__debug(INDATATYPE Sample) noexcept { -======= // TODO: return something const.. cannot remember exactly (ask benedikt) // - // maby: you are returning a pointer to the state info so who ever has that + // maybe: you are returning a pointer to the state info so who ever has that // pointer can actually change the information if you want to return only the // *current info* return a copy of the state info // like this: // // StateInfoPtr detectState__debug(INDATATYPE Sample) -> // StateInformation detectState__debug(INDATATYPE Sample) // // return CurrentState->stateInformation(); -> // return *(CurrentState->stateInformation()); - StateInfoPtr detectState__debug(INDATATYPE Sample) { ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 + StateInfoPtr detectState__debug(INDATATYPE Sample) noexcept { if (!CurrentState) { ASSERT(DetectedStates.empty()); StatePtr S = createNewState(); CurrentState = S; } else { CONFDATATYPE ConfidenceSampleMatchesState = CurrentState->confSampleMatchesState(Sample); CONFDATATYPE ConfidenceSampleMismatchesState = CurrentState->confSampleMismatchesState(Sample); if (ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) { SignalStateHasChanged = false; } else { SignalStateHasChanged = true; if (CurrentState->stateInformation()->StateIsValid) { CurrentState->leaveState(); } else { DetectedStates.erase(std::find(DetectedStates.begin(), DetectedStates.end(), CurrentState)); } // TODO (future): additionally save averages to enable fast // iteration through recorded state vector (maybe sort vector based on // these average values) CurrentState = nullptr; for (auto &SavedState : DetectedStates) { if (SavedState != CurrentState) { CONFDATATYPE ConfidenceSampleMatchesState = SavedState->confSampleMatchesState(Sample); CONFDATATYPE ConfidenceSampleMismatchesState = SavedState->confSampleMismatchesState(Sample); if (ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) { // TODO (future): maybe it would be better to compare // ConfidenceSampleMatchesState of all states in the vector in // order to find the best matching state. CurrentState = SavedState; break; } } } if (!CurrentState) { StatePtr S = createNewState(); CurrentState = S; } } } -<<<<<<< HEAD StateInformation StateInfo = CurrentState->insertSample(Sample); -======= - // State::insertSample() current return type: void - StateInfoPtr StateInfo = CurrentState->insertSample(Sample); ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 if (StateInfo.StateJustGotValid) { NextStateID++; } return StateInfo; } #ifdef STATEDETECTORDEBUGMODE public: #else private: #endif // STATEDETECTORDEBUGMODE - //@maxi here again are you sure you want to return the pointer? /// Gives information about the current state. /// -<<<<<<< HEAD /// \return a struct StateInformation that contains information about the /// current state or NULL if no current state exists. StateInformation currentStateInformation__debug(void) noexcept { -======= - /// \return a pointer to a struct StateInformation that contains information - /// about the current state or NULL if no current state exists. - StateInfoPtr currentStateInformation__debug(void) { ->>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 if (CurrentState) { return CurrentState->stateInformation(); } else { return NULL; } } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_STATEDETECTOR_HPP