Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F5298467
ccam.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
15 KB
Referenced Files
None
Subscribers
None
ccam.cpp
View Options
//===-- 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/FunctionAbstractions.hpp"
#include
<iostream>
#include
"rosa/config/version.h"
#include
"rosa/agent/SignalStateDetector.hpp"
#include
"rosa/agent/SystemStateDetector.hpp"
#include
"rosa/deluxe/DeluxeContext.hpp"
#include
"rosa/support/csv/CSVReader.hpp"
#include
"rosa/support/csv/CSVWriter.hpp"
#include
"rosa/deluxe/DeluxeTuple.hpp"
#include
<fstream>
#include
<limits>
#include
<memory>
#include
<streambuf>
#include
"configuration.h"
#include
"statehandlerutils.h"
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'
;
// ONLYFORTEST
// std::cout << "Starting?" << std::endl;
// getchar();
// TSETROFYLNO
//
// 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!
\n
Usage:
\n\t
ccam 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
;
}
// ONLYFORTEST
// Maxi: Do we need the following line? I outcommented it because I think it
// is unnecessary.
// std::string InputFilePath, OutputFilePath;
// TSETROFYLNO
//
// Create a CCAM context.
//
LOG_INFO
(
"Creating Context"
);
std
::
unique_ptr
<
DeluxeContext
>
ContextCCAM
=
DeluxeContext
::
create
(
AppName
);
//
// Create following function.
// ____________
// /
// /
// __________/
//
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.
// ____________
// \
// \
// \__________
//
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 DeluxeAgent with SystemStateDetector functionality.
//
LOG_INFO
(
"Create SystemStateDetector agent."
);
AgentHandle
SystemStateDetectorAgent
=
createSystemStateDetectorAgent
(
ContextCCAM
,
"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
);
ContextCCAM
->
setExecutionPolicy
(
SystemStateDetectorAgent
,
DeluxeExecutionPolicy
::
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.
//
// @Benedikt: why do we use "std::set<size_t>" above (positions for master
// agent and here "std::vector"?
//
LOG_INFO
(
"Creating sensors, SignalStateDetector functionalities and their "
"Abstractions."
);
std
::
vector
<
AgentHandle
>
Sensors
;
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
;
std
::
vector
<
std
::
shared_ptr
<
StepFunction
<
float
,
float
>>>
NumOfSamplesMatchFunctions
;
std
::
vector
<
std
::
shared_ptr
<
StepFunction
<
float
,
float
>>>
NumOfSamplesMismatchFunctions
;
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 deluxe sensors.
//
Sensors
.
emplace_back
(
ContextCCAM
->
createSensor
<
float
>
(
SignalConfiguration
.
Name
+
"_Sensor"
));
//
// Create following function(s).
// ____________
// / \
// / \
// __________/ \__________
//
//
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).
// ____________ ____________
// \ /
// \ /
// \__________/
//
//
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).
// ____________
// / \
// / \
// __________/ \__________
//
//
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).
// ____________ ____________
// \ /
// \ /
// \__________/
//
//
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
));
//
//
//
//
//
//
NumOfSamplesMatchFunctions
.
emplace_back
(
new
StepFunction
<
float
,
float
>
(
1.0f
/
SignalConfiguration
.
SampleHistorySize
,
StepDirection
::
StepUp
));
NumOfSamplesMismatchFunctions
.
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
(),
SampleMatchesFunctions
.
back
(),
SampleMismatchesFunctions
.
back
(),
NumOfSamplesMatchFunctions
.
back
(),
NumOfSamplesMismatchFunctions
.
back
(),
SignalIsDriftingFunctions
.
back
(),
SignalIsStableFunctions
.
back
(),
SignalConfiguration
.
SampleHistorySize
,
SignalConfiguration
.
DABSize
,
SignalConfiguration
.
DABHistorySize
));
//
// Create low-level deluxe agents
//
SignalStateDetectorAgents
.
push_back
(
createSignalStateDetectorAgent
(
ContextCCAM
,
SignalConfiguration
.
Name
,
SignalStateDetectors
.
back
()));
ContextCCAM
->
setExecutionPolicy
(
SignalStateDetectorAgents
.
back
(),
DeluxeExecutionPolicy
::
decimation
(
AppConfig
.
DownsamplingRate
));
//
// Connect sensors to low-level agents.
//
LOG_INFO
(
"Connect sensors to their corresponding low-level agents."
);
ContextCCAM
->
connectSensor
(
SignalStateDetectorAgents
.
back
(),
0
,
Sensors
.
back
(),
SignalConfiguration
.
Name
+
"_Sensor ->"
+
SignalConfiguration
.
Name
+
"_SignalStateDetector_Agent-Channel"
);
ContextCCAM
->
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,"
;
OutputCSV
<<
"State Condition,"
;
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
<
DeluxeTuple
<
unit_t
>>
;
using
Handler
=
std
::
function
<
Result
(
Input
)
>
;
std
::
string
Name
=
"Logger Agent"
;
AgentHandle
LoggerAgent
=
ContextCCAM
->
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."
);
ContextCCAM
->
connectAgents
(
LoggerAgent
,
0
,
SystemStateDetectorAgent
,
"SystemStateDetector Channel"
);
//
// Only log if the SystemStateDetector actually ran
//
ContextCCAM
->
setExecutionPolicy
(
LoggerAgent
,
DeluxeExecutionPolicy
::
awaitAll
({
0
}));
//
// Do simulation.
//
LOG_INFO
(
"Setting up and performing simulation."
);
//
// Initialize deluxe context for simulation.
//
ContextCCAM
->
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
;
for
(
auto
SignalConfiguration
:
AppConfig
.
SignalConfigurations
)
{
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
;
}
ContextCCAM
->
registerSensorValues
(
Sensors
.
at
(
i
),
csv
::
CSVIterator
<
float
>
(
DataFiles
.
at
(
i
)),
csv
::
CSVIterator
<
float
>
());
i
++
;
}
//
// Start simulation.
//
ContextCCAM
->
simulate
(
AppConfig
.
NumberOfSimulationCycles
);
return
0
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Apr 12, 11:36 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
307490
Default Alt Text
ccam.cpp (15 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment