Page MenuHomePhorge

No OneTemporary

Size
44 KB
Referenced Files
None
Subscribers
None
diff --git a/include/rosa/agent/SignalState.hpp b/include/rosa/agent/SignalState.hpp
index 04ad2ff..6db80d0 100644
--- a/include/rosa/agent/SignalState.hpp
+++ b/include/rosa/agent/SignalState.hpp
@@ -1,696 +1,692 @@
//===-- 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/DistanceMetrics.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
};
/// TODO: write description
template <typename PROCDATATYPE, typename CONFDATATYPE> struct DABHistoryEntry {
/// TODO: write description
PROCDATATYPE AvgValue;
/// TODO: write description
CONFDATATYPE DecisionDABIsStable;
/// TODO: write description
CONFDATATYPE DecisionDABIsDriftingDown;
/// TODO: write description
CONFDATATYPE DecisionDABIsDriftingUp;
/// TODO: write description
bool DABWasCurrent;
public:
DABHistoryEntry(PROCDATATYPE AvgValue) {
this->AvgValue = AvgValue;
this->DecisionDABIsStable = 0;
this->DecisionDABIsDriftingDown = 0;
this->DecisionDABIsDriftingUp = 0;
this->DABWasCurrent = false;
}
DABHistoryEntry() = default;
};
/// TODO: write description
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");
/// ConfidenceOfMatchingState is the confidence how good the new sample
/// matches the state.
CONFDATATYPE ConfidenceOfMatchingState;
/// ConfidenceOfMatchingState is the confidence how bad the new sample
/// matches the state.
CONFDATATYPE ConfidenceOfMismatchingState;
/// The SignalProperty saves whether the monitored signal is an input our
/// output signal.
SignalProperties SignalProperty;
/// The SignalStateIsValid saves the number of samples which have been
/// inserted into the state after entering it.
uint32_t NumberOfInsertedSamplesAfterEntrance;
public:
SignalStateInformation(unsigned int SignalStateID,
SignalProperties _SignalProperty) {
this->StateID = SignalStateID;
this->SignalProperty = _SignalProperty;
this->StateCondition = StateConditions::UNKNOWN;
this->NumberOfInsertedSamplesAfterEntrance = 0;
this->StateIsValid = false;
this->StateJustGotValid = false;
this->StateIsValidAfterReentrance = false;
this->ConfidenceStateIsValid = 0;
this->ConfidenceStateIsInvalid = 0;
this->ConfidenceStateIsStable = 0;
this->ConfidenceStateIsDrifting = 0;
this->ConfidenceStateIsDriftingDown = 0;
this->ConfidenceStateIsDriftingUp = 0;
}
SignalStateInformation() = default;
};
/// \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:
// The metric to calculate the distance between two points
using DistanceMetricAbstraction =
Abstraction<std::pair<INDATATYPE, INDATATYPE>, PROCDATATYPE> &;
// For the convinience to write a shorter data type name
using PartFuncReference = PartialFunction<INDATATYPE, CONFDATATYPE> &;
// using PartFuncReference2 = ;
using StepFuncReference = StepFunction<INDATATYPE, CONFDATATYPE> &;
private:
/// SignalStateInfo is a struct of SignalStateInformation that contains
/// information about the current signal state.
SignalStateInformation<CONFDATATYPE> SignalStateInfo;
/// The metric to calculate the distance between two points
DistanceMetricAbstraction DistanceMetric;
/// 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 FuzzyFunctionSampleValid is the fuzzy function that gives the
/// confidence how good one matches another sample in the sample
/// history. This is done to evaluate whether a state is valid.
PartFuncReference FuzzyFunctionSampleValid;
/// The FuzzyFunctionSampleInvalid is the fuzzy function that gives the
/// confidence how bad one sample matches another sample in the sample
/// history. This is done to evaluate whether a state is invalid.
PartFuncReference FuzzyFunctionSampleInvalid;
/// The FuzzyFunctionNumOfSamplesValid is the fuzzy function that gives the
/// confidence how many samples from the sample history match another sample.
/// This is done to evaluate whether a state is valid.
StepFuncReference FuzzyFunctionNumOfSamplesValid;
/// The FuzzyFunctionNumOfSamplesInvalid is the fuzzy function that gives
/// the confidence how many samples from the sample history mismatch another
/// sample. This is done to evaluate whether a state is invalid.
StepFuncReference FuzzyFunctionNumOfSamplesInvalid;
/// The FuzzyFunctionSignalIsDriftingDown is the fuzzy function that gives the
/// confidence how likely it is that the signal (resp. the state of a signal)
/// is drifting down.
PartFuncReference FuzzyFunctionSignalIsDriftingDown;
/// The FuzzyFunctionSignalIsDriftingUp is the fuzzy function that gives the
/// confidence how likely it is that the signal (resp. the state of a signal)
/// is drifting up.
PartFuncReference FuzzyFunctionSignalIsDriftingUp;
/// 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;
/// TODO: description
PartialFunction<uint32_t, float> &FuzzyFunctionSignalConditionLookBack;
/// TODO: description
PartialFunction<uint32_t, float> &FuzzyFunctionSignalConditionHistoryDesicion;
/// TODO: description
uint32_t DriftLookbackRange;
/// 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<DABHistoryEntry<INDATATYPE, CONFDATATYPE>,
HistoryPolicy::FIFO>
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;
/// TempConfidenceMatching is the confidence how good a sample matches the
/// state. However, the value of this variable is only needed temporarly.
CONFDATATYPE TempConfidenceMatching = 0;
/// TempConfidenceMatching is the confidence how bad a sample matches the
/// state. However, the value of this variable is only needed temporarly.
CONFDATATYPE TempConfidenceMismatching = 0;
public:
/// Creates an instance by setting all parameters
/// \param SignalStateID The Id of the SignalStateinfo \c
/// SignalStateInformation.
///
/// \param DistanceMetric the distance metric to calculate the distance
/// between two points
///
/// \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 FuzzyFunctionSignalIsDriftingDown The
/// FuzzyFunctionSignalIsDriftingDown is the fuzzy function that gives the
/// confidence how likely it is that the signal (resp. the state of a signal)
/// is drifting down.
///
///
/// \param FuzzyFunctionSignalIsDriftingUp The FuzzyFunctionSignalIsDriftingUp
/// is the fuzzy function that gives the confidence how likely it is that the
/// signal (resp. the state of a signal) is drifting down.
///
/// \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.
- ///
SignalState(
uint32_t SignalStateID, SignalProperties SignalProperty,
uint32_t SampleHistorySize, uint32_t DABSize,
DistanceMetricAbstraction DistanceMetric,
PartFuncReference FuzzyFunctionSampleMatches,
PartFuncReference FuzzyFunctionSampleMismatches,
StepFuncReference FuzzyFunctionNumOfSamplesMatches,
StepFuncReference FuzzyFunctionNumOfSamplesMismatches,
PartFuncReference FuzzyFunctionSampleValid,
PartFuncReference FuzzyFunctionSampleInvalid,
StepFuncReference FuzzyFunctionNumOfSamplesValid,
StepFuncReference FuzzyFunctionNumOfSamplesInvalid,
PartFuncReference FuzzyFunctionSignalIsDriftingDown,
PartFuncReference FuzzyFunctionSignalIsDriftingUp,
PartFuncReference FuzzyFunctionSignalIsStable,
PartialFunction<uint32_t, float> &FuzzyFunctionSignalConditionLookBack,
PartialFunction<uint32_t, float>
&FuzzyFunctionSignalConditionHistoryDesicion,
uint32_t DriftLookbackRange) noexcept
: SignalStateInfo{SignalStateID, SignalProperty},
DistanceMetric(DistanceMetric),
FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches),
FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches),
FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches),
FuzzyFunctionNumOfSamplesMismatches(
FuzzyFunctionNumOfSamplesMismatches),
FuzzyFunctionSampleValid(FuzzyFunctionSampleValid),
FuzzyFunctionSampleInvalid(FuzzyFunctionSampleInvalid),
FuzzyFunctionNumOfSamplesValid(FuzzyFunctionNumOfSamplesValid),
FuzzyFunctionNumOfSamplesInvalid(FuzzyFunctionNumOfSamplesInvalid),
FuzzyFunctionSignalIsDriftingDown(FuzzyFunctionSignalIsDriftingDown),
FuzzyFunctionSignalIsDriftingUp(FuzzyFunctionSignalIsDriftingUp),
FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable),
FuzzyFunctionSignalConditionLookBack(
FuzzyFunctionSignalConditionLookBack),
FuzzyFunctionSignalConditionHistoryDesicion(
FuzzyFunctionSignalConditionHistoryDesicion),
DriftLookbackRange(DriftLookbackRange),
SampleHistory(SampleHistorySize), DAB(DABSize),
DABHistory(DriftLookbackRange + 1),
LowestConfidenceMatchingHistory(SampleHistorySize),
HighestConfidenceMismatchingHistory(SampleHistorySize) {}
/// Destroys \p this object.
~SignalState(void) = default;
void leaveSignalState(void) noexcept {
DAB.clear();
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance = 0;
SignalStateInfo.StateIsValidAfterReentrance = false;
}
SignalStateInformation<CONFDATATYPE>
insertSample(INDATATYPE Sample) noexcept {
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance++;
validateSignalState(Sample);
SampleHistory.addEntry(Sample);
DAB.addEntry(Sample);
if (DAB.full()) {
// TODO: try median instead of avg
PROCDATATYPE AvgOfDAB = DAB.template average<PROCDATATYPE>();
// DABHistory.addEntry(AvgOfDAB);
DABHistory.addEntry(
DABHistoryEntry<PROCDATATYPE, CONFDATATYPE>(AvgOfDAB));
DAB.clear();
}
FuzzyFunctionNumOfSamplesMatches.setRightLimit(
static_cast<INDATATYPE>(SampleHistory.numberOfEntries()));
FuzzyFunctionNumOfSamplesMismatches.setRightLimit(
static_cast<INDATATYPE>(SampleHistory.numberOfEntries()));
checkSignalStability();
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 =
DistanceMetric(std::make_pair(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)));
}
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(
DistanceMetric(std::make_pair(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)));
}
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(
DistanceMetric(std::make_pair(Sample, HistorySample))));
HighestConfidenceMismatching =
fuzzyOR(HighestConfidenceMismatching,
FuzzyFunctionSampleMismatches(
DistanceMetric(std::make_pair(Sample, HistorySample))));
}
LowestConfidenceMatchingHistory.addEntry(LowestConfidenceMatching);
HighestConfidenceMismatchingHistory.addEntry(HighestConfidenceMismatching);
LowestConfidenceMatching = LowestConfidenceMatchingHistory.lowestEntry();
HighestConfidenceMismatching =
HighestConfidenceMismatchingHistory.highestEntry();
SignalStateInfo.ConfidenceStateIsValid =
fuzzyAND(LowestConfidenceMatching,
FuzzyFunctionNumOfSamplesValid(static_cast<INDATATYPE>(
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
SignalStateInfo.ConfidenceStateIsInvalid =
fuzzyOR(HighestConfidenceMismatching,
FuzzyFunctionNumOfSamplesInvalid(static_cast<INDATATYPE>(
SignalStateInfo.NumberOfInsertedSamplesAfterEntrance)));
if (SignalStateInfo.ConfidenceStateIsValid >
SignalStateInfo.ConfidenceStateIsInvalid) {
if (SignalStateInfo.StateIsValid) {
SignalStateInfo.StateJustGotValid = false;
} else {
SignalStateInfo.StateJustGotValid = true;
}
SignalStateInfo.StateIsValid = true;
SignalStateInfo.StateIsValidAfterReentrance = true;
}
}
void checkSignalStability(void) {
CONFDATATYPE CurrentConfidenceStable = 0;
CONFDATATYPE CurrentConfidenceStateDriftingDown = 0;
CONFDATATYPE CurrentConfidenceStateDriftingUp = 0;
CONFDATATYPE HistoryConfidenceStable = 0;
CONFDATATYPE HistoryConfidenceStateDriftingDown = 0;
CONFDATATYPE HistoryConfidenceStateDriftingUp = 0;
if (DABHistory.numberOfEntries() >= 2) {
DABHistoryEntry<PROCDATATYPE, CONFDATATYPE> CurrentDAB =
DABHistory[DABHistory.numberOfEntries() - 1];
if (CurrentDAB.DABWasCurrent == false) {
DABHistoryEntry<PROCDATATYPE, CONFDATATYPE> DAB2Compare;
// THIS WOULD BE FOR EQUATION NORMALIZATION
// TODO: make the following also for distance measurement when comparing
// sample with state and validate state
/*
// sigma correction
if (NormalizedDistanceMetric<INDATATYPE, PROCDATATYPE>
*NormalizableDistanceMetric = dynamic_cast<
NormalizedDistanceMetric<INDATATYPE, PROCDATATYPE> *>(
DistanceMetric)) {
// old was safely casted to NewType
NormalizableDistanceMetric->setNorm(
// TODO: (1) Sigma von Sample
// History(!) abholen, (2) irgendwas mit Sigma hier reinschreiben,
// und (3) überlegen wegen zweiter History (länger) für
// Sigmaberechnung
);
}
*/
// Iterate through all history DABs
for (unsigned int t = 1;
t <= DriftLookbackRange && t < DABHistory.numberOfEntries(); t++) {
// Pick one history DAB
DAB2Compare = DABHistory[DABHistory.numberOfEntries() - (t + 1)];
// Calculate distance between most recent (completed) DAB and the
// chosen history DAB
PROCDATATYPE dist = DistanceMetric(
std::make_pair(CurrentDAB.AvgValue, DAB2Compare.AvgValue));
// Add current confidences for Stable, drift down and drift up
// together
CurrentConfidenceStable += FuzzyFunctionSignalIsStable(dist);
CurrentConfidenceStateDriftingDown +=
FuzzyFunctionSignalIsDriftingDown(dist);
CurrentConfidenceStateDriftingUp +=
FuzzyFunctionSignalIsDriftingUp(dist);
// Add history confidences for Stable, drift down and drift up
// together
HistoryConfidenceStable += DAB2Compare.DecisionDABIsStable;
HistoryConfidenceStateDriftingDown +=
DAB2Compare.DecisionDABIsDriftingDown;
HistoryConfidenceStateDriftingUp +=
DAB2Compare.DecisionDABIsDriftingUp;
}
// chose right divisor for average calculation
unsigned int numOfCompares;
if (DriftLookbackRange <= DABHistory.numberOfEntries())
numOfCompares = DriftLookbackRange;
else
numOfCompares =
static_cast<unsigned int>(DABHistory.numberOfEntries());
// calculate the average of the current confidence decision
CurrentConfidenceStable /= numOfCompares;
CurrentConfidenceStateDriftingDown /= numOfCompares;
CurrentConfidenceStateDriftingUp /= numOfCompares;
// store the current confidence decision in current DAB
CurrentDAB.DecisionDABIsStable = CurrentConfidenceStable;
CurrentDAB.DecisionDABIsDriftingDown =
CurrentConfidenceStateDriftingDown;
CurrentDAB.DecisionDABIsDriftingUp = CurrentConfidenceStateDriftingUp;
CurrentDAB.DABWasCurrent = true;
// calculate the confidences for SignalStateInfo (current output)
HistoryConfidenceStable =
(HistoryConfidenceStable + CurrentConfidenceStable) /
(numOfCompares + 1);
HistoryConfidenceStateDriftingDown =
(HistoryConfidenceStateDriftingDown +
CurrentConfidenceStateDriftingDown) /
(numOfCompares + 1);
HistoryConfidenceStateDriftingUp = (HistoryConfidenceStateDriftingUp +
CurrentConfidenceStateDriftingUp) /
(numOfCompares + 1);
// set SignalStateInfo Confidences
SignalStateInfo.ConfidenceStateIsStable = HistoryConfidenceStable;
SignalStateInfo.ConfidenceStateIsDrifting =
HistoryConfidenceStateDriftingDown >
HistoryConfidenceStateDriftingUp
? HistoryConfidenceStateDriftingDown
: HistoryConfidenceStateDriftingUp;
SignalStateInfo.ConfidenceStateIsDriftingDown =
HistoryConfidenceStateDriftingDown;
SignalStateInfo.ConfidenceStateIsDriftingUp =
HistoryConfidenceStateDriftingUp;
// set SignalStateInfo StateCondition
if (SignalStateInfo.ConfidenceStateIsStable >
SignalStateInfo.ConfidenceStateIsDrifting)
SignalStateInfo.StateCondition = StateConditions::STABLE;
else if (SignalStateInfo.ConfidenceStateIsStable <
SignalStateInfo.ConfidenceStateIsDrifting)
if (SignalStateInfo.ConfidenceStateIsDriftingDown >
SignalStateInfo.ConfidenceStateIsDriftingUp)
SignalStateInfo.StateCondition = StateConditions::DRIFTING_DN;
else if (SignalStateInfo.ConfidenceStateIsDriftingDown <
SignalStateInfo.ConfidenceStateIsDriftingUp)
SignalStateInfo.StateCondition = StateConditions::DRIFTING_UP;
else
SignalStateInfo.StateCondition = StateConditions::UNKNOWN;
else
SignalStateInfo.StateCondition = StateConditions::UNKNOWN;
}
} else {
SignalStateInfo.ConfidenceStateIsStable = 0;
SignalStateInfo.ConfidenceStateIsDrifting = 0;
SignalStateInfo.ConfidenceStateIsDriftingDown = 0;
SignalStateInfo.ConfidenceStateIsDriftingUp = 0;
SignalStateInfo.StateCondition = StateConditions::UNKNOWN;
}
}
}; // namespace agent
} // 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 d8437c5..e07d78b 100644
--- a/include/rosa/agent/SignalStateDetector.hpp
+++ b/include/rosa/agent/SignalStateDetector.hpp
@@ -1,348 +1,346 @@
//===-- rosa/agent/SignalStateDetector.hpp ----------------------*- C++ -*-===//
//
// The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/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> {
using StateDetector =
StateDetector<INDATATYPE, CONFDATATYPE, PROCDATATYPE, HP>;
using DistanceMetricAbstraction =
typename StateDetector::DistanceMetricAbstraction;
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 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 metric to calculate the distance between two points
DistanceMetricAbstraction DistanceMetric;
/// The FuzzyFunctionSampleMatches is the fuzzy function that gives the
/// confidence how good the new sample matches another sample in the sample
/// history. This is done to evaluate whether one sample belongs to an
/// existing state.
PartFuncPointer FuzzyFunctionSampleMatches;
/// The FuzzyFunctionSampleMismatches is the fuzzy function that gives the
/// confidence how bad the new sample matches another sample in the sample
/// history. This is done to evaluate whether one sample does not belong to an
/// existing state.
PartFuncPointer FuzzyFunctionSampleMismatches;
/// The FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the
/// confidence how many samples from the sample history match the new sample.
/// This is done to evaluate whether one sample belongs to an existing state.
StepFuncPointer FuzzyFunctionNumOfSamplesMatches;
/// The FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives
/// the confidence how many samples from the sample history mismatch the new
/// sample. This is done to evaluate whether one sample does not belong to an
/// existing state.
StepFuncPointer FuzzyFunctionNumOfSamplesMismatches;
/// The FuzzyFunctionSampleValid is the fuzzy function that gives the
/// confidence how good one matches another sample in the sample
/// history. This is done to evaluate whether a state is valid.
PartFuncPointer FuzzyFunctionSampleValid;
/// The FuzzyFunctionSampleInvalid is the fuzzy function that gives the
/// confidence how bad one sample matches another sample in the sample
/// history. This is done to evaluate whether a state is invalid.
PartFuncPointer FuzzyFunctionSampleInvalid;
/// The FuzzyFunctionNumOfSamplesValid is the fuzzy function that gives the
/// confidence how many samples from the sample history match another sample.
/// This is done to evaluate whether a state is valid.
StepFuncPointer FuzzyFunctionNumOfSamplesValid;
/// The FuzzyFunctionNumOfSamplesInvalid is the fuzzy function that gives
/// the confidence how many samples from the sample history mismatch another
/// sample. This is done to evaluate whether a state is invalid.
StepFuncPointer FuzzyFunctionNumOfSamplesInvalid;
/// The FuzzyFunctionSignalIsDriftingDown is the fuzzy function that gives the
/// confidence how likely it is that the signal is drifting down.
PartFuncPointer FuzzyFunctionSignalIsDriftingDown;
/// The FuzzyFunctionSignalIsDriftingUp is the fuzzy function that gives the
/// confidence how likely it is that the signal is drifting up.
PartFuncPointer FuzzyFunctionSignalIsDriftingUp;
/// The FuzzyFunctionSignalIsStable is the fuzzy function that gives the
/// confidence how likely it is that the signal is stable (not drifting).
PartFuncPointer FuzzyFunctionSignalIsStable;
/// TODO: describe
std::shared_ptr<PartialFunction<uint32_t, float>>
FuzzyFunctionSignalConditionLookBack;
/// TODO: describe
std::shared_ptr<PartialFunction<uint32_t, float>>
FuzzyFunctionSignalConditionHistoryDesicion;
/// TODO: describe -> how man steps back in comparison and is also size of
/// DABhistory
uint32_t DriftLookbackRange;
/// SampleHistorySize is the (maximum) size of the sample history.
uint32_t SampleHistorySize;
/// DABSize the size of a DAB (Discrete Average Block).
uint32_t DABSize;
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 DistanceMetric The metric to calculate the distance between two
/// points
///
/// \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 FuzzyFunctionSignalIsDriftingDown The
/// FuzzyFunctionSignalIsDriftingDown is the fuzzy function that gives the
/// confidence how likely it is that the signal (resp. the state of a signal)
/// is drifting down.
///
/// \param FuzzyFunctionSignalIsDriftingUp The FuzzyFunctionSignalIsDriftingUp
/// is the fuzzy function that gives the confidence how likely it is that the
/// signal (resp. the state of a signal) is drifting up.
///
/// \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.
- ///
SignalStateDetector(SignalProperties SignalProperty,
uint32_t MaximumNumberOfSignalStates,
DistanceMetricAbstraction DistanceMetric,
PartFuncPointer FuzzyFunctionSampleMatches,
PartFuncPointer FuzzyFunctionSampleMismatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMatches,
StepFuncPointer FuzzyFunctionNumOfSamplesMismatches,
PartFuncPointer FuzzyFunctionSampleValid,
PartFuncPointer FuzzyFunctionSampleInvalid,
StepFuncPointer FuzzyFunctionNumOfSamplesValid,
StepFuncPointer FuzzyFunctionNumOfSamplesInvalid,
PartFuncPointer FuzzyFunctionSignalIsDriftingDown,
PartFuncPointer FuzzyFunctionSignalIsDriftingUp,
PartFuncPointer FuzzyFunctionSignalIsStable,
std::shared_ptr<PartialFunction<uint32_t, float>>
FuzzyFunctionSignalConditionLookBack,
std::shared_ptr<PartialFunction<uint32_t, float>>
FuzzyFunctionSignalConditionHistoryDesicion,
uint32_t DriftLookbackRange,
uint32_t SampleHistorySize) noexcept
: SignalProperty(SignalProperty), CurrentSignalState(nullptr),
DetectedSignalStates(MaximumNumberOfSignalStates),
DistanceMetric(DistanceMetric),
FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches),
FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches),
FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches),
FuzzyFunctionNumOfSamplesMismatches(
FuzzyFunctionNumOfSamplesMismatches),
FuzzyFunctionSampleValid(FuzzyFunctionSampleValid),
FuzzyFunctionSampleInvalid(FuzzyFunctionSampleInvalid),
FuzzyFunctionNumOfSamplesValid(FuzzyFunctionNumOfSamplesValid),
FuzzyFunctionNumOfSamplesInvalid(FuzzyFunctionNumOfSamplesInvalid),
FuzzyFunctionSignalIsDriftingDown(FuzzyFunctionSignalIsDriftingDown),
FuzzyFunctionSignalIsDriftingUp(FuzzyFunctionSignalIsDriftingUp),
FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable),
FuzzyFunctionSignalConditionLookBack(
FuzzyFunctionSignalConditionLookBack),
FuzzyFunctionSignalConditionHistoryDesicion(
FuzzyFunctionSignalConditionHistoryDesicion),
DriftLookbackRange(DriftLookbackRange),
SampleHistorySize(SampleHistorySize) {
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 this function to an operator()-function
SignalStateInformation<CONFDATATYPE>
detectSignalState(INDATATYPE Sample) noexcept {
if (!CurrentSignalState) {
ASSERT(DetectedSignalStates.empty());
SignalStatePtr S = createNewSignalState();
CurrentSignalState = S;
} else {
// TODO (future): maybe there is a better way than a relative distance
// comparison. Maybe somehow a mix of relative and absolute?
CONFDATATYPE ConfidenceSampleMatchesSignalState =
CurrentSignalState->confidenceSampleMatchesSignalState(Sample);
CONFDATATYPE ConfidenceSampleMismatchesSignalState =
CurrentSignalState->confidenceSampleMismatchesSignalState(Sample);
this->StateHasChanged = ConfidenceSampleMatchesSignalState <=
ConfidenceSampleMismatchesSignalState;
if (this->StateHasChanged) {
if (CurrentSignalState->signalStateInformation().StateIsValid)
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;
for (auto &SavedSignalState : DetectedSignalStates) {
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.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 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>(
this->NextStateID, SignalProperty, SampleHistorySize, DABSize,
*DistanceMetric, *FuzzyFunctionSampleMatches,
*FuzzyFunctionSampleMismatches, *FuzzyFunctionNumOfSamplesMatches,
*FuzzyFunctionNumOfSamplesMismatches, *FuzzyFunctionSampleValid,
*FuzzyFunctionSampleInvalid, *FuzzyFunctionNumOfSamplesValid,
*FuzzyFunctionNumOfSamplesInvalid, *FuzzyFunctionSignalIsDriftingDown,
*FuzzyFunctionSignalIsDriftingUp, *FuzzyFunctionSignalIsStable,
*FuzzyFunctionSignalConditionLookBack,
*FuzzyFunctionSignalConditionHistoryDesicion, DriftLookbackRange));
DetectedSignalStates.addEntry(S);
return S;
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SIGNALSTATEDETECTOR_HPP

File Metadata

Mime Type
text/x-diff
Expires
Sun, Oct 19, 5:29 PM (14 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
199615
Default Alt Text
(44 KB)

Event Timeline