#[derive(Clone, Debug)]
pub struct FirstOrderLowpassFilter {
kf: f64,
x1: f64,
}
impl FirstOrderLowpassFilter {
pub fn new(fc: f64, dt: f64, x1: f64) -> Self {
let kf =
2.0 * std::f64::consts::PI * fc * dt / (1.0 + 2.0 * std::f64::consts::PI * fc * dt);
Self { kf, x1 }
}
pub fn apply(&mut self, x: f64) -> f64 {
self.x1 = (1.0 - self.kf) * self.x1 + self.kf * x;
if self.x1.is_nan() {
self.x1 = 0.0;
}
self.x1
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_lowpass_filter_creation() {
let fc = 5.0;
let dt = 0.02;
let filter = FirstOrderLowpassFilter::new(fc, dt, 0.0);
assert_eq!(filter.kf, 0.38586954509503757);
assert_eq!(filter.x1, 0.0);
}
#[test]
fn test_lowpass_filter_application() {
let fc = 5.0;
let dt = 0.02;
let mut filter = FirstOrderLowpassFilter::new(fc, dt, 0.0);
let filtered_output = filter.apply(10.0);
assert_eq!(filtered_output, 3.8586954509503757);
let filtered_output2 = filter.apply(15.0);
assert_eq!(filtered_output2, 8.157785569057427);
}
#[test]
fn test_lowpass_filter_nan_reset() {
let fc = 5.0;
let dt = 0.02;
let mut filter = FirstOrderLowpassFilter::new(fc, dt, 0.0);
let filtered_output = filter.apply(std::f64::NAN);
assert_eq!(filtered_output, 0.0);
let filtered_output2 = filter.apply(15.0);
assert_eq!(filtered_output2, 5.788043176425564);
}
}