Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1497444
Reliability.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
18 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 (danielschnoell@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *reliability* *functionality*.
///
/// \note By defining and seeting 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
///
//===----------------------------------------------------------------------===//
#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 adds the Reliabilities of the same Scores
/// \param me The vector to wich is written to
/// \param other The other data vector
friend
std
::
vector
<
ConfOrRel
>
operator
+=
(
std
::
vector
<
ConfOrRel
>
&
me
,
std
::
vector
<
ConfOrRel
>
other
)
{
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
);
for
(
auto
&
tmp_me
:
me
)
for
(
auto
&
tmp_other
:
other
)
{
if
(
tmp_me
.
score
==
tmp_other
.
score
)
{
tmp_me
.
Reliability
=
tmp_me
.
Reliability
+
tmp_other
.
Reliability
;
}
}
return
me
;
}
/// This is to push the data inside a vector in a humanreadable 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 Reliabilites
/// \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 is the Reliability Functionality for a low level Agent
/// \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)
///
/// use the \c operator() to get the reliability and \c feedback() the
/// information from the master back to this
template
<
typename
SensorValueType
,
typename
StateType
,
typename
ReliabilityType
>
class
LowLevel
{
public
:
/// Typedef to shorten the writing.
/// \c ConfOrRel
typedef
ConfOrRel
<
StateType
,
ReliabilityType
>
ConfOrRel
;
/// Calculates the Conf/ Reliability
/// \param SensorValue The current Values of the Sensor
///
/// \return Reliability of the current Value
ConfOrRel
operator
()(
SensorValueType
SensorValue
)
{
static_assert
(
std
::
is_arithmetic
<
SensorValueType
>::
value
);
static_assert
(
std
::
is_arithmetic
<
StateType
>::
value
);
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
);
#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
=
getRelibility
(
SensorValue
,
previousSensorValue
,
valueSetCounter
);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM
<<
"
\n
input Rel: "
<<
inputReliability
<<
trace_end
;
#endif
possibleScores
<<
Confidence
->
operator
()(
SensorValue
);
possibleScores
=
min
(
possibleScores
,
inputReliability
);
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
{
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
);
return
A
.
Reliability
>
B
.
Reliability
;
});
previousSensorValue
=
SensorValue
;
PreviousSensorValueExists
=
true
;
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM
<<
"
\n
output lowlevel: "
<<
possibleScores
.
at
(
0
)
<<
trace_end
;
#endif
return
possibleScores
.
at
(
0
);
}
/// Needed feedback from the Master
/// \param ValuesFromMaster The Scores + Reliability from the Master for this
/// Agent
void
feedback
(
std
::
vector
<
ConfOrRel
>
ValuesFromMaster
)
{
this
->
ValuesFromMaster
=
ValuesFromMaster
;
}
/// This is the setter for Confidence Function
/// \param Confidence A pointer to the Functional for the Confidence
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
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
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
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 vertor containing all states
void
setStates
(
std
::
vector
<
StateType
>
states
)
{
this
->
States
=
states
;
}
/// This sets the Maximum length of the Histpory
/// \param length The length
void
setHistoryLength
(
std
::
size_t
length
)
{
this
->
HistoryMaxSize
=
length
;
}
/// This sets the Value set Counter
/// \param ValueSetCounter the new Value
void
setValueSetCounter
(
unsigned
int
ValueSetCounter
)
{
this
->
valueSetCounter
=
ValueSetCounter
;
}
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
;
/*--------------------------------- needed Funktions
* -----------------------------------------------------*/
/// 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
ReliabilityType
getRelibility
(
SensorValueType
actualValue
,
SensorValueType
lastValue
,
unsigned
int
valueSetCounter
)
{
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
);
ReliabilityType
relAbs
=
Reliability
->
operator
()(
actualValue
);
if
(
PreviousSensorValueExists
)
{
ReliabilityType
relSlo
=
ReliabilitySlope
->
operator
()(
(
lastValue
-
actualValue
)
/
(
SensorValueType
)
valueSetCounter
);
// calculate signal input reliability
// NOTE: options would be multiply, average, AND (best to worst:
// average = AND > multiply) rel = relAbs * relSlo; rel = (relAbs +
// relSlo)/2;
return
std
::
min
(
relAbs
,
relSlo
);
}
else
return
relAbs
;
}
/// adabts the possible Scores by checking the History and combines those
/// values currently with max
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
;
// combine each history score with the confidence of time
// NOTE: multiplication, AND, or average would be alternatives (best to
// worst: multiplication = AND = average)
historyConf
=
historyConf
*
TimeConfidence
->
operator
()(
posInHistory
);
// historyConf = (historyConf + TimeConfidence(posInHistory)) / 2;
// historyConf = std::min(historyConf, TimeConfidence(posInHistory));
bool
foundScore
=
false
;
for
(
ConfOrRel
&
pS
:
possibleScores
)
{
if
(
pS
.
score
==
historyScore
)
{
// calculate confidence for score
// NOTE: multiplication, AND, or average would be alternatives (best
// to worst: AND >> average = multiplication ) pS->confOrRel =
// pS->confOrRel * historyConf; pS->confOrRel = (pS->confOrRel +
// historyConf) / 2;
pS
.
Reliability
=
std
::
max
(
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
/// \param actualPossibleScores The Scores which should be saved
///
/// \note Does the History realy make sence if the values are to smal it only
/// stores something if its empty and not if it isn't completly 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, savo oldest element
while
(
History
.
size
()
>
HistoryMaxSize
)
{
// delete possibleScoreHistory.back();
History
.
pop_back
();
}
}
}
};
/// This is the Reliability Functionality for the Highlevel Agent
/// \tparam StateType Datatype of the State (
/// Typically double or float) \tparam ReliabilityType Datatype of the
/// Reliability ( Typically long or int)
///
/// use the () operator to calculate the Reliability and all cross confidences
/// for all slaves.
template
<
typename
StateType
,
typename
ReliabilityType
>
class
HighLevel
{
public
:
/// typedef To shorten the writing.
/// \c ConfOrRel
typedef
ConfOrRel
<
StateType
,
ReliabilityType
>
ConfOrRel
;
/// The return type for the \c HighLevel::operator() Method
struct
returnType
{
ReliabilityType
CrossReliability
;
std
::
map
<
id_t
,
std
::
vector
<
ConfOrRel
>>
CrossConfidence
;
};
/// Calculates the Reliability and the Cross Confidenceses for each slave 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
returnType
operator
()(
std
::
vector
<
std
::
tuple
<
id_t
,
StateType
,
ReliabilityType
>>
&
Values
)
{
static_assert
(
std
::
is_arithmetic
<
StateType
>::
value
);
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
);
StateType
EWS
=
0
;
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
);
EWS
=
EWS
+
sc
;
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 >> )
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
({
std
::
get
<
0
>
(
Value
),
output_temporary
});
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;
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
void
setFunction
(
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 CrossConfidence
void
setFunction
(
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 spezific states. this will be copied So that if Slaves
/// have different States they can be used correctly.
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, Mar 1, 9:34 PM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
289080
Default Alt Text
Reliability.h (18 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment