Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386625
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
47 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/rosa/agent/SignalState.hpp b/include/rosa/agent/SignalState.hpp
index 7f8d206..7557729 100644
--- a/include/rosa/agent/SignalState.hpp
+++ b/include/rosa/agent/SignalState.hpp
@@ -1,462 +1,528 @@
//===-- 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/support/math.hpp"
namespace rosa {
namespace agent {
/// 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 {
// 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 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;
/// The SignalIsStableNotDrifting shows whether a signal is stable and not
/// drifting.
bool SignalIsStable;
};
/// \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");
private:
// For the convinience to write a shorter data type name
using PartFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, CONFDATATYPE>>;
using StepFuncPointer =
std::shared_ptr<StepFunction<INDATATYPE, CONFDATATYPE>>;
/// SignalStateInfo is a struct SignalStateInformation that contains
/// information about the current 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.
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 (resp. the state of a signal)
/// is drifting.
PartFuncPointer 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).
PartFuncPointer 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;
public:
// @Maxi doxygen per default doesn't display private attributes of a class. So
// I copied them to the constructor. So the user has more information.
/// 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, uint32_t SampleHistorySize,
uint32_t DABSize, uint32_t DABHistorySize,
PartFuncPointer FuzzyFunctionSampleMatches,
PartFuncPointer FuzzyFunctionSampleMismatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMismatches,
PartFuncPointer FuzzyFunctionSignalIsDrifting,
PartFuncPointer FuzzyFunctionSignalIsStable) noexcept
: SignalStateInfo{SignalStateID, 0, SignalStateCondition::UNKNOWN, 0,
false, false,
false, //@maxi added the Signal is stable bool
true},
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;
}
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();
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.
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
//@David: because we are using these operator functions, here I have to
// direference in a not (in my opionin) not so beautiful way
//("(*FuzzyFunctionSampleMatches)"), or I have to write
//"FuzzyFunctionSampleMatches->operator()(...)". Can we just write
// functions like "->getBlabla()" or something like that?
ConfidenceFromRelativeDistance = 0;
} else {
ConfidenceFromRelativeDistance =
(*FuzzyFunctionSampleMatches)(RelativeDistanceHistory[Case]);
}
+#if false
+ //@maxi why the 2?
+ ConfidenceOfWorstFittingSample =
+ fuzzyAND((CONFDATATYPE)2, ConfidenceOfWorstFittingSample,
+ ConfidenceFromRelativeDistance);
+
+ //@maxi you could also use it like this then you can define the type and the size
+ ConfidenceOfWorstFittingSample =
+ fuzzyAND<CONFDATATYPE,2>({ConfidenceOfWorstFittingSample,
+ ConfidenceFromRelativeDistance});
+#else
+ //@maxi is this what you wanted? you don't need to define the data type
+ // nor the size
+ ConfidenceOfWorstFittingSample = fuzzyAND(ConfidenceOfWorstFittingSample,
+ ConfidenceFromRelativeDistance);
+#endif
- ConfidenceOfWorstFittingSample = fuzzyAND<CONFDATATYPE>(
- 2, ConfidenceOfWorstFittingSample, ConfidenceFromRelativeDistance);
//@benedikt: same as before with "->operator()"
+ //@maxi the same as before
+#if false
ConfidenceOfBestCase = fuzzyOR<CONFDATATYPE>(
2, ConfidenceOfBestCase,
fuzzyAND<CONFDATATYPE>(2, ConfidenceOfWorstFittingSample,
FuzzyFunctionNumOfSamplesMatches->operator()(
static_cast<CONFDATATYPE>(Case) + 1)));
+#else
+ ConfidenceOfBestCase =
+ fuzzyOR(ConfidenceOfBestCase,
+ fuzzyAND(ConfidenceOfWorstFittingSample,
+ FuzzyFunctionNumOfSamplesMatches->operator()(
+ static_cast<CONFDATATYPE>(Case) + 1)));
+
+#endif
}
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;
// 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.
// TODO (future): to accelerate -> don't go until end. Confidences will only
// get higher. See comment in "CONFDATATYPE
// confidenceSampleMatchesSignalState(INDATATYPE Sample)".
for (uint32_t Case = 0; Case < RelativeDistanceHistory.numberOfEntries();
Case++) {
CONFDATATYPE ConfidenceFromRelativeDistance;
if (std::isinf(RelativeDistanceHistory[Case])) {
ConfidenceFromRelativeDistance = 1;
} else {
//@benedikt: I had to change the following line. The outcommented line
// was the original one. I think it is ugly like that (new line). Do you
// have an idea how to make it better/more beautiful?
ConfidenceFromRelativeDistance =
FuzzyFunctionSampleMismatches->operator()(
RelativeDistanceHistory[Case]);
}
+//@maxi you don't have to define the data type or the amount
+#if false
ConfidenceOfBestFittingSample = fuzzyOR<CONFDATATYPE>(
2, ConfidenceOfBestFittingSample, ConfidenceFromRelativeDistance);
//@benedikt: same as before with "->operator()"
ConfidenceOfWorstCase = fuzzyAND<CONFDATATYPE>(
2, ConfidenceOfWorstCase,
fuzzyOR<CONFDATATYPE>(2, ConfidenceOfBestFittingSample,
FuzzyFunctionNumOfSamplesMismatches->operator()(
static_cast<CONFDATATYPE>(Case) + 1)));
+#else
+ ConfidenceOfBestFittingSample = fuzzyOR(ConfidenceOfBestFittingSample,
+ ConfidenceFromRelativeDistance);
+
+ //@benedikt: same as before with "->operator()"
+ ConfidenceOfWorstCase =
+ fuzzyAND(ConfidenceOfWorstCase,
+ fuzzyOR(ConfidenceOfBestFittingSample,
+ FuzzyFunctionNumOfSamplesMismatches->operator()(
+ static_cast<CONFDATATYPE>(Case) + 1)));
+#endif
}
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.
//@benedikt: same with "->operator()"
+ //@maxi you don't have to deine the data type nor the amount
+#if false
LowestConfidenceMatching =
fuzzyAND<CONFDATATYPE>(2, LowestConfidenceMatching,
FuzzyFunctionSampleMatches->operator()(
relativeDistance<INDATATYPE, PROCDATATYPE>(
Sample, HistorySample)));
//@benedikt: same with "->operator()"
HighestConfidenceMismatching =
fuzzyOR<CONFDATATYPE>(2, HighestConfidenceMismatching,
FuzzyFunctionSampleMismatches->operator()(
relativeDistance<INDATATYPE, PROCDATATYPE>(
Sample, HistorySample)));
+#else
+ LowestConfidenceMatching =
+ fuzzyAND(LowestConfidenceMatching,
+ FuzzyFunctionSampleMatches->operator()(
+ relativeDistance<INDATATYPE, PROCDATATYPE>(
+ Sample, HistorySample)));
+ //@benedikt: same with "->operator()"
+ HighestConfidenceMismatching =
+ fuzzyOR(HighestConfidenceMismatching,
+ FuzzyFunctionSampleMismatches->operator()(
+ relativeDistance<INDATATYPE, PROCDATATYPE>(
+ Sample, HistorySample)));
+#endif
}
LowestConfidenceMatchingHistory.addEntry(LowestConfidenceMatching);
HighestConfidenceMismatchingHistory.addEntry(HighestConfidenceMismatching);
LowestConfidenceMatching = LowestConfidenceMatchingHistory.lowestEntry();
HighestConfidenceMismatching =
HighestConfidenceMismatchingHistory.highestEntry();
+ //@maxi you don't have to define the data type or the amount
+#if false
//@benedikt: same with "->operator()"
CONFDATATYPE ConfidenceSignalStateIsValid = fuzzyAND<CONFDATATYPE>(
2, LowestConfidenceMatching,
FuzzyFunctionNumOfSamplesMatches->operator()(static_cast<INDATATYPE>(
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
//@benedikt: same with "->operator()"
CONFDATATYPE ConfidenceSignalStateIsInvalid = fuzzyOR<CONFDATATYPE>(
2, HighestConfidenceMismatching,
FuzzyFunctionNumOfSamplesMismatches->operator()(static_cast<INDATATYPE>(
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
+#else
+ //@benedikt: same with "->operator()"
+ CONFDATATYPE ConfidenceSignalStateIsValid = fuzzyAND(
+ LowestConfidenceMatching,
+ FuzzyFunctionNumOfSamplesMatches->operator()(static_cast<INDATATYPE>(
+ SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
+ //@benedikt: same with "->operator()"
+ CONFDATATYPE ConfidenceSignalStateIsInvalid = fuzzyOR(
+ HighestConfidenceMismatching,
+ FuzzyFunctionNumOfSamplesMismatches->operator()(static_cast<INDATATYPE>(
+ SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
+#endif
if (ConfidenceSignalStateIsValid > ConfidenceSignalStateIsInvalid) {
if (SignalStateInfo.SignalStateIsValid) {
SignalStateInfo.SignalStateJustGotValid = false;
} else {
SignalStateInfo.SignalStateJustGotValid = true;
}
SignalStateInfo.SignalStateIsValid = true;
SignalStateInfo.SignalStateIsValidAfterReentrance = true;
}
}
void checkSignalStability(void) {
CONFDATATYPE ConfidenceSignalIsStable;
CONFDATATYPE ConfidenceSignalIsDrifting;
if (DABHistory.numberOfEntries() >= 2) {
//@benedikt: same "->operator()"
ConfidenceSignalIsStable = FuzzyFunctionSignalIsStable->operator()(
relativeDistance<INDATATYPE, PROCDATATYPE>(
DABHistory[DABHistory.numberOfEntries() - 1], DABHistory[0]));
//@benedikt: same "->operator()"
ConfidenceSignalIsDrifting = FuzzyFunctionSignalIsDrifting->operator()(
relativeDistance<INDATATYPE, PROCDATATYPE>(
DABHistory[DABHistory.numberOfEntries() - 1], DABHistory[0]));
} else {
// TODO: change to enum
ConfidenceSignalIsStable = 1;
ConfidenceSignalIsDrifting = 0;
}
SignalStateInfo.SignalIsStable =
ConfidenceSignalIsStable >= ConfidenceSignalIsDrifting;
}
};
} // 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 99af791..d7b10e9 100644
--- a/include/rosa/agent/SignalStateDetector.hpp
+++ b/include/rosa/agent/SignalStateDetector.hpp
@@ -1,272 +1,278 @@
//===-- rosa/agent/SignalStateDetector.hpp ----------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/SignalStateDetector.hpp
///
/// \author Maximilian Götzinger (maximilian.goetzinger@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 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(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
: NextSignalStateID(1), SignalStateHasChanged(false),
CurrentSignalState(nullptr),
DetectedSignalStates(MaximumNumberOfSignalStates),
FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches),
FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches),
FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches),
FuzzyFunctionNumOfSamplesMismatches(
FuzzyFunctionNumOfSamplesMismatches),
FuzzyFunctionSignalIsDrifting(FuzzyFunctionSignalIsDrifting),
FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable),
SampleHistorySize(SampleHistorySize), DABSize(DABSize),
DABHistorySize(DABHistorySize) {}
/// Destroys \p this object.
~SignalStateDetector(void) = default;
/// Detects 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;
if (CurrentSignalState->signalStateInformation().SignalStateIsValid) {
CurrentSignalState->leaveSignalState();
} 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;
}
}
}
if (!CurrentSignalState) {
SignalStatePtr S = createNewSignalState();
CurrentSignalState = S;
}
}
}
SignalStateInformation<CONFDATATYPE> SignalStateInfo =
CurrentSignalState->insertSample(Sample);
if (SignalStateInfo.SignalStateJustGotValid) {
NextSignalStateID++;
}
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; }
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, 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/StateDetector.hpp b/include/rosa/agent/StateDetector.hpp
index aa341f6..9bd7430 100644
--- a/include/rosa/agent/StateDetector.hpp
+++ b/include/rosa/agent/StateDetector.hpp
@@ -1,56 +1,57 @@
//===-- 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");
-protected:
+public:
using PartFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, CONFDATATYPE>>;
using StepFuncPointer =
std::shared_ptr<StepFunction<INDATATYPE, CONFDATATYPE>>;
+protected:
/// The NextSignalStateID is a counter variable which stores the ID which the
/// next signal state shall have.
unsigned int 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/SystemStateDetector.hpp b/include/rosa/agent/SystemStateDetector.hpp
index ac9072e..31335bf 100644
--- a/include/rosa/agent/SystemStateDetector.hpp
+++ b/include/rosa/agent/SystemStateDetector.hpp
@@ -1,141 +1,146 @@
//===-- 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/StateDetector.hpp"
#include "rosa/agent/SystemState.hpp"
#include "rosa/support/debug.hpp"
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 {
STABLE, ///< The system state is stable
DRIFTING, ///< The system state is drifting
MALFUNCTIONING, ///< The system state is malfunctioning
UNKNOWN ///< The system state is unknown
};
/// 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)
//@David: is it ok to name the variable exactly as the type is named?
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;
/// The SystemIsStable shows whether a signa is stable and not
/// drifting.
bool SystemIsStable;
};
/// TODO: write description
template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE,
HistoryPolicy HP, std::size_t NUMOFINPUTSIGNALS,
std::size_t NUMOFOUTPUTSIGNALS>
class SystemStateDetector
: public StateDetector<INDATATYPE, CONFDATATYPE, PROCDATATYPE, HP> {
+ //@maxi added them to make it compilable is this what you wanted?
+ 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,
NUMOFINPUTSIGNALS, NUMOFOUTPUTSIGNALS>>;
/// The NextSystemStateID is a counter variable which stores the ID which
/// the
/// next system state shall have.
uint32_t NextSystemStateID;
/// The SystemStateHasChanged is a flag that show whether the observed
/// system
/// has changed its state.
bool SystemStateHasChanged;
/// 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;
/// 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: write description
SystemStateDetector(
uint32_t MaximumNumberOfSystemStates,
PartFuncPointer FuzzyFunctionDelayTimeToGetBroken,
PartFuncPointer FuzzyFunctionDelayTimeToBeWorking) noexcept
: NextSystemStateID(1), SystemStateHasChanged(false),
CurrentSystemState(nullptr),
DetectedSystemStates(MaximumNumberOfSystemStates),
FuzzyFunctionDelayTimeToGetBroken(FuzzyFunctionDelayTimeToGetBroken),
FuzzyFunctionDelayTimeToBeWorking(FuzzyFunctionDelayTimeToBeWorking) {}
/// Destroys \p this object.
~SystemStateDetector(void) = default;
/// TODO: write description
SystemStateInformation<CONFDATATYPE>
detectSystemState(INDATATYPE Sample) noexcept {
// dummy line
Sample = 1;
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SYSTEMSTATEDETECTOR_HPP
diff --git a/include/rosa/support/math.hpp b/include/rosa/support/math.hpp
index 30e11fb..95a7363 100644
--- a/include/rosa/support/math.hpp
+++ b/include/rosa/support/math.hpp
@@ -1,153 +1,153 @@
//===-- rosa/support/math.hpp -----------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/support/math.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017
///
/// \brief Math helpers.
///
//===----------------------------------------------------------------------===//
// !!!!!! Please check lines 60 - 180 forward !!!!!!!!!!!!!!
#ifndef ROSA_SUPPORT_MATH_HPP
#define ROSA_SUPPORT_MATH_HPP
#include "debug.hpp"
#include <algorithm>
#include <array>
#include <cmath>
#include <cstdarg>
#include <cstdlib>
#include <limits>
#include <type_traits>
namespace rosa {
/// Computes log base 2 of a number.
///
/// \param N the number to compute log base 2 for
///
/// \return log base 2 of \p N
constexpr size_t log2(const size_t N) {
return ((N < 2) ? 1 : 1 + log2(N / 2));
}
/// Tells the next representable floating point value.
///
/// \tparam T type to operate on
///
/// \note The second type argument enforces \p T being a floating point type,
/// always use the default value!
///
/// \param V value to which find the next representable one
///
/// \return the next representable value of type \p T after value \p V
///
/// \pre Type \p T must be a floating point type, which is enforced by
/// `std::enable_if` in the second type argument.
template <typename T,
typename = std::enable_if_t<std::is_floating_point<T>::value>>
T nextRepresentableFloatingPoint(const T V) {
return std::nextafter(V, std::numeric_limits<T>::infinity());
}
/// Conjuncts two or more values with each other.
///
/// \param Data an array of the data
///
/// \return the conjunction of the values given as parameter.
template <typename CONFDATATYPE, std::size_t size>
CONFDATATYPE fuzzyAND(const std::array<CONFDATATYPE, size> & Data) noexcept {
STATIC_ASSERT(std::is_arithmetic<CONFDATATYPE>::value,
"Type of FuzzyAnd is not arithmetic");
STATIC_ASSERT(size > 1, "Number of Arguments is to little");
for (auto tmp : Data)
ASSERT(tmp <= 1 && tmp >= 0);
return *std::min_element(Data.begin(), Data.end());
}
/// Conjuncts two or more values with each other. It's a wrapper for \c fuzzyAND() [array]
///
/// \param Data first data to get the type explicitly
///
/// \param Datan a package of data
///
/// \note the types of Datan must be the same type as Data
///
/// \return the conjunction of the values given as parameter.
template <typename CONFDATATYPE, typename... _CONFDATATYPE>
std::enable_if_t<
std::conjunction_v<std::is_same<CONFDATATYPE, _CONFDATATYPE>...>,
CONFDATATYPE>
-fuzzyAND(CONFDATATYPE & Data, _CONFDATATYPE&... Datan) noexcept {
+fuzzyAND(const CONFDATATYPE Data, const _CONFDATATYPE... Datan) noexcept {
return fuzzyAND(
std::array<CONFDATATYPE, sizeof...(Datan) + 1>{Data, Datan...});
}
/// Disjuncts two or more values with each other.
///
/// \param Data an array with the data.
///
/// \return the disjunction of the values given as parameter.
template <typename CONFDATATYPE, std::size_t size>
CONFDATATYPE fuzzyOR(const std::array<CONFDATATYPE, size> & Data) noexcept {
STATIC_ASSERT(std::is_arithmetic<CONFDATATYPE>::value,
"Type of FuzzyAnd is not arithmetic");
STATIC_ASSERT(size > 1, "Number of Arguments is to little");
ASSERT(std::all_of(Data.begin(), Data.end(),
[](const auto &v) { return v <= 1 && v >= 0; }));
return *std::max_element(Data.begin(), Data.end());
}
/// Disjuncts two or more values with each other. It's a wrapper for \c fuzzyOR() [array]
///
/// \param Data first data to get the type explicitly
///
/// \param Datan a package of data
///
/// \note the types of Datan must be the same type as Data
///
/// \return the disjunction of the values given as parameter.
template <typename CONFDATATYPE, typename... _CONFDATATYPE>
std::enable_if_t<
std::conjunction_v<std::is_same<CONFDATATYPE, _CONFDATATYPE>...>,
CONFDATATYPE>
-fuzzyOR(const CONFDATATYPE & Data, const _CONFDATATYPE&... Datan) noexcept {
+fuzzyOR(const CONFDATATYPE Data, const _CONFDATATYPE... Datan) noexcept {
return fuzzyOR(
std::array<CONFDATATYPE, sizeof...(Datan) + 1>{Data, Datan...});
}
template <typename INDATATYPE, typename PROCDATATYPE>
PROCDATATYPE relativeDistance(INDATATYPE NewValue,
INDATATYPE HistoryValue) noexcept {
PROCDATATYPE Dist = HistoryValue - NewValue;
if (Dist == 0) {
return 0;
} else {
Dist = Dist / NewValue;
if (Dist < 0) {
// TODO: I guess this multiplication here should not be done because
// it could be that the distance fuzzy functions are not symetrical
//(negative and positive side)
Dist = Dist * (-1);
}
return (Dist);
}
}
} // End namespace rosa
#endif // ROSA_SUPPORT_MATH_HPP
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jul 3, 11:10 PM (9 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157414
Default Alt Text
(47 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment