Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386622
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
61 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment