diff --git a/apps/ccam/CMakeLists.txt b/apps/ccam/CMakeLists.txt index b4eaa07..004f0aa 100644 --- a/apps/ccam/CMakeLists.txt +++ b/apps/ccam/CMakeLists.txt @@ -1,14 +1,11 @@ if ( ROSA_COMPILER_IS_GCC_COMPATIBLE ) # Allow exceptions by removing restricting flag (needed by cxxopts) remove("-fno-exceptions" CMAKE_CXX_FLAGS) - - # Allow dynamic casts by removing restriction flag (needed by cxxopts) - remove("-fno-rtti" CMAKE_CXX_FLAGS) endif() set(SOURCES configuration.h) ROSA_add_app(ccam ccam.cpp) ROSA_add_library_dependencies(ccam ROSAConfig) ROSA_add_library_dependencies(ccam ROSADeluxe) ROSA_add_library_dependencies(ccam ROSAAgent) diff --git a/apps/ccam/ccam.cpp b/apps/ccam/ccam.cpp index 249fef0..acd6afb 100644 --- a/apps/ccam/ccam.cpp +++ b/apps/ccam/ccam.cpp @@ -1,227 +1,263 @@ //===-- apps/ccam/ccam.cpp --------------------------------------*- C++ -*-===// // // The RoSA Framework -- Application CCAM // //===----------------------------------------------------------------------===// /// /// \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 //===----------------------------------------------------------------------===// -#include "cxxopts/cxxopts.hpp" #include "rosa/agent/Abstraction.hpp" #include "rosa/agent/Confidence.hpp" #include "rosa/agent/FunctionAbstractions.hpp" #include #include "rosa/config/version.h" #include "rosa/deluxe/DeluxeContext.hpp" #include "rosa/support/csv/CSVReader.hpp" #include "rosa/support/csv/CSVWriter.hpp" #include #include #include -/* -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#pragma GCC diagnostic ignored "-Wreorder" -#pragma GCC diagnostic ignored "-Wunused-local-typedef" -#pragma GCC diagnostic ignored "-Wgnu-folding-constant"*/ + #include "configuration.h" -//#pragma GCC diagnostic pop using namespace rosa; using namespace rosa::agent; using namespace rosa::deluxe; using namespace rosa::terminal; const std::string AppName = "CCAM"; int main(int argc, char **argv) { LOG_INFO_STREAM << '\n' << library_string() << " -- " << Color::Red << AppName << "app" << Color::Default << '\n'; - cxxopts::Options Options( - "CCAM", "Confidence-based Context-Aware condition Monitoring"); - - // clang-format off - Options.add_options() - ("c,config", "Path to config file", - cxxopts::value()->default_value("config.json")) - ("i,infile", "Path to input file", - cxxopts::value()->default_value("in.csv")) - ("o,outfile", "Path to output file", - cxxopts::value()->default_value("out.csv")) - ("b,broken", "Broken counter", - cxxopts::value()->default_value("10")) - ("l,length", "Length of fuzzy function for match-check", - cxxopts::value()->default_value("10")) - ("s,sig", "Signal", - cxxopts::value()->default_value("10")) - ; - // clang-format on - - auto ParsedOptions = Options.parse(argc, argv); - std::string ConfigPath = ParsedOptions["config"].as(); + if (argc < 2) { + LOG_ERROR("Specify config File!\nUsage:\n\tccam config.json"); + return 1; + } + std::string ConfigPath = argv[1]; if (!readConfigFile(ConfigPath)) { LOG_ERROR_STREAM << "Could not read config from \"" << ConfigPath << "\"\n"; - return 1; + return 2; } - /* - std::string ConfigString((std::istreambuf_iterator(ConfigFile)), - std::istreambuf_iterator()); - - AppConfiguration ConfigObj; - json_object(s::InputFilePath, s::OutputFilePath, s::BrokenCounter, - s::Length, s::SignalConfigurations = json_vector(s::Name, s::Output, - s::InnerBound, s::OuterBound, s::InnerBoundDrift, s::OuterBoundDrift)) - .decode(ConfigString, ConfigObj); - - std::string test = iod::json_encode(ConfigObj); - LOG_INFO_STREAM << test; - */ std::string InputFilePath, OutputFilePath; - LOG_INFO("Creating Context\n"); + LOG_INFO("Creating Context"); std::unique_ptr C = DeluxeContext::create(AppName); // // Create deluxe sensors. // LOG_INFO("Creating sensors, SignalStateDetector functionalities and their " "Abstractions."); std::vector Sensors; std::vector>> SampleMatchesFunctions; std::vector>> SampleMismatchesFunctions; + std::vector>> + SignalIsStableFunctions; + std::vector>> + SignalIsDriftingFunctions; std::vector>> NumOfSamplesMatchFunctions; std::vector>> NumOfSamplesMismatchFunctions; for (auto SignalConfiguration : AppConfig.SignalConfigurations) { - Sensors.emplace(Sensors.end(), - C->createSensor(SignalConfiguration.Name)); + Sensors.emplace_back(C->createSensor(SignalConfiguration.Name)); + SampleMatchesFunctions.emplace_back(new PartialFunction( + { + {{-SignalConfiguration.OuterBound, -SignalConfiguration.InnerBound}, + std::make_shared>( + -SignalConfiguration.OuterBound, 0.f, + -SignalConfiguration.InnerBound, 1.f)}, + {{-SignalConfiguration.InnerBound, SignalConfiguration.InnerBound}, + std::make_shared>(1.f, 0.f)}, + {{SignalConfiguration.InnerBound, SignalConfiguration.OuterBound}, + std::make_shared>( + SignalConfiguration.InnerBound, 1.f, + SignalConfiguration.OuterBound, 0.f)}, + }, + 0)); + + SampleMismatchesFunctions.emplace_back(new PartialFunction( + { + {{-SignalConfiguration.OuterBound, -SignalConfiguration.InnerBound}, + std::make_shared>( + -SignalConfiguration.OuterBound, 1.f, + -SignalConfiguration.InnerBound, 0.f)}, + {{-SignalConfiguration.InnerBound, SignalConfiguration.InnerBound}, + std::make_shared>(0.f, 0.f)}, + {{SignalConfiguration.InnerBound, SignalConfiguration.OuterBound}, + std::make_shared>( + SignalConfiguration.InnerBound, 0.f, + SignalConfiguration.OuterBound, 1.f)}, + }, + 1)); + + SignalIsStableFunctions.emplace_back(new PartialFunction( + { + {{-SignalConfiguration.OuterBoundDrift, + -SignalConfiguration.InnerBoundDrift}, + std::make_shared>( + -SignalConfiguration.OuterBoundDrift, 0.f, + -SignalConfiguration.InnerBoundDrift, 1.f)}, + {{-SignalConfiguration.InnerBoundDrift, + SignalConfiguration.InnerBoundDrift}, + std::make_shared>(1.f, 0.f)}, + {{SignalConfiguration.InnerBoundDrift, + SignalConfiguration.OuterBoundDrift}, + std::make_shared>( + SignalConfiguration.InnerBoundDrift, 1.f, + SignalConfiguration.OuterBoundDrift, 0.f)}, + }, + 0)); + + SignalIsDriftingFunctions.emplace_back(new PartialFunction( + { + {{-SignalConfiguration.OuterBoundDrift, + -SignalConfiguration.InnerBoundDrift}, + std::make_shared>( + -SignalConfiguration.OuterBoundDrift, 1.f, + -SignalConfiguration.InnerBoundDrift, 0.f)}, + {{-SignalConfiguration.InnerBoundDrift, + SignalConfiguration.InnerBoundDrift}, + std::make_shared>(0.f, 0.f)}, + {{SignalConfiguration.InnerBoundDrift, + SignalConfiguration.OuterBoundDrift}, + std::make_shared>( + SignalConfiguration.InnerBoundDrift, 0.f, + SignalConfiguration.OuterBoundDrift, 1.f)}, + }, + 1)); + + NumOfSamplesMatchFunctions.emplace_back(new StepFunction( + SignalConfiguration.Length, StepDirection::StepUp)); + + NumOfSamplesMismatchFunctions.emplace_back(new StepFunction( + SignalConfiguration.Length, StepDirection::StepDown)); // // Create functionalities. // // // Create low-level deluxe agents with \c createLowLevelAgent. // /// AgentHandle HRAgent = /// createLowLevelAgent(C, "HR Agent", HRConfidence, HRAbstraction); // // Connect sensors to low-level agents. // LOG_INFO("Connect sensors to their corresponding low-level agents."); /// C->connectSensor(HRAgent, 0, HRSensor, "HR Sensor Channel"); } // // Create a high-level deluxe agent. // LOG_INFO("Create high-level agent."); // The new agent logs its input values and results in the the sum of them. /** AgentHandle BodyAgent = C->createAgent( "Body Agent", DeluxeAgent::D( [](std::pair HR, std::pair BR, std::pair SpO2, std::pair BPSys, std::pair BodyTemp) -> Optional { LOG_INFO_STREAM << "\n*******\nBody Agent trigged with values:\n" << (HR.second ? "" : "") << " HR warning score: " << HR.first << "\n" << (BR.second ? "" : "") << " BR warning score: " << BR.first << "\n" << (SpO2.second ? "" : "") << " SpO2 warning score: " << SpO2.first << "\n" << (BPSys.second ? "" : "") << " BPSys warning score: " << BPSys.first << "\n" << (BodyTemp.second ? "" : "") << " BodyTemp warning score: " << BodyTemp.first << "\n******\n"; return {HR.first + BR.first + SpO2.first + BPSys.first + BodyTemp.first}; })); */ // // Connect low-level agents to the high-level agent. // LOG_INFO("Connect low-level agents to the high-level agent."); /// C->connectAgents(BodyAgent, 0, HRAgent, "HR 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 ScoreCSV(ScoreCSVPath); /// csv::CSVWriter ScoreWriter(ScoreCSV); // The agent writes each new input value into a CSV file and produces nothing. /** AgentHandle LoggerAgent = C->createAgent( "Logger Agent", DeluxeAgent::D( [&ScoreWriter](std::pair Score) -> Optional { if (Score.second) { // The state of \p ScoreWriter is not checked, expecting good. ScoreWriter << Score.first; } return {}; })); -*/ + */ // // Connect the high-level agent to the logger agent. // LOG_INFO("Connect the high-level agent to the logger agent."); /// C->connectAgents(LoggerAgent, 0, BodyAgent, "Body Agent Channel"); // // Do simulation. // LOG_INFO("Setting up and performing simulation."); // // Initialize deluxe context for simulation. // - C->initializeSimulation(); + // C->initializeSimulation(); // // Open CSV files and register them for their corresponding sensors. // // // Simulate. // /// C->simulate(NumberOfSimulationCycles); return 0; }