use crate::flight::PidConfig;
#[cfg(feature = "storage")]
use sequential_storage::map::PostcardValue;
#[cfg(feature = "serde")]
use {
postcard::experimental::max_size::MaxSize,
serde::{Deserialize, Serialize},
};
pub struct AutopilotRxLoss {}
#[allow(unused)]
impl AutopilotRxLoss {
pub const DISABLE: u8 = 0; pub const CONTINUE: u8 = 1; pub const LAND: u8 = 2; }
pub struct AutopilotYawMode {}
#[allow(unused)]
impl AutopilotYawMode {
pub const VELOCITY: u8 = 0; pub const BEARING: u8 = 1; pub const HYBRID: u8 = 2; pub const FIXED: u8 = 3; pub const DAMPENER: u8 = 4; }
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize, MaxSize))]
pub struct AutopilotConfig {
pub landing_altitude_m: u8, pub hover_throttle: u16, pub throttle_min: u16,
pub throttle_max: u16,
pub altitude_pid: PidConfig,
pub position_pid: PidConfig,
pub position_i_i: u8,
pub position_a: u8,
pub position_cutoff: u8,
pub max_angle: u8,
pub velocity_control_enable: u8, pub velocity_pid: PidConfig,
pub velocity_drag_coeff: u16, pub max_velocity_cmps: u16,
pub waypoint_arrival_radius_cm: u16, pub waypoint_hold_radius_cm: u16, pub stick_deadband: u16, pub throttle_deadband: u16,
pub yaw_mode: u8,
pub yaw_pid: PidConfig, pub max_yaw_rate_dps: u16, pub min_forward_velocity_cmps: u16,
pub velocity_buildup_max_pitch: u8,
pub max_turn_rate_dps: u8, pub hold_orbit_radius_cm: u16, pub hold_figure8_width_cm: u16,
pub landing_descent_rate: u8, pub landing_detection_time: u8, pub landing_spiral_enable: u8, pub landing_spiral_radius: u16, pub landing_spiral_rate: u8, pub landing_velocity_threshold: u8, pub landing_throttle_threshold: u16,
pub l1_enable: u8, pub l1_period: u16, pub l1_min_lookahead: u16, pub l1_max_lookahead: u16, pub l1_max_cross_track_error: u16, pub l1_turn_rate: u8,
pub min_nav_altitude_m: u8,
pub rx_loss_policy: u8,
pub max_distance_from_home_m: u8, pub geofence_action: u8,
}
#[cfg(feature = "storage")]
impl PostcardValue<'_> for AutopilotConfig {}
impl Default for AutopilotConfig {
fn default() -> Self {
Self::new()
}
}
impl AutopilotConfig {
pub const fn new() -> Self {
Self {
landing_altitude_m: 4,
hover_throttle: 1275,
throttle_min: 1100,
throttle_max: 1900,
altitude_pid: PidConfig { kp: 15, ki: 15, kd: 15, ks: 0, kk: 15 },
position_pid: PidConfig { kp: 30, ki: 30, kd: 30, ks: 0, kk: 30 },
position_i_i: 30,
position_a: 30,
position_cutoff: 30,
max_angle: 50,
velocity_control_enable: 1,
velocity_pid: PidConfig { kp: 50, ki: 10, kd: 5, ks: 0, kk: 0 },
velocity_drag_coeff: 50, max_velocity_cmps: 1000,
waypoint_arrival_radius_cm: 500, waypoint_hold_radius_cm: 200, stick_deadband: 50, throttle_deadband: 50,
yaw_mode: AutopilotYawMode::VELOCITY,
yaw_pid: PidConfig { kp: 0, ki: 0, kd: 0, ks: 0, kk: 0 },
max_yaw_rate_dps: 0,
min_forward_velocity_cmps: 0,
velocity_buildup_max_pitch: 0,
max_turn_rate_dps: 0,
hold_orbit_radius_cm: 0,
hold_figure8_width_cm: 0,
landing_descent_rate: 0,
landing_detection_time: 0,
landing_spiral_enable: 0,
landing_spiral_radius: 0,
landing_spiral_rate: 0,
landing_velocity_threshold: 0,
landing_throttle_threshold: 0,
l1_enable: 0,
l1_period: 0,
l1_min_lookahead: 0,
l1_max_lookahead: 0,
l1_max_cross_track_error: 0,
l1_turn_rate: 0,
min_nav_altitude_m: 0,
rx_loss_policy: 0,
max_distance_from_home_m: 0,
geofence_action: 0,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize, MaxSize))]
pub struct PositionHoldConfig {
pub deadband: u8,
pub position_source: u8,
pub optical_flow_quality_min: u8,
pub optical_flow_max_range_cm: u16,
}
#[cfg(feature = "storage")]
impl PostcardValue<'_> for PositionHoldConfig {}
impl Default for PositionHoldConfig {
fn default() -> Self {
Self::new()
}
}
#[allow(unused)]
impl PositionHoldConfig {
pub const SOURCE_AUTO: u8 = 0;
pub const SOURCE_GPS_ONLY: u8 = 1;
pub const SOURCE_OPTICAL_FLOW_ONLY: u8 = 2;
pub const fn new() -> Self {
Self { deadband: 0, position_source: 0, optical_flow_quality_min: 0, optical_flow_max_range_cm: 0 }
}
}
#[cfg(test)]
mod test_traits {
use super::*;
fn _is_normal<T: Sized + Send + Sync + Unpin>() {}
fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
#[cfg(feature = "serde")]
fn is_serde<T: Serialize + MaxSize + for<'a> Deserialize<'a>>() {}
#[cfg(feature = "storage")]
fn is_storage<T: for<'a> PostcardValue<'a>>() {}
#[test]
fn normal_types() {
is_full::<AutopilotConfig>();
is_full::<PositionHoldConfig>();
#[cfg(feature = "serde")]
is_serde::<AutopilotConfig>();
#[cfg(feature = "serde")]
is_serde::<PositionHoldConfig>();
}
#[cfg(feature = "serde")]
#[test]
fn serde_types() {
is_serde::<AutopilotConfig>();
is_serde::<PositionHoldConfig>();
}
#[cfg(feature = "storage")]
#[test]
fn storage_types() {
is_storage::<AutopilotConfig>();
is_storage::<PositionHoldConfig>();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let config = AutopilotConfig::new();
assert_eq!(4, config.landing_altitude_m);
}
}