use super::DecodedBds;
#[must_use]
pub fn penalty(decoded: &DecodedBds) -> f64 {
let mut p = 0.0_f64;
match decoded {
DecodedBds::Bds50(t) => {
if let (Some(tas), Some(gs)) = (t.true_airspeed, t.groundspeed) {
p -= (f64::from(tas) - f64::from(gs)).abs() / 100.0;
}
if let (Some(roll), Some(rate)) = (t.roll_angle, t.track_rate) {
if roll.abs() > 5.0
&& rate.abs() > 0.3
&& (roll > 0.0) != (rate > 0.0)
{
p -= 2.0;
}
}
}
DecodedBds::Bds60(h) => {
if let (Some(ias), Some(mach)) =
(h.indicated_airspeed, h.mach_number)
{
if mach > 0.0 {
let ratio = f64::from(ias) / mach;
if !(250.0..=800.0).contains(&ratio) {
p -= 3.0;
}
}
}
}
_ => {}
}
p
}
#[cfg(test)]
mod tests {
use super::*;
use crate::decode::bds::{decode_bds, DecodedBds};
use hexlit::hex;
#[test]
fn cruise_bds50_small_penalty() {
let payload = hex!("A0001838CA3E51B250C38D000000");
let mb = &payload[4..11];
if let Ok(d @ DecodedBds::Bds50(_)) = decode_bds(mb, 0x50) {
let p = penalty(&d);
assert!(p > -1.0, "penalty for cruise BDS 50 = {p}");
}
}
#[test]
fn empty_decoded_bds_no_penalty() {
let mb = hex!("30000000000000");
if let Ok(d) = decode_bds(&mb, 0x30) {
assert_eq!(penalty(&d), 0.0);
}
}
}