use deep_causality_algebra::RealField;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct InsErrorState<R> {
position: [R; 3],
velocity: [R; 3],
attitude: [R; 3],
accel_bias: [R; 3],
gyro_bias: [R; 3],
clock_bias: R,
clock_drift: R,
}
impl<R> InsErrorState<R>
where
R: RealField,
{
pub fn zero() -> Self {
let z = [R::zero(); 3];
Self {
position: z,
velocity: z,
attitude: z,
accel_bias: z,
gyro_bias: z,
clock_bias: R::zero(),
clock_drift: R::zero(),
}
}
pub fn from_biases(accel_bias: [R; 3], gyro_bias: [R; 3]) -> Self {
Self {
accel_bias,
gyro_bias,
..Self::zero()
}
}
pub fn with_clock(mut self, clock_bias: R, clock_drift: R) -> Self {
self.clock_bias = clock_bias;
self.clock_drift = clock_drift;
self
}
pub fn propagate(&self, dt: R, specific_force: [R; 3]) -> Self {
let f = specific_force;
let psi = self.attitude;
let fx = [
f[1] * psi[2] - f[2] * psi[1],
f[2] * psi[0] - f[0] * psi[2],
f[0] * psi[1] - f[1] * psi[0],
];
let mut out = *self;
out.position = core::array::from_fn(|i| self.position[i] + self.velocity[i] * dt);
out.velocity =
core::array::from_fn(|i| self.velocity[i] + (-fx[i] - self.accel_bias[i]) * dt);
out.attitude = core::array::from_fn(|i| self.attitude[i] + (-self.gyro_bias[i]) * dt);
out.clock_bias = self.clock_bias + self.clock_drift * dt;
out.clock_drift = self.clock_drift;
out
}
pub fn position_error(&self) -> [R; 3] {
self.position
}
pub fn velocity_error(&self) -> [R; 3] {
self.velocity
}
pub fn attitude_error(&self) -> [R; 3] {
self.attitude
}
pub fn accel_bias(&self) -> [R; 3] {
self.accel_bias
}
pub fn gyro_bias(&self) -> [R; 3] {
self.gyro_bias
}
pub fn clock_bias(&self) -> R {
self.clock_bias
}
pub fn clock_drift(&self) -> R {
self.clock_drift
}
pub fn to_array(&self) -> [R; 17] {
[
self.position[0],
self.position[1],
self.position[2],
self.velocity[0],
self.velocity[1],
self.velocity[2],
self.attitude[0],
self.attitude[1],
self.attitude[2],
self.accel_bias[0],
self.accel_bias[1],
self.accel_bias[2],
self.gyro_bias[0],
self.gyro_bias[1],
self.gyro_bias[2],
self.clock_bias,
self.clock_drift,
]
}
pub fn from_array(a: [R; 17]) -> Self {
Self {
position: [a[0], a[1], a[2]],
velocity: [a[3], a[4], a[5]],
attitude: [a[6], a[7], a[8]],
accel_bias: [a[9], a[10], a[11]],
gyro_bias: [a[12], a[13], a[14]],
clock_bias: a[15],
clock_drift: a[16],
}
}
pub fn reset_navigation(&self) -> Self {
Self {
position: [R::zero(); 3],
velocity: [R::zero(); 3],
attitude: [R::zero(); 3],
..*self
}
}
pub fn position_error_norm(&self) -> R {
(self.position[0] * self.position[0]
+ self.position[1] * self.position[1]
+ self.position[2] * self.position[2])
.sqrt()
}
}