gmt_m2_ctrl_asm_pid_damping/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4#![allow(improper_ctypes)]
5
6include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
7
8include!(concat!(env!("OUT_DIR"), "/controller.rs"));
9
10#[cfg(test)]
11mod tests {
12    use super::*;
13    use matio_rs::MatFile;
14
15    #[test]
16    fn impulse() {
17        let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
18            .join("..")
19            .join("simulink-models")
20            .join("m2asm_tests.mat");
21        let mat = MatFile::load(path.to_str().unwrap()).unwrap();
22        let asm_fb_t: Vec<f64> = mat.var("asm_fb_imp_t").unwrap();
23        let asm_fb_y: Vec<f64> = mat.var("asm_fb_imp_y").unwrap();
24
25        let n = asm_fb_t.len();
26
27        let sim_y: Vec<_> = asm_fb_y
28            .chunks(n)
29            .take(1)
30            .zip(asm_fb_y.chunks(n).skip(1).take(1))
31            .flat_map(|(x, dx)| x.iter().zip(dx).flat_map(|(x, dx)| vec![*x, *dx]))
32            .collect();
33        dbg!(&sim_y[..10]);
34
35        let mut ctrl = AsmPidDamping::new();
36        let mut y = vec![];
37        for i in 0..n {
38            ctrl.inputs.asm_FB = if i == 0 { 8000f64 } else { 0f64 };
39            ctrl.step();
40            y.push(ctrl.outputs.asm_U);
41            y.push(ctrl.outputs.asm_Fd);
42        }
43        dbg!(&y[..10]);
44
45        let y_err = (asm_fb_y
46            .chunks(n)
47            .take(1)
48            .zip(asm_fb_y.chunks(n).skip(1).take(1))
49            .flat_map(|(x, dx)| x.iter().zip(dx).flat_map(|(x, dx)| vec![*x, *dx]))
50            .zip(&y)
51            .map(|(sim_y, y)| sim_y - y)
52            .map(|x| x * x)
53            .sum::<f64>()
54            / ((3 * n) as f64))
55            .sqrt();
56        assert!(dbg!(y_err) < 1e-6);
57    }
58}