Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386417
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
41 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/rosa/agent/SignalState.hpp b/include/rosa/agent/SignalState.hpp
index 99b135b..cb545fe 100644
--- a/include/rosa/agent/SignalState.hpp
+++ b/include/rosa/agent/SignalState.hpp
@@ -1,472 +1,471 @@
//===-- 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"
-#include <cstdarg>
-
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 class SignalStateCondition {
STABLE, ///< The signal state is stable
DRIFTING, ///< The signal state is drifting
UNKNOWN ///< 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 unsigned integer number
unsigned int SignalStateID;
/// The SignalStateConfidence shows the overall confidence value of the signal
/// state.
CONFDATATYPE SignalStateConfidence;
- /// The SignalStateCondition shows the condition of a signal state (stable or
- /// drifting)
+ /// 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.
unsigned int 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 signa 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>>;
// @Benedikt: are INDATATYPE, CONFDATATYPE right here?
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(unsigned int SignalStateID, unsigned int SampleHistorySize,
unsigned int DABSize, unsigned int 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();
}
//@Benedikt: Do I really have to cast here?
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 (unsigned int 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
//@benedikt: check if your partialfunctions can take infinity as
// argument
//@benedikt: same as before "->operator()"
ConfidenceFromRelativeDistance = 0;
} else {
ConfidenceFromRelativeDistance = FuzzyFunctionSampleMatches->operator()(
RelativeDistanceHistory[Case]);
}
ConfidenceOfWorstFittingSample = fuzzyAND<CONFDATATYPE>(
2, ConfidenceOfWorstFittingSample, ConfidenceFromRelativeDistance);
//@benedikt: do i have to pass the number 2 to tell the function how many
// arguments are following?
//@benedikt: same as before with "->operator()"
ConfidenceOfBestCase = fuzzyOR<CONFDATATYPE>(
2, ConfidenceOfBestCase,
fuzzyAND<CONFDATATYPE>(2, ConfidenceOfWorstFittingSample,
FuzzyFunctionNumOfSamplesMatches->operator()(
static_cast<CONFDATATYPE>(Case) + 1)));
}
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 (unsigned int 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]);
// FuzzyFunctionSampleMismatches(RelativeDistanceHistory[Case]);
}
//@benedikt: do i have to pass the number 2 to tell the function how many
// arguments are following?
ConfidenceOfBestFittingSample = fuzzyOR<CONFDATATYPE>(
2, ConfidenceOfBestFittingSample, ConfidenceFromRelativeDistance);
//@benedikt: do i have to pass the number 2 to tell the function how many
// arguments are following?
//@benedikt: same as before with "->operator()"
ConfidenceOfWorstCase = fuzzyAND<CONFDATATYPE>(
2, ConfidenceOfWorstCase,
fuzzyOR<CONFDATATYPE>(2, ConfidenceOfBestFittingSample,
FuzzyFunctionNumOfSamplesMismatches->operator()(
static_cast<CONFDATATYPE>(Case) + 1)));
}
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()"
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)));
}
LowestConfidenceMatchingHistory.addEntry(LowestConfidenceMatching);
HighestConfidenceMismatchingHistory.addEntry(HighestConfidenceMismatching);
LowestConfidenceMatching = LowestConfidenceMatchingHistory.lowestEntry();
HighestConfidenceMismatching =
HighestConfidenceMismatchingHistory.highestEntry();
//@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)));
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 {
// QUESTION: is it ok to say stable = 1 and drift = 0, when I simply don't
// know because the state is so new. Is there an option for saying don't
// know?
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 b608dc0..7923b49 100644
--- a/include/rosa/agent/SignalStateDetector.hpp
+++ b/include/rosa/agent/SignalStateDetector.hpp
@@ -1,285 +1,285 @@
//===-- 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/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/History.hpp"
#include "rosa/agent/SignalState.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 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");
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>>;
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.
unsigned int 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 vector in that all detected signal states are
- /// saved.
+ /// 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.
unsigned int SampleHistorySize;
/// DABSize the size of a DAB (Discrete Average Block).
unsigned int DABSize;
/// DABHistorySize is the (maximum) size of the DAB history.
unsigned int DABHistorySize;
public:
/// Creates an instance by setting all parameters
/// \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(unsigned int MaximumNumberOfSignalStates,
PartFuncPointer FuzzyFunctionSampleMatches,
PartFuncPointer FuzzyFunctionSampleMismatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMismatches,
PartFuncPointer FuzzyFunctionSignalIsDrifting,
PartFuncPointer FuzzyFunctionSignalIsStable,
unsigned int SampleHistorySize, unsigned int DABSize,
unsigned int DABHistorySize) noexcept
: NextSignalStateID(1), SignalStateHasChanged(false),
- CurrentSignalState(NULL),
+ 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).
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 {
//@benedikt: changed from vector to history. can i still do the next
// line?
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));
// @benedikt: todo: assert in history, which checks if push_back worked
DetectedSignalStates.addEntry(S);
return S;
}
};
} // 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 207e284..5012940 100644
--- a/include/rosa/agent/SystemState.hpp
+++ b/include/rosa/agent/SystemState.hpp
@@ -1,44 +1,54 @@
//===-- 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/support/debug.hpp"
+
+#include <array>
namespace rosa {
namespace agent {
/// TODO TEXT
-template <typename CONFDATATYPE> class SystemState : public Functionality {
+template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE,
+ std::size_t NUMOFINPUTSIGNALS, std::size_t NUMOFOUTPUTSIGNALS>
+class SystemState : public Functionality {
- /* //TODO: STATIC_ASSERT
-// Make sure the actual type arguments are matching our expectations.
-STATIC_ASSERT(std::is_arithmetic<CONFDATATYPE>::value,
- "confidence abstraction type is not to arithmetic");
-*/
+ // Make sure the actual type arguments are matching our expectations.
+ STATIC_ASSERT(std::is_arithmetic<CONFDATATYPE>::value,
+ "confidence abstraction type is not to arithmetic");
private:
- unsigned int x;
+ std::array<SignalState<INDATATYPE, CONFDATATYPE, PROCDATATYPE>,
+ NUMOFINPUTSIGNALS>
+ InputSignalStates;
+ std::array<SignalState<INDATATYPE, CONFDATATYPE, PROCDATATYPE>,
+ NUMOFOUTPUTSIGNALS>
+ OutputSignalStates;
public:
SystemState() {}
};
} // 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 c159991..316e51e 100644
--- a/include/rosa/agent/SystemStateDetector.hpp
+++ b/include/rosa/agent/SystemStateDetector.hpp
@@ -1,51 +1,152 @@
//===-- 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/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/History.hpp"
-#include <type_traits>
+#include "rosa/agent/SystemState.hpp"
+
+#include "rosa/support/debug.hpp"
namespace rosa {
namespace agent {
-/// TODO TEXT
-template <typename CONFDATATYPE, HistoryPolicy HP>
+/// 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 unsigned integer number
+ unsigned int 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.
+ unsigned int 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 Functionality {
- /* //TODO: STATIC_ASSERT
-// Make sure the actual type arguments are matching our expectations.
-STATIC_ASSERT(std::is_arithmetic<CONFDATATYPE>::value,
- "confidence abstraction type is not to arithmetic");
-*/
+ // 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");
private:
- unsigned int NextSignalStateID;
+ // For the convinience to write a shorter data type name
+ using PartFuncPointer =
+ std::shared_ptr<PartialFunction<INDATATYPE, CONFDATATYPE>>;
+ 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.
+ unsigned int NextSystemStateID;
+ /// The SystemStateHasChanged is a flag that show whether the observed
+ /// system
+ /// has changed its state.
bool SystemStateHasChanged;
- // DynamicLengthHistory<SignalStatePtr, HP> DetectedSignalStates;
+ /// 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:
- SystemStateDetector() : NextSignalStateID(1) {}
+ /// TODO: write description
+ SystemStateDetector(
+ unsigned int 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>
+ detectSignalState(INDATATYPE Sample) noexcept {
+
+ // dummy line
+ Sample = 1;
+ }
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SYSTEMSTATEDETECTOR_HPP
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jul 3, 12:05 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157241
Default Alt Text
(41 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment