#[allow(unused)]
use radio_controllers::{Rates, RcModes, RcSticks, RxFrame};
use simple_bitset::BitSet64;
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub struct RcControls {
pub tick_count: u32,
pub throttle_stick: f32,
pub roll_stick_dps: f32,
pub pitch_stick_dps: f32,
pub yaw_stick_dps: f32,
pub roll_stick_degrees: f32,
pub pitch_stick_degrees: f32,
pub controls_pwm: [u16; 4],
pub failsafe: u8,
}
const _: () = assert!(core::mem::size_of::<RcControls>() == 40);
impl Default for RcControls {
fn default() -> Self {
Self::new()
}
}
impl RcControls {
pub const fn new() -> Self {
Self {
tick_count: 0,
throttle_stick: 0.0,
roll_stick_dps: 0.0,
pitch_stick_dps: 0.0,
yaw_stick_dps: 0.0,
roll_stick_degrees: 0.0,
pitch_stick_degrees: 0.0,
controls_pwm: [0u16; 4],
failsafe: 0,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub struct RxMessage {
pub rc_modes: BitSet64,
pub rc_controls: RcControls,
}
const _: () = assert!(core::mem::size_of::<RxMessage>() == 48);
impl Default for RxMessage {
fn default() -> Self {
Self::new()
}
}
impl RxMessage {
pub const fn new() -> Self {
Self { rc_modes: BitSet64::new(), rc_controls: RcControls::new() }
}
}
impl RxMessage {
pub fn new_from(rx_frame: &RxFrame, rates: &Rates, rc_modes: &RcModes, tick_count: u32, failsafe: u8) -> RxMessage {
let sticks = RcSticks::from(*rx_frame);
let roll_stick_dps = rates.apply(Rates::ROLL, sticks.roll);
let pitch_stick_dps = rates.apply(Rates::PITCH, sticks.pitch);
let yaw_stick_dps = rates.apply(Rates::YAW, sticks.yaw);
let roll_stick_degrees = sticks.roll * rates.max_roll_angle_degrees;
let pitch_stick_degrees = sticks.pitch * rates.max_pitch_angle_degrees;
RxMessage {
rc_modes: rc_modes.active_modes,
rc_controls: RcControls {
tick_count,
throttle_stick: sticks.throttle,
roll_stick_dps,
pitch_stick_dps,
yaw_stick_dps,
roll_stick_degrees,
pitch_stick_degrees,
controls_pwm: [rx_frame.channels[0], rx_frame.channels[1], rx_frame.channels[2], rx_frame.channels[3]],
failsafe,
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn _is_normal<T: Sized + Send + Sync + Unpin>() {}
fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
#[test]
fn normal_types() {
is_full::<RxMessage>();
}
#[test]
fn sizeof() {
assert_eq!(48, core::mem::size_of::<RxMessage>());
}
}