Commit 77956e9f authored by Andreas Schmidt's avatar Andreas Schmidt
Browse files

artifact submission

parent cbc6d9ea
# Live-in-Conserts
# [EDCC 2021] Live in ConSerts: Model-Driven Runtime Safety Assurance on Microcontrollers, Edge, and Cloud
Live in ConSerts: Model-Driven Runtime Safety Assurance on Microcontrollers, Edge, and Cloud
\ No newline at end of file
## Code Synthesis
* Input Model File: [edcc2021.xml](./edcc2021.xml)
* Compile Command: `conserts compile --ros -i .\edcc2021.xml -o .`
* Output Rust Crate: [consert_edcc2021](./consert_edcc2021)
## Evaluations on Embedded Microcontroller
### Inference Time Results
![Inference Time](./time.svg)
### Binary Size Results
![Binary Size](./size.svg)
/target
\ No newline at end of file
cmake_minimum_required(VERSION 3.0.2)
project(consert_edcc2021)
find_package(catkin REQUIRED COMPONENTS
message_generation
)
generate_messages()
catkin_package()
\ No newline at end of file
This diff is collapsed.
[package]
name = "consert_edcc2021"
version = "0.1.0"
authors = ["ConSert <consert@iese.fraunhofer.de>"]
edition = "2018"
autobins = false
[[bin]]
name = "ros-monitor"
path = "src/bin/ros-monitor.rs"
[[bin]]
name = "test-plant"
path = "src/bin/test-plant.rs"
[dependencies]
heapless = "0.6.0"
[dependencies.uom]
version = "0.31.0"
default-features = false
features = ["f64", "si"]
[dependencies.crossbeam]
version = "0.7.3"
default-features = false
[dependencies.env_logger]
version = "0.7.1"
[dependencies.clap]
version = "2.33.2"
[dependencies.rosrust]
version = "0.9.4"
\ No newline at end of file
language = "C++"
include_guard = "CONSERTS_H"
\ No newline at end of file
float64 meter_per_second
\ No newline at end of file
bool fulfilled
\ No newline at end of file
bool fulfilled
\ No newline at end of file
bool fulfilled
\ No newline at end of file
bool fulfilled
\ No newline at end of file
<?xml version='1.0'?>
<package format='2'>
<name>consert_edcc2021</name>
<version>0.0.0</version>
<description>The consert-monitor package</description>
<maintainer email='consert@iese.fraunhofer.de'>ConSert</maintainer>
<license>TODO</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>message_generation</build_depend>
</package>
\ No newline at end of file
use clap::{App, Arg, SubCommand};
use consert_edcc2021::ros::RosMonitor;
use env_logger;
use uom::si::f64::*;
use uom::si::frequency::hertz;
fn main() {
env_logger::init();
let matches = App::new("ros-monitor")
.subcommand(
SubCommand::with_name("standalone").arg(
Arg::with_name("frequency")
.short("f")
.takes_value(true)
.default_value("1.0")
.help("frequency in Hz"),
),
)
.subcommand(
SubCommand::with_name("test")
.arg(
Arg::with_name("iterations")
.short("i")
.takes_value(true)
.default_value("3")
.help("Number of iterations"),
)
.arg(
Arg::with_name("frequency")
.short("f")
.takes_value(true)
.default_value("1.0")
.help("frequency in Hz"),
),
)
.get_matches();
if let Some(matches) = matches.subcommand_matches("standalone") {
let freq = Frequency::new::<hertz>(
matches
.value_of("frequency")
.unwrap()
.parse()
.expect("Invalid frequency value"),
);
RosMonitor::new().run_standalone(freq);
} else if let Some(matches) = matches.subcommand_matches("test") {
let freq = Frequency::new::<hertz>(
matches
.value_of("frequency")
.unwrap()
.parse()
.expect("Invalid frequency value"),
);
let iter: u32 = matches
.value_of("iterations")
.unwrap()
.parse()
.expect("Invalid iterations value");
RosMonitor::new().run_test(freq, iter);
}
}
use env_logger;
use rosrust;
fn main() {
env_logger::init();
rosrust::init("test_plant_consert_edcc2021");
let approximation_speed_of_detected_object =
rosrust::publish("consert_edcc2021/ApproximationSpeedOfDetectedObject", 1).unwrap();
let far_zone_unoccupied = rosrust::publish("consert_edcc2021/FarZoneUnoccupied", 1).unwrap();
let installation_approved_by_health_and_safety_engineer = rosrust::publish(
"consert_edcc2021/InstallationApprovedByHealthAndSafetyEngineer",
1,
)
.unwrap();
let near_zone_unoccupied = rosrust::publish("consert_edcc2021/NearZoneUnoccupied", 1).unwrap();
let rate = rosrust::rate(4.0);
while rosrust::is_ok() {
{
let msg =
consert_edcc2021::msg::consert_edcc2021::ApproximationSpeedOfDetectedObject::random(
);
rosrust::ros_info!("Publishing: {:#?}", msg);
approximation_speed_of_detected_object.send(msg).unwrap();
}
{
let msg = consert_edcc2021::msg::consert_edcc2021::FarZoneUnoccupied::random();
rosrust::ros_info!("Publishing: {:#?}", msg);
far_zone_unoccupied.send(msg).unwrap();
}
{
let msg = consert_edcc2021 :: msg :: consert_edcc2021 :: InstallationApprovedByHealthAndSafetyEngineer :: random () ;
rosrust::ros_info!("Publishing: {:#?}", msg);
installation_approved_by_health_and_safety_engineer
.send(msg)
.unwrap();
}
{
let msg = consert_edcc2021::msg::consert_edcc2021::NearZoneUnoccupied::random();
rosrust::ros_info!("Publishing: {:#?}", msg);
near_zone_unoccupied.send(msg).unwrap();
}
rate.sleep();
}
}
#![allow(non_snake_case)]
use crate::properties::*;
#[derive(Debug, Copy, Clone)]
pub struct RuntimeEvidence {
pub(crate) RtE3: bool,
pub(crate) RtE4: bool,
pub(crate) RtE5: bool,
pub(crate) RtE6: bool,
pub(crate) RtE7: bool,
}
impl RuntimeEvidence {
pub fn from(runtime_properties: &RuntimeProperties) -> RuntimeEvidence {
let RtE3 = {
use crate::properties::NearZoneUnoccupied::*;
match &runtime_properties.near_zone_unoccupied {
Unknown => false,
Known(value) => *value,
}
};
let RtE4 = {
use crate::properties::ApproximationSpeedOfDetectedObject::*;
match &runtime_properties.approximation_speed_of_detected_object {
Unknown => false,
Known(value) => {
(0f64..=1f64).contains(&value.get::<uom::si::velocity::meter_per_second>())
}
}
};
let RtE5 = {
use crate::properties::InstallationApprovedByHealthAndSafetyEngineer::*;
match &runtime_properties.installation_approved_by_health_and_safety_engineer {
Unknown => false,
Known(value) => *value,
}
};
let RtE6 = {
use crate::properties::FarZoneUnoccupied::*;
match &runtime_properties.far_zone_unoccupied {
Unknown => false,
Known(value) => *value,
}
};
let RtE7 = {
use crate::properties::ApproximationSpeedOfDetectedObject::*;
match &runtime_properties.approximation_speed_of_detected_object {
Unknown => false,
Known(value) => {
(0f64..=2f64).contains(&value.get::<uom::si::velocity::meter_per_second>())
}
}
};
RuntimeEvidence {
RtE3,
RtE4,
RtE5,
RtE6,
RtE7,
}
}
}
impl core::default::Default for RuntimeEvidence {
fn default() -> Self {
RuntimeEvidence::from(&RuntimeProperties::unknown())
}
}
#![allow(non_camel_case_types)]
#![allow(unused_doc_comments)]
use super::evidence::RuntimeEvidence;
#[doc = "Near Environment Unoccupied by Humans"]
pub struct SG4;
impl SG4 {
pub fn evaluate(runtime_evidence: &RuntimeEvidence) -> bool {
{
let c0 = {
#[doc = "Near Zone Unoccupied."]
let c0 = runtime_evidence.RtE3;
#[doc = "Approximation Speed of Detected Object <= 1m/s"]
let c1 = runtime_evidence.RtE4;
c0 || c1
};
#[doc = "Installation Approved by Health and Safety Engineer"]
let c1 = runtime_evidence.RtE5;
c0 && c1
}
}
}
#[doc = "Far Environment Unoccupied by Humans"]
pub struct SG5;
impl SG5 {
pub fn evaluate(runtime_evidence: &RuntimeEvidence) -> bool {
{
let c0 = {
#[doc = "Far Zone Unoccupied."]
let c0 = runtime_evidence.RtE6;
#[doc = "Approximation Speed of Detected Object <= 2m/s"]
let c1 = runtime_evidence.RtE7;
c0 || c1
};
#[doc = "Installation Approved by Health and Safety Engineer"]
let c1 = runtime_evidence.RtE5;
c0 && c1
}
}
}
pub mod evidence;
pub mod guarantees;
pub mod monitor;
pub mod msg;
pub mod prelude;
pub mod properties;
pub mod ros;
pub use uom;
#![allow(non_snake_case)]
use crate::evidence::RuntimeEvidence;
use crate::properties::*;
use heapless::HistoryBuffer;
#[derive(Debug, Default)]
struct PopCount {
t: usize,
f: usize,
}
#[derive(Debug, Default)]
pub struct RuntimeEvidencePopCount {
RtE3: PopCount,
RtE4: PopCount,
RtE5: PopCount,
RtE6: PopCount,
RtE7: PopCount,
}
impl RuntimeEvidencePopCount {
fn from(evidence: &[RuntimeEvidence]) -> RuntimeEvidencePopCount {
let mut pop_count = RuntimeEvidencePopCount::default();
for evidence in evidence {
if evidence.RtE3 {
pop_count.RtE3.t += 1;
} else {
pop_count.RtE3.f += 1;
}
if evidence.RtE4 {
pop_count.RtE4.t += 1;
} else {
pop_count.RtE4.f += 1;
}
if evidence.RtE5 {
pop_count.RtE5.t += 1;
} else {
pop_count.RtE5.f += 1;
}
if evidence.RtE6 {
pop_count.RtE6.t += 1;
} else {
pop_count.RtE6.f += 1;
}
if evidence.RtE7 {
pop_count.RtE7.t += 1;
} else {
pop_count.RtE7.f += 1;
}
}
pop_count
}
fn majority_vote(&self) -> RuntimeEvidence {
RuntimeEvidence {
RtE3: (self.RtE3.t > self.RtE3.f),
RtE4: (self.RtE4.t > self.RtE4.f),
RtE5: (self.RtE5.t > self.RtE5.f),
RtE6: (self.RtE6.t > self.RtE6.f),
RtE7: (self.RtE7.t > self.RtE7.f),
}
}
}
pub struct Monitor {
values: HistoryBuffer<RuntimeEvidence, heapless::consts::U3>,
}
impl Default for Monitor {
fn default() -> Self {
Self {
values: HistoryBuffer::new(),
}
}
}
impl Monitor {
pub fn new() -> Monitor {
Monitor::default()
}
pub fn add_sample(&mut self, value: RuntimeProperties) {
let evidence = RuntimeEvidence::from(&value);
self.values.write(evidence);
}
pub fn get_sample(&mut self) -> RuntimeEvidence {
let evidence = self.values.as_slice();
RuntimeEvidencePopCount::from(evidence).majority_vote()
}
}
rosrust::rosmsg_include!(
rosgraph_msgs / Clock,
consert_edcc2021 / ApproximationSpeedOfDetectedObject,
consert_edcc2021 / FarZoneUnoccupied,
consert_edcc2021 / InstallationApprovedByHealthAndSafetyEngineer,
consert_edcc2021 / NearZoneUnoccupied,
consert_edcc2021 / SG4,
consert_edcc2021 / SG5
);
struct Bool;
impl Bool {
pub fn random() -> bool {
true
}
}
struct Float64;
impl Float64 {
pub fn random() -> f64 {
0.75
}
}
impl consert_edcc2021::ApproximationSpeedOfDetectedObject {
pub fn random() -> consert_edcc2021::ApproximationSpeedOfDetectedObject {
consert_edcc2021::ApproximationSpeedOfDetectedObject {
meter_per_second: Float64::random(),
}
}
}
impl consert_edcc2021::FarZoneUnoccupied {
pub fn random() -> consert_edcc2021::FarZoneUnoccupied {
consert_edcc2021::FarZoneUnoccupied {
fulfilled: Bool::random(),
}
}
}
impl consert_edcc2021::InstallationApprovedByHealthAndSafetyEngineer {
pub fn random() -> consert_edcc2021::InstallationApprovedByHealthAndSafetyEngineer {
consert_edcc2021::InstallationApprovedByHealthAndSafetyEngineer {
fulfilled: Bool::random(),
}
}
}
impl consert_edcc2021::NearZoneUnoccupied {
pub fn random() -> consert_edcc2021::NearZoneUnoccupied {
consert_edcc2021::NearZoneUnoccupied {
fulfilled: Bool::random(),
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment