Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10705791
Reliability.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
34 KB
Referenced Files
None
Subscribers
None
Reliability.h
View Options
//===-- rosa/agent/Reliability.h --------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/Reliability.h
///
/// \author Daniel Schnoell (daniel.schnoell@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *reliability* *functionality*.
///
/// \note based on Maximilian Goetzinger (maxgot@utu.fi) code in
/// CAM_Dirty_include SA-EWS2_Version... inside Agent.cpp
///
/// \note By defining and setting Reliability_trace_level it is possible to
/// change the level to which it should be traced. \note All classes throw
/// runtime errors if not all things are set
///
/// \note should the Reliability be capped?
///
///
//===----------------------------------------------------------------------===//
// make combination modular
#ifndef ROSA_AGENT_RELIABILITY_H
#define ROSA_AGENT_RELIABILITY_H
#include
"rosa/agent/CrossReliability.h"
#include
"rosa/agent/FunctionAbstractions.hpp"
#include
"rosa/agent/Functionality.h"
#include
"rosa/agent/RangeConfidence.hpp"
#include
<algorithm>
#include
<type_traits>
#include
<vector>
/// 0 everything
/// 1 vectors
/// 2 outputs
#define trace_everything 0
#define trace_vectors 1
#define trace_outputs 2
#ifndef Reliability_trace_level
#define Reliability_trace_level 0
#endif
#define trace_end "\n\n\n"
namespace
rosa
{
namespace
agent
{
/// This is a struct with a few methods that make lowlevel/highlevel Reliability
/// more readable \tparam StateType The datatype of the States \tparam
/// ReliabilityType The datatype of the Reliability
template
<
typename
StateType
,
typename
ReliabilityType
>
struct
ConfOrRel
{
/// making both Template Arguments readable to make a few things easier
typedef
StateType
_StateType
;
/// making both Template Arguments readable to make a few things easier
typedef
ReliabilityType
_ReliabilityType
;
/// The actual place where the data is stored
StateType
score
;
/// The actual place where the data is stored
ReliabilityType
Reliability
;
ConfOrRel
(
StateType
_score
,
ReliabilityType
_Reliability
)
:
score
(
_score
),
Reliability
(
_Reliability
){};
ConfOrRel
(){};
/// Pushes the Data in a Human readable form
/// \param out The stream where it is written to
/// \param c The struct itself
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
ConfOrRel
&
c
)
{
out
<<
"Score: "
<<
c
.
score
<<
"
\t
Reliability: "
<<
c
.
Reliability
<<
" "
;
return
out
;
}
/// needed or it throws an clang diagnosic error
typedef
std
::
map
<
StateType
,
ReliabilityType
>
map
;
// needed or it throws an clang diagnosic error
/// Filles the vector with the data inside the map
/// \param me The vector to be filled
/// \param data The data wich is to be pushed into the vector
friend
std
::
vector
<
ConfOrRel
>
&
operator
<<
(
std
::
vector
<
ConfOrRel
>
&
me
,
map
&&
data
)
{
for
(
auto
tmp
:
data
)
{
me
.
push_back
(
ConfOrRel
(
tmp
.
first
,
tmp
.
second
));
#if Reliability_trace_level <= trace_everything
LOG_TRACE_STREAM
<<
"
\n
"
<<
ConfOrRel
(
tmp
.
first
,
tmp
.
second
)
<<
trace_end
;
#endif
}
return
me
;
}
/// This is to push the data inside a vector in a human readable way into the
/// ostream \param out The ostream \param c The vector which is read
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
std
::
vector
<
ConfOrRel
>
&
c
)
{
std
::
size_t
index
=
0
;
for
(
ConfOrRel
data
:
c
)
{
out
<<
index
<<
" : "
<<
data
<<
"
\n
"
;
index
++
;
}
return
out
;
}
};
/// This calculates the minimum of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template
<
typename
Conf
>
std
::
vector
<
Conf
>
min
(
std
::
vector
<
Conf
>
me
,
typename
Conf
::
_ReliabilityType
value
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
tmp
:
me
)
tmp
.
Reliability
=
std
::
min
(
tmp
.
Reliability
,
value
);
return
me
;
}
/// This calculates the maximum of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template
<
typename
Conf
>
std
::
vector
<
Conf
>
max
(
std
::
vector
<
Conf
>
me
,
typename
Conf
::
_ReliabilityType
value
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
tmp
:
me
)
tmp
.
Reliability
=
std
::
max
(
tmp
.
Reliability
,
value
);
return
me
;
}
/// This calculates the average of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template
<
typename
Conf
>
std
::
vector
<
Conf
>
average
(
std
::
vector
<
Conf
>
me
,
typename
Conf
::
_ReliabilityType
value
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
tmp
:
me
)
tmp
.
Reliability
=
(
tmp
.
Reliability
+
value
)
/
2
;
return
me
;
}
/// This calculates the average of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template
<
typename
Conf
>
std
::
vector
<
Conf
>
mult
(
std
::
vector
<
Conf
>
me
,
typename
Conf
::
_ReliabilityType
value
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
tmp
:
me
)
tmp
.
Reliability
=
tmp
.
Reliability
*
value
/
2
;
return
me
;
}
/// This average's the Reliabilities of the same Scores
template
<
typename
Conf
>
std
::
vector
<
Conf
>
average
(
std
::
vector
<
Conf
>
A
,
std
::
vector
<
Conf
>
B
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
&
tmp_me
:
A
)
for
(
auto
&
tmp_other
:
B
)
{
if
(
tmp_me
.
score
==
tmp_other
.
score
)
{
tmp_me
.
Reliability
=
(
tmp_me
.
Reliability
+
tmp_other
.
Reliability
)
/
2
;
}
}
return
A
;
}
/// This min's the Reliabilities of the same Scores
template
<
typename
Conf
>
std
::
vector
<
Conf
>
min
(
std
::
vector
<
Conf
>
A
,
std
::
vector
<
Conf
>
B
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
&
tmp_me
:
A
)
for
(
auto
&
tmp_other
:
B
)
{
if
(
tmp_me
.
score
==
tmp_other
.
score
)
{
tmp_me
.
Reliability
=
std
::
min
(
tmp_me
.
Reliability
+
tmp_other
.
Reliability
);
}
}
return
A
;
}
/// This max's the Reliabilities of the same Scores
template
<
typename
Conf
>
std
::
vector
<
Conf
>
max
(
std
::
vector
<
Conf
>
A
,
std
::
vector
<
Conf
>
B
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
&
tmp_me
:
A
)
for
(
auto
&
tmp_other
:
B
)
{
if
(
tmp_me
.
score
==
tmp_other
.
score
)
{
tmp_me
.
Reliability
=
std
::
max
(
tmp_me
.
Reliability
+
tmp_other
.
Reliability
);
}
}
return
A
;
}
/// This mult's the Reliabilities of the same Scores
template
<
typename
Conf
>
std
::
vector
<
Conf
>
mult
(
std
::
vector
<
Conf
>
A
,
std
::
vector
<
Conf
>
B
)
{
static_assert
(
std
::
is_arithmetic
<
typename
Conf
::
_ReliabilityType
>::
value
);
for
(
auto
&
tmp_me
:
A
)
for
(
auto
&
tmp_other
:
B
)
{
if
(
tmp_me
.
score
==
tmp_other
.
score
)
{
tmp_me
.
Reliability
=
tmp_me
.
Reliability
*
tmp_other
.
Reliability
;
}
}
return
A
;
}
/// This is the combinator for Reliability and confidences it takes the
/// Sensor value, its "History" and feedback from \c
/// CrossCombinator to calculate different Reliabilities.
/// \tparam SensorValueType Datatype of the Sensor value ( Typically
/// double or float) \tparam StateType Datatype of the State ( Typically long or
/// int)
/// \tparam ReliabilityType Datatype of the Reliability (
/// Typically double or float)
///
/// \note more information about how it calculates
/// the Reliabilities
/// \verbatim
///----------------------------------------------------------------------------------
///
///
/// ->Reliability---> getInputReliability()
/// | |
/// | V
/// Sensor Value ---| PossibleScoreCombinationMethod -> next line
/// | A |
/// | | V
/// ->Confidence--- getPossibleScores()
///
///-----------------------------------------------------------------------------------
///
/// feedback
/// |
/// V
/// ValuesFromMaster
/// | -> History ---|
/// V | V
/// here -> FeedbackCombinatorMethod --------> HistoryCombinatorMethod->nextline
/// | |
/// V V
/// getpossibleScoresWithMasterFeedback() getPossibleScoresWithHistory()
///
///----------------------------------------------------------------------------------
///
/// here -> sort -> most likely -> mostLikelySoreAndReliability()
///
/// ---------------------------------------------------------------------------------
/// \endverbatim
/// the mentioned methods are early outs so if two ore more of them are run in
/// the same step they will be interpreted as different time steps
/// <pre>
/// Default values for Combinators:
/// InputReliabilityCombinator = combinationMin;
/// PossibleScoreCombinationMethod = PossibleScoreCombinationMethodMin;
/// FeedbackCombinatorMethod = FeedbackCombinatorMethodAverage;
/// HistoryCombinatorMethod = HistoryCombinatorMethodMax;
/// </pre>
///
///
///
template
<
typename
SensorValueType
,
typename
StateType
,
typename
ReliabilityType
>
class
ReliabilityAndConfidenceCombinator
{
public
:
static_assert
(
std
::
is_arithmetic
<
SensorValueType
>::
value
,
"LowLevel: SensorValueType has to an arithmetic type
\n
"
);
static_assert
(
std
::
is_arithmetic
<
StateType
>::
value
,
"LowLevel: StateType has to an arithmetic type
\n
"
);
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
,
"LowLevel: ReliabilityType has to an arithmetic type
\n
"
);
/// Typedef to shorten the writing.
/// \c ConfOrRel
typedef
ConfOrRel
<
StateType
,
ReliabilityType
>
ConfOrRel
;
/// Calculates the input reliability by combining Reliability of the Sensor
/// and the Slope Reliability \param SensorValue The sensor Value \note to set
/// the combination method \c setInputReliabilityCombinator()
auto
getInputReliability
(
SensorValueType
SensorValue
)
{
auto
inputReliability
=
getReliability
(
SensorValue
,
previousSensorValue
,
valueSetCounter
);
previousSensorValue
=
SensorValue
;
PreviousSensorValueExists
=
true
;
return
inputReliability
;
}
/// Calculates the Reliability
/// \param SensorValue The current Values of the Sensor
///
/// \return Reliability and Score of the current SensorValue
///
ConfOrRel
mostLikelySoreAndReliability
(
SensorValueType
SensorValue
)
{
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM
<<
"
\n
Trace level is set to: "
<<
Reliability_trace_level
<<
"
\n
"
<<
"Will trace: "
<<
((
Reliability_trace_level
==
trace_outputs
)
?
"outputs"
:
(
Reliability_trace_level
==
trace_vectors
)
?
"vectors"
:
(
Reliability_trace_level
==
trace_everything
)
?
"everything"
:
"undefined"
)
<<
trace_end
;
#endif
std
::
vector
<
ConfOrRel
>
ActuallPossibleScores
;
std
::
vector
<
ConfOrRel
>
possibleScores
;
ReliabilityType
inputReliability
=
getInputReliability
(
SensorValue
);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM
<<
"
\n
input Rel: "
<<
inputReliability
<<
trace_end
;
#endif
possibleScores
<<
Confidence
->
operator
()(
SensorValue
);
possibleScores
=
PossibleScoreCombinationMethod
(
possibleScores
,
inputReliability
);
possibleScores
=
FeedbackCombinatorMethod
(
possibleScores
,
ValuesFromMaster
);
saveInHistory
(
possibleScores
);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM
<<
"
\n
ActuallPossibleScores:
\n
"
<<
possibleScores
<<
trace_end
;
LOG_TRACE_STREAM
<<
"
\n
possibleScores:
\n
"
<<
possibleScores
<<
trace_end
;
#endif
possibleScores
.
clear
();
possibleScores
=
getAllPossibleScoresBasedOnHistory
();
std
::
sort
(
possibleScores
.
begin
(),
possibleScores
.
end
(),
[](
ConfOrRel
A
,
ConfOrRel
B
)
->
bool
{
return
A
.
Reliability
>
B
.
Reliability
;
});
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM
<<
"
\n
output lowlevel: "
<<
possibleScores
.
at
(
0
)
<<
trace_end
;
#endif
return
possibleScores
.
at
(
0
);
}
/// Calculates the possible Scores
/// \param SensorValue the Sensor Value
/// \brief it combines the input reliability and the confidence of the Sensor.
/// The use combination method can be set using \c
/// setPossibleScoreCombinationMethod()
auto
getPossibleScores
(
SensorValueType
SensorValue
)
{
std
::
vector
<
ConfOrRel
>
possibleScores
;
ReliabilityType
inputReliability
=
getInputReliability
(
SensorValue
);
// get input rel()
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM
<<
"
\n
input Rel: "
<<
inputReliability
<<
trace_end
;
#endif
possibleScores
<<
Confidence
->
operator
()(
SensorValue
);
possibleScores
=
PossibleScoreCombinationMethod
(
possibleScores
,
inputReliability
);
return
possibleScores
;
}
/// return the Possible Values with the feedback in mind
/// \param SensorValue The sensor Value
/// \brief it combines the input reliability and the confidence of the Sensor.
/// The combines them with FeedbackCombinatorMethod and returns the result.
auto
getpossibleScoresWithMasterFeedback
(
SensorValueType
SensorValue
)
{
std
::
vector
<
ConfOrRel
>
possibleScores
;
ReliabilityType
inputReliability
=
getInputReliability
(
SensorValue
);
// get input rel()
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM
<<
"
\n
input Rel: "
<<
inputReliability
<<
trace_end
;
#endif
possibleScores
<<
Confidence
->
operator
()(
SensorValue
);
possibleScores
=
PossibleScoreCombinationMethod
(
possibleScores
,
inputReliability
);
// set comb method with values from master ( class :: min | max | average |
// mult | [] ()-> {} )
possibleScores
=
FeedbackCombinatorMethod
(
possibleScores
,
ValuesFromMaster
);
return
possibleScores
;
}
/// returns all possible Scores and Reliabilities with the History in mind
/// \param SensorValue the Sensor value
/// how this is done is described at the class.
auto
getPossibleScoresWithHistory
(
SensorValueType
SensorValue
)
{
std
::
vector
<
ConfOrRel
>
ActuallPossibleScores
;
std
::
vector
<
ConfOrRel
>
possibleScores
;
ReliabilityType
inputReliability
=
getInputReliability
(
SensorValue
);
// get input rel()
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM
<<
"
\n
input Rel: "
<<
inputReliability
<<
trace_end
;
#endif
possibleScores
<<
Confidence
->
operator
()(
SensorValue
);
possibleScores
=
PossibleScoreCombinationMethod
(
possibleScores
,
inputReliability
);
possibleScores
=
FeedbackCombinatorMethod
(
possibleScores
,
ValuesFromMaster
);
saveInHistory
(
possibleScores
);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM
<<
"
\n
ActuallPossibleScores:
\n
"
<<
possibleScores
<<
trace_end
;
LOG_TRACE_STREAM
<<
"
\n
possibleScores:
\n
"
<<
possibleScores
<<
trace_end
;
#endif
possibleScores
.
clear
();
return
getAllPossibleScoresBasedOnHistory
();
}
/// feedback for this functionality most commonly it comes from a Master Agent
/// \param ValuesFromMaster The Scores + Reliability for the feedback
/// \brief This input kind of resembles a confidence but not
/// directly it more or less says: compared to the other Scores inside the
/// System these are the Scores with the Reliability that you have.
void
feedback
(
std
::
vector
<
ConfOrRel
>
ValuesFromMaster
)
{
this
->
ValuesFromMaster
=
ValuesFromMaster
;
}
//
// ----------------------Reliability and Confidence Function setters----------
//
/// This is the setter for Confidence Function
/// \param Confidence A pointer to the Functional for the \c Confidence of the
/// Sensor value
void
setConfidenceFunction
(
std
::
unique_ptr
<
RangeConfidence
<
ReliabilityType
,
StateType
,
SensorValueType
>>
&
Confidence
)
{
this
->
Confidence
=
std
::
move
(
Confidence
);
}
/// This is the setter for Reliability Function
/// \param Reliability A pointer to the Functional for the Reliability
/// \brief The Reliability takes the current Sensor value and return the
/// Reliability of the value.
void
setReliabilityFunction
(
std
::
unique_ptr
<
Abstraction
<
SensorValueType
,
ReliabilityType
>>
&
Reliability
)
{
this
->
Reliability
=
std
::
move
(
Reliability
);
}
/// This is the setter for ReliabilitySlope Function
/// \param ReliabilitySlope A pointer to the Functional for the
/// ReliabilitySlope
/// \brief The ReliabilitySlope takes the difference of the current Sensor
/// Value to the last one and tells you how likely the change is.
void
setReliabilitySlopeFunction
(
std
::
unique_ptr
<
Abstraction
<
SensorValueType
,
ReliabilityType
>>
&
ReliabilitySlope
)
{
this
->
ReliabilitySlope
=
std
::
move
(
ReliabilitySlope
);
}
/// This is the setter for TimeConfidence Function
/// \param TimeConfidence A pointer to the Functional for the TimeConfidence
/// \brief The time function takes the position in the History with greater
/// equals older and return a Reliability of how "relevant" it is.
void
setTimeConfidenceFunction
(
std
::
unique_ptr
<
Abstraction
<
std
::
size_t
,
ReliabilityType
>>
&
TimeConfidence
)
{
this
->
TimeConfidence
=
std
::
move
(
TimeConfidence
);
}
/// This is the setter for all possible States
/// \param states A vector containing all states
/// \brief This exists even though \c State Type is an arithmetic Type because
/// the states do not need to be "next" to each other ( ex. states={ 1 7 24 })
void
setStates
(
std
::
vector
<
StateType
>
states
)
{
this
->
States
=
states
;
}
/// This sets the Maximum length of the History
/// \param length The length
void
setHistoryLength
(
std
::
size_t
length
)
{
this
->
HistoryMaxSize
=
length
;
}
/// This sets the Value set Counter
/// \param ValueSetCounter the new Value
/// \note This might actually be only an artifact. It is only used to get the
/// reliability from the \c ReliabilitySlope [ ReliabilitySlope->operator()(
/// (lastValue - actualValue) / (SensorValueType)valueSetCounter) ]
void
setValueSetCounter
(
unsigned
int
ValueSetCounter
)
{
this
->
valueSetCounter
=
ValueSetCounter
;
}
//
// ----------------combinator setters-----------------------------------------
//
/// This sets the combination method used by the History
/// \param Meth the method which should be used. predefined \c
/// HistoryCombinatorMethodMin() \c HistoryCombinatorMethodMax() \c
/// HistoryCombinatorMethodMult() \c HistoryCombinatorMethodAverage()
void
setHistoryCombinatorMethod
(
ReliabilityType
(
*
Meth
)(
ReliabilityType
,
ReliabilityType
))
{
HistoryCombinatorMethod
=
Meth
;
}
/// sets the predefined method for the combination of the possible scores and
/// the master \param Meth the method predefined ones are
/// \c FeedbackCombinatorMethodAverage() \c FeedbackCombinatorMethodMin() \c
/// FeedbackCombinatorMethodMax() \c FeedbackCombinatorMethodMult()
void
setFeedbackCombinatorMethod
(
std
::
vector
<
ConfOrRel
>
(
*
Meth
)(
std
::
vector
<
ConfOrRel
>
,
std
::
vector
<
ConfOrRel
>
))
{
FeedbackCombinatorMethod
=
Meth
;
}
/// Sets the used combination method for Possible Scores
/// \param Meth a Pointer for the used Method. Predefined methods \c
/// PossibleScoreCombinationMethodMin() \c PossibleScoreCombinationMethodMax()
/// \c PossibleScoreCombinationMethodAverage()
void
setPossibleScoreCombinationMethod
(
std
::
vector
<
ConfOrRel
>
(
*
Meth
)(
std
::
vector
<
ConfOrRel
>
,
ReliabilityType
))
{
PossibleScoreCombinationMethod
=
Meth
;
}
/// sets the input reliability combinator method
/// \param method the to be used method
/// \note there are predefined methods \c combinationMin() \c combinationMax()
/// \c combinationAverage()
void
setInputReliabilityCombinator
(
ReliabilityType
(
*
method
)(
ReliabilityType
,
ReliabilityType
))
{
InputReliabilityCombinator
=
method
;
}
//
// ----------------predefined combinators------------------------------------
//
/// predefined Method
static
ReliabilityType
HistoryCombinatorMethodMin
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
std
::
min
(
A
,
B
);
}
/// predefined Method
static
ReliabilityType
HistoryCombinatorMethodMax
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
std
::
max
(
A
,
B
);
}
/// predefined Method
static
ReliabilityType
HistoryCombinatorMethodMult
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
A
*
B
;
}
/// predefined Method
static
ReliabilityType
HistoryCombinatorMethodAverage
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
(
A
+
B
)
/
2
;
}
/// predefined method
static
std
::
vector
<
ConfOrRel
>
FeedbackCombinatorMethodAverage
(
std
::
vector
<
ConfOrRel
>
A
,
std
::
vector
<
ConfOrRel
>
B
)
{
return
average
(
A
,
B
);
}
/// predefined method
static
std
::
vector
<
ConfOrRel
>
FeedbackCombinatorMethodMin
(
std
::
vector
<
ConfOrRel
>
A
,
std
::
vector
<
ConfOrRel
>
B
)
{
return
min
(
A
,
B
);
}
/// predefined method
static
std
::
vector
<
ConfOrRel
>
FeedbackCombinatorMethodMax
(
std
::
vector
<
ConfOrRel
>
A
,
std
::
vector
<
ConfOrRel
>
B
)
{
return
max
(
A
,
B
);
}
/// predefined method
static
std
::
vector
<
ConfOrRel
>
FeedbackCombinatorMethodMult
(
std
::
vector
<
ConfOrRel
>
A
,
std
::
vector
<
ConfOrRel
>
B
)
{
return
mult
(
A
,
B
);
}
/// Predefined combination method for possible Scores
static
std
::
vector
<
ConfOrRel
>
PossibleScoreCombinationMethodMin
(
std
::
vector
<
ConfOrRel
>
A
,
ReliabilityType
B
)
{
return
min
(
A
,
B
);
}
/// Predefined combination method for possible Scores
static
std
::
vector
<
ConfOrRel
>
PossibleScoreCombinationMethodMax
(
std
::
vector
<
ConfOrRel
>
A
,
ReliabilityType
B
)
{
return
max
(
A
,
B
);
}
/// Predefined combination method for possible Scores
static
std
::
vector
<
ConfOrRel
>
PossibleScoreCombinationMethodAverage
(
std
::
vector
<
ConfOrRel
>
A
,
ReliabilityType
B
)
{
return
average
(
A
,
B
);
}
/// Predefined combination method for possible Scores
static
std
::
vector
<
ConfOrRel
>
PossibleScoreCombinationMethodMult
(
std
::
vector
<
ConfOrRel
>
A
,
ReliabilityType
B
)
{
return
mult
(
A
,
B
);
}
/// The predefined min combinator method
static
ReliabilityType
combinationMin
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
std
::
min
(
A
,
B
);
}
/// The predefined max combinator method
static
ReliabilityType
combinationMax
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
std
::
max
(
A
,
B
);
}
/// The predefined average combinator method
static
ReliabilityType
combinationAverage
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
(
A
+
B
)
/
2
;
}
/// The predefined average combinator method
static
ReliabilityType
combinationMult
(
ReliabilityType
A
,
ReliabilityType
B
)
{
return
A
*
B
;
}
private
:
std
::
vector
<
std
::
vector
<
ConfOrRel
>>
History
;
std
::
size_t
HistoryMaxSize
;
std
::
vector
<
ConfOrRel
>
ValuesFromMaster
;
SensorValueType
previousSensorValue
;
unsigned
int
valueSetCounter
;
std
::
vector
<
StateType
>
States
;
bool
PreviousSensorValueExists
=
false
;
std
::
unique_ptr
<
RangeConfidence
<
ReliabilityType
,
StateType
,
SensorValueType
>>
Confidence
;
std
::
unique_ptr
<
Abstraction
<
SensorValueType
,
ReliabilityType
>>
Reliability
;
std
::
unique_ptr
<
Abstraction
<
SensorValueType
,
ReliabilityType
>>
ReliabilitySlope
;
std
::
unique_ptr
<
Abstraction
<
std
::
size_t
,
ReliabilityType
>>
TimeConfidence
;
// combination functions
ReliabilityType
(
*
InputReliabilityCombinator
)(
ReliabilityType
,
ReliabilityType
)
=
combinationMin
;
std
::
vector
<
ConfOrRel
>
(
*
PossibleScoreCombinationMethod
)(
std
::
vector
<
ConfOrRel
>
,
ReliabilityType
)
=
PossibleScoreCombinationMethodMin
;
std
::
vector
<
ConfOrRel
>
(
*
FeedbackCombinatorMethod
)(
std
::
vector
<
ConfOrRel
>
,
std
::
vector
<
ConfOrRel
>
)
=
FeedbackCombinatorMethodAverage
;
ReliabilityType
(
*
HistoryCombinatorMethod
)(
ReliabilityType
,
ReliabilityType
)
=
HistoryCombinatorMethodMax
;
/*--------------------------------- needed Functions
* -----------------------------------------------------*/
/// returns the Reliability
/// \param actualValue The Value of the Sensor
/// \param lastValue of the Sensor this is stored in the class
/// \param valueSetCounter It has an effect on the difference of the current
/// and last value This might not be needed anymore
/// \brief it returns the combination the \c Reliability function and \c
/// ReliabilitySlope if the previous value exists. if it doesn't it only
/// returns the \c Reliability function value.
ReliabilityType
getReliability
(
SensorValueType
actualValue
,
SensorValueType
lastValue
,
unsigned
int
valueSetCounter
)
{
ReliabilityType
relAbs
=
Reliability
->
operator
()(
actualValue
);
if
(
PreviousSensorValueExists
)
{
ReliabilityType
relSlo
=
ReliabilitySlope
->
operator
()(
(
lastValue
-
actualValue
)
/
(
SensorValueType
)
valueSetCounter
);
return
InputReliabilityCombinator
(
relAbs
,
relSlo
);
}
else
return
relAbs
;
}
/// adapts the possible Scores by checking the History and combines those
/// values. currently with max
/// \brief combines the historic values with the \c TimeConfidence function
/// and returns the maximum Reliability for all Scores.
std
::
vector
<
ConfOrRel
>
getAllPossibleScoresBasedOnHistory
()
{
// iterate through all history entries
std
::
size_t
posInHistory
=
0
;
std
::
vector
<
ConfOrRel
>
possibleScores
;
for
(
auto
pShE
=
History
.
begin
();
pShE
<
History
.
end
();
pShE
++
,
posInHistory
++
)
{
// iterate through all possible scores of each history entry
for
(
ConfOrRel
&
pSh
:
*
pShE
)
{
StateType
historyScore
=
pSh
.
score
;
ReliabilityType
historyConf
=
pSh
.
Reliability
;
historyConf
=
historyConf
*
TimeConfidence
->
operator
()(
posInHistory
);
bool
foundScore
=
false
;
for
(
ConfOrRel
&
pS
:
possibleScores
)
{
if
(
pS
.
score
==
historyScore
)
{
pS
.
Reliability
=
HistoryCombinatorMethod
(
pS
.
Reliability
,
historyConf
);
foundScore
=
true
;
}
}
if
(
foundScore
==
false
)
{
ConfOrRel
possibleScore
;
possibleScore
.
score
=
historyScore
;
possibleScore
.
Reliability
=
historyConf
;
possibleScores
.
push_back
(
possibleScore
);
}
}
}
return
possibleScores
;
}
/// saves the Scores in the History
/// \brief It checks the incoming scores if any have a Reliability greater
/// than 0.5 all of them get saved inside the History and then the
/// History get shortened to the maximal length. It only saves the Value if
/// the History is empty.
///
/// \param actualPossibleScores The Scores which should be saved
///
/// \note Does the History really make sense if the values are to small it
/// only stores something if it's empty and not if it isn't completely filled
void
saveInHistory
(
std
::
vector
<
ConfOrRel
>
actualPossibleScores
)
{
// check if the reliability of at least one possible score is high enough
bool
atLeastOneRelIsHigh
=
false
;
for
(
ConfOrRel
pS
:
actualPossibleScores
)
{
if
(
pS
.
Reliability
>
0.5
)
{
atLeastOneRelIsHigh
=
true
;
}
}
// save possible scores if at least one possible score is high enough (or if
// the history is empty)
if
(
History
.
size
()
<
1
||
atLeastOneRelIsHigh
==
true
)
{
History
.
insert
(
History
.
begin
(),
actualPossibleScores
);
// if history size is higher than allowed, save oldest element
while
(
History
.
size
()
>
HistoryMaxSize
)
{
// delete possibleScoreHistory.back();
History
.
pop_back
();
}
}
}
};
/// This is the Reliability Functionality for the highlevel Agent.
/// \brief It takes the scores and reliabilities of all connected lowlevel
/// Agents and calculates the Reliability of them together. Also it creates the
/// feedback that is needed by the \c ReliabilityForLowLevelAgents, which is a
/// kind of confidence.
///
/// \tparam StateType Datatype of the State ( Typically double or float)
/// \tparam ReliabilityType Datatype of the Reliability (
/// Typically long or int)
///
/// \note A highlevel Agent is commonly in a master slave relationship with the
/// lowlevel Agents as the master. It combines the Reliability of all connected
/// Slaves and uses that as its own Reliability.
///
/// \note more information about how the Reliability and feedback is
/// created at \c operator()()
// State Type rename
// merge cross rel/conf darein
template
<
typename
StateType
,
typename
ReliabilityType
>
class
CrossCombinator
{
public
:
static_assert
(
std
::
is_arithmetic
<
StateType
>::
value
,
"HighLevel: StateType has to be an arithmetic type
\n
"
);
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
,
"HighLevel: ReliabilityType has to be an arithmetic type
\n
"
);
/// typedef To shorten the writing.
/// \c ConfOrRel
typedef
ConfOrRel
<
StateType
,
ReliabilityType
>
ConfOrRel
;
/// typedef of the input type for the operator() defined explicitly to
/// simplify interaction
///
typedef
std
::
vector
<
std
::
tuple
<
id_t
,
StateType
,
ReliabilityType
>>
InputType
;
/// The return type for the \c operator()() Method
struct
returnType
{
ReliabilityType
CrossReliability
;
std
::
map
<
id_t
,
std
::
vector
<
ConfOrRel
>>
CrossConfidence
;
};
/// Calculates the Reliability and the Cross Confidences for each lowlevel
/// Agent for all of there states.
///
/// \param Values It gets the States and Reliabilities of
/// all connected Slaves inside a vector.
///
/// \return it returns a struct \c returnType containing the CrossReliability
/// and all CrossConfidence's
///
/// \brief To calculate the Reliability it combines [\c std::min() ] the \c
/// CrossReliability of all connected Agents. To calculate the feedback it
/// iterates over all Agents and their states and uses the \c CrossConfidence
/// Function to play what if with the states.
returnType
operator
()(
std
::
vector
<
std
::
tuple
<
id_t
,
StateType
,
ReliabilityType
>>
&
Values
)
{
ReliabilityType
combinedInputRel
=
1
;
ReliabilityType
combinedCrossRel
=
1
;
ReliabilityType
outputReliability
;
std
::
vector
<
std
::
pair
<
id_t
,
StateType
>>
Agents
;
std
::
map
<
id_t
,
std
::
vector
<
ConfOrRel
>>
output
;
std
::
vector
<
ConfOrRel
>
output_temporary
;
for
(
auto
tmp
:
Values
)
{
std
::
pair
<
id_t
,
StateType
>
tmp2
;
tmp2
.
first
=
std
::
get
<
0
>
(
tmp
);
tmp2
.
second
=
std
::
get
<
1
>
(
tmp
);
Agents
.
push_back
(
tmp2
);
}
for
(
auto
Value
:
Values
)
{
id_t
id
=
std
::
get
<
0
>
(
Value
);
StateType
sc
=
std
::
get
<
1
>
(
Value
);
ReliabilityType
rel
=
std
::
get
<
2
>
(
Value
);
// combination method ([])
// get input reliability
combinedInputRel
=
std
::
min
(
combinedInputRel
,
rel
);
// calculate the cross reliability for this slave agent
ReliabilityType
realCrossReliabilityOfSlaveAgent
=
CrossReliability
->
operator
()(
{
id
,
sc
},
Agents
);
// AVERAGE, MULTIPLICATION, CONJUNCTION (best to worst:
// AVERAGE = CONJUNCTION > MULTIPLICATION >> )
// get cross confidence
output_temporary
.
clear
();
for
(
StateType
thoScore
:
States
[
id
])
{
// calculate the cross reliability for this slave agent
ConfOrRel
data
;
data
.
score
=
thoScore
;
data
.
Reliability
=
CrossConfidence
->
operator
()(
id
,
thoScore
,
Agents
);
output_temporary
.
push_back
(
data
);
}
output
.
insert
({
id
,
output_temporary
});
// set combination method
// get combined cross reliability
combinedCrossRel
=
std
::
min
(
combinedCrossRel
,
realCrossReliabilityOfSlaveAgent
);
}
// combine cross reliabilites and input reliabilites of all slave agents
// NOTE: options would be multiply, average, AND (best to worst: )
// outputReliability = combinedInputRel * combinedCrossRel;
// outputReliability = (combinedInputRel + combinedCrossRel) / 2;
// set combination method
// get output reliability
outputReliability
=
std
::
min
(
combinedInputRel
,
combinedCrossRel
);
return
{
outputReliability
,
output
};
}
/// This is the setter for CrossReliability Function
/// \param CrossReliability A pointer to the Functional for the
/// CrossReliability
/// \brief This is needed to calculate the Reliability. It uses this on all
/// values of all lowlevel Agnets.
void
setCrossReliability
(
std
::
unique_ptr
<
CrossReliability
<
StateType
,
ReliabilityType
>>
&
CrossReliability
)
{
this
->
CrossReliability
=
std
::
move
(
CrossReliability
);
}
/// This is the setter for CrossConfidence Function
/// \param CrossConfidence A pointer to the Functional for the \c
/// CrossConfidence \brief This is needed for the feedback for the \c
/// ReliabilityForLowLevelAgents.
void
setCrossConfidence
(
std
::
unique_ptr
<
CrossConfidence
<
StateType
,
ReliabilityType
>>
&
CrossConfidence
)
{
this
->
CrossConfidence
=
std
::
move
(
CrossConfidence
);
}
/// This is the adder for the states
/// \param id The id of the Agent of the states
/// \param States id specific states. this will be copied So that if Slaves
/// have different States they can be used correctly.
/// \brief The States of all connected lowlevel Agents has to be known to be
/// able to iterate over them
void
addStates
(
id_t
id
,
std
::
vector
<
StateType
>
States
)
{
this
->
States
.
insert
({
id
,
States
});
}
private
:
std
::
unique_ptr
<
CrossReliability
<
StateType
,
ReliabilityType
>>
CrossReliability
;
std
::
unique_ptr
<
CrossConfidence
<
StateType
,
ReliabilityType
>>
CrossConfidence
;
std
::
map
<
id_t
,
std
::
vector
<
StateType
>>
States
;
};
}
// namespace agent
}
// namespace rosa
#endif
// !ROSA_AGENT_RELIABILITY_H
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, May 31, 4:42 PM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
330688
Default Alt Text
Reliability.h (34 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment