diff --git a/include/rosa/agent/SystemState.hpp b/include/rosa/agent/SystemState.hpp index b6cdf4c..3d3774f 100644 --- a/include/rosa/agent/SystemState.hpp +++ b/include/rosa/agent/SystemState.hpp @@ -1,297 +1,289 @@ //===-- rosa/agent/SystemState.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/SystemState.hpp /// /// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *system state* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_SYSTEMSTATE_HPP #define ROSA_AGENT_SYSTEMSTATE_HPP #include "rosa/agent/Functionality.h" #include "rosa/agent/SignalState.hpp" #include "rosa/agent/State.hpp" #include "rosa/support/debug.hpp" #include namespace rosa { namespace agent { enum class SystemStateRelation : uint8_t { STATEISMATCHING = 0, ///< The system state is matching ONLYINPUTISMATCHING = 1, ///< Only inputs of the system state are matching ONLYOUTPUTISMATCHING = 2, ///< Only outputs of the system state are matching STATEISMISMATCHING = 3 ///< The system state is mismatching }; /// TODO: write description template struct SystemStateInformation : StateInformation { /// TODO: describe CONFDATATYPE ConfidenceOfInputsMatchingState; CONFDATATYPE ConfidenceOfInputsMismatchingState; CONFDATATYPE ConfidenceOfOutputsMatchingState; CONFDATATYPE ConfidenceOfOutputsMismatchingState; CONFDATATYPE ConfidenceSystemIsFunctioning; CONFDATATYPE ConfidenceSystemIsMalfunctioning; CONFDATATYPE ConfidenceOfAllDecisions; public: SystemStateInformation() {} SystemStateInformation(unsigned int _SystemStateID, StateConditions _StateCondition) { this->StateID = _SystemStateID; this->StateCondition = _StateCondition; this->StateIsValid = false; this->StateJustGotValid = false; this->StateIsValidAfterReentrance = false; this->ConfidenceOfInputsMatchingState = 0; this->ConfidenceOfInputsMismatchingState = 0; this->ConfidenceOfOutputsMatchingState = 0; this->ConfidenceOfOutputsMismatchingState = 0; this->ConfidenceSystemIsFunctioning = 0; this->ConfidenceSystemIsMalfunctioning = 0; this->ConfidenceOfAllDecisions = 0; } }; // todo: do we need PROCDATATYPE? /// TODO TEXT template class SystemState : public State { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT(std::is_arithmetic::value, "input data type is not to arithmetic"); STATIC_ASSERT(std::is_arithmetic::value, "confidence abstraction type is not to arithmetic"); STATIC_ASSERT(std::is_arithmetic::value, "process data type is not to arithmetic"); private: /// SignalStateInfo is a struct of SignalStateInformation that contains /// information about the current signal state. SystemStateInformation SystemStateInfo; std::vector> SignalStateInfos; uint32_t NumberOfSignals; public: /// TODO: write description SystemState(uint32_t StateID, uint32_t NumberOfSignals) noexcept : SystemStateInfo(StateID, StateConditions::UNKNOWN), NumberOfSignals(NumberOfSignals) { SignalStateInfos.resize(NumberOfSignals); } /// Destroys \p this object. ~SystemState(void) = default; /// TODO: write description SystemStateInformation insertSignalStateInformation( const std::vector> _SignalStateInfos) noexcept { ASSERT(_SignalStateInfos.size() == NumberOfSignals); bool AllSignalsAreValid = true; bool AtLeastOneSignalJustGotValid = false; bool AllSignalsAreValidAfterReentrance = true; bool AtLeastOneSignalIsUnknown = false; bool AllSignalsAreStable = true; // TODO: change this SystemStateInfo.ConfidenceOfInputsMatchingState = 1; SystemStateInfo.ConfidenceOfInputsMismatchingState = 0; SystemStateInfo.ConfidenceOfOutputsMatchingState = 1; SystemStateInfo.ConfidenceOfOutputsMismatchingState = 0; SystemStateInfo.ConfidenceStateIsValid = 1; SystemStateInfo.ConfidenceStateIsInvalid = 0; SystemStateInfo.ConfidenceStateIsStable = 1; SystemStateInfo.ConfidenceStateIsDrifting = 0; std::size_t counter = 0; for (auto SSI : _SignalStateInfos) { if (!SSI.StateIsValid) AllSignalsAreValid = false; if (SSI.StateJustGotValid) AtLeastOneSignalJustGotValid = true; if (!SSI.StateIsValidAfterReentrance) AllSignalsAreValidAfterReentrance = false; if (SSI.StateCondition == StateConditions::UNKNOWN) AtLeastOneSignalIsUnknown = true; if (SSI.StateCondition == StateConditions::DRIFTING) AllSignalsAreStable = false; if (SSI.SignalProperty == SignalProperties::INPUT) { - // printf("AAAAAAAAAAAAAAAA 6\n"); - // printf("SystemStateInfo.ConfidenceOfInputsMatchingState = %f\nSSI." - //"ConfidenceOfMatchingState = %f\n", - // SystemStateInfo.ConfidenceOfInputsMatchingState, - // SSI.ConfidenceOfMatchingState); - SystemStateInfo.ConfidenceOfInputsMatchingState = - fuzzyAND(SystemStateInfo.ConfidenceOfInputsMatchingState, - SSI.ConfidenceOfMatchingState); + SystemStateInfo.ConfidenceOfInputsMatchingState = + fuzzyAND(SystemStateInfo.ConfidenceOfInputsMatchingState, + SSI.ConfidenceOfMatchingState); SystemStateInfo.ConfidenceOfInputsMismatchingState = fuzzyOR(SystemStateInfo.ConfidenceOfInputsMismatchingState, SSI.ConfidenceOfMismatchingState); } else { - // printf("AAAAAAAAAAAAAAAA 7\n"); SystemStateInfo.ConfidenceOfOutputsMatchingState = fuzzyAND(SystemStateInfo.ConfidenceOfOutputsMatchingState, SSI.ConfidenceOfMatchingState); SystemStateInfo.ConfidenceOfOutputsMismatchingState = fuzzyOR(SystemStateInfo.ConfidenceOfOutputsMismatchingState, SSI.ConfidenceOfMismatchingState); } - // printf("AAAAAAAAAAAAAAAA 8\n"); SystemStateInfo.ConfidenceStateIsValid = fuzzyAND( SystemStateInfo.ConfidenceStateIsValid, SSI.ConfidenceStateIsValid); - // printf("AAAAAAAAAAAAAAAA 9\n"); SystemStateInfo.ConfidenceStateIsInvalid = fuzzyOR(SystemStateInfo.ConfidenceStateIsInvalid, SSI.ConfidenceStateIsInvalid); SystemStateInfo.ConfidenceStateIsStable = fuzzyAND( SystemStateInfo.ConfidenceStateIsStable, SSI.ConfidenceStateIsStable); SystemStateInfo.ConfidenceStateIsDrifting = fuzzyOR(SystemStateInfo.ConfidenceStateIsDrifting, SSI.ConfidenceStateIsDrifting); this->SignalStateInfos.at(counter) = SSI; counter++; } SystemStateInfo.StateIsValid = AllSignalsAreValid; SystemStateInfo.StateJustGotValid = AllSignalsAreValid && AtLeastOneSignalJustGotValid; SystemStateInfo.StateIsValidAfterReentrance = AllSignalsAreValidAfterReentrance; if (AtLeastOneSignalIsUnknown) SystemStateInfo.StateCondition = StateConditions::UNKNOWN; else if (AllSignalsAreStable) SystemStateInfo.StateCondition = StateConditions::STABLE; else SystemStateInfo.StateCondition = StateConditions::DRIFTING; return SystemStateInfo; } /// TODO: write description // TODO (future): think about saving the state information in a history SystemStateRelation compareSignalStateInformation( const std::vector> _SignalStateInfos) noexcept { bool inputsAreMatching = true; bool outputsAreMatching = true; std::size_t counter = 0; for (auto SSI : _SignalStateInfos) { if (this->SignalStateInfos.at(counter).StateID != SSI.StateID) { if (SSI.SignalProperty == SignalProperties::INPUT) inputsAreMatching = false; else // SignalProperties::OUTPUT outputsAreMatching = false; } counter++; } if (inputsAreMatching && outputsAreMatching) return SystemStateRelation::STATEISMATCHING; else if (inputsAreMatching && !outputsAreMatching) return SystemStateRelation::ONLYINPUTISMATCHING; else if (!inputsAreMatching && outputsAreMatching) return SystemStateRelation::ONLYOUTPUTISMATCHING; else return SystemStateRelation::STATEISMISMATCHING; } #ifdef ADDITIONAL_FUNCTIONS /// TODO: write description template void insertSignalStateInformation( const std::array, size> &Data) noexcept { ASSERT(size <= NumberOfSignals); std::size_t counter = 0; for (auto tmp : Data) { Signals.at(counter) = tmp; counter++; } } /// TODO: write description template std::enable_if_t>...>, void> insertSignalStateInformation(Types... Data) { // TODO (future): think about saving the state information in a history insertSignalStateInfos( std::array, sizeof...(Data)>( {Data...})); } // returns true if they are identical /// TODO: write description template bool compareSignalStateInformation( const std::array, size> &Data) noexcept { // TODO (future): think about saving the state information in a history std::size_t counter = 0; for (auto tmp : Data) { if (Signals.at(counter) != tmp) return false; counter++; } return true; } // checks only the given amount /// TODO: write description template std::enable_if_t>...>, bool> compareSignalStateInformation(Types... Data) { return compareSignalStateInfos( std::array, sizeof...(Data)>( {Data...})); } #endif /// Gives information about the current signal state. /// /// \return a struct SignalStateInformation that contains information about /// the current signal state. SystemStateInformation systemStateInformation(void) noexcept { return SystemStateInfo; } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_SYSTEMSTATE_HPP diff --git a/include/rosa/agent/SystemStateDetector.hpp b/include/rosa/agent/SystemStateDetector.hpp index a25fa82..17e5f98 100644 --- a/include/rosa/agent/SystemStateDetector.hpp +++ b/include/rosa/agent/SystemStateDetector.hpp @@ -1,245 +1,242 @@ //===-- rosa/agent/SystemStateDetector.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/SystemStateDetector.hpp /// /// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *system state detector* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_SYSTEMSTATEDETECTOR_HPP #define ROSA_AGENT_SYSTEMSTATEDETECTOR_HPP #include "rosa/agent/Functionality.h" #include "rosa/agent/SignalState.hpp" #include "rosa/agent/StateDetector.hpp" #include "rosa/agent/SystemState.hpp" #include "rosa/support/debug.hpp" namespace rosa { namespace agent { /// TODO: write description template class SystemStateDetector : public StateDetector { using StateDetector = StateDetector; using PartFuncPointer = typename StateDetector::PartFuncPointer; private: // For the convinience to write a shorter data type name using SystemStatePtr = std::shared_ptr>; /// TODO: description uint32_t NumberOfSignals; /// The CurrentSystemState is a pointer to the (saved) system state in which /// the actual state of the observed system is. SystemStatePtr CurrentSystemState; /// The DetectedSystemStates is a history in that all detected system states /// are saved. DynamicLengthHistory DetectedSystemStates; /// TODO: description unsigned int TimeOfDisparity; /// The FuzzyFunctionDelayTimeToBeWorking is the fuzzy function that gives /// the /// confidence whether the system is still OK allthough an input change /// without an output change or vice versa. PartFuncPointer FuzzyFunctionTimeSystemFunctioning; /// The FuzzyFunctionDelayTimeToGetBroken is the fuzzy function that gives /// the confidence whether the system is Broken because of an input change /// without an output change or vice versa. A small time gap between the two /// shall be allowed. PartFuncPointer FuzzyFunctionTimeSystemMalfunctioning; public: // todo zwei parameter für variablen anzahl /// TODO: write description SystemStateDetector( uint32_t MaximumNumberOfSystemStates, uint32_t NumberOfSignals, PartFuncPointer FuzzyFunctionTimeSystemMalfunctioning, PartFuncPointer FuzzyFunctionTimeSystemFunctioning) noexcept : NumberOfSignals(NumberOfSignals), CurrentSystemState(nullptr), DetectedSystemStates(MaximumNumberOfSystemStates), TimeOfDisparity(0), FuzzyFunctionTimeSystemFunctioning(FuzzyFunctionTimeSystemFunctioning), FuzzyFunctionTimeSystemMalfunctioning( FuzzyFunctionTimeSystemMalfunctioning) { //@Benedikt: if I write "NextStateID(1), StateHasChanged(false)" before the //{}-brackets, the compiler tells me: "SystemStateDetector.hpp:72:9: error: // member initializer 'NextStateID'/'StateHasChanged' does not name a // non-static data member or base class" this->NextStateID = 1; this->StateHasChanged = false; } /// Destroys \p this object. ~SystemStateDetector(void) = default; /// TODO: write description SystemStateInformation detectSystemState(std::vector> SignalStateInfos) noexcept { SystemStateInformation SystemStateInfo; if (!CurrentSystemState) { ASSERT(DetectedSystemStates.empty()); SystemStatePtr S = createNewSystemState(); CurrentSystemState = S; SystemStateInfo = CurrentSystemState->insertSignalStateInformation(SignalStateInfos); } else { SystemStateRelation SysStateRel = CurrentSystemState->compareSignalStateInformation(SignalStateInfos); if (SysStateRel == SystemStateRelation::STATEISMATCHING) { TimeOfDisparity = 0; SystemStateInfo = CurrentSystemState->insertSignalStateInformation(SignalStateInfos); } else { // ONLYINPUTISMATCHING, ONLYOUTPUTISMATCHING, STATEISMISMATCHING if (!CurrentSystemState->systemStateInformation().StateIsValid) DetectedSystemStates.deleteEntry(CurrentSystemState); CurrentSystemState = nullptr; SystemStatePtr potentialSystemState = nullptr; // search all saved system states for (auto &SavedSystemState : DetectedSystemStates) { SysStateRel = SavedSystemState->compareSignalStateInformation(SignalStateInfos); if (SysStateRel == SystemStateRelation::STATEISMATCHING) { CurrentSystemState = SavedSystemState; break; } else if (SysStateRel == SystemStateRelation::ONLYINPUTISMATCHING || SysStateRel == SystemStateRelation::ONLYOUTPUTISMATCHING) { // TODO: choose best matching potentialSystemState = SavedSystemState; } } // actions depending whether state is matchin fully or only half if (CurrentSystemState) { TimeOfDisparity = 0; SystemStateInfo = CurrentSystemState->insertSignalStateInformation( SignalStateInfos); } else if (potentialSystemState) { TimeOfDisparity++; CurrentSystemState = potentialSystemState; SystemStateInfo = CurrentSystemState->systemStateInformation(); } else { SystemStatePtr S = createNewSystemState(); TimeOfDisparity = 0; CurrentSystemState = S; SystemStateInfo = CurrentSystemState->insertSignalStateInformation( SignalStateInfos); } } } // TODO: is this right? if i don't insert if broke, it will never be valid?! // right? if (!SystemStateInfo.StateIsValidAfterReentrance) { TimeOfDisparity = 0; } // TODO: maybe make reference instead of pointer SystemStateInfo.ConfidenceSystemIsFunctioning = (*FuzzyFunctionTimeSystemFunctioning)( static_cast(TimeOfDisparity)); SystemStateInfo.ConfidenceSystemIsMalfunctioning = (*FuzzyFunctionTimeSystemMalfunctioning)( static_cast(TimeOfDisparity)); if (SystemStateInfo.ConfidenceSystemIsMalfunctioning > SystemStateInfo.ConfidenceSystemIsFunctioning) SystemStateInfo.StateCondition = StateConditions::MALFUNCTIONING; if (SystemStateInfo.StateCondition == StateConditions::UNKNOWN) // TODO: think about a Confidence calculation when system state is unkown SystemStateInfo.ConfidenceOfAllDecisions = 0; else if (SystemStateInfo.StateCondition == StateConditions::STABLE) { - //printf("AAAAAAAAAAAAAAAA 10\n"); SystemStateInfo.ConfidenceOfAllDecisions = fuzzyAND( fuzzyOR( fuzzyAND(SystemStateInfo.ConfidenceOfInputsMatchingState, SystemStateInfo.ConfidenceOfOutputsMatchingState), fuzzyAND(SystemStateInfo.ConfidenceOfInputsMismatchingState, SystemStateInfo.ConfidenceOfOutputsMismatchingState)), SystemStateInfo.ConfidenceSystemIsFunctioning, SystemStateInfo.ConfidenceStateIsStable, SystemStateInfo.ConfidenceStateIsValid); } else if (SystemStateInfo.StateCondition == StateConditions::DRIFTING) { - //printf("AAAAAAAAAAAAAAAA 11\n"); SystemStateInfo.ConfidenceOfAllDecisions = fuzzyAND(SystemStateInfo.ConfidenceOfInputsMatchingState, SystemStateInfo.ConfidenceOfOutputsMatchingState, SystemStateInfo.ConfidenceStateIsDrifting, SystemStateInfo.ConfidenceStateIsValid); } else if (SystemStateInfo.StateCondition == StateConditions::MALFUNCTIONING) { - //printf("AAAAAAAAAAAAAAAA 12\n"); SystemStateInfo.ConfidenceOfAllDecisions = fuzzyAND(SystemStateInfo.ConfidenceOfInputsMismatchingState, SystemStateInfo.ConfidenceOfOutputsMismatchingState, SystemStateInfo.ConfidenceSystemIsMalfunctioning, SystemStateInfo.ConfidenceStateIsValid); } if (SystemStateInfo.StateJustGotValid) { this->NextStateID++; } return SystemStateInfo; } private: /// Creates a new system state and adds it to the system state vector in /// which /// all known states are saved. /// /// \return a pointer to the newly created signal state or NULL if no state /// could be created. SystemStatePtr createNewSystemState(void) noexcept { SystemStatePtr S(new SystemState( this->NextStateID, this->NumberOfSignals)); DetectedSystemStates.addEntry(S); return S; } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_SYSTEMSTATEDETECTOR_HPP