Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F332132
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
44 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/examples/agent-functionalities/Reliability-functionality-agent-context/Reliability-agents.cpp b/examples/agent-functionalities/Reliability-functionality-agent-context/Reliability-agents.cpp
index b509b8d..fcf63e0 100644
--- a/examples/agent-functionalities/Reliability-functionality-agent-context/Reliability-agents.cpp
+++ b/examples/agent-functionalities/Reliability-functionality-agent-context/Reliability-agents.cpp
@@ -1,315 +1,296 @@
//===- examples/agent-functionalities/Reliability-functionality.cpp *C++-*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file examples/agent-functionalities/Reliability-functionality.cpp
///
/// \author Daniel Schnoell (daniel.schnoell@tuwien.ac.at )
///
/// \date 2019
///
/// \brief A simple example on defining Relianility Functionalities inside a
/// master slave context.
+/// \note This is not finished
///
//===----------------------------------------------------------------------===//
#define Reliability_trace_level 5
#include "rosa/config/version.h"
#include "rosa/support/log.h"
#include "rosa/agent/CrossReliability.h"
#include "rosa/agent/RangeConfidence.hpp"
#include "rosa/agent/Reliability.h"
#include "rosa/deluxe/DeluxeContext.hpp"
#include <map>
#include <vector>
typedef double SensorValueType;
typedef long StateType;
typedef double ReliabilityType;
#include "./helper.h" // just stuff from Rel-func to increase readability
using namespace rosa::agent;
using namespace rosa;
using namespace rosa::deluxe;
using namespace rosa::terminal;
-/// Helper structs for conversion
+// -------------------------------------------------------------------------------
+// Bunch of recusive templates to simplify usage
+// -------------------------------------------------------------------------------
+
template <std::size_t, typename... types> struct conversion;
template <std::size_t size, typename... TypesA, template <typename...> class A,
typename... TypesB, template <typename...> class B>
struct conversion<size, A<TypesA...>, B<TypesB...>> {
using type = typename conversion<size - 1, std::tuple<TypesA...>,
std::tuple<TypesB..., TypesA...>>::type;
};
template <typename... TypesA, template <typename...> class A,
typename... TypesB, template <typename...> class B>
struct conversion<0, A<TypesA...>, B<TypesB...>> {
using type = DeluxeTuple<TypesB...>;
};
template <std::size_t size, typename... Types>
using unrolled_data_type =
typename conversion<size, std::tuple<Types...>, std::tuple<>>::type;
-template <std::size_t max, std::size_t at>
-struct __convert_to_vector {
-void operator()(
- std::vector<ConfOrRel<StateType, ReliabilityType>> &feedback,
- unrolled_data_type<max/2, StateType, ReliabilityType> I) {
- __convert_to_vector<max, at - 2>(feedback, I);
- feedback.push_back({std::get<at>(I.first), std::get<at + 1>(I.first)});
-}
-}
-;
+//--------------------------------------------------------------------------------
+template <std::size_t max, std::size_t at> struct __convert_to_vector {
+ void operator()(std::vector<ConfOrRel<StateType, ReliabilityType>> &feedback,
+ unrolled_data_type<max / 2, StateType, ReliabilityType> I) {
+ __convert_to_vector<max, at - 2>()(feedback, I);
+ feedback.push_back({std::get<at>(I), std::get<at + 1>(I)});
+ }
+};
template <std::size_t max> struct __convert_to_vector<max, 0> {
void operator()(std::vector<ConfOrRel<StateType, ReliabilityType>> &feedback,
unrolled_data_type<max / 2, StateType, ReliabilityType> I) {
- feedback.push_back({std::get<0>(I.first), std::get<1>(I.first)});
+ feedback.push_back({std::get<0>(I), std::get<1>(I)});
}
};
template <std::size_t number>
void convert_to_vector(
std::vector<ConfOrRel<StateType, ReliabilityType>> &feedback,
unrolled_data_type<number, StateType, ReliabilityType> I) {
- __convert_to_vector<number*2, number*2-2>()(feedback, I);
+ __convert_to_vector<number * 2, number * 2 - 2>()(feedback, I);
}
-
-
+//----------------------------------------------------------------------------
+// template <std::size_t size, typename... types> struct unrole_vector {};
+//
+// template <std::size_t size, template <typename...> v, typename... vT,
+// template <typename...> class T, typename... TT, typename... types>
+// struct unrole_vector<size, v<vT...>,T<TT...>, types...> {
+// void operator()(c vec, types... A) {
+// unrole_vector<size - 1, v<vT...>, T<TT...>, auto>()(vec,
+// vec.at(size).score,
+// vec.at(size).score);
+// }
+//};
+
+// ---------------------------------------------------------------------------
+// main
+// ---------------------------------------------------------------------------
int main(void) {
const std::size_t number_of_states = 3;
std::unique_ptr<DeluxeContext> C = DeluxeContext::create("Deluxe");
//---------------------- Sensors -------------------------------------
//--------------------------------------------------------------------
const std::string SensorName1 = "Sensor1";
const std::string SensorName2 = "Sensor2";
const std::string SensorName3 = "Sensor3";
AgentHandle Sensor1 = C->createSensor<uint32_t, SensorValueType>(
SensorName1, [&SensorName1](std::pair<uint32_t, bool> I) {
LOG_INFO_STREAM << "\n******\n"
<< SensorName1 << " master-input "
<< (I.second ? "<New>" : "<Old>")
<< " value: " << I.first << "\n******\n";
});
AgentHandle Sensor2 = C->createSensor<uint32_t, SensorValueType>(
SensorName2, [&SensorName2](std::pair<uint32_t, bool> I) {
LOG_INFO_STREAM << "\n******\n"
<< SensorName2 << " master-input "
<< (I.second ? "<New>" : "<Old>")
<< " value: " << I.first << "\n******\n";
});
AgentHandle Sensor3 = C->createSensor<uint32_t, SensorValueType>(
SensorName3, [&SensorName3](std::pair<uint32_t, bool> I) {
LOG_INFO_STREAM << "\n******\n"
<< SensorName3 << " master-input "
<< (I.second ? "<New>" : "<Old>")
<< " value: " << I.first << "\n******\n";
});
//------------------------- lowlevel agents --------------------------------
//--------------------------------------------------------------------------
const std::string LowLevelAgentName1 = "LowLevelAgent1";
const std::string LowLevelAgentName2 = "LowLevelAgent2";
const std::string LowLevelAgentName3 = "LowLevelAgent3";
using conf = unrolled_data_type<
number_of_states, StateType,
ReliabilityType>; // this is the confidence expressed as one tuple it
// uses the format
// (first.state,first.rel,second.sate...)
using LowLevelAgentMasterResult = void; // no return
using LowLevelReturnFromMaster = std::pair<conf, bool>;
using FloatMasterHandler =
std::function<LowLevelAgentMasterResult(LowLevelReturnFromMaster)>;
using FloatResult = Optional<DeluxeTuple<StateType, ReliabilityType>>;
using FloatHandler =
std::function<FloatResult(std::pair<DeluxeTuple<SensorValueType>, bool>)>;
auto lowlevel1 = create_lowlevel_func();
auto lowlevel2 = create_lowlevel_func();
auto lowlevel3 = create_lowlevel_func();
AgentHandle SlaveAgent = C->createAgent(
LowLevelAgentName1,
// Master-input handler.
FloatMasterHandler(
[&LowLevelAgentName1,
lowlevel1](LowLevelReturnFromMaster I) -> LowLevelAgentMasterResult {
LOG_INFO_STREAM << "inside: " << LowLevelAgentName1 << "feedback\n";
if (I.second) {
std::vector<ConfOrRel<StateType, ReliabilityType>> feedback;
convert_to_vector<number_of_states>(feedback, I.first);
lowlevel1->feedback(feedback);
}
}),
// Slave-input handler.
FloatHandler(
[&LowLevelAgentName1, lowlevel1](
std::pair<DeluxeTuple<SensorValueType>, bool> I) -> FloatResult {
LOG_INFO_STREAM
<< "\n******\n"
<< LowLevelAgentName1 << " " << (I.second ? "<New>" : "<Old>")
<< " value: " << std::get<0>(I.first) << "\n******\n";
auto tmp = lowlevel1->operator()(std::get<0>(I.first));
DeluxeTuple<long, double> ret(tmp.score, tmp.Reliability);
return {ret};
}));
AgentHandle SlaveAgent2 = C->createAgent(
LowLevelAgentName2,
// Master-input handler.
FloatMasterHandler(
[&LowLevelAgentName2,
lowlevel2](LowLevelReturnFromMaster I) -> LowLevelAgentMasterResult {
LOG_INFO_STREAM << "inside: " << LowLevelAgentName2 << "feedback\n";
if (I.second) {
std::vector<ConfOrRel<StateType, ReliabilityType>> feedback;
convert_to_vector<number_of_states>(feedback, I.first);
lowlevel2->feedback(feedback);
}
}),
// Slave-input handler.
FloatHandler(
[&LowLevelAgentName2, lowlevel2](
std::pair<DeluxeTuple<SensorValueType>, bool> I) -> FloatResult {
LOG_INFO_STREAM
<< "\n******\n"
<< LowLevelAgentName2 << " " << (I.second ? "<New>" : "<Old>")
<< " value: " << std::get<0>(I.first) << "\n******\n";
auto tmp = lowlevel2->operator()(std::get<0>(I.first));
DeluxeTuple<long, double> ret(tmp.score, tmp.Reliability);
return {ret};
}));
AgentHandle SlaveAgent3 = C->createAgent(
LowLevelAgentName3,
// Master-input handler.
FloatMasterHandler(
[&LowLevelAgentName3,
lowlevel3](LowLevelReturnFromMaster I) -> LowLevelAgentMasterResult {
LOG_INFO_STREAM << "inside: " << LowLevelAgentName3 << "feedback\n";
if (I.second) {
std::vector<ConfOrRel<StateType, ReliabilityType>> feedback;
convert_to_vector<number_of_states>(feedback, I.first);
lowlevel3->feedback(feedback);
}
}),
// Slave-input handler.
FloatHandler(
[&LowLevelAgentName3, lowlevel3](
std::pair<DeluxeTuple<SensorValueType>, bool> I) -> FloatResult {
LOG_INFO_STREAM
<< "\n******\n"
<< LowLevelAgentName3 << " " << (I.second ? "<New>" : "<Old>")
<< " value: " << std::get<0>(I.first) << "\n******\n";
auto tmp = lowlevel3->operator()(std::get<0>(I.first));
DeluxeTuple<long, double> ret(tmp.score, tmp.Reliability);
return {ret};
}));
//------------------------- lookup copy of rel------------------------------
//--------------------------------------------------------------------------
- std::cout << "---------------------------------------------------------------"
- "---------------------------------\n";
- std::cout << "------------------------------------High level "
- "Test---------------------------------------------\n";
-
- std::cout
- << "Configured in a way that the Master thinks that both Sensors "
- "should have the same State.\n While feeding both the \"opposite\" "
- "values one acending the other decending from the maximum.\n";
-
- ReliabilityForHighLevelAgents<StateType, ReliabilityType> *highlevel =
- new ReliabilityForHighLevelAgents<StateType, ReliabilityType>();
-
- std::unique_ptr<CrossReliability<StateType, ReliabilityType>>
- CrossReliability1(new CrossReliability<StateType, ReliabilityType>());
-
- std::unique_ptr<Abstraction<long, double>> func1(
- new PartialFunction<long, double>(
- {
- {{0, 1}, std::make_shared<LinearFunction<long, double>>(1, 0)},
- {{1, 2}, std::make_shared<LinearFunction<long, double>>(2, -1.0)},
- },
- 0));
-
- CrossReliability1->addCrossReliabilityProfile(0, 1, func1);
- CrossReliability1->setCrossReliabilityMethod(
- CrossReliability<StateType, ReliabilityType>::AVERAGE);
- CrossReliability1->setCrossReliabilityParameter(1);
-
- std::unique_ptr<CrossConfidence<StateType, ReliabilityType>> CrossConfidence1(
- new CrossConfidence<StateType, ReliabilityType>());
-
- std::unique_ptr<Abstraction<long, double>> func2(
- new PartialFunction<long, double>(
- {
- {{0, 1}, std::make_shared<LinearFunction<long, double>>(1, 0)},
- {{1, 2}, std::make_shared<LinearFunction<long, double>>(2, -1.0)},
- },
- 0));
-
- CrossConfidence1->addCrossReliabilityProfile(0, 1, func2);
- CrossConfidence1->setCrossReliabilityMethod(
- CrossConfidence<StateType, ReliabilityType>::AVERAGE);
- CrossConfidence1->setCrossReliabilityParameter(1);
-
- highlevel->setCrossConfidence(CrossConfidence1);
- highlevel->setCrossReliability(CrossReliability1);
-
- highlevel->addStates(0, states);
- highlevel->addStates(1, states);
-
- for (int a = 0; a < 21; a++) {
- auto out1 = lowlevel->operator()(a),
- out2 = lowlevel2->operator()((int)21 - a);
- std::cout << "s1: " << out1 << "\ns2:" << out2 << "\n";
- std::vector<std::tuple<rosa::id_t, StateType, ReliabilityType>> tmp2;
- tmp2.push_back({0, out1.score, out1.Reliability});
- tmp2.push_back({1, out2.score, out2.Reliability});
-
- auto out_o = highlevel->operator()(tmp2);
- std::cout << "it: " << a << "\t rel: " << out_o.CrossReliability << "\n";
- std::cout << "\t subs:\n";
- for (auto q : out_o.CrossConfidence) {
- std::cout << "\t\t id:" << q.first << "\n";
- /*
- for(auto z: q.second)
- {
- std::cout << "\t\t\t score: " << z.score << "\tRel: " << z.Reliability
- << "\n"; tmp.push_back({z.score,z.Reliability});
- }
- */
- for (auto z : q.second) {
- std::cout << "\t\t\t score: " << z.score << "\tRel: " << z.Reliability
- << "\n";
- }
-
- if (q.first == 0)
- lowlevel->feedback(q.second);
- else
- lowlevel2->feedback(q.second);
- }
- }
+ auto highlevel = create_highlevel_func();
+ using conf1 = Optional<unrolled_data_type<
+ number_of_states, StateType,
+ ReliabilityType>>; // this is the confidence expressed as one tuple it
+ // uses the format
+ // (first.state,first.rel,second.sate...)
+
+ using MasterResult =
+ std::tuple<Optional<DeluxeTuple<ReliabilityType>>, conf1, conf1, conf1>;
+ using SlaveOutputs = DeluxeTuple<StateType, ReliabilityType>;
+ using MasterHandler = std::function<MasterResult(
+ std::pair<SlaveOutputs, bool>, std::pair<SlaveOutputs, bool>,
+ std::pair<SlaveOutputs, bool>)>;
+ AgentHandle SumAgent = C->createAgent(
+ "Master Agent",
+ MasterHandler([&](std::pair<SlaveOutputs, bool> I0,
+ std::pair<SlaveOutputs, bool> I1,
+ std::pair<SlaveOutputs, bool> I2) -> MasterResult {
+ ReliabilityForHighLevelAgents<StateType, ReliabilityType>::InputType
+ input;
+ input.push_back({0, std::get<0>(I0.first), std::get<1>(I0.first)});
+ input.push_back({1, std::get<0>(I1.first), std::get<1>(I1.first)});
+ input.push_back({2, std::get<0>(I2.first), std::get<1>(I2.first)});
+ auto out = highlevel->operator()(input);
+
+ DeluxeTuple<ReliabilityType> rel(out.CrossReliability);
+
+ conf c[3];
+ for (std::size_t at = 0; at < 3; at++) {
+ std::get<0>(c[at]) = out.CrossConfidence.at(at).at(0).score;
+ std::get<1>(c[at]) = out.CrossConfidence.at(at).at(0).Reliability;
+ std::get<2>(c[at]) = out.CrossConfidence.at(at).at(1).score;
+ std::get<3>(c[at]) = out.CrossConfidence.at(at).at(1).Reliability;
+ std::get<4>(c[at]) = out.CrossConfidence.at(at).at(2).score;
+ std::get<5>(c[at]) = out.CrossConfidence.at(at).at(2).Reliability;
+ }
+ return {{rel}, {c[0]}, {c[1]}, {c[2]}};
+ }));
+
+ // -------------------------------------------------------------------------
+ // Input data into sensors and listen to output
+ // -------------------------------------------------------------------------
+
+
+
+
+ delete highlevel;
delete lowlevel1;
delete lowlevel2;
}
\ No newline at end of file
diff --git a/examples/agent-functionalities/Reliability-functionality-agent-context/helper.h b/examples/agent-functionalities/Reliability-functionality-agent-context/helper.h
index 17bbf7f..6055fb9 100644
--- a/examples/agent-functionalities/Reliability-functionality-agent-context/helper.h
+++ b/examples/agent-functionalities/Reliability-functionality-agent-context/helper.h
@@ -1,87 +1,137 @@
#include "rosa/config/version.h"
#include "rosa/support/log.h"
#include "rosa/agent/CrossReliability.h"
#include "rosa/agent/RangeConfidence.hpp"
#include "rosa/agent/Reliability.h"
#include "rosa/deluxe/DeluxeContext.hpp"
#include <map>
#include <vector>
using namespace rosa::agent;
using namespace rosa;
using namespace rosa::deluxe;
using namespace rosa::terminal;
auto create_lowlevel_func() {
std::unique_ptr<RangeConfidence<ReliabilityType, StateType, SensorValueType>>
Confidence(new RangeConfidence<ReliabilityType, StateType,
SensorValueType>(
{{0, PartialFunction<double, double>(
{
{{0, 3},
std::make_shared<LinearFunction<double, double>>(
0, 1.0 / 3)},
{{3, 6},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{6, 9},
std::make_shared<LinearFunction<double, double>>(
3.0, -1.0 / 3)},
},
0)},
{1, PartialFunction<double, double>(
{
{{6, 9},
std::make_shared<LinearFunction<double, double>>(
-2, 1.0 / 3)},
{{9, 12},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{12, 15},
std::make_shared<LinearFunction<double, double>>(
5, -1.0 / 3)},
},
0)},
{2, PartialFunction<double, double>(
{
{{12, 15},
std::make_shared<LinearFunction<double, double>>(
-4, 1.0 / 3)},
{{15, 18},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{18, 21},
std::make_shared<LinearFunction<double, double>>(
7, -1.0 / 3)},
},
0)}}));
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>> Reliability(
new LinearFunction<SensorValueType, ReliabilityType>(1, -1.0 / 3));
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>>
ReliabilitySlope(
new LinearFunction<SensorValueType, ReliabilityType>(1, -1.0 / 3));
std::unique_ptr<Abstraction<std::size_t, ReliabilityType>> TimeConfidence(
new LinearFunction<std::size_t, ReliabilityType>(1, -1.0 / 3));
auto lowlevel = new ReliabilityForLowLevelAgents<SensorValueType, StateType,
ReliabilityType>();
std::vector<long> states;
states.push_back(0);
states.push_back(1);
states.push_back(2);
lowlevel->setConfidenceFunction(Confidence);
lowlevel->setReliabilityFunction(Reliability);
lowlevel->setReliabilitySlopeFunction(ReliabilitySlope);
lowlevel->setTimeConfidenceFunction(TimeConfidence);
lowlevel->setStates(states);
lowlevel->setHistoryLength(2);
lowlevel->setValueSetCounter(1);
return lowlevel;
+}
+
+auto create_highlevel_func(){
+ std::vector<long> states;
+ states.push_back(0);
+ states.push_back(1);
+ states.push_back(2);
+
+ ReliabilityForHighLevelAgents<StateType, ReliabilityType> *highlevel =
+ new ReliabilityForHighLevelAgents<StateType, ReliabilityType>();
+
+ std::unique_ptr<CrossReliability<StateType, ReliabilityType>>
+ CrossReliability1(new CrossReliability<StateType, ReliabilityType>());
+
+ std::unique_ptr<Abstraction<long, double>> func1(
+ new PartialFunction<long, double>(
+ {
+ {{0, 1}, std::make_shared<LinearFunction<long, double>>(1, 0)},
+ {{1, 2}, std::make_shared<LinearFunction<long, double>>(2, -1.0)},
+ },
+ 0));
+
+ CrossReliability1->addCrossReliabilityProfile(0, 1, func1);
+ CrossReliability1->setCrossReliabilityMethod(
+ CrossReliability<StateType, ReliabilityType>::AVERAGE);
+ CrossReliability1->setCrossReliabilityParameter(1);
+
+ std::unique_ptr<CrossConfidence<StateType, ReliabilityType>> CrossConfidence1(
+ new CrossConfidence<StateType, ReliabilityType>());
+
+ std::unique_ptr<Abstraction<long, double>> func2(
+ new PartialFunction<long, double>(
+ {
+ {{0, 1}, std::make_shared<LinearFunction<long, double>>(1, 0)},
+ {{1, 2}, std::make_shared<LinearFunction<long, double>>(2, -1.0)},
+ },
+ 0));
+
+ CrossConfidence1->addCrossReliabilityProfile(0, 1, func2);
+ CrossConfidence1->setCrossReliabilityMethod(
+ CrossConfidence<StateType, ReliabilityType>::AVERAGE);
+ CrossConfidence1->setCrossReliabilityParameter(1);
+
+ highlevel->setCrossConfidence(CrossConfidence1);
+ highlevel->setCrossReliability(CrossReliability1);
+
+ highlevel->addStates(0, states);
+ highlevel->addStates(1, states);
+
+ return highlevel;
}
\ No newline at end of file
diff --git a/include/rosa/agent/Reliability.h b/include/rosa/agent/Reliability.h
index 167c18d..5dfb11d 100644
--- a/include/rosa/agent/Reliability.h
+++ b/include/rosa/agent/Reliability.h
@@ -1,573 +1,578 @@
//===-- 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 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
///
//===----------------------------------------------------------------------===//
#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 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 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 it takes the
/// Sensor value, its "History" and feedback from \c
/// ReliabilityForHighLevelAgents to calculate the Reliability.
/// \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 A lowlevel Agent is close to the sensor and uses the Sensor value to
/// as part of its calculation. \note more information about how it calculates
/// the Reliability at the \c operator()()
/// \note more information about the needed feedback at \c feedback()
template <typename SensorValueType, typename StateType,
typename ReliabilityType>
class ReliabilityForLowLevelAgents {
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 Reliability
/// \param SensorValue The current Values of the Sensor
///
/// \return Reliability and Score of the current SensorValue
///
/// \brief It calculates the input Reliability of the Sensor and combines [
/// min() ] it with the Confidence of Sensor value. Then it combines [ \c
/// std::vector<ConfOrRel>::operator+=() [ addition ] ] it with the feedback
/// from the highlevel Agent and stores it inside the history at the first
/// location. Afterwards its combines[ private: \c
/// getAllPossibleScoresBasedOnHistory() ] the whole History and return the
/// most likely pair of values.
ConfOrRel operator()(SensorValueType SensorValue) {
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM << "\nTrace 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 << "\ninput 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 << "\nActuallPossibleScores:\n"
<< possibleScores << trace_end;
LOG_TRACE_STREAM << "\npossibleScores:\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;
});
previousSensorValue = SensorValue;
PreviousSensorValueExists = true;
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM << "\noutput 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
/// \brief This input kind of resembles a confidence but not directly it more
/// or less says: compared to the other lowlevel Agents these are the Scores
/// with the Reliability that you have.
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 \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;
}
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 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 getRelibility(SensorValueType actualValue,
SensorValueType lastValue,
unsigned int valueSetCounter) {
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;
}
/// 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;
// 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
/// \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()()
template <typename StateType, typename ReliabilityType>
class ReliabilityForHighLevelAgents {
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) {
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
/// \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-diff
Expires
Sat, Mar 15, 12:28 PM (18 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
129084
Default Alt Text
(44 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment