use crate::types::AltitudeSettings;
#[derive(Debug, Clone)]
pub struct AltitudeEstimator {
settings: AltitudeSettings,
altitude: f32,
velocity: f32,
accel_bias: f32,
baro_residual: f32,
reference_set: bool,
}
impl AltitudeEstimator {
pub fn new() -> Self {
Self::with_settings(AltitudeSettings::default())
}
pub fn with_settings(settings: AltitudeSettings) -> Self {
Self {
settings,
altitude: 0.0,
velocity: 0.0,
accel_bias: 0.0,
baro_residual: 0.0,
reference_set: false,
}
}
pub fn reset(&mut self, baro_altitude: f32) {
self.altitude = baro_altitude;
self.velocity = 0.0;
self.baro_residual = 0.0;
self.reference_set = true;
}
pub fn update(&mut self, vertical_accel: f32, baro_altitude: f32, dt: f32) {
if !self.reference_set {
self.reset(baro_altitude);
return;
}
let residual = baro_altitude - self.altitude;
let corrected_accel = vertical_accel - self.accel_bias;
self.velocity += (corrected_accel + self.settings.velocity_gain * residual) * dt;
self.altitude += (self.velocity + self.settings.position_gain * residual) * dt;
self.accel_bias -= self.settings.bias_gain * residual * dt;
self.baro_residual = residual;
}
pub fn altitude(&self) -> f32 {
self.altitude
}
pub fn vertical_velocity(&self) -> f32 {
self.velocity
}
pub fn accel_bias(&self) -> f32 {
self.accel_bias
}
pub fn baro_residual(&self) -> f32 {
self.baro_residual
}
}
impl Default for AltitudeEstimator {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
#[path = "altitude_tests.rs"]
mod tests;