-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcustom_residual.rs
74 lines (61 loc) · 1.85 KB
/
custom_residual.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use core::fmt;
use factrs::{
dtype,
linalg::{vectorx, ForwardProp, Numeric, VectorX},
residuals::Residual1,
traits::Variable,
variables::SE2,
};
use nalgebra::Const;
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct XPrior {
x: dtype,
}
impl XPrior {
pub fn new(x: dtype) -> XPrior {
XPrior { x }
}
}
#[factrs::mark]
impl Residual1 for XPrior {
type Differ = ForwardProp<<Self as Residual1>::DimIn>;
type V1 = SE2;
type DimIn = <SE2 as Variable>::Dim;
type DimOut = Const<1>;
fn residual1<T: Numeric>(&self, v: SE2<T>) -> VectorX<T> {
let z_meas = T::from(self.x);
vectorx![z_meas - v.xy().x]
}
}
impl fmt::Display for XPrior {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "XPrior({})", self.x)
}
}
// TODO: Some tests to make sure it optimizes
#[cfg(feature = "serde")]
mod ser_de {
use factrs::{containers::Values, symbols::X, traits::Residual};
use super::*;
// Make sure it serializes properly
#[test]
fn test_json_serialize() {
let trait_object = &XPrior::new(1.2) as &dyn Residual;
let json = serde_json::to_string(trait_object).unwrap();
let expected = r#"{"tag":"XPrior","x":1.2}"#;
println!("json: {}", json);
assert_eq!(json, expected);
}
#[test]
fn test_json_deserialize() {
let json = r#"{"tag":"XPrior","x":1.2}"#;
let trait_object: Box<dyn Residual> = serde_json::from_str(json).unwrap();
let mut values = Values::new();
values.insert_unchecked(X(0), SE2::new(0.0, 1.2, 0.0));
let error = trait_object.residual(&values, &[X(0).into()])[0];
assert_eq!(trait_object.dim_in(), 3);
assert_eq!(trait_object.dim_out(), 1);
assert_eq!(error, 0.0);
}
}