Skip to content

Commit

Permalink
more bound options
Browse files Browse the repository at this point in the history
  • Loading branch information
andtsa committed Jul 11, 2024
1 parent e897e50 commit 2c38130
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 48 deletions.
31 changes: 27 additions & 4 deletions app/src/core/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
mod batteries;
mod sources;

use crate::Datatype;
use crate::ValueCheckResult;
use crate::DataReceiver;
use crate::DataSender;
use crate::Event;
use crate::EventSender;

use crate::Datapoint;
/// ## Individual handling of datapoints
/// A lot of the subsystems on the pod use their own "encoding" for data.
/// In order to make a reasonable matching between semantic meaning of
Expand All @@ -25,11 +26,33 @@ pub async fn data_middle_step(
let data = incoming.receive().await;

// 1. check thresholds
if data.datatype.check_bounds(data.value) {
event_sender.send(Event::ValueOutOfBounds).await;
match data.datatype.check_bounds(data.value) {
ValueCheckResult::Fine => {},
ValueCheckResult::Warn => {
outgoing.send(value_warning(data.datatype, data.value)).await;
}
ValueCheckResult::Error => {
outgoing.send(value_error(data.datatype, data.value)).await;
}
ValueCheckResult::BrakeNow => {
event_sender.send(Event::ValueOutOfBounds).await;
outgoing.send(value_critical(data.datatype, data.value)).await;
}
}
// 2. check specific data types

outgoing.send(data).await;
}
}

fn value_warning(dt: Datatype, v: u64) -> Datapoint {
Datapoint::new(Datatype::ValueWarning, dt.to_id() as u64, v)
}

fn value_error(dt: Datatype, v: u64) -> Datapoint {
Datapoint::new(Datatype::ValueError, dt.to_id() as u64, v)
}

fn value_critical(dt: Datatype, v: u64) -> Datapoint {
Datapoint::new(Datatype::ValueCausedBraking, dt.to_id() as u64, v)
}
2 changes: 2 additions & 0 deletions app/src/core/data/sources.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(unused)]

use crate::Datatype;

pub enum Subsystems {
Expand Down
66 changes: 55 additions & 11 deletions config/datatypes.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,52 @@
## -
##### -----
# Format for new datatypes:
# ```
# [[Datatype]]
# name = "YourNewDatatypeName"
# id = 42 # must be unique. code will not compile if there is a collision. Values can be from 0-2047, or 0x000 to 0x7FF.
# upper = 100 # an upper bound for the values of this datatype.
# lower = 12 # a lower bound for the values of this datatype.
# id = 42 # must be unique.
# # the code will not compile if there is a collision.
# # Values can be from 0-2047, or 0x000 to 0x7FF.
# ```
# when a datapoint is received there's a check if
# lower <= value <= upper
# If this is false, then an emergency brake is triggered.
# Keep in mind that lower, value, and upper are all of type u64.
# This means that:
# - everything has a lower bound of 0
# - careful when setting bounds for floating point numbers.
#
# Limits:
# ---------
# Every time a datapoint is received by the main pcb,
# it checks the limits of that datatype, and produces
# an error if any of the limits are surpassed.
#
# There are 3 severities for surpassing bounds:
# - warn: the associated field on the ground station will turn yellow
# - err: the associated field on the ground station will turn red and blink
# - brake: critical limit, the main pcb will immediately deploy emergency brakes
#
# Not specifying a specific limit means nothing will happen.
#
# ```
[[Datatype]]
name = "Example1"
id = 50
lower = 5
upper = { warn = 50, err = 60, brake = 100 }
# ```
# as you can see, you can either specify *one* limit (e.g. `lower = 5`),
# which if surpassed will function equivalent to `warn`, just informing the
# ground station operator,
# or you can specify multiple limits of different severities (as in `upper = { ... }`).
#
# If you don't want a certain severity to ever happen,
# just don't include the field:
# ```
# [[Datatype]]
# name = "Example2"
# id = 51
# lower = { warn = 10, err = 4, brake = 3 }
# ```
# For this one, there will be
# - no upper limit,
# - a warning when it's below 10
# - a (ground station) error when it's below 4,
# - and no emergency braking at any point.


[[Datatype]]
name = "DefaultDatatype"
Expand Down Expand Up @@ -826,4 +859,15 @@ id = 0x168
name = "DataHash"
id = 0x169

[[Datatype]]
name = "ValueError"
id = 0x16a

[[Datatype]]
name = "ValueWarning"
id = 0x16b

[[Datatype]]
name = "ValueCausedBraking"
id = 0x16c

2 changes: 1 addition & 1 deletion gs/station/src/tests/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ fn import_procedures() {
assert_eq!(example[2], "DH08.PROC.SC.x");
assert_eq!(example[3], "Kiko\nKiril\n");
assert_eq!(example[4], "Andreas\n");
assert_eq!(example[5], "1. I refuse to elaborate.\n2. :)\n3. if in trouble just call me\njust text is also fine in a procedure.\n");
assert_eq!(example[5], "<p>1. I refuse to elaborate.</p><br>\n<p>2. :)</p><br>\n<p>3. if in trouble just call me</p><br>\n<p>just text is also fine in a procedure.</p><br>");
}
1 change: 1 addition & 0 deletions util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ edition = "2021"
local-ip-address = "=0.6.1"
serde = { version = "1.0.201", features = ["derive"] }
toml = "0.8.12"

168 changes: 136 additions & 32 deletions util/src/datatypes.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#![allow(non_snake_case, non_camel_case_types)]

use std::fmt::Display;
use std::fs;
use std::hash::DefaultHasher;
use std::hash::Hash;
use std::hash::Hasher;

use serde::Deserialize;
use std::fmt::Formatter;
const NONE: fn() -> Limit = || Limit::No;

#[derive(Deserialize, Hash)]
pub struct Config {
Expand All @@ -16,8 +17,42 @@ pub struct Config {
pub struct Datatype {
pub name: String,
pub id: u16,
pub lower: Option<u64>,
pub upper: Option<u64>,
#[serde(default = "NONE")]
pub lower: Limit,
#[serde(default = "NONE")]
pub upper: Limit,
}

#[derive(Hash, Clone, Copy)]
pub enum Limit {
No,
Single(u64),
Multiple(Severities)
}

impl Display for Limit {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match *self {
Limit::No => write!(f, "Limit::No"),
Limit::Single(x) => write!(f, "Limit::Single({x})"),
Limit::Multiple(y) => {
write!(f,
"Limit::Multiple(Severities {{ warn: {}, err: {}, brake: {} }})",
y.warn.map(|x| format!("Some({x})")).unwrap_or("None".into()),
y.err.map(|x| format!("Some({x})")).unwrap_or("None".into()),
y.brake.map(|x| format!("Some({x})")).unwrap_or("None".into()),
)
}
}
}
}


#[derive(Deserialize, Hash, Clone, Copy)]
pub struct Severities {
pub warn: Option<u64>,
pub err: Option<u64>,
pub brake: Option<u64>,
}

pub fn get_data_config(path: &str) -> Config {
Expand Down Expand Up @@ -50,39 +85,64 @@ pub fn generate_datatypes(path: &str, drv: bool) -> String {
match_from_id.push_str(&format!(" {} => Datatype::{},\n", dtype.id, dtype.name));
from_str.push_str(&format!(" {:?} => Datatype::{},\n", dtype.name, dtype.name));
bounds.push_str(&format!(
" Datatype::{} => {} {} {},\n",
" Datatype::{} => ({}, {}),\n",
dtype.name,
dtype.lower.map(|x| format!("other >= {}u64", x)).unwrap_or("".to_string()),
if dtype.lower.is_some() && dtype.upper.is_some() {
"&&".to_string()
} else {
"".to_string()
},
dtype.upper.map(|x| format!("other <= {}u64", x)).unwrap_or_else(|| {
if dtype.lower.is_none() && dtype.upper.is_none() {
"true".to_string()
} else {
"".to_string()
}
}),
dtype.upper,
dtype.lower,
));
if let Some(l) = dtype.lower {
if l == 0 {
panic!(
"
You set a lower bound of 0 for {}. \
Since all values are treated as u64, \
values less than 0 are impossible.
Please ommit specifying this to keep the config clean :)
",
dtype.name
);
}
}
// bounds.push_str(&format!(
// " Datatype::{} => {} {} {},\n",
// dtype.name,
// dtype.lower.map(|x| format!("other >= {}u64", x)).unwrap_or("".to_string()),
// if dtype.lower.is_some() && dtype.upper.is_some() {
// "&&".to_string()
// } else {
// "".to_string()
// },
// dtype.upper.map(|x| format!("other <= {}u64", x)).unwrap_or_else(|| {
// if dtype.lower.is_none() && dtype.upper.is_none() {
// "true".to_string()
// } else {
// "".to_string()
// }
// }),
// ));
// if let Some(l) = dtype.lower {
// if l == 0 {
// panic!(
// "
// You set a lower bound of 0 for {}. \
// Since all values are treated as u64, \
// values less than 0 are impossible.
// Please ommit specifying this to keep the config clean :)
// ",
// dtype.name
// );
// }
// }
}

format!(
"\n
pub enum Limit {{
No,
Single(u64),
Multiple(Severities)
}}
pub struct Severities {{
pub warn: Option<u64>,
pub err: Option<u64>,
pub brake: Option<u64>,
}}
pub enum ValueCheckResult {{
Fine,
Warn,
Error,
BrakeNow,
}}
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
{}
Expand Down Expand Up @@ -113,11 +173,55 @@ impl Datatype {{
}}
pub fn check_bounds(&self, other: u64) -> bool {{
pub fn bounds(&self) -> (Limit, Limit) {{
match *self {{
{}
}}
}}
pub fn check_bounds(&self, value: u64) -> ValueCheckResult {{
let (up, low) = self.bounds();
let ok_up = match up {{
Limit::No => 0,
Limit::Single(x) => if value > x {{ 1 }} else {{ 0 }},
Limit::Multiple(Severities {{
warn: a,
err: b,
brake: c,
}}) => {{
if let Some(cc) = c {{
if value > cc {{ 100 }} else {{ 0 }}
}} else if let Some(bb) = b {{
if value > bb {{ 10 }} else {{ 0 }}
}} else if let Some(aa) = a {{
if value > aa {{ 1 }} else {{ 0 }}
}} else {{ 0 }}
}}
}};
let ok_low = match low {{
Limit::No => 0,
Limit::Single(x) => if value < x {{ 1 }} else {{ 0 }},
Limit::Multiple(Severities {{
warn: a,
err: b,
brake: c,
}}) => {{
if let Some(cc) = c {{
if value < cc {{ 100 }} else {{ 0 }}
}} else if let Some(bb) = b {{
if value < bb {{ 10 }} else {{ 0 }}
}} else if let Some(aa) = a {{
if value < aa {{ 1 }} else {{ 0 }}
}} else {{ 0 }}
}}
}};
match ok_up + ok_low {{
0 => ValueCheckResult::Fine,
1..10 => ValueCheckResult::Warn,
10..100 => ValueCheckResult::Error,
_ => ValueCheckResult::BrakeNow,
}}
}}
}}
",
if drv {
Expand Down
1 change: 1 addition & 0 deletions util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod events;
pub mod info;
pub mod ip;
mod shared;
pub mod limits;

pub fn check_ids(dp: &str, cp: &str, ep: &str) -> Vec<u16> {
let mut ids = vec![];
Expand Down
Loading

0 comments on commit 2c38130

Please sign in to comment.