1use num_traits::{One, Zero};
5
6use nalgebra::allocator::Allocator;
7use nalgebra::dimension::U6;
8use nalgebra::{DefaultAllocator, OMatrix, RealField};
9
10use crate::motion_model_3d_fixed_dt::MotionModel3D;
11use crate::motion_model_3d_fixed_dt::MotionModel3DFixedDt;
12
13#[derive(Debug, Clone)]
20pub struct FlatZZero3DModel<R: RealField + Copy>
21where
22 DefaultAllocator: Allocator<U6, U6>,
23 DefaultAllocator: Allocator<U6>,
24{
25 motion_noise_scale: R,
26}
27
28impl<R: RealField + Copy> FlatZZero3DModel<R>
29where
30 DefaultAllocator: Allocator<U6, U6>,
31 DefaultAllocator: Allocator<U6>,
32{
33 pub fn new(motion_noise_scale: R) -> Self {
34 Self { motion_noise_scale }
35 }
36}
37
38impl<R: RealField + Copy> MotionModel3D<R> for FlatZZero3DModel<R>
39where
40 DefaultAllocator: Allocator<U6, U6>,
41 DefaultAllocator: Allocator<U6>,
42{
43 fn calc_for_dt(&self, dt: R) -> MotionModel3DFixedDt<R> {
44 let zero: R = Zero::zero();
45 let one: R = One::one();
46 let two: R = one + one;
47 let three: R = two + one;
48
49 #[rustfmt::skip]
52 let transition_model = {
53 OMatrix::<R,U6,U6>::from_row_slice(
54 &[one, zero, zero, dt, zero, zero,
55 zero, one, zero, zero, dt, zero,
56 zero, zero, zero, zero, zero, zero,
57 zero, zero, zero, one, zero, zero,
58 zero, zero, zero, zero, one, zero,
59 zero, zero, zero, zero, zero, zero])
60 };
61 let transition_model_transpose = transition_model.transpose();
62
63 let t33 = (dt * dt * dt) / three;
64 let t22 = (dt * dt) / two;
65
66 #[rustfmt::skip]
68 let transition_noise_covariance = {
69 OMatrix::<R,U6,U6>::from_row_slice(
70 &[t33, zero, zero, t22, zero, zero,
71 zero, t33, zero, zero, t22, zero,
72 zero, zero, zero, zero, zero, zero,
73 t22, zero, zero, dt, zero, zero,
74 zero, t22, zero, zero, dt, zero,
75 zero, zero, zero, zero, zero, zero]) * self.motion_noise_scale
76 };
77 MotionModel3DFixedDt {
78 transition_model,
79 transition_model_transpose,
80 transition_noise_covariance,
81 }
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use super::*;
88 use adskalman::TransitionModelLinearNoControl;
89
90 #[test]
91 fn test_fix_z() {
92 let model = FlatZZero3DModel::new(1.0);
93 let m2 = model.calc_for_dt(1.0);
94 let matrix = m2.F();
95
96 let pos1 = na::OVector::<_, U6>::from_row_slice(&[0.1, 0.2, 0.3, 0.4, 0.5, 0.6]);
97 let pos2 = matrix * pos1;
98
99 assert_eq!(pos2[2], 0.0);
101
102 assert_eq!(pos2[5], 0.0);
104 }
105}