Page MenuHomePhorge

No OneTemporary

Size
44 KB
Referenced Files
None
Subscribers
None
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

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)

Event Timeline