-
Notifications
You must be signed in to change notification settings - Fork 0
/
robot.rs
72 lines (61 loc) · 1.74 KB
/
robot.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
use nalgebra::{Matrix2x1, Matrix3, Matrix3x1, Matrix3x2};
// x: [X, Y, θ]ᵀ
pub type StateVec = Matrix3x1<f64>;
// u: [v, dθ]ᵀ
pub type InputVec = Matrix2x1<f64>;
// A
pub type SystemMat = Matrix3<f64>;
// B
pub type InputMat = Matrix3x2<f64>;
pub trait System {
fn tick(&self, u: InputVec, dt: f64) -> StateVec;
fn new(x: StateVec, u: InputVec, dt: f64) -> Self;
}
pub trait LinearSystem: System {
fn matrices(&self) -> (SystemMat, InputMat);
}
pub struct LinearUnicycleSystem {
pub x: StateVec,
pub A: SystemMat,
pub B: InputMat,
}
pub struct NonlinearUnicycleSystem {
pub x: StateVec,
}
impl System for NonlinearUnicycleSystem {
fn tick(&self, u: InputVec, dt: f64) -> StateVec {
let mut x = self.x.clone();
x[0] += u[0] * f64::cos(self.x[2]) * dt; // X
x[1] += u[0] * f64::sin(self.x[2]) * dt; // Y
x[2] += u[1] * dt; // θ
x
}
fn new(x: StateVec, _u: InputVec, _dt: f64) -> Self {
NonlinearUnicycleSystem { x }
}
}
impl System for LinearUnicycleSystem {
fn tick(&self, u: InputVec, _dt: f64) -> StateVec {
self.A * self.x + self.B * u
}
fn new(x: StateVec, u: InputVec, dt: f64) -> Self {
LinearUnicycleSystem {
x,
A: SystemMat::new(
1.0, 0.0, -u[0] * f64::sin(x[2]) * dt,
0.0, 1.0, u[0] * f64::cos(x[2]) * dt,
0.0, 0.0, 1.0,
),
B: InputMat::new(
f64::cos(x[2]) * dt, 0.0,
f64::sin(x[2]) * dt, 0.0,
0.0, dt,
),
}
}
}
impl LinearSystem for LinearUnicycleSystem {
fn matrices(&self) -> (SystemMat, InputMat) {
(self.A, self.B)
}
}