use nalgebra::{Matrix2, Vector2};
#[derive(Copy, Clone, Debug)]
pub struct Kalman {
angle: f32, bias: f32, rate: f32, cov_error: Matrix2<f32>, k: Vector2<f32>, y: f32, s: f32, q_angle: f32, q_bias: f32, r_measure: f32, }
impl Kalman {
pub fn new() -> Self {
Kalman {
angle: 0.0,
bias: 0.0,
rate: 0.0,
cov_error: Matrix2::<f32>::identity(),
k: Vector2::<f32>::zeros(),
y: 0.0,
s: 0.0,
q_angle: 0.001,
q_bias: 0.003,
r_measure: 0.03
}
}
pub fn compute_angle(&mut self, new_angle: f32, new_rate: f32, dt: f32) {
self.rate = new_rate - self.bias;
self.angle += dt * self.rate;
self.cov_error[(0, 0)] += dt * (dt * self.cov_error[(1, 1)] - self.cov_error[(0, 1)] - self.cov_error[(1, 0)] + self.q_angle);
self.cov_error[(0, 1)] -= dt * self.cov_error[(1, 1)];
self.cov_error[(1, 0)] -= dt * self.cov_error[(1, 1)];
self.cov_error[(1, 1)] += self.q_bias * dt;
self.y = new_angle - self.angle;
self.s = self.cov_error[(0, 0)] + self.r_measure;
self.k[0] = self.cov_error[(0, 0)] / self.s;
self.k[1] = self.cov_error[(1, 0)] / self.s;
self.angle += self.k[0] * self.y;
self.bias += self.k[1] * self.y;
self.cov_error[(0, 0)] -= self.k[0] * self.cov_error[(0, 0)];
self.cov_error[(0, 1)] -= self.k[0] * self.cov_error[(0, 1)];
self.cov_error[(1, 0)] -= self.k[1] * self.cov_error[(0, 0)];
self.cov_error[(1, 1)] -= self.k[1] * self.cov_error[(0, 1)];
}
pub fn set_angle(&mut self, angle: f32) {
self.angle = angle;
}
pub fn get_angle(&self) -> f32 {
self.angle
}
pub fn get_rate(&self) -> f32 {
self.rate
}
pub fn set_q_angle(&mut self, q_angle: f32) {
self.q_angle = q_angle;
}
pub fn set_q_bias(&mut self, q_bias: f32) {
self.q_bias = q_bias;
}
pub fn set_r_measure(&mut self, r_measure: f32) {
self.r_measure = r_measure;
}
pub fn get_q_angle(&self) -> f32 {
self.q_angle
}
pub fn get_q_bias(&self) -> f32 {
self.q_bias
}
pub fn get_r_measure(&self) -> f32 {
self.r_measure
}
}