Page MenuHomePhorge

No OneTemporary

Size
49 KB
Referenced Files
None
Subscribers
None
diff --git a/apps/ccam/ccam.cpp b/apps/ccam/ccam.cpp
index a2488dd..a83aec1 100644
--- a/apps/ccam/ccam.cpp
+++ b/apps/ccam/ccam.cpp
@@ -1,620 +1,621 @@
//===-- 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 Matching,";
//OutputCSV << "Confidence Outputs Mismatching,";
OutputCSV << "State Condition,";
//OutputCSV << "Confidence System Functioning,";
//OutputCSV << "Confidence System Malfunctioning,";
+ OutputCSV << "Confidence Stable,";
OutputCSV << "Confidence Drift,";
OutputCSV << "Confidence Drift Up,";
OutputCSV << "Confidence Drift Down,";
- OutputCSV << "Overall Confidence,";
+ //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 60620d4..4ec0205 100644
--- a/apps/ccam/statehandlerutils.h
+++ b/apps/ccam/statehandlerutils.h
@@ -1,277 +1,287 @@
#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.ConfidenceOfMismatchingState, //ASK DAVID
StateInfo.ConfidenceStateIsValid,
- StateInfo.ConfidenceStateIsInvalid,
+ //StateInfo.ConfidenceStateIsInvalid, //ASK DAVID
StateInfo.ConfidenceStateIsStable,
StateInfo.ConfidenceStateIsDrifting,
+ StateInfo.ConfidenceStateIsDriftingUp, //
+ StateInfo.ConfidenceStateIsDriftingDown, //
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) << ",";
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.ConfidenceOfMismatchingState = std::get<4>(_SignalStateTuple.first); //ASK DAVID
+ Info.ConfidenceOfMismatchingState = 1-std::get<3>(_SignalStateTuple.first);
+ //Info.ConfidenceStateIsValid = std::get<5>(_SignalStateTuple.first);
+ Info.ConfidenceStateIsValid = std::get<4>(_SignalStateTuple.first);
+ //Info.ConfidenceStateIsInvalid = std::get<6>(_SignalStateTuple.first); //ASK DAVID
+ Info.ConfidenceStateIsInvalid = 1-std::get<4>(_SignalStateTuple.first);
+ //Info.ConfidenceStateIsStable = std::get<7>(_SignalStateTuple.first); //ASK DAVID
+ Info.ConfidenceStateIsStable = std::get<5>(_SignalStateTuple.first);
+ //Info.ConfidenceStateIsDrifting = std::get<8>(_SignalStateTuple.first); //ASK DAVID
+ Info.ConfidenceStateIsDrifting = std::get<6>(_SignalStateTuple.first);
+ Info.ConfidenceStateIsDriftingUp = std::get<7>(_SignalStateTuple.first);
+ Info.ConfidenceStateIsDriftingDown = 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.StateCondition << ",";
//OutString << SystemStateInfo.ConfidenceSystemIsFunctioning << ",";
//OutString << SystemStateInfo.ConfidenceSystemIsMalfunctioning << ",";
+ OutString << SystemStateInfo.ConfidenceStateIsStable << ",";
OutString << SystemStateInfo.ConfidenceStateIsDrifting << ",";
OutString << SystemStateInfo.ConfidenceStateIsDriftingUp << ",";
OutString << SystemStateInfo.ConfidenceStateIsDriftingDown << ",";
- OutString << SystemStateInfo.ConfidenceOfAllDecisions << ",";
+ //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
diff --git a/include/rosa/agent/SystemState.hpp b/include/rosa/agent/SystemState.hpp
index d9e3ce5..6712d89 100644
--- a/include/rosa/agent/SystemState.hpp
+++ b/include/rosa/agent/SystemState.hpp
@@ -1,312 +1,311 @@
//===-- rosa/agent/SystemState.hpp ------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
// 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 rosa/agent/SystemState.hpp
///
/// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *system state* *functionality*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_SYSTEMSTATE_HPP
#define ROSA_AGENT_SYSTEMSTATE_HPP
#include "rosa/agent/Functionality.h"
#include "rosa/agent/SignalState.hpp"
#include "rosa/agent/State.hpp"
#include "rosa/support/debug.hpp"
#include <vector>
namespace rosa {
namespace agent {
enum class SystemStateRelation : uint8_t {
STATEISMATCHING = 0, ///< The system state is matching
ONLYINPUTISMATCHING = 1, ///< Only inputs of the system state are matching
ONLYOUTPUTISMATCHING = 2, ///< Only outputs of the system state are matching
STATEISMISMATCHING = 3 ///< The system state is mismatching
};
/// TODO: write description
template <typename CONFDATATYPE>
struct SystemStateInformation : StateInformation<CONFDATATYPE> {
/// TODO: describe
CONFDATATYPE ConfidenceOfInputsMatchingState;
CONFDATATYPE ConfidenceOfInputsMismatchingState;
CONFDATATYPE ConfidenceOfOutputsMatchingState;
CONFDATATYPE ConfidenceOfOutputsMismatchingState;
CONFDATATYPE ConfidenceSystemIsFunctioning;
CONFDATATYPE ConfidenceSystemIsMalfunctioning;
CONFDATATYPE ConfidenceOfAllDecisions;
public:
SystemStateInformation() = default;
SystemStateInformation(unsigned int _SystemStateID,
StateConditions _StateCondition) {
this->StateID = _SystemStateID;
this->StateCondition = _StateCondition;
this->StateIsValid = false;
this->StateJustGotValid = false;
this->StateIsValidAfterReentrance = false;
this->ConfidenceOfInputsMatchingState = 0;
this->ConfidenceOfInputsMismatchingState = 0;
this->ConfidenceOfOutputsMatchingState = 0;
this->ConfidenceOfOutputsMismatchingState = 0;
this->ConfidenceSystemIsFunctioning = 0;
this->ConfidenceSystemIsMalfunctioning = 0;
this->ConfidenceOfAllDecisions = 0;
}
};
// todo: do we need PROCDATATYPE?
/// TODO TEXT
template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE>
class SystemState : public State<INDATATYPE, CONFDATATYPE, PROCDATATYPE> {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT(std::is_arithmetic<INDATATYPE>::value,
"input data type is not to arithmetic");
STATIC_ASSERT(std::is_arithmetic<CONFDATATYPE>::value,
"confidence abstraction type is not to arithmetic");
STATIC_ASSERT(std::is_arithmetic<PROCDATATYPE>::value,
"process data type is not to arithmetic");
private:
/// SignalStateInfo is a struct of SignalStateInformation that contains
/// information about the current signal state.
SystemStateInformation<CONFDATATYPE> SystemStateInfo;
std::vector<SignalStateInformation<CONFDATATYPE>> SignalStateInfos;
uint32_t NumberOfSignals;
public:
/// TODO: write description
SystemState(uint32_t StateID, uint32_t NumberOfSignals) noexcept
: SystemStateInfo(StateID, StateConditions::UNKNOWN),
NumberOfSignals(NumberOfSignals) {
SignalStateInfos.resize(NumberOfSignals);
}
/// Destroys \p this object.
~SystemState(void) = default;
/// TODO: write description
SystemStateInformation<CONFDATATYPE> insertSignalStateInformation(
const std::vector<SignalStateInformation<CONFDATATYPE>>
_SignalStateInfos) noexcept {
ASSERT(_SignalStateInfos.size() == NumberOfSignals);
bool AllSignalsAreValid = true;
bool AtLeastOneSignalJustGotValid = false;
bool AllSignalsAreValidAfterReentrance = true;
bool AtLeastOneSignalIsUnknown = false;
bool AllSignalsAreStable = true;
uint32_t DriftDnCounter = 0;
uint32_t DriftUpCounter = 0;
// TODO: change this
SystemStateInfo.ConfidenceOfInputsMatchingState = 1;
SystemStateInfo.ConfidenceOfInputsMismatchingState = 0;
SystemStateInfo.ConfidenceOfOutputsMatchingState = 1;
SystemStateInfo.ConfidenceOfOutputsMismatchingState = 0;
SystemStateInfo.ConfidenceStateIsValid = 1;
SystemStateInfo.ConfidenceStateIsInvalid = 0;
SystemStateInfo.ConfidenceStateIsStable = 1;
SystemStateInfo.ConfidenceStateIsDrifting = 0;
SystemStateInfo.ConfidenceStateIsDriftingUp = 0;
SystemStateInfo.ConfidenceStateIsDriftingDown = 0;
std::size_t counter = 0;
for (auto SSI : _SignalStateInfos) {
if (!SSI.StateIsValid)
AllSignalsAreValid = false;
if (SSI.StateJustGotValid)
AtLeastOneSignalJustGotValid = true;
if (!SSI.StateIsValidAfterReentrance)
AllSignalsAreValidAfterReentrance = false;
if (SSI.StateCondition == StateConditions::UNKNOWN)
AtLeastOneSignalIsUnknown = true;
if (SSI.StateCondition == StateConditions::DRIFTING_DN) {
AllSignalsAreStable = false;
DriftDnCounter++;
}
if (SSI.StateCondition == StateConditions::DRIFTING_UP) {
AllSignalsAreStable = false;
DriftUpCounter++;
}
if (SSI.SignalProperty == SignalProperties::INPUT) {
SystemStateInfo.ConfidenceOfInputsMatchingState =
fuzzyAND(SystemStateInfo.ConfidenceOfInputsMatchingState,
SSI.ConfidenceOfMatchingState);
SystemStateInfo.ConfidenceOfInputsMismatchingState =
fuzzyOR(SystemStateInfo.ConfidenceOfInputsMismatchingState,
SSI.ConfidenceOfMismatchingState);
} else {
SystemStateInfo.ConfidenceOfOutputsMatchingState =
fuzzyAND(SystemStateInfo.ConfidenceOfOutputsMatchingState,
SSI.ConfidenceOfMatchingState);
SystemStateInfo.ConfidenceOfOutputsMismatchingState =
fuzzyOR(SystemStateInfo.ConfidenceOfOutputsMismatchingState,
SSI.ConfidenceOfMismatchingState);
}
SystemStateInfo.ConfidenceStateIsValid = fuzzyAND(
SystemStateInfo.ConfidenceStateIsValid, SSI.ConfidenceStateIsValid);
SystemStateInfo.ConfidenceStateIsInvalid =
fuzzyOR(SystemStateInfo.ConfidenceStateIsInvalid,
SSI.ConfidenceStateIsInvalid);
SystemStateInfo.ConfidenceStateIsStable = fuzzyAND(
- SystemStateInfo.ConfidenceStateIsStable, SSI.ConfidenceStateIsStable);
+ SystemStateInfo.ConfidenceStateIsStable, SSI.ConfidenceStateIsStable);
SystemStateInfo.ConfidenceStateIsDrifting =
fuzzyOR(SystemStateInfo.ConfidenceStateIsDrifting,
SSI.ConfidenceStateIsDrifting);
SystemStateInfo.ConfidenceStateIsDriftingUp =
fuzzyOR(SystemStateInfo.ConfidenceStateIsDriftingUp,
- SSI.ConfidenceStateIsDriftingUp);
+ SSI.ConfidenceStateIsDriftingUp);
SystemStateInfo.ConfidenceStateIsDriftingDown =
fuzzyOR(SystemStateInfo.ConfidenceStateIsDriftingDown,
SSI.ConfidenceStateIsDriftingDown);
-
this->SignalStateInfos.at(counter) = SSI;
counter++;
}
SystemStateInfo.StateIsValid = AllSignalsAreValid;
SystemStateInfo.StateJustGotValid =
AllSignalsAreValid && AtLeastOneSignalJustGotValid;
SystemStateInfo.StateIsValidAfterReentrance =
AllSignalsAreValidAfterReentrance;
if (AtLeastOneSignalIsUnknown)
SystemStateInfo.StateCondition = StateConditions::UNKNOWN;
else if (AllSignalsAreStable)
SystemStateInfo.StateCondition = StateConditions::STABLE;
else {
if (DriftDnCounter > DriftUpCounter)
SystemStateInfo.StateCondition = StateConditions::DRIFTING_DN;
else if (DriftDnCounter < DriftUpCounter)
SystemStateInfo.StateCondition = StateConditions::DRIFTING_UP;
else {
SystemStateInfo.StateCondition = StateConditions::DRIFTING;
}
}
return SystemStateInfo;
}
/// TODO: write description
// TODO (future): think about saving the state information in a history
SystemStateRelation compareSignalStateInformation(
const std::vector<SignalStateInformation<CONFDATATYPE>>
_SignalStateInfos) noexcept {
bool inputsAreMatching = true;
bool outputsAreMatching = true;
std::size_t counter = 0;
for (auto SSI : _SignalStateInfos) {
if (this->SignalStateInfos.at(counter).StateID != SSI.StateID) {
if (SSI.SignalProperty == SignalProperties::INPUT)
inputsAreMatching = false;
else // SignalProperties::OUTPUT
outputsAreMatching = false;
}
counter++;
}
if (inputsAreMatching && outputsAreMatching)
return SystemStateRelation::STATEISMATCHING;
else if (inputsAreMatching && !outputsAreMatching)
return SystemStateRelation::ONLYINPUTISMATCHING;
else if (!inputsAreMatching && outputsAreMatching)
return SystemStateRelation::ONLYOUTPUTISMATCHING;
else
return SystemStateRelation::STATEISMISMATCHING;
}
#ifdef ADDITIONAL_FUNCTIONS
/// TODO: write description
template <std::size_t size>
void insertSignalStateInformation(
const std::array<SystemStateInformation<CONFDATATYPE>, size>
&Data) noexcept {
ASSERT(size <= NumberOfSignals);
std::size_t counter = 0;
for (auto tmp : Data) {
Signals.at(counter) = tmp;
counter++;
}
}
/// TODO: write description
template <typename... Types>
std::enable_if_t<std::conjunction_v<std::is_same<
Types, SystemStateInformation<CONFDATATYPE>>...>,
void>
insertSignalStateInformation(Types... Data) {
// TODO (future): think about saving the state information in a history
insertSignalStateInfos(
std::array<SystemStateInformation<CONFDATATYPE>, sizeof...(Data)>(
{Data...}));
}
// returns true if they are identical
/// TODO: write description
template <std::size_t size>
bool compareSignalStateInformation(
const std::array<SystemStateInformation<CONFDATATYPE>, size>
&Data) noexcept {
// TODO (future): think about saving the state information in a history
std::size_t counter = 0;
for (auto tmp : Data) {
if (Signals.at(counter) != tmp)
return false;
counter++;
}
return true;
}
// checks only the given amount
/// TODO: write description
template <typename... Types>
std::enable_if_t<std::conjunction_v<std::is_same<
Types, SystemStateInformation<CONFDATATYPE>>...>,
bool>
compareSignalStateInformation(Types... Data) {
return compareSignalStateInfos(
std::array<SystemStateInformation<CONFDATATYPE>, sizeof...(Data)>(
{Data...}));
}
#endif
/// Gives information about the current signal state.
///
/// \return a struct SignalStateInformation that contains information about
/// the current signal state.
SystemStateInformation<CONFDATATYPE> systemStateInformation(void) noexcept {
return SystemStateInfo;
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_SYSTEMSTATE_HPP

File Metadata

Mime Type
text/x-diff
Expires
Sun, Apr 27, 2:18 PM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
134525
Default Alt Text
(49 KB)

Event Timeline