cecile_supercool_tracker/utils/
kalman.rs1use crate::prelude::{BoundingBox, Universal2DBox};
2use crate::Errors;
3use nalgebra::{SMatrix, SVector};
4
5pub mod kalman_2d_box;
8pub mod kalman_2d_point;
11pub mod kalman_2d_point_vec;
14
15pub const CHI2_UPPER_BOUND: f32 = 100.0;
16
17pub const CHI2INV95: [f32; 9] = [
18 3.8415, 5.9915, 7.8147, 9.4877, 11.070, 12.592, 14.067, 15.507, 16.919,
19];
20
21macro_rules! pretty_print {
22 ($arr:expr) => {{
23 let indent = 4;
24 let prefix = String::from_utf8(vec![b' '; indent]).unwrap();
25 let mut result_els = vec!["".to_string()];
26 for i in 0..$arr.nrows() {
27 let mut row_els = vec![];
28 for j in 0..$arr.ncols() {
29 row_els.push(format!("{:12.3}", $arr[(i, j)]));
30 }
31 let row_str = row_els.into_iter().collect::<Vec<_>>().join(" ");
32 let row_str = format!("{}{}", prefix, row_str);
33 result_els.push(row_str);
34 }
35 result_els.into_iter().collect::<Vec<_>>().join("\n")
36 }};
37}
38
39#[derive(Copy, Clone, Debug)]
42pub struct KalmanState<const X: usize> {
43 mean: SVector<f32, X>,
44 covariance: SMatrix<f32, X, X>,
45}
46
47impl<const X: usize> KalmanState<X> {
48 pub fn dump(&self) {
51 eprintln!("Mean={}", pretty_print!(self.mean.transpose()));
52 eprintln!("Covariance={}", pretty_print!(self.covariance));
53 }
54}
55
56impl<const X: usize> TryFrom<KalmanState<X>> for Universal2DBox {
57 type Error = Errors;
58
59 fn try_from(value: KalmanState<X>) -> Result<Self, Self::Error> {
60 if value.mean.len() < 5 {
61 Err(Self::Error::OutOfRange)
62 } else {
63 Ok(Universal2DBox::new(
64 value.mean[0],
65 value.mean[1],
66 if value.mean[2] == 0.0 {
67 None
68 } else {
69 Some(value.mean[2])
70 },
71 value.mean[3],
72 value.mean[4],
73 ))
74 }
75 }
76}
77
78impl<const X: usize> TryFrom<KalmanState<X>> for BoundingBox {
79 type Error = Errors;
80
81 fn try_from(value: KalmanState<X>) -> Result<Self, Self::Error> {
82 let bb = Universal2DBox::try_from(value)?;
83 BoundingBox::try_from(&bb)
84 }
85}
86
87pub const DT: u64 = 1;