Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10547180
State.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
11 KB
Referenced Files
None
Subscribers
None
State.hpp
View Options
//===-- rosa/agent/State.hpp ----------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/State.hpp
///
/// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *state* *functionality*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_STATE_HPP
#define ROSA_AGENT_STATE_HPP
#include
"rosa/agent/FunctionAbstractions.hpp"
#include
"rosa/agent/Functionality.h"
#include
"rosa/agent/History.hpp"
#include
<cstdarg>
namespace
rosa
{
namespace
agent
{
/// State conditions defining how the condition of a \c rosa::agent::State is
/// saved in \c rosa::agent::StateInformation.
enum
class
VariableStateCondition
{
STABLE
,
///< The state is stable
DRIFTING
,
///< The state is drifting
UNKNOWN
///< The state is unknown
};
template
<
typename
CONFDATATYPE
>
struct
StateInformation
{
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT
((
std
::
is_arithmetic
<
CONFDATATYPE
>::
value
),
"confidence type is not to arithmetic"
);
/// The state ID saved as an unsigned integer number
unsigned
int
StateID
;
/// The StateConfidence shows the overall confidence value of the state.
CONFDATATYPE
StateConfidence
;
/// The VariableStateCondition shows the condition of a state (stable or
/// drifting)
VariableStateCondition
VariableStateCondition
;
/// The StateIsValid shows whether a state is valid or invalid. In this
/// context, valid means that enough samples which are in close proximitry
/// have been inserted into the state.
bool
StateIsValid
;
/// The StateJustGotValid shows whether a state got valid (toggled from
/// invalid to valid) during the current inserted sample.
bool
StateJustGotValid
;
/// The StateIsValidAfterReentrance shows whether a state is valid after the
/// variable changed back to it again.
bool
StateIsValidAfterReentrance
;
};
// @Benedikt: now there are 4 datatypes. Do you think we can merge DISTDATATYPE
// and DABDATATYPE somehow?
/// \tparam INDATATYPE type of input data, \tparam CONFDATATYPE type of
/// data in that the confidence values are given, \param DISTDATATYPE type of
/// the relative distance, \tparam DABDATATYPE type of data in which DABs are
/// saved.
template
<
typename
INDATATYPE
,
typename
CONFDATATYPE
,
typename
DISTDATATYPE
,
typename
DABDATATYPE
>
class
State
:
public
Functionality
{
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT
((
std
::
is_arithmetic
<
INDATATYPE
>::
value
),
"input data type not arithmetic"
);
STATIC_ASSERT
((
std
::
is_arithmetic
<
CONFDATATYPE
>::
value
),
"DAB storage 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
StateInfoPtr
=
std
::
shared_ptr
<
StateInformation
<
CONFDATATYPE
>>
;
/// StateInfo is a struct StateInformation that contains information about the
/// current state.
StateInfoPtr
StateInfo
;
/// 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 FuzzyFunctionSampleMatches is the fuzzy function that gives the
/// confidence how bad the new sample matches another sample in the sample
/// history.
PartFuncPointer
FuzzyFunctionSampleMismatches
;
/// The FuzzyFunctionSampleMatches is the fuzzy function that gives the
/// confidence how many samples from the sampe history match the new sample.
StepFuncPointer
FuzzyFunctionNumOfSamplesMatches
;
/// The FuzzyFunctionSampleMatches 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
<
DABDATATYPE
,
HistoryPolicy
::
LIFO
>
DABHistory
;
/// The StateIsValid shows whether a state is valid or invalid. In this
/// context, valid means that enough samples which are in close proximitry
/// have been inserted into the state.
bool
StateIsValid
;
/// The StateIsValidAfterReentrance shows whether a state is valid after the
/// variable changed back to it again.
bool
StateIsValidAfterReentrance
;
public
:
/// Creates an instance by setting all parameters
State
(
unsigned
int
StateID
,
PartFuncPointer
FuzzyFunctionSampleMatches
,
PartFuncPointer
FuzzyFunctionSampleMismatches
,
StepFuncPointer
FuzzyFunctionNumOfSamplesMatches
,
StepFuncPointer
FuzzyFunctionNumOfSamplesMismatches
,
PartFuncPointer
FuzzyFunctionSignalIsDrifting
,
PartFuncPointer
FuzzyFunctionSignalIsStable
,
unsigned
int
sampleHistorySize
,
unsigned
int
DABSize
,
unsigned
int
DABHistorySize
)
noexcept
:
StateInfo
(
StateID
,
0
,
VariableStateCondition
::
UNKNOWN
,
false
,
false
),
SampleHistory
(
sampleHistorySize
),
DAB
(
DABSize
),
DABHistory
(
DABHistorySize
),
FuzzyFunctionSampleMatches
(
FuzzyFunctionSampleMatches
),
FuzzyFunctionSampleMismatches
(
FuzzyFunctionSampleMismatches
),
FuzzyFunctionNumOfSamplesMatches
(
FuzzyFunctionNumOfSamplesMatches
),
FuzzyFunctionNumOfSamplesMismatches
(
FuzzyFunctionNumOfSamplesMismatches
),
FuzzyFunctionSignalIsDrifting
(
FuzzyFunctionSignalIsDrifting
),
FuzzyFunctionSignalIsStable
(
FuzzyFunctionSignalIsStable
)
{}
/// Destroys \p this object.
~
State
(
void
)
=
default
;
void
leaveState
(
void
)
{
DAB
.
clear
();
StateIsValidAfterReentrance
=
false
;
}
void
insertSample
(
INDATATYPE
Sample
)
{
SampleHistory
.
addEntry
(
Sample
);
DAB
.
addEntry
(
Sample
);
if
(
DAB
.
full
())
{
DABDATATYPE
AvgOfDAB
=
DAB
.
template
average
<
DABDATATYPE
>
();
DABHistory
.
addEntry
(
AvgOfDAB
);
DAB
.
clear
();
}
// TODO @Benedikt: stepfunction auch andere richtung
FuzzyFunctionNumOfSamplesMatches
->
setRightLimit
(
SampleHistory
->
numberOfEntries
());
FuzzyFunctionNumOfSamplesMismatches
->
setRightLimit
(
SampleHistory
->
numberOfEntries
());
// TODO: calculate whether state is valid and properly set StateIsValid,
// StateJustGotValid, StateIsValidAfterReentrance
// TODO: check actual state whether it drifts
// TODO: write in StateInfo
}
// TODO: check this function again
CONFDATATYPE
confSampleMatchesState
(
INDATATYPE
sample
)
{
DISTDATATYPE
RelDist
;
CONFDATATYPE
HighestConf
=
0
;
// QUESTION: should I also use a history (array) for that?
std
::
vector
<
DISTDATATYPE
>
RelDistHistValuesAndSampleValue
;
for
(
auto
&
hs
:
SampleHistory
)
{
RelDist
=
relativeDistance
(
sample
,
hs
);
RelDistHistValuesAndSampleValue
.
push_back
(
RelDist
);
}
sort
(
begin
(
RelDistHistValuesAndSampleValue
),
end
(
RelDistHistValuesAndSampleValue
));
// 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
numOfHistSamplesIncluded
=
1
;
numOfHistSamplesIncluded
<=
RelDistHistValuesAndSampleValue
.
size
();
numOfHistSamplesIncluded
++
)
{
CONFDATATYPE
LowestConfOfSamplesIncluded
=
1
;
unsigned
int
HistSampleCounter
=
0
;
for
(
auto
&
D
:
RelDistHistValuesAndSampleValue
)
{
if
(
HistSampleCounter
>=
numOfHistSamplesIncluded
)
break
;
CONFDATATYPE
confRelDist
;
if
(
std
::
isinf
(
D
)
==
false
)
{
confRelDist
=
FuzzyFunctionSampleMatches
(
D
);
}
else
{
confRelDist
=
0
;
}
// std::min is equal to Fuzzy AND -> maybe using
LowestConfOfSamplesIncluded
=
fuzzyAND
(
LowestConfOfSamplesIncluded
,
confRelDist
);
HistSampleCounter
++
;
}
// @benedikt: do you think my fuzzyOR function does the same as the next
// out-commented lines?
// HighestConf = std::max(HighestConf,
// std::max(LowestConfOfSamplesIncluded,
// FuzzyFunctionNumOfSamplesMatches((CONFDATATYPE)HistSampleCounter)));
// @benedikt: TODO: change old-style cast to one of these
// reinterpret_cast,
// static_cast, dynamic_cast or const_cast. Which should I use? Or should
// the HistSampleCounter variable already be CONFDATATYPE type?
fuzzyOR
(
HighestConf
,
LowestConfOfSamplesIncluded
,
FuzzyFunctionNumOfSamplesMatches
((
CONFDATATYPE
)
HistSampleCounter
));
}
}
CONFDATATYPE
confSampleMismatchesState
(
INDATATYPE
sample
)
{
// TODO: do it in the same way as confSampleMatchesState(INDATATYPE sample)
}
/// Gives information about the current state.
///
/// \return a struct StateInformation that contains information about the
/// current state.
StateInfoPtr
stateInformation
(
void
)
{
return
StateInfo
;
}
private
:
// copied from the internet and adapted
// (https://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c)
CONFDATATYPE
fuzzyAND
(
CONFDATATYPE
n_args
,
...)
{
va_list
ap
;
va_start
(
ap
,
n_args
);
CONFDATATYPE
min
=
va_arg
(
ap
,
CONFDATATYPE
);
for
(
CONFDATATYPE
i
=
2
;
i
<=
n_args
;
i
++
)
{
CONFDATATYPE
a
=
va_arg
(
ap
,
CONFDATATYPE
);
//@benedikt: instead of the if, I could use "std::min"
if
(
a
<
min
)
min
=
a
;
}
va_end
(
ap
);
return
min
;
}
// copied from the internet
// (https://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c)
CONFDATATYPE
fuzzyOR
(
CONFDATATYPE
n_args
,
...)
{
va_list
ap
;
va_start
(
ap
,
n_args
);
CONFDATATYPE
max
=
va_arg
(
ap
,
CONFDATATYPE
);
for
(
CONFDATATYPE
i
=
2
;
i
<=
n_args
;
i
++
)
{
CONFDATATYPE
a
=
va_arg
(
ap
,
CONFDATATYPE
);
//@benedikt: instead of the if, I could use "std::max"
if
(
a
>
max
)
max
=
a
;
}
va_end
(
ap
);
return
max
;
}
// TODO: Ask David where to move that function (or if it should stay here).
DISTDATATYPE
relativeDistance
(
INDATATYPE
SampleValue
,
INDATATYPE
HistoryValue
)
{
DISTDATATYPE
Dist
=
HistoryValue
-
SampleValue
;
if
(
Dist
==
0
)
{
return
0
;
}
else
{
Dist
=
Dist
/
SampleValue
;
if
(
Dist
<
0
)
{
//@benedikt: 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 agent
}
// End namespace rosa
#endif
// ROSA_AGENT_STATE_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sat, May 30, 11:42 PM (19 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
329808
Default Alt Text
State.hpp (11 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment