Page MenuHomePhorge

No OneTemporary

Size
37 KB
Referenced Files
None
Subscribers
None
diff --git a/apps/ccam/ccam.cpp b/apps/ccam/ccam.cpp
index 9a8f49a..e11ff21 100644
--- a/apps/ccam/ccam.cpp
+++ b/apps/ccam/ccam.cpp
@@ -1,617 +1,617 @@
//===-- apps/ccam/ccam.cpp --------------------------------------*- C++ -*-===//
//
// The RoSA Framework -- Application CCAM
//
// Distributed under the terms and conditions of the Boost Software
/// License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file apps/ccam/ccam.cpp
///
/// \author Maximilian Goetzinger (maximilian.goetzinger@tuwien.ac.at)
/// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at)
///
/// \date 2019
///
/// \brief The application CCAM implements the case study from the paper:
/// M. Goetzinger, N. TaheriNejad, H. A. Kholerdi, A. Jantsch, E. Willegger,
/// T. Glatzl, A.M. Rahmani, T.Sauter, P. Liljeberg: Model - Free Condition
/// Monitoring with Confidence
///
/// \todo Clean up source files of this app: add standard RoSA header comment
/// for own files and do something with 3rd party files...
//===----------------------------------------------------------------------===//
#include "rosa/agent/Abstraction.hpp"
#include "rosa/agent/Confidence.hpp"
#include "rosa/agent/DistanceMetrics.hpp"
#include "rosa/agent/FunctionAbstractions.hpp"
#include <iostream>
#include "rosa/config/version.h"
#include "rosa/agent/SignalStateDetector.hpp"
#include "rosa/agent/SystemStateDetector.hpp"
#include "rosa/app/Application.hpp"
#include "rosa/support/csv/CSVReader.hpp"
#include "rosa/support/csv/CSVWriter.hpp"
#include "rosa/support/mqtt/MQTTReader.hpp"
#include "rosa/app/AppTuple.hpp"
#include <fstream>
#include <limits>
#include <memory>
#include <streambuf>
#include <string>
#include "configuration.h"
#include "statehandlerutils.h"
using namespace rosa;
using namespace rosa::agent;
using namespace rosa::app;
using namespace rosa::terminal;
using namespace rosa::mqtt;
const std::string AppName = "CCAM";
int main(int argc, char **argv) {
LOG_INFO_STREAM << '\n'
<< library_string() << " -- " << Color::Red << AppName
<< "app" << Color::Default << '\n';
//
// Read the filepath of the config file of the observed system. The filepath
// is in the first argument passed to the application. Fuzzy functions etc.
// are described in this file.
//
if (argc < 2) {
LOG_ERROR("Specify config File!\nUsage:\n\tccam config.json");
return 1;
}
std::string ConfigPath = argv[1];
//
// Load config file and read in all parameters. Fuzzy functions etc. are
// described in this file.
//
if (!readConfigFile(ConfigPath)) {
LOG_ERROR_STREAM << "Could not read config from \"" << ConfigPath << "\"\n";
return 2;
}
//
// Create a CCAM context.
//
LOG_INFO("Creating Context");
std::unique_ptr<Application> AppCCAM = Application::create(AppName);
//
// Create following function which shall give information if the time gap
// between changed input(s) and changed output(s) shows already a malfunction
// of the system.
//
// ____________
// /
// /
// __________/
//
std::shared_ptr<PartialFunction<uint32_t, float>> BrokenDelayFunction(
new PartialFunction<uint32_t, float>(
{{{0, AppConfig.BrokenCounter},
std::make_shared<LinearFunction<uint32_t, float>>(
0, 0.f, AppConfig.BrokenCounter, 1.f)},
{{AppConfig.BrokenCounter, std::numeric_limits<uint32_t>::max()},
std::make_shared<LinearFunction<uint32_t, float>>(1.f, 0.f)}},
0.f));
//
// Create following function which shall give information if the time gap
// between changed input(s) and changed output(s) still shows a
// well-functioning system.
//
// ____________
// \
// \
// \__________
//
std::shared_ptr<PartialFunction<uint32_t, float>> OkDelayFunction(
new PartialFunction<uint32_t, float>(
{{{0, AppConfig.BrokenCounter},
std::make_shared<LinearFunction<uint32_t, float>>(
0, 1.f, AppConfig.BrokenCounter, 0.f)},
{{AppConfig.BrokenCounter, std::numeric_limits<uint32_t>::max()},
std::make_shared<LinearFunction<uint32_t, float>>(0.f, 0.f)}},
1.f));
//
// Create a AppAgent with SystemStateDetector functionality.
//
LOG_INFO("Create SystemStateDetector agent.");
AgentHandle SystemStateDetectorAgent = createSystemStateDetectorAgent(
AppCCAM, "SystemStateDetector", AppConfig.SignalConfigurations.size(),
BrokenDelayFunction, OkDelayFunction);
//
// Set policy of SystemStateDetectorAgent that it wait for all
// SignalStateDetectorAgents
//
std::set<size_t> pos;
for (size_t i = 0; i < AppConfig.SignalConfigurations.size(); ++i)
pos.insert(pos.end(), i);
AppCCAM->setExecutionPolicy(SystemStateDetectorAgent,
AppExecutionPolicy::awaitAll(pos));
//
// Create Vectors for all sensors, all signal related fuzzy functions, all
// signal state detectors, all signal state agents, and all input data files.
//
LOG_INFO("Creating sensors, SignalStateDetector functionalities and their "
"Abstractions.");
std::vector<AgentHandle> Sensors;
std::vector<std::shared_ptr<Abstraction<std::pair<float, float>, float>>> DistanceMetrics;
std::vector<std::shared_ptr<PartialFunction<float, float>>>
SampleMatchesFunctions;
std::vector<std::shared_ptr<PartialFunction<float, float>>>
SampleMismatchesFunctions;
std::vector<std::shared_ptr<PartialFunction<float, float>>>
SignalIsStableFunctions;
std::vector<std::shared_ptr<PartialFunction<float, float>>>
SignalIsDriftingFunctions;
// SAVE CHANGES
std::vector<std::shared_ptr<PartialFunction<uint32_t, float>>>
SignalConditionLookBackFunctions;
std::vector<std::shared_ptr<PartialFunction<uint32_t, float>>>
SignalConditionHistoryDesicionFunctions;
// - SAVE CHANGES
std::vector<std::shared_ptr<StepFunction<float, float>>>
NumOfSamplesMatchFunctions;
std::vector<std::shared_ptr<StepFunction<float, float>>>
NumOfSamplesMismatchFunctions;
std::vector<std::shared_ptr<PartialFunction<float, float>>>
SampleValidFunctions;
std::vector<std::shared_ptr<PartialFunction<float, float>>>
SampleInvalidFunctions;
std::vector<std::shared_ptr<StepFunction<float, float>>>
NumOfSamplesValidFunctions;
std::vector<std::shared_ptr<StepFunction<float, float>>>
NumOfSamplesInvalidFunctions;
std::vector<std::shared_ptr<
SignalStateDetector<float, float, float, HistoryPolicy::FIFO>>>
SignalStateDetectors;
std::vector<AgentHandle> SignalStateDetectorAgents;
std::vector<std::ifstream> DataFiles;
//
// Go through all signal state configurations (number of signals), and create
// functionalities for SignalStateDetector.
//
for (auto SignalConfiguration : AppConfig.SignalConfigurations) {
//
// Create application sensors.
//
Sensors.emplace_back(
AppCCAM->createSensor<float>(SignalConfiguration.Name + "_Sensor"));
//
// Create following function(s) which shall give information whether one
// sample matches another one (based on the relative distance between them).
//
// ____________
// / \
// / \
// __________/ \__________
//
//
if (std::strcmp(SignalConfiguration.DistanceMetric.c_str(), "absolute") == 0 ) {
DistanceMetrics.emplace_back(new AbsoluteDistance<float, float>());
} else if (std::strcmp(SignalConfiguration.DistanceMetric.c_str(), "daniel1") == 0 ) {
DistanceMetrics.emplace_back(new DanielsDistance1<float, float>());
} else if (std::strcmp(SignalConfiguration.DistanceMetric.c_str(), "daniel2") == 0 ) {
DistanceMetrics.emplace_back(new DanielsDistance2<float, float>());
} else if (std::strcmp(SignalConfiguration.DistanceMetric.c_str(), "daniel3") == 0 ) {
DistanceMetrics.emplace_back(new DanielsDistance3<float, float>());
} else if (std::strcmp(SignalConfiguration.DistanceMetric.c_str(), "maxi1") == 0 ) {
DistanceMetrics.emplace_back(new MaxisDistance1<float, float>());
} else {
//default is relative distance
DistanceMetrics.emplace_back(new RelativeDistance<float, float>());
}
SampleMatchesFunctions.emplace_back(new PartialFunction<float, float>(
{
{{-SignalConfiguration.OuterBound, -SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(
-SignalConfiguration.OuterBound, 0.f,
-SignalConfiguration.InnerBound, 1.f)},
{{-SignalConfiguration.InnerBound, SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(1.f, 0.f)},
{{SignalConfiguration.InnerBound, SignalConfiguration.OuterBound},
std::make_shared<LinearFunction<float, float>>(
SignalConfiguration.InnerBound, 1.f,
SignalConfiguration.OuterBound, 0.f)},
},
0));
//
// Create following function(s) which shall give information whether one
// sample mismatches another one (based on the relative distance between
// them).
//
// ____________ ____________
// \ /
// \ /
// \__________/
//
//
SampleMismatchesFunctions.emplace_back(new PartialFunction<float, float>(
{
{{-SignalConfiguration.OuterBound, -SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(
-SignalConfiguration.OuterBound, 1.f,
-SignalConfiguration.InnerBound, 0.f)},
{{-SignalConfiguration.InnerBound, SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(0.f, 0.f)},
{{SignalConfiguration.InnerBound, SignalConfiguration.OuterBound},
std::make_shared<LinearFunction<float, float>>(
SignalConfiguration.InnerBound, 0.f,
SignalConfiguration.OuterBound, 1.f)},
},
1));
//
// Create following function(s) which shall give information whether a
// signal is stable.
//
// ____________
// / \
// / \
// __________/ \__________
//
//
SignalIsStableFunctions.emplace_back(new PartialFunction<float, float>(
{
{{-SignalConfiguration.OuterBoundDrift,
-SignalConfiguration.InnerBoundDrift},
std::make_shared<LinearFunction<float, float>>(
-SignalConfiguration.OuterBoundDrift, 0.f,
-SignalConfiguration.InnerBoundDrift, 1.f)},
{{-SignalConfiguration.InnerBoundDrift,
SignalConfiguration.InnerBoundDrift},
std::make_shared<LinearFunction<float, float>>(1.f, 0.f)},
{{SignalConfiguration.InnerBoundDrift,
SignalConfiguration.OuterBoundDrift},
std::make_shared<LinearFunction<float, float>>(
SignalConfiguration.InnerBoundDrift, 1.f,
SignalConfiguration.OuterBoundDrift, 0.f)},
},
0));
//
// Create following function(s) which shall give information whether a
// signal is drifting.
//
// ____________ ____________
// \ /
// \ /
// \__________/
//
//
SignalIsDriftingFunctions.emplace_back(new PartialFunction<float, float>(
{
{{-SignalConfiguration.OuterBoundDrift,
-SignalConfiguration.InnerBoundDrift},
std::make_shared<LinearFunction<float, float>>(
-SignalConfiguration.OuterBoundDrift, 1.f,
-SignalConfiguration.InnerBoundDrift, 0.f)},
{{-SignalConfiguration.InnerBoundDrift,
SignalConfiguration.InnerBoundDrift},
std::make_shared<LinearFunction<float, float>>(0.f, 0.f)},
{{SignalConfiguration.InnerBoundDrift,
SignalConfiguration.OuterBoundDrift},
std::make_shared<LinearFunction<float, float>>(
SignalConfiguration.InnerBoundDrift, 0.f,
SignalConfiguration.OuterBoundDrift, 1.f)},
},
1));
// SAVE CHANGES
SignalConditionLookBackFunctions.emplace_back(
new PartialFunction<uint32_t, float>(
{{{1, SignalConfiguration.DriftLookbackRange + 1},
std::make_shared<LinearFunction<uint32_t, float>>(
1, 1.f, SignalConfiguration.DriftLookbackRange + 1, 0.f)},
{{SignalConfiguration.DriftLookbackRange + 1,
std::numeric_limits<uint32_t>::max()},
std::make_shared<LinearFunction<uint32_t, float>>(0.f, 0.f)}},
1.f));
SignalConditionHistoryDesicionFunctions.emplace_back(
new PartialFunction<uint32_t, float>(
{{{0, SignalConfiguration.DriftLookbackRange},
std::make_shared<LinearFunction<uint32_t, float>>(
0, 0.f, SignalConfiguration.DriftLookbackRange, 1.f)},
{{SignalConfiguration.DriftLookbackRange,
std::numeric_limits<uint32_t>::max()},
std::make_shared<LinearFunction<uint32_t, float>>(1.f, 0.f)}},
0.f));
// - SAVE CHANGES
//
// Create following function(s) which shall give information how many
// history samples match another sample.
//
// ____________
// /
// /
// __________/
//
NumOfSamplesMatchFunctions.emplace_back(new StepFunction<float, float>(
1.0f / SignalConfiguration.SampleHistorySize, StepDirection::StepUp));
//
// Create following function(s) which shall give information how many
// history samples mismatch another sample.
//
// ____________
// \
// \
// \__________
//
NumOfSamplesMismatchFunctions.emplace_back(new StepFunction<float, float>(
1.0f / SignalConfiguration.SampleHistorySize, StepDirection::StepDown));
//
// Create following function(s) which shall give information how good all
// samples in a state match each other.
//
// ____________
// / \
// / \
// __________/ \__________
//
//
SampleValidFunctions.emplace_back(new PartialFunction<float, float>(
{
{{-SignalConfiguration.OuterBound, -SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(
-SignalConfiguration.OuterBound, 0.f,
-SignalConfiguration.InnerBound, 1.f)},
{{-SignalConfiguration.InnerBound, SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(1.f, 0.f)},
{{SignalConfiguration.InnerBound, SignalConfiguration.OuterBound},
std::make_shared<LinearFunction<float, float>>(
SignalConfiguration.InnerBound, 1.f,
SignalConfiguration.OuterBound, 0.f)},
},
0));
//
// Create following function(s) which shall give information how good all
// samples in a state mismatch each other.
//
// ____________ ____________
// \ /
// \ /
// \__________/
//
//
SampleInvalidFunctions.emplace_back(new PartialFunction<float, float>(
{
{{-SignalConfiguration.OuterBound, -SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(
-SignalConfiguration.OuterBound, 1.f,
-SignalConfiguration.InnerBound, 0.f)},
{{-SignalConfiguration.InnerBound, SignalConfiguration.InnerBound},
std::make_shared<LinearFunction<float, float>>(0.f, 0.f)},
{{SignalConfiguration.InnerBound, SignalConfiguration.OuterBound},
std::make_shared<LinearFunction<float, float>>(
SignalConfiguration.InnerBound, 0.f,
SignalConfiguration.OuterBound, 1.f)},
},
1));
//
// Create following function(s) which shall give information how many
// history samples match each other.
//
// ____________
// /
// /
// __________/
//
NumOfSamplesValidFunctions.emplace_back(new StepFunction<float, float>(
1.0f / SignalConfiguration.SampleHistorySize, StepDirection::StepUp));
//
// Create following function(s) which shall give information how many
// history samples mismatch each other.
//
// ____________
// \
// \
// \__________
//
NumOfSamplesInvalidFunctions.emplace_back(new StepFunction<float, float>(
1.0f / SignalConfiguration.SampleHistorySize, StepDirection::StepDown));
//
// Create SignalStateDetector functionality
//
SignalStateDetectors.emplace_back(
new SignalStateDetector<float, float, float, HistoryPolicy::FIFO>(
SignalConfiguration.Output ? SignalProperties::OUTPUT
: SignalProperties::INPUT,
std::numeric_limits<int>::max(), DistanceMetrics.back(), SampleMatchesFunctions.back(),
SampleMismatchesFunctions.back(), NumOfSamplesMatchFunctions.back(),
NumOfSamplesMismatchFunctions.back(), SampleValidFunctions.back(),
SampleInvalidFunctions.back(), NumOfSamplesValidFunctions.back(),
NumOfSamplesInvalidFunctions.back(),
SignalIsDriftingFunctions.back(), SignalIsStableFunctions.back(),
// SAVE CHANGES
SignalConditionLookBackFunctions.back(),
SignalConditionHistoryDesicionFunctions.back(),
SignalConfiguration.DriftLookbackRange,
// - SAVE CHANGES
SignalConfiguration.SampleHistorySize, SignalConfiguration.DABSize,
SignalConfiguration.DABHistorySize));
//
// Create low-level application agents
//
SignalStateDetectorAgents.push_back(createSignalStateDetectorAgent(
AppCCAM, SignalConfiguration.Name, SignalStateDetectors.back()));
AppCCAM->setExecutionPolicy(
SignalStateDetectorAgents.back(),
AppExecutionPolicy::decimation(AppConfig.DownsamplingRate));
//
// Connect sensors to low-level agents.
//
LOG_INFO("Connect sensors to their corresponding low-level agents.");
AppCCAM->connectSensor(SignalStateDetectorAgents.back(), 0, Sensors.back(),
SignalConfiguration.Name + "_Sensor ->" +
SignalConfiguration.Name +
"_SignalStateDetector_Agent-Channel");
AppCCAM->connectAgents(
SystemStateDetectorAgent, SignalStateDetectors.size() - 1,
SignalStateDetectorAgents.back(),
SignalConfiguration.Name +
"_SignalStateDetector_Agent->SystemStateDetector_Agent_Channel");
}
//
// For simulation output, create a logger agent writing the output of the
// high-level agent into a CSV file.
//
LOG_INFO("Create a logger agent.");
// Create CSV writer.
std::ofstream OutputCSV(AppConfig.OutputFilePath);
- for (auto SignalConfiguration : AppConfig.SignalConfigurations) {
- OutputCSV << SignalConfiguration.Name + ",";
- }
- OutputCSV << "StateID,";
- OutputCSV << "Confidence State Valid,";
- OutputCSV << "Confidence State Invalid,";
- OutputCSV << "Confidence Inputs Matching,";
- OutputCSV << "Confidence Outputs Matching,";
- OutputCSV << "Confidence Inputs Mismatching,";
- OutputCSV << "Confidence Outputs Mismatching,";
+ //for (auto SignalConfiguration : AppConfig.SignalConfigurations) {
+ // OutputCSV << SignalConfiguration.Name + ",";
+ //}
+ //OutputCSV << "StateID,";
+ //OutputCSV << "Confidence State Valid,";
+ //OutputCSV << "Confidence State Invalid,";
+ //OutputCSV << "Confidence Inputs Matching,";
+ //OutputCSV << "Confidence Outputs Matching,";
+ //OutputCSV << "Confidence Inputs Mismatching,";
+ //OutputCSV << "Confidence Outputs Mismatching,";
OutputCSV << "State Condition,";
- OutputCSV << "Confidence System Functioning,";
- OutputCSV << "Confidence System Malfunctioning,";
- OutputCSV << "Overall Confidence,";
+ //OutputCSV << "Confidence System Functioning,";
+ //OutputCSV << "Confidence System Malfunctioning,";
+ //OutputCSV << "Overall Confidence,";
OutputCSV << "\n";
// The agent writes each new input value into a CSV file and produces
// nothing.
using Input = std::pair<SystemStateTuple, bool>;
using Result = Optional<AppTuple<unit_t>>;
using Handler = std::function<Result(Input)>;
std::string Name = "Logger Agent";
AgentHandle LoggerAgent = AppCCAM->createAgent(
"Logger Agent", Handler([&OutputCSV](Input I) -> Result {
const SystemStateTuple &T = I.first;
OutputCSV << std::get<0>(
static_cast<const std::tuple<std::string> &>(T))
<< std::endl;
return Result();
}));
//
// Connect the high-level agent to the logger agent.
//
LOG_INFO("Connect the high-level agent to the logger agent.");
AppCCAM->connectAgents(LoggerAgent, 0, SystemStateDetectorAgent,
"SystemStateDetector Channel");
//
// Only log if the SystemStateDetector actually ran
//
AppCCAM->setExecutionPolicy(LoggerAgent, AppExecutionPolicy::awaitAll({0}));
//
// Do simulation.
//
LOG_INFO("Setting up and performing simulation.");
//
// Initialize application for simulation.
//
AppCCAM->initializeSimulation();
//
// Open CSV files and register them for their corresponding sensors.
//
// Make sure DataFiles will not change capacity while adding elements to it.
// Changing capacity moves elements away, which invalidates references
// captured by CSVIterator.
DataFiles.reserve(AppConfig.SignalConfigurations.size());
uint32_t i = 0;
bool hasMQTT = false;
for (auto SignalConfiguration : AppConfig.SignalConfigurations) {
switch (SignalConfiguration.DataInterfaceType) {
case DataInterfaceTypes::CSV:
DataFiles.emplace_back(SignalConfiguration.InputPath);
if (!DataFiles.at(i)) {
LOG_ERROR_STREAM << "Cannot open Input File \""
<< SignalConfiguration.InputPath << "\" for Signal \""
<< SignalConfiguration.Name << "\"" << std::endl;
return 3;
}
AppCCAM->registerSensorValues(Sensors.at(i),
csv::CSVIterator<float>(DataFiles.at(i)),
csv::CSVIterator<float>());
LOG_INFO_STREAM << "Sensor " << SignalConfiguration.Name
<< " is fed by csv file " << SignalConfiguration.InputPath
<< std::endl;
break;
case DataInterfaceTypes::MQTT: {
hasMQTT = true;
auto it = MQTTIterator<float>(SignalConfiguration.MQTTTopic);
AppCCAM->registerSensorValues(Sensors.at(i), std::move(it),
MQTTIterator<float>());
LOG_INFO_STREAM << "Sensor " << SignalConfiguration.Name
<< " is fed by MQTT topic "
<< SignalConfiguration.MQTTTopic << std::endl;
break;
}
default:
LOG_ERROR_STREAM << "No data source for " << SignalConfiguration.Name
<< std::endl;
break;
}
i++;
}
//
// Start simulation.
//
auto &log = LOG_WARNING_STREAM;
log << "Simulation starting.";
if (hasMQTT) {
log << " Publishing MQTT messages may start.";
}
log << std::endl;
AppCCAM->simulate(AppConfig.NumberOfSimulationCycles);
return 0;
}
diff --git a/apps/ccam/statehandlerutils.h b/apps/ccam/statehandlerutils.h
index 99efe19..dc40d6c 100644
--- a/apps/ccam/statehandlerutils.h
+++ b/apps/ccam/statehandlerutils.h
@@ -1,274 +1,274 @@
#ifndef STATEHANDLERUTILS_H
#define STATEHANDLERUTILS_H
#include "rosa/agent/Abstraction.hpp"
#include "rosa/agent/Confidence.hpp"
#include "rosa/agent/FunctionAbstractions.hpp"
#include <functional>
#include <iostream>
#include <tuple>
#include <vector>
#include "rosa/config/version.h"
#include "rosa/agent/SignalStateDetector.hpp"
#include "rosa/agent/SystemStateDetector.hpp"
#include "rosa/app/Application.hpp"
#include "rosa/support/csv/CSVReader.hpp"
#include "rosa/support/csv/CSVWriter.hpp"
#include <fstream>
#include <limits>
#include <memory>
#include <streambuf>
using namespace rosa;
using namespace rosa::agent;
using namespace rosa::app;
using namespace rosa::terminal;
// For the convinience to write a shorter data type name
using SignalStateTuple =
AppTuple<float, uint32_t, uint8_t, float, float, float, float, float, float,
uint8_t, uint32_t, uint8_t>;
AgentHandle createSignalStateDetectorAgent(
std::unique_ptr<Application> &C, const std::string &Name,
std::shared_ptr<
SignalStateDetector<float, float, float, HistoryPolicy::FIFO>>
SigSD) {
using Input = std::pair<AppTuple<float>, bool>;
using Result = Optional<SignalStateTuple>;
using Handler = std::function<Result(Input)>;
return C->createAgent(
Name, Handler([&, Name, SigSD](Input I) -> Result {
LOG_INFO_STREAM << "\n******\n"
<< Name << " " << (I.second ? "<New>" : "<Old>")
<< " value: "
<< std::get<0>(
static_cast<std::tuple<float> &>(I.first))
<< "\n******\n";
auto StateInfo = SigSD->detectSignalState(
std::get<0>(static_cast<std::tuple<float> &>(I.first)));
if (I.second) {
SignalStateTuple Res = {
std::get<0>(static_cast<std::tuple<float> &>(I.first)),
StateInfo.StateID,
StateInfo.SignalProperty,
StateInfo.ConfidenceOfMatchingState,
StateInfo.ConfidenceOfMismatchingState,
StateInfo.ConfidenceStateIsValid,
StateInfo.ConfidenceStateIsInvalid,
StateInfo.ConfidenceStateIsStable,
StateInfo.ConfidenceStateIsDrifting,
StateInfo.StateCondition,
StateInfo.NumberOfInsertedSamplesAfterEntrance,
static_cast<uint8_t>(
(StateInfo.StateIsValid ? 4 : 0) +
(StateInfo.StateJustGotValid ? 2 : 0) +
(StateInfo.StateIsValidAfterReentrance ? 1 : 0))};
return Result(Res);
}
return Result();
}));
}
// System State
using SystemStateTuple = AppTuple<std::string>;
template <std::size_t size, typename ret, typename functype, typename... A>
struct Handler_helper;
template <typename B, typename func, typename A, typename... As>
struct function_helper {
static_assert(std::conjunction_v<std::is_same<A, As>...>,
"All types need to be identical");
static B function(A valA, As... valAs) {
std::vector<A> ar({valA, valAs...});
return func()(ar);
}
};
template <typename ret, typename typeA, typename functype, typename... B>
struct Handler_helper<0, ret, functype, typeA, B...> {
using handler = function_helper<ret, functype, B...>;
};
template <std::size_t size, typename ret, typename typeA, typename functype,
typename... B>
struct Handler_helper<size, ret, functype, typeA, B...> {
using handler =
typename Handler_helper<size - 1, ret, functype, typeA,
std::pair<typeA, bool>, B...>::handler;
};
template <std::size_t size, typename ret, typename functype, typename typeA>
using Handler = typename Handler_helper<size, ret, functype, typeA>::handler;
// TODO: Change it from global to local variable if possible
std::shared_ptr<
SystemStateDetector<uint32_t, float, float, HistoryPolicy::FIFO>>
SysSD;
template <typename ret, typename A> struct function {
ret operator()(A a) {
std::vector<SignalStateInformation<float>> SignalStateInfos;
std::stringstream OutString;
for (auto _SignalStateTuple : a) {
// convert tuple to info struct out.push_back({});
- OutString << std::get<0>(_SignalStateTuple.first) << ",";
+ //OutString << std::get<0>(_SignalStateTuple.first) << ",";
SignalStateInformation<float> Info;
Info.StateID = std::get<1>(_SignalStateTuple.first);
Info.SignalProperty =
static_cast<SignalProperties>(std::get<2>(_SignalStateTuple.first));
Info.ConfidenceOfMatchingState = std::get<3>(_SignalStateTuple.first);
Info.ConfidenceOfMismatchingState = std::get<4>(_SignalStateTuple.first);
Info.ConfidenceStateIsValid = std::get<5>(_SignalStateTuple.first);
Info.ConfidenceStateIsInvalid = std::get<6>(_SignalStateTuple.first);
Info.ConfidenceStateIsStable = std::get<7>(_SignalStateTuple.first);
Info.ConfidenceStateIsDrifting = std::get<8>(_SignalStateTuple.first);
Info.StateCondition =
static_cast<StateConditions>(std::get<9>(_SignalStateTuple.first));
Info.NumberOfInsertedSamplesAfterEntrance =
std::get<10>(_SignalStateTuple.first);
Info.StateIsValid = (std::get<11>(_SignalStateTuple.first) & 4) > 0;
Info.StateJustGotValid = (std::get<11>(_SignalStateTuple.first) & 2) > 0;
Info.StateIsValidAfterReentrance =
(std::get<11>(_SignalStateTuple.first) & 1) > 0;
SignalStateInfos.push_back(Info);
}
SystemStateInformation<float> SystemStateInfo =
SysSD->detectSystemState(SignalStateInfos);
- OutString << SystemStateInfo.StateID << ",";
- OutString << SystemStateInfo.ConfidenceStateIsValid << ",";
- OutString << SystemStateInfo.ConfidenceStateIsInvalid << ",";
- OutString << SystemStateInfo.ConfidenceOfInputsMatchingState << ",";
- OutString << SystemStateInfo.ConfidenceOfInputsMismatchingState << ",";
- OutString << SystemStateInfo.ConfidenceOfOutputsMatchingState << ",";
- OutString << SystemStateInfo.ConfidenceOfOutputsMismatchingState << ",";
+ //OutString << SystemStateInfo.StateID << ",";
+ //OutString << SystemStateInfo.ConfidenceStateIsValid << ",";
+ //OutString << SystemStateInfo.ConfidenceStateIsInvalid << ",";
+ //OutString << SystemStateInfo.ConfidenceOfInputsMatchingState << ",";
+ //OutString << SystemStateInfo.ConfidenceOfInputsMismatchingState << ",";
+ //OutString << SystemStateInfo.ConfidenceOfOutputsMatchingState << ",";
+ //OutString << SystemStateInfo.ConfidenceOfOutputsMismatchingState << ",";
OutString << SystemStateInfo.StateCondition << ",";
- OutString << SystemStateInfo.ConfidenceSystemIsFunctioning << ",";
- OutString << SystemStateInfo.ConfidenceSystemIsMalfunctioning << ",";
- OutString << SystemStateInfo.ConfidenceOfAllDecisions << ",";
+ //OutString << SystemStateInfo.ConfidenceSystemIsFunctioning << ",";
+ //OutString << SystemStateInfo.ConfidenceSystemIsMalfunctioning << ",";
+ //OutString << SystemStateInfo.ConfidenceOfAllDecisions << ",";
return ret(std::make_tuple<std::string>(OutString.str()));
}
};
using arr = std::vector<std::pair<SignalStateTuple, bool>>;
template <size_t NumOfSlaves>
AgentHandle createSystemStateDetectorAgent(
std::unique_ptr<Application> &C, const std::string &Name,
std::shared_ptr<PartialFunction<uint32_t, float>> BrokenDelayFunction,
std::shared_ptr<PartialFunction<uint32_t, float>> OkDelayFunction) {
LOG_TRACE("Creating fixed SystemStateDetectorAgent");
using Input = SignalStateTuple;
using Result = Optional<SystemStateTuple>;
std::shared_ptr<
SystemStateDetector<uint32_t, float, float, HistoryPolicy::FIFO>>
_SysSD(
new SystemStateDetector<uint32_t, float, float, HistoryPolicy::FIFO>(
std::numeric_limits<uint32_t>::max(), NumOfSlaves,
BrokenDelayFunction, OkDelayFunction));
SysSD = _SysSD;
auto HandlerFunction =
Handler<NumOfSlaves, Result, function<Optional<SystemStateTuple>, arr>,
Input>::function;
return C->createAgent(Name, std::function(HandlerFunction));
}
AgentHandle createSystemStateDetectorAgent(
std::unique_ptr<Application> &C, const std::string &Name,
size_t NumOfSlaves,
std::shared_ptr<PartialFunction<uint32_t, float>> BrokenDelayFunction,
std::shared_ptr<PartialFunction<uint32_t, float>> OkDelayFunction) {
LOG_TRACE("Creating dynamic SystemStateDetectorAgent");
switch (NumOfSlaves) {
// clang-format off
case 2: return createSystemStateDetectorAgent< 2>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 3: return createSystemStateDetectorAgent< 3>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 4: return createSystemStateDetectorAgent< 4>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 5: return createSystemStateDetectorAgent< 5>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 6: return createSystemStateDetectorAgent< 6>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 7: return createSystemStateDetectorAgent< 7>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 8: return createSystemStateDetectorAgent< 8>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 9: return createSystemStateDetectorAgent< 9>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 10: return createSystemStateDetectorAgent<10>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 11: return createSystemStateDetectorAgent<11>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 12: return createSystemStateDetectorAgent<12>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 13: return createSystemStateDetectorAgent<13>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 14: return createSystemStateDetectorAgent<14>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 15: return createSystemStateDetectorAgent<15>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 16: return createSystemStateDetectorAgent<16>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 17: return createSystemStateDetectorAgent<17>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 18: return createSystemStateDetectorAgent<18>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 19: return createSystemStateDetectorAgent<19>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 20: return createSystemStateDetectorAgent<20>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 21: return createSystemStateDetectorAgent<21>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 22: return createSystemStateDetectorAgent<22>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 23: return createSystemStateDetectorAgent<23>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 24: return createSystemStateDetectorAgent<24>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 25: return createSystemStateDetectorAgent<25>(C, Name, BrokenDelayFunction, OkDelayFunction);
case 1:
default: return createSystemStateDetectorAgent<1>(C, Name, BrokenDelayFunction, OkDelayFunction);
// clang-format on
}
}
// template <typename T, typename>
// AgentHandle createMQTTSensor(std::string MQTTTopic) {
// using Input = void;
// using Result = Optional<T>;
// using Handler = std::function<Result(Input)>;
// return C->createAgent(
// Name, Handler([&, Name, SigSD](Input I) -> Result {
// LOG_INFO_STREAM << "\n******\n"
// << Name << " " << (I.second ? "<New>" : "<Old>")
// << " value: "
// << std::get<0>(
// static_cast<std::tuple<float> &>(I.first))
// << "\n******\n";
// auto StateInfo = SigSD->detectSignalState(
// std::get<0>(static_cast<std::tuple<float> &>(I.first)));
// if (I.second) {
// SignalStateTuple Res = {
// std::get<0>(static_cast<std::tuple<float> &>(I.first)),
// StateInfo.StateID,
// StateInfo.SignalProperty,
// StateInfo.ConfidenceOfMatchingState,
// StateInfo.ConfidenceOfMismatchingState,
// StateInfo.ConfidenceStateIsValid,
// StateInfo.ConfidenceStateIsInvalid,
// StateInfo.ConfidenceStateIsStable,
// StateInfo.ConfidenceStateIsDrifting,
// StateInfo.StateCondition,
// StateInfo.NumberOfInsertedSamplesAfterEntrance,
// static_cast<uint8_t>(
// (StateInfo.StateIsValid ? 4 : 0) +
// (StateInfo.StateJustGotValid ? 2 : 0) +
// (StateInfo.StateIsValidAfterReentrance ? 1 : 0))};
// return Result(Res);
// }
// return Result();
// }));
// }
#endif // STATEHANDLERUTILS_H

File Metadata

Mime Type
text/x-diff
Expires
Sat, Mar 15, 8:34 PM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
129098
Default Alt Text
(37 KB)

Event Timeline