Page MenuHomePhorge

No OneTemporary

Size
61 KB
Referenced Files
None
Subscribers
None
diff --git a/include/rosa/agent/SignalState.hpp b/include/rosa/agent/SignalState.hpp
index b6149a4..a4b3cd8 100644
--- a/include/rosa/agent/SignalState.hpp
+++ b/include/rosa/agent/SignalState.hpp
@@ -1,470 +1,469 @@
//===-- 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/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
};
-/// Signal state conditions defining how the condition of a \c
-/// rosa::agent::SignalState is saved in \c rosa::agent::SignalStateInformation.
-enum SignalStateCondition : uint8_t {
- STABLE = 0, ///< The signal state is stable
- DRIFTING = 1, ///< The signal state is drifting
- UNKNOWN = 2 ///< The signal state is unknown
-};
-
/// TODO: write description
-template <typename CONFDATATYPE> struct SignalStateInformation {
+template <typename CONFDATATYPE>
+struct SignalStateInformation : StateInformation<CONFDATATYPE> {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::value),
"confidence type is not to arithmetic");
-
- /// The signal state ID saved as an uint32_teger number
- uint32_t SignalStateID;
/// The SignalProperty saves whether the monitored signal is an input our
/// output signal.
SignalProperties SignalProperty;
- /// The SignalStateConfidence shows the overall confidence value of the signal
- /// state.
- CONFDATATYPE SignalStateConfidence;
- /// The SignalStateCondition shows the condition of a signal state (stable,
- /// drifting, or unknown)
- SignalStateCondition SignalStateCondition;
+
/// The SignalStateIsValid saves the number of samples which have been
/// inserted into the state after entering it.
uint32_t NumberOfInsertedSamplesAfterEntrance;
- /// The SignalStateIsValid shows whether a signal state is valid or invalid.
- /// In this context, valid means that enough samples which are in close
- /// proximitry have been inserted into the signal state.
- bool SignalStateIsValid;
- /// The SignalStateJustGotValid shows whether a signal state got valid
- /// (toggled from invalid to valid) during the current inserted sample.
- bool SignalStateJustGotValid;
- /// The SignalStateIsValidAfterReentrance shows whether a signal state is
- /// valid after the variable changed back to it again.
- bool SignalStateIsValidAfterReentrance;
};
/// \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 <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE>
class SignalState : public Functionality {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
"input data type not arithmetic");
STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::value),
"confidence data type is not to arithmetic");
STATIC_ASSERT(
(std::is_arithmetic<PROCDATATYPE>::value),
"process data type (DAB and Relative Distance) is not to arithmetic");
public:
// For the convinience to write a shorter data type name
using PartFuncReference = PartialFunction<INDATATYPE, CONFDATATYPE> &;
using StepFuncReference = StepFunction<INDATATYPE, CONFDATATYPE> &;
private:
- /// SignalStateInfo is a struct SignalStateInformation that contains
- /// information about the current state.
+ /// SignalStateInfo is a struct of SignalStateInformation that contains
+ /// information about the current signal state.
SignalStateInformation<CONFDATATYPE> SignalStateInfo;
/// 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 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;
/// SampleHistory is a history in that the last sample values are stored.
DynamicLengthHistory<INDATATYPE, HistoryPolicy::FIFO> SampleHistory;
/// DAB is a (usually) small history of the last sample values of which a
/// average is calculated if the DAB is full.
DynamicLengthHistory<INDATATYPE, HistoryPolicy::SRWF> DAB;
/// DABHistory is a history in that the last DABs (to be exact, the averages
/// of the last DABs) are stored.
DynamicLengthHistory<PROCDATATYPE, HistoryPolicy::LIFO> DABHistory;
/// LowestConfidenceMatchingHistory is a history in that the lowest confidence
/// for the current sample matches all history samples are saved.
DynamicLengthHistory<INDATATYPE, HistoryPolicy::FIFO>
LowestConfidenceMatchingHistory;
/// HighestConfidenceMatchingHistory is a history in that the highest
/// confidence for the current sample matches all history samples are saved.
DynamicLengthHistory<INDATATYPE, HistoryPolicy::FIFO>
HighestConfidenceMismatchingHistory;
+ //@benedikt: neu (passt das so?)
+ CONFDATATYPE TempConfidenceMatching;
+ CONFDATATYPE TempConfidenceMismatching;
+
public:
/// Creates an instance by setting all parameters
/// \param SignalStateID The Id of the SignalStateinfo \c
/// SignalStateInformation.
///
/// \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,
PartFuncReference FuzzyFunctionSampleMatches,
PartFuncReference FuzzyFunctionSampleMismatches,
StepFuncReference FuzzyFunctionNumOfSamplesMatches,
StepFuncReference FuzzyFunctionNumOfSamplesMismatches,
PartFuncReference FuzzyFunctionSignalIsDrifting,
PartFuncReference FuzzyFunctionSignalIsStable) noexcept
- : SignalStateInfo{SignalStateID,
- SignalProperty,
- 0,
- SignalStateCondition::UNKNOWN,
- 0,
+ : //@benedikt/@david: I don't know if i am allowed to initialize it like
+ // that because the struct is a derivate of another struct
+ SignalStateInfo{SignalStateID,
+ StateConditions::UNKNOWN,
+ false,
false,
false,
- false},
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ SignalProperty,
+ 0},
FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches),
FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches),
FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches),
FuzzyFunctionNumOfSamplesMismatches(
FuzzyFunctionNumOfSamplesMismatches),
FuzzyFunctionSignalIsDrifting(FuzzyFunctionSignalIsDrifting),
FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable),
SampleHistory(SampleHistorySize), DAB(DABSize),
DABHistory(DABHistorySize),
LowestConfidenceMatchingHistory(SampleHistorySize),
HighestConfidenceMismatchingHistory(SampleHistorySize) {}
/// Destroys \p this object.
~SignalState(void) = default;
void leaveSignalState(void) noexcept {
DAB.clear();
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance = 0;
- SignalStateInfo.SignalStateIsValidAfterReentrance = false;
+ SignalStateInfo.StateIsValidAfterReentrance = false;
}
SignalStateInformation<CONFDATATYPE>
insertSample(INDATATYPE Sample) noexcept {
validateSignalState(Sample);
SampleHistory.addEntry(Sample);
DAB.addEntry(Sample);
if (DAB.full()) {
PROCDATATYPE AvgOfDAB = DAB.template average<PROCDATATYPE>();
DABHistory.addEntry(AvgOfDAB);
DAB.clear();
}
FuzzyFunctionNumOfSamplesMatches.setRightLimit(
static_cast<INDATATYPE>(SampleHistory.numberOfEntries()));
FuzzyFunctionNumOfSamplesMismatches.setRightLimit(
static_cast<INDATATYPE>(SampleHistory.numberOfEntries()));
checkSignalStability();
+ //@benedikt (das gehört dazu)
+ 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<PROCDATATYPE, HistoryPolicy::FIFO>
RelativeDistanceHistory(SampleHistory.maxLength());
// calculate distances to all history samples
for (auto &HistorySample : SampleHistory) {
PROCDATATYPE RelativeDistance =
relativeDistance<INDATATYPE, PROCDATATYPE>(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<CONFDATATYPE>(Case) + 1)));
}
+ //@benedikt (das gehört dazu)
+ 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<PROCDATATYPE, HistoryPolicy::FIFO>
RelativeDistanceHistory(SampleHistory.maxLength());
// calculate distances to all history samples
for (auto &HistorySample : SampleHistory) {
RelativeDistanceHistory.addEntry(
relativeDistance<INDATATYPE, PROCDATATYPE>(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<CONFDATATYPE>(Case) + 1)));
}
+ //@benedikt (das gehört dazu)
+ TempConfidenceMismatching = ConfidenceOfWorstCase;
+
return ConfidenceOfWorstCase;
}
/// Gives information about the current signal state.
///
/// \return a struct SignalStateInformation that contains information about
/// the current signal state.
SignalStateInformation<CONFDATATYPE> 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(relativeDistance<INDATATYPE, PROCDATATYPE>(
Sample, HistorySample)));
HighestConfidenceMismatching =
fuzzyOR(HighestConfidenceMismatching,
FuzzyFunctionSampleMismatches(
relativeDistance<INDATATYPE, PROCDATATYPE>(
Sample, HistorySample)));
}
LowestConfidenceMatchingHistory.addEntry(LowestConfidenceMatching);
HighestConfidenceMismatchingHistory.addEntry(HighestConfidenceMismatching);
LowestConfidenceMatching = LowestConfidenceMatchingHistory.lowestEntry();
HighestConfidenceMismatching =
HighestConfidenceMismatchingHistory.highestEntry();
- CONFDATATYPE ConfidenceSignalStateIsValid =
+ SignalStateInfo.ConfidenceStateIsValid =
fuzzyAND(LowestConfidenceMatching,
FuzzyFunctionNumOfSamplesMatches(static_cast<INDATATYPE>(
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
- CONFDATATYPE ConfidenceSignalStateIsInvalid =
+ SignalStateInfo.ConfidenceStateIsInvalid =
fuzzyOR(HighestConfidenceMismatching,
FuzzyFunctionNumOfSamplesMismatches(static_cast<INDATATYPE>(
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
- if (ConfidenceSignalStateIsValid > ConfidenceSignalStateIsInvalid) {
- if (SignalStateInfo.SignalStateIsValid) {
- SignalStateInfo.SignalStateJustGotValid = false;
+ if (SignalStateInfo.ConfidenceStateIsValid >
+ SignalStateInfo.ConfidenceStateIsInvalid) {
+ if (SignalStateInfo.StateIsValid) {
+ SignalStateInfo.StateJustGotValid = false;
} else {
- SignalStateInfo.SignalStateJustGotValid = true;
+ SignalStateInfo.StateJustGotValid = true;
}
- SignalStateInfo.SignalStateIsValid = true;
- SignalStateInfo.SignalStateIsValidAfterReentrance = true;
+ SignalStateInfo.StateIsValid = true;
+ SignalStateInfo.StateIsValidAfterReentrance = true;
}
}
void checkSignalStability(void) {
- CONFDATATYPE ConfidenceSignalIsStable;
- CONFDATATYPE ConfidenceSignalIsDrifting;
if (DABHistory.numberOfEntries() >= 2) {
- ConfidenceSignalIsStable = FuzzyFunctionSignalIsStable(
+ SignalStateInfo.ConfidenceStateIsStable = FuzzyFunctionSignalIsStable(
relativeDistance<INDATATYPE, PROCDATATYPE>(
DABHistory[DABHistory.numberOfEntries() - 1], DABHistory[0]));
- ConfidenceSignalIsDrifting = FuzzyFunctionSignalIsDrifting(
+ SignalStateInfo.ConfidenceStateIsDrifting = FuzzyFunctionSignalIsDrifting(
relativeDistance<INDATATYPE, PROCDATATYPE>(
DABHistory[DABHistory.numberOfEntries() - 1], DABHistory[0]));
} else {
// @benedikt: I do not know if this "initializing" is the best, but I
// think it makes sense because we do not know if it is stable or
// drifting.
- ConfidenceSignalIsStable = 0;
- ConfidenceSignalIsDrifting = 0;
+ SignalStateInfo.ConfidenceStateIsStable = 0;
+ SignalStateInfo.ConfidenceStateIsDrifting = 0;
}
//@benedikt: before it was "ConfidenceSignalIsStable >=
// ConfidenceSignalIsDrifting" -> stable. However, I think like that it
// makes
// more sense. What do you mean?
- if (ConfidenceSignalIsStable > ConfidenceSignalIsDrifting) {
- SignalStateInfo.SignalStateCondition = SignalStateCondition::STABLE;
- } else if (ConfidenceSignalIsStable < ConfidenceSignalIsDrifting) {
- SignalStateInfo.SignalStateCondition = SignalStateCondition::DRIFTING;
+ if (SignalStateInfo.ConfidenceStateIsStable >
+ SignalStateInfo.ConfidenceStateIsDrifting) {
+ SignalStateInfo.StateCondition = StateConditions::STABLE;
+ } else if (SignalStateInfo.ConfidenceStateIsStable <
+ SignalStateInfo.ConfidenceStateIsDrifting) {
+ SignalStateInfo.StateCondition = StateConditions::DRIFTING;
} else {
- SignalStateInfo.SignalStateCondition = SignalStateCondition::UNKNOWN;
+ SignalStateInfo.StateCondition = StateConditions::UNKNOWN;
}
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SIGNALSTATE_HPP
diff --git a/include/rosa/agent/SignalStateDetector.hpp b/include/rosa/agent/SignalStateDetector.hpp
index 207a094..b5b6d71 100644
--- a/include/rosa/agent/SignalStateDetector.hpp
+++ b/include/rosa/agent/SignalStateDetector.hpp
@@ -1,285 +1,272 @@
//===-- rosa/agent/SignalStateDetector.hpp ----------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/SignalStateDetector.hpp
///
-/// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at)
+/// \author Maximilian Götzinger (maximilian.goet5zinger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *signal state detector* *functionality*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_SIGNALSTATEDETECTOR_HPP
#define ROSA_AGENT_SIGNALSTATEDETECTOR_HPP
#include "rosa/agent/Functionality.h"
#include "rosa/agent/SignalState.hpp"
#include "rosa/agent/StateDetector.hpp"
#include <vector>
namespace rosa {
namespace agent {
/// Implements \c rosa::agent::SignalStateDetector as a functionality that
/// detects signal states given on input samples.
///
/// \note This implementation is supposed to be used for samples of an
/// arithmetic type.
///
/// \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 <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE,
HistoryPolicy HP>
class SignalStateDetector
: public StateDetector<INDATATYPE, CONFDATATYPE, PROCDATATYPE, HP> {
// @maxi added them so it is compilable is this what you intended?
using StateDetector =
StateDetector<INDATATYPE, CONFDATATYPE, PROCDATATYPE, HP>;
using PartFuncPointer = typename StateDetector::PartFuncPointer;
using StepFuncPointer = typename StateDetector::StepFuncPointer;
private:
// For the convinience to write a shorter data type name
using SignalStatePtr =
std::shared_ptr<SignalState<INDATATYPE, CONFDATATYPE, PROCDATATYPE>>;
/// The SignalProperty saves whether the monitored signal is an input our
/// output signal.
SignalProperties SignalProperty;
- /// The NextSignalStateID is a counter variable which stores the ID which the
- /// next signal state shall have.
- uint32_t NextSignalStateID;
-
- /// The SignalStateHasChanged is a flag that show whether a signal has changed
- /// its state.
- bool SignalStateHasChanged;
-
/// The CurrentSignalState is a pointer to the (saved) signal state in which
/// the actual variable (signal) of the observed system is.
SignalStatePtr CurrentSignalState;
/// The DetectedSignalStates is a history in that all detected signal states
/// are saved.
DynamicLengthHistory<SignalStatePtr, HP> DetectedSignalStates;
/// 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.
uint32_t SampleHistorySize;
/// DABSize the size of a DAB (Discrete Average Block).
uint32_t DABSize;
/// DABHistorySize is the (maximum) size of the DAB history.
uint32_t DABHistorySize;
public:
/// Creates an instance by setting all parameters
/// \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
/// SignalState.
///
/// \param DABSize Sets the DAB size which will be used by \c SignalState.
///
/// \param DABHistorySize Sets the size which will be used by \c SignalState.
///
SignalStateDetector(SignalProperties SignalProperty,
uint32_t MaximumNumberOfSignalStates,
PartFuncPointer FuzzyFunctionSampleMatches,
PartFuncPointer FuzzyFunctionSampleMismatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMismatches,
PartFuncPointer FuzzyFunctionSignalIsDrifting,
PartFuncPointer FuzzyFunctionSignalIsStable,
uint32_t SampleHistorySize, uint32_t DABSize,
uint32_t DABHistorySize) noexcept
- : // needed to be reorderd
- SignalProperty(SignalProperty), NextSignalStateID(1),
- SignalStateHasChanged(false), CurrentSignalState(nullptr),
+ : SignalProperty(SignalProperty), CurrentSignalState(nullptr),
DetectedSignalStates(MaximumNumberOfSignalStates),
FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches),
FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches),
FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches),
FuzzyFunctionNumOfSamplesMismatches(
FuzzyFunctionNumOfSamplesMismatches),
FuzzyFunctionSignalIsDrifting(FuzzyFunctionSignalIsDrifting),
FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable),
SampleHistorySize(SampleHistorySize), DABSize(DABSize),
- DABHistorySize(DABHistorySize) {}
+ DABHistorySize(DABHistorySize) {
+ this->NextStateID = 1;
+ this->StateHasChanged = false;
+ }
/// Destroys \p this object.
~SignalStateDetector(void) = default;
/// Detects the signal state to which the new sample belongs or create a new
/// signal 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 current signal state (signal state ID and
/// other parameters).
// TODO (future): change to operator()
SignalStateInformation<CONFDATATYPE>
detectSignalState(INDATATYPE Sample) noexcept {
if (!CurrentSignalState) {
ASSERT(DetectedSignalStates.empty());
-
SignalStatePtr S = createNewSignalState();
CurrentSignalState = S;
} else {
CONFDATATYPE ConfidenceSampleMatchesSignalState =
CurrentSignalState->confidenceSampleMatchesSignalState(Sample);
CONFDATATYPE ConfidenceSampleMismatchesSignalState =
CurrentSignalState->confidenceSampleMismatchesSignalState(Sample);
- if (ConfidenceSampleMatchesSignalState >
- ConfidenceSampleMismatchesSignalState) {
- SignalStateHasChanged = false;
- } else {
- SignalStateHasChanged = true;
+ this->StateHasChanged = ConfidenceSampleMatchesSignalState <=
+ ConfidenceSampleMismatchesSignalState;
+
+ if (this->StateHasChanged) {
- if (CurrentSignalState->signalStateInformation().SignalStateIsValid) {
+ if (CurrentSignalState->signalStateInformation().StateIsValid)
CurrentSignalState->leaveSignalState();
- } else {
+ else
DetectedSignalStates.deleteEntry(CurrentSignalState);
- }
// TODO (future): additionally save averages to enable fast iteration
// through recorded signl state history (maybe sort vector based on
// these average values)
CurrentSignalState = nullptr;
- //@benedikt: same question
for (auto &SavedSignalState : DetectedSignalStates) {
- if (SavedSignalState != CurrentSignalState) {
- ConfidenceSampleMatchesSignalState =
- SavedSignalState->confidenceSampleMatchesSignalState(Sample);
- ConfidenceSampleMismatchesSignalState =
- SavedSignalState->confidenceSampleMismatchesSignalState(Sample);
-
- if (ConfidenceSampleMatchesSignalState >
- ConfidenceSampleMismatchesSignalState) {
- // TODO (future): maybe it would be better to compare
- // ConfidenceSampleMatchesSignalState of all signal states in the
- // vector in order to find the best matching signal state.
- CurrentSignalState = SavedSignalState;
- break;
- }
+ ConfidenceSampleMatchesSignalState =
+ SavedSignalState->confidenceSampleMatchesSignalState(Sample);
+ ConfidenceSampleMismatchesSignalState =
+ SavedSignalState->confidenceSampleMismatchesSignalState(Sample);
+
+ if (ConfidenceSampleMatchesSignalState >
+ ConfidenceSampleMismatchesSignalState) {
+ // TODO (future): maybe it would be better to compare
+ // ConfidenceSampleMatchesSignalState of all signal states in the
+ // vector in order to find the best matching signal state.
+ CurrentSignalState = SavedSignalState;
+ break;
}
}
if (!CurrentSignalState) {
SignalStatePtr S = createNewSignalState();
CurrentSignalState = S;
}
}
}
SignalStateInformation<CONFDATATYPE> SignalStateInfo =
CurrentSignalState->insertSample(Sample);
- if (SignalStateInfo.SignalStateJustGotValid) {
- NextSignalStateID++;
+ if (SignalStateInfo.StateJustGotValid) {
+ this->NextStateID++;
}
return SignalStateInfo;
}
/// Gives information about the current signal state.
///
/// \return a struct SignalStateInformation that contains information about
/// the current signal state or NULL if no current signal state exists.
SignalStateInformation<CONFDATATYPE>
currentSignalStateInformation(void) noexcept {
if (CurrentSignalState) {
return CurrentSignalState->signalStateInformation();
} else {
return NULL;
}
}
/// Gives information whether a signal state change has happened or not.
///
/// \return true if a signal state change has happened, and false if not.
- bool signalStateHasChanged(void) noexcept { return SignalStateHasChanged; }
+ bool stateHasChanged(void) noexcept { return this->StateHasChanged; }
private:
/// Creates a new signal state and adds it to the signal 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.
SignalStatePtr createNewSignalState(void) noexcept {
SignalStatePtr S(new SignalState<INDATATYPE, CONFDATATYPE, PROCDATATYPE>(
- NextSignalStateID, SignalProperty, SampleHistorySize, DABSize,
+ this->NextStateID, SignalProperty, SampleHistorySize, DABSize,
DABHistorySize, *FuzzyFunctionSampleMatches,
*FuzzyFunctionSampleMismatches, *FuzzyFunctionNumOfSamplesMatches,
*FuzzyFunctionNumOfSamplesMismatches, *FuzzyFunctionSignalIsDrifting,
*FuzzyFunctionSignalIsStable));
DetectedSignalStates.addEntry(S);
return S;
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SIGNALSTATEDETECTOR_HPP
diff --git a/include/rosa/agent/State.hpp b/include/rosa/agent/State.hpp
new file mode 100644
index 0000000..1e19ef5
--- /dev/null
+++ b/include/rosa/agent/State.hpp
@@ -0,0 +1,90 @@
+//===-- rosa/agent/State.hpp ------------------------------------*- C++ -*-===//
+//
+// The RoSA Framework
+//
+//===----------------------------------------------------------------------===//
+///
+/// \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 <stdint.h>
+
+//#include <vector>
+
+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 = 2, ///< The state is drifting
+ MALFUNCTIONING = 3 ///< Malfunction
+};
+
+template <typename CONFDATATYPE> struct StateInformation {
+ // Make sure the actual type arguments are matching our expectations.
+ STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::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 ConfidenceOfMatchingState;
+ CONFDATATYPE ConfidenceOfMismatchingState;
+
+ CONFDATATYPE ConfidenceStateIsValid;
+ CONFDATATYPE ConfidenceStateIsInvalid;
+
+ CONFDATATYPE ConfidenceStateIsStable;
+ CONFDATATYPE ConfidenceStateIsDrifting;
+};
+
+template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE>
+class State : public Functionality {
+
+ // Make sure the actual type arguments are matching our expectations.
+ STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
+ "input data type not arithmetic");
+ STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::value),
+ "confidence abstraction type is not to arithmetic");
+ STATIC_ASSERT((std::is_arithmetic<PROCDATATYPE>::value),
+ "process type is not to arithmetic");
+
+protected:
+};
+
+} // End namespace agent
+} // End namespace rosa
+
+#endif // ROSA_AGENT_SIGNALSTATEDETECTOR_HPP
diff --git a/include/rosa/agent/StateDetector.hpp b/include/rosa/agent/StateDetector.hpp
index aa341f6..34b5298 100644
--- a/include/rosa/agent/StateDetector.hpp
+++ b/include/rosa/agent/StateDetector.hpp
@@ -1,56 +1,58 @@
//===-- 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*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_STATEDETECTOR_HPP
#define ROSA_AGENT_STATEDETECTOR_HPP
#include "rosa/agent/FunctionAbstractions.hpp"
#include "rosa/agent/History.hpp"
#include <vector>
namespace rosa {
namespace agent {
template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE,
HistoryPolicy HP>
class StateDetector : public Functionality {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
"input data type not arithmetic");
STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::value),
"confidence abstraction type is not to arithmetic");
+ STATIC_ASSERT((std::is_arithmetic<PROCDATATYPE>::value),
+ "process type is not to arithmetic");
protected:
using PartFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, CONFDATATYPE>>;
using StepFuncPointer =
std::shared_ptr<StepFunction<INDATATYPE, CONFDATATYPE>>;
/// The NextSignalStateID is a counter variable which stores the ID which the
/// next signal state shall have.
- unsigned int NextStateID;
+ uint32_t NextStateID;
/// The SignalStateHasChanged is a flag that show whether a signal has changed
/// its state.
bool StateHasChanged;
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SIGNALSTATEDETECTOR_HPP
diff --git a/include/rosa/agent/SystemState.hpp b/include/rosa/agent/SystemState.hpp
index d1b8920..7599e8e 100644
--- a/include/rosa/agent/SystemState.hpp
+++ b/include/rosa/agent/SystemState.hpp
@@ -1,173 +1,223 @@
//===-- rosa/agent/SystemState.hpp ------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \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 <vector>
namespace rosa {
namespace agent {
-// System state conditions defining how the condition of a \c
-/// rosa::agent::SystemState is saved in \c rosa::agent::SystemStateInformation.
-enum class SystemStateCondition : uint8_t {
- STABLE = 0, ///< The system state is stable
- DRIFTING = 1, ///< The system state is drifting
- MALFUNCTIONING = 2, ///< The system state is malfunctioning
- UNKNOWN = 3 ///< The system state is unknown
+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 <typename CONFDATATYPE> struct SystemStateInformation {
- // Make sure the actual type arguments are matching our expectations.
- STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::value),
- "confidence type is not to arithmetic");
-
- /// The system state ID saved as an uint32_teger number
- uint32_t SystemStateID;
- /// The SystemStateConfidence shows the overall confidence value of the system
- /// state.
- CONFDATATYPE OverallDetectionConfidence;
- /// The SystemStateCondition shows the condition of a system state (stable,
- /// drifting, malfunctioning, or unknown)
- SystemStateCondition SystemStateCondition;
- /// The SystemStateIsValid saves the number of samples which have been
- /// inserted into the state after entering it.
- uint32_t NumberOfInsertedSamplesAfterEntrance;
- /// The SystemStateIsValid 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 SystemStateIsValid;
- /// The SystemStateJustGotValid shows whether a system state got valid
- /// (toggled from invalid to valid) during the current inserted sample.
- bool SystemStateJustGotValid;
- /// The SystemStateIsValidAfterReentrance shows whether a system state is
- /// valid after the variable changed back to it again.
- bool SystemStateIsValidAfterReentrance;
+template <typename CONFDATATYPE>
+struct SystemStateInformation : StateInformation<CONFDATATYPE> {
+ /// TODO: describe
+ CONFDATATYPE ConfidenceStateIsFunctioning;
+ CONFDATATYPE ConfidenceStateIsMalfunctioning;
+ CONFDATATYPE ConfidenceOfAllDecisions;
};
// todo: do we need PROCDATATYPE?
/// TODO TEXT
template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE>
-class SystemState : public Functionality {
+class SystemState : public State<INDATATYPE, CONFDATATYPE, PROCDATATYPE> {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT(std::is_arithmetic<INDATATYPE>::value,
"input data type is not to arithmetic");
STATIC_ASSERT(std::is_arithmetic<CONFDATATYPE>::value,
"confidence abstraction type is not to arithmetic");
STATIC_ASSERT(std::is_arithmetic<PROCDATATYPE>::value,
"process data type is not to arithmetic");
private:
+ /// SignalStateInfo is a struct of SignalStateInformation that contains
+ /// information about the current signal state.
SystemStateInformation<CONFDATATYPE> SystemStateInfo;
- std::vector<SignalStateInformation<CONFDATATYPE>> Signals;
+ std::vector<SignalStateInformation<CONFDATATYPE>> SignalStateInfos;
uint32_t NumberOfSignals;
public:
/// TODO: write description
SystemState(uint32_t StateID, uint32_t NumberOfSignals) noexcept
- : SystemStateInfo{StateID, 0, SystemStateCondition::UNKNOWN, 0, false,
- false, false},
+ : SystemStateInfo{StateID, StateConditions::UNKNOWN,
+ false, false,
+ false, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0},
NumberOfSignals(NumberOfSignals) {
//@benedikt: there is now possibility to not doing the resize within these
//{}-brackets, right?
- Signals.resize(NumberOfSignals);
+ SignalStateInfos.resize(NumberOfSignals);
}
/// Destroys \p this object.
~SystemState(void) = default;
+ /// TODO: write description
+ SystemStateInformation<CONFDATATYPE> insertSignalStateInformation(
+ const std::vector<SignalStateInformation<CONFDATATYPE>>
+ _SignalStateInfos) noexcept {
+ ASSERT(_SignalStateInfos.size() < NumberOfSignals);
+
+ bool AllSignalsAreValid = true;
+ bool AtLeastOneSignalJustGotValid = false;
+ bool AllSignalsAreValidAfterReentrance = true;
+
+ bool AllSignalsAreStable = true;
+
+ 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::DRIFTING)
+ AllSignalsAreStable = false;
+
+ this->SignalStateInfos.at(counter) = SSI;
+ counter++;
+ }
+
+ SystemStateInfo.StateIsValid = AllSignalsAreValid;
+ SystemStateInfo.StateJustGotValid =
+ AllSignalsAreValid && AtLeastOneSignalJustGotValid;
+ SystemStateInfo.StateIsValidAfterReentrance =
+ AllSignalsAreValidAfterReentrance;
+
+ return SystemStateInfo;
+ }
+
+ /// TODO: write description
+ // TODO (future): think about saving the state information in a history
+ SystemStateRelation compareSignalStateInformation(
+ const std::vector<SignalStateInformation<CONFDATATYPE>>
+ _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 <std::size_t size>
void insertSignalStateInformation(
const std::array<SystemStateInformation<CONFDATATYPE>, size>
&Data) noexcept {
- //@Daniel: is it possible to check with a ASSERT/STATIC_ASSERT whether the
- // number of parameter is the same as NumberOfSignals (which is the length
- // of the vectror)?
ASSERT(size <= NumberOfSignals);
std::size_t counter = 0;
for (auto tmp : Data) {
Signals.at(counter) = tmp;
counter++;
}
}
/// TODO: write description
template <typename... Types>
std::enable_if_t<std::conjunction_v<std::is_same<
Types, SystemStateInformation<CONFDATATYPE>>...>,
void>
insertSignalStateInformation(Types... Data) {
- //@Daniel: is it possible to check with a ASSERT/STATIC_ASSERT whether the
- // number of parameter is the same as NumberOfSignals (which is the length
- // of the vectror)?
- //
// TODO (future): think about saving the state information in a history
insertSignalStateInfos(
std::array<SystemStateInformation<CONFDATATYPE>, sizeof...(Data)>(
{Data...}));
}
// returns true if they are identical
/// TODO: write description
template <std::size_t size>
bool compareSignalStateInformation(
const std::array<SystemStateInformation<CONFDATATYPE>, size>
&Data) noexcept {
- //@Daniel: is it possible to check with a ASSERT/STATIC_ASSERT whether the
- // number of parameter is the same as NumberOfSignals (which is the length
- // of the vectror)?
- //
// 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 <typename... Types>
std::enable_if_t<std::conjunction_v<std::is_same<
Types, SystemStateInformation<CONFDATATYPE>>...>,
bool>
compareSignalStateInformation(Types... Data) {
- //@Daniel: is it possible to check with a ASSERT/STATIC_ASSERT whether the
- // number of parameter is the same as NumberOfSignals (which is the length
- // of the vectror)?
return compareSignalStateInfos(
std::array<SystemStateInformation<CONFDATATYPE>, sizeof...(Data)>(
{Data...}));
}
+#endif
+
+ /// Gives information about the current signal state.
+ ///
+ /// \return a struct SignalStateInformation that contains information about
+ /// the current signal state.
+ SystemStateInformation<CONFDATATYPE> 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 b3fc125..2fe3f2c 100644
--- a/include/rosa/agent/SystemStateDetector.hpp
+++ b/include/rosa/agent/SystemStateDetector.hpp
@@ -1,114 +1,221 @@
//===-- rosa/agent/SystemStateDetector.hpp ----------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \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: löschen , std::size_t NUMOFINPUTSIGNALS, std::size_t NUMOFOUTPUTSIGNALS
+/// System state conditions defining how the condition of a \c
+/// rosa::agent::SystemState is saved in \c rosa::agent::SystemStateInformation.
+// TODO: think about shifting this in SystemStateDetector and make a
+// StateCondition with only stable, drifting, unknown
+enum class SystemStateCondition : uint8_t {
+ STABLE = 0, ///< The system state is stable
+ DRIFTING = 1, ///< The system state is drifting
+ MALFUNCTIONING = 2, ///< The system state is malfunctioning
+ UNKNOWN = 3 ///< The system state is unknown
+};
+
/// TODO: write description
template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE,
HistoryPolicy HP>
class SystemStateDetector
: public StateDetector<INDATATYPE, CONFDATATYPE, PROCDATATYPE, HP> {
using StateDetector =
StateDetector<INDATATYPE, CONFDATATYPE, PROCDATATYPE, HP>;
using PartFuncPointer = typename StateDetector::PartFuncPointer;
private:
// For the convinience to write a shorter data type name
using SystemStatePtr =
std::shared_ptr<SystemState<INDATATYPE, CONFDATATYPE, PROCDATATYPE>>;
+ /// 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<SystemStatePtr, HP> DetectedSystemStates;
+ /// TODO: description
+ unsigned int TimeOfDisparity;
+
/// 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 FuzzyFunctionDelayTimeToGetBroken;
/// 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 FuzzyFunctionDelayTimeToBeWorking;
public:
// todo zwei parameter für variablen anzahl
/// TODO: write description
SystemStateDetector(
- uint32_t MaximumNumberOfSystemStates,
+ uint32_t MaximumNumberOfSystemStates, uint32_t NumberOfSignals,
PartFuncPointer FuzzyFunctionDelayTimeToGetBroken,
PartFuncPointer FuzzyFunctionDelayTimeToBeWorking) noexcept
: CurrentSystemState(nullptr),
DetectedSystemStates(MaximumNumberOfSystemStates),
+ NumberOfSignals(NumberOfSignals), TimeOfDisparity(0),
FuzzyFunctionDelayTimeToGetBroken(FuzzyFunctionDelayTimeToGetBroken),
FuzzyFunctionDelayTimeToBeWorking(FuzzyFunctionDelayTimeToBeWorking) {
//@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<CONFDATATYPE>
- detectSystemState(INDATATYPE Sample) noexcept {
+ detectSystemState(std::vector<SignalStateInformation<CONFDATATYPE>>
+ SignalStateInfos) noexcept {
+
+ SystemStateInformation<CONFDATATYPE> 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) {
+ potentialSystemState = SavedSystemState;
+ }
+ }
+
+ // actions depending whether state is matchin fully or only half
+ if (CurrentSystemState) {
+ TimeOfDisparity = 0;
- // dummy line
- Sample = 1;
+ 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.StateIsValid ||
+ !SystemStateInfo.StateIsValidAfterReentrance) {
+ TimeOfDisparity = 0;
+ }
+
+ // TODO: maybe make reference instead of pointer
+ CONFDATATYPE ConfidenceSystemIsMalfunctioning =
+ FuzzyFunctionDelayTimeToGetBroken->operator()(
+ static_cast<INDATATYPE>(TimeOfDisparity));
+ CONFDATATYPE ConfidenceSystemIsFunctioning =
+ FuzzyFunctionDelayTimeToBeWorking->operator()(
+ static_cast<INDATATYPE>(TimeOfDisparity));
+
+ if (ConfidenceSystemIsMalfunctioning > ConfidenceSystemIsFunctioning)
+ SystemStateInfo.StateCondition = StateConditions::MALFUNCTIONING;
+
+ // TODO: calculate overall confidence
+
+ if (SystemStateInfo.StateJustGotValid) {
+ this->NextStateID++;
+ }
+
+ return SystemStateInfo;
}
private:
- /// Creates a new signal state and adds it to the signal state vector in which
+ /// 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 createNewSignalState(void) noexcept {
- SystemStatePtr S(new SignalState<INDATATYPE, CONFDATATYPE, PROCDATATYPE>(
+ SystemStatePtr createNewSystemState(void) noexcept {
+ SystemStatePtr S(new SystemState<INDATATYPE, CONFDATATYPE, PROCDATATYPE>(
this->NextStateID, this->NumberOfSignals));
-
DetectedSystemStates.addEntry(S);
-
return S;
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SYSTEMSTATEDETECTOR_HPP
diff --git a/lib/agent/CMakeLists.txt b/lib/agent/CMakeLists.txt
index 1c59f8e..70457fd 100644
--- a/lib/agent/CMakeLists.txt
+++ b/lib/agent/CMakeLists.txt
@@ -1,28 +1,30 @@
set(LIB_INCLUDE_DIR ${ROSA_MAIN_INCLUDE_DIR}/rosa/agent)
add_library(ROSAAgent
${LIB_INCLUDE_DIR}/namespace.h
namespace.cpp
${LIB_INCLUDE_DIR}/Functionality.h
Functionality.cpp
${LIB_INCLUDE_DIR}/Abstraction.hpp
Abstraction.cpp
${LIB_INCLUDE_DIR}/FunctionAbstractions.hpp
FunctionAbstractions.cpp
${LIB_INCLUDE_DIR}/RangeConfidence.hpp
RangeConfidence.cpp
${LIB_INCLUDE_DIR}/History.hpp
History.cpp
${LIB_INCLUDE_DIR}/Confidence.hpp
Confidence.cpp
${LIB_INCLUDE_DIR}/SignalState.hpp
SignalState.cpp
${LIB_INCLUDE_DIR}/SignalStateDetector.hpp
SignalStateDetector.cpp
+ ${LIB_INCLUDE_DIR}/State.hpp
+ State.cpp
${LIB_INCLUDE_DIR}/StateDetector.hpp
StateDetector.cpp
${LIB_INCLUDE_DIR}/SystemState.hpp
SystemState.cpp
${LIB_INCLUDE_DIR}/SystemStateDetector.hpp
SystemStateDetector.cpp
)
diff --git a/lib/agent/State.cpp b/lib/agent/State.cpp
new file mode 100644
index 0000000..c3ae669
--- /dev/null
+++ b/lib/agent/State.cpp
@@ -0,0 +1,20 @@
+//===-- agent/State.cpp -----------------------------------------*- C++ -*-===//
+//
+// The RoSA Framework
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file agent/State.cpp
+///
+/// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at)
+///
+/// \date 2019
+///
+/// \brief Implementation for rosa/agent/State.hpp.
+///
+/// \note Empty implementation, source file here to have a compile database
+/// entry for rosa/agent/State.hpp.
+///
+//===----------------------------------------------------------------------===//
+
+#include "rosa/agent/State.hpp"

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 11:06 PM (2 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157411
Default Alt Text
(61 KB)

Event Timeline