extern crate hyperdual;
extern crate serde;
use self::hyperdual::{hyperspace_from_vector, Hyperdual, Owned};
use crate::dimensions::allocator::Allocator;
use crate::dimensions::{DefaultAllocator, DimName, MatrixMN, VectorN};
use crate::hifitime::Epoch;
use dynamics::Dynamics;
use std::fmt;
pub mod kalman;
pub mod ranging;
pub mod estimate;
pub mod residual;
pub mod ui;
pub mod srif;
pub trait Estimable<N>
where
Self: Dynamics + Sized,
{
type LinStateSize: DimName;
fn extract_estimated_state(
&self,
prop_state: &Self::StateType,
) -> VectorN<f64, Self::LinStateSize>
where
DefaultAllocator: Allocator<f64, Self::LinStateSize>;
fn estimated_state(&self) -> VectorN<f64, Self::LinStateSize>
where
DefaultAllocator: Allocator<f64, Self::LinStateSize>,
{
self.extract_estimated_state(&self.state())
}
fn set_estimated_state(&mut self, new_state: VectorN<f64, Self::LinStateSize>)
where
DefaultAllocator: Allocator<f64, Self::LinStateSize>;
fn stm(&self) -> MatrixMN<f64, Self::LinStateSize, Self::LinStateSize>
where
DefaultAllocator: Allocator<f64, Self::LinStateSize>
+ Allocator<f64, Self::LinStateSize, Self::LinStateSize>,
{
self.extract_stm(&self.state())
}
fn to_measurement(&self, prop_state: &Self::StateType) -> (Epoch, N);
fn extract_stm(
&self,
prop_state: &Self::StateType,
) -> MatrixMN<f64, Self::LinStateSize, Self::LinStateSize>
where
DefaultAllocator: Allocator<f64, Self::LinStateSize>
+ Allocator<f64, Self::LinStateSize, Self::LinStateSize>;
}
pub trait Filter<S, A, M>
where
S: DimName,
A: DimName,
M: DimName,
DefaultAllocator: Allocator<f64, M>
+ Allocator<f64, S>
+ Allocator<f64, M, M>
+ Allocator<f64, M, S>
+ Allocator<f64, S, S>
+ Allocator<f64, A, A>
+ Allocator<f64, S, A>
+ Allocator<f64, A, S>,
{
type Estimate: estimate::Estimate<S>;
fn previous_estimate(&self) -> &Self::Estimate;
fn update_stm(&mut self, new_stm: MatrixMN<f64, S, S>);
fn update_h_tilde(&mut self, h_tilde: MatrixMN<f64, M, S>);
fn time_update(&mut self, dt: Epoch) -> Result<Self::Estimate, FilterError>;
fn measurement_update(
&mut self,
dt: Epoch,
real_obs: VectorN<f64, M>,
computed_obs: VectorN<f64, M>,
) -> Result<(Self::Estimate, residual::Residual<M>), FilterError>;
fn is_extended(&self) -> bool;
fn set_extended(&mut self, status: bool);
fn set_process_noise(&mut self, prc: MatrixMN<f64, A, A>);
}
#[derive(Debug, PartialEq)]
pub enum FilterError {
StateTransitionMatrixNotUpdated,
SensitivityNotUpdated,
GainSingular,
StateTransitionMatrixSingular,
}
impl fmt::Display for FilterError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
FilterError::StateTransitionMatrixNotUpdated => {
write!(f, "STM was not updated prior to time or measurement update")
}
FilterError::SensitivityNotUpdated => write!(
f,
"The measurement matrix H_tilde was not updated prior to measurement update"
),
FilterError::GainSingular => write!(
f,
"Gain could not be computed because H*P_bar*H + R is singular"
),
FilterError::StateTransitionMatrixSingular => {
write!(f, "STM is singular, smoothing cannot proceed")
}
}
}
}
pub trait Measurement
where
Self: Sized,
DefaultAllocator: Allocator<f64, Self::MeasurementSize>
+ Allocator<f64, Self::MeasurementSize, Self::StateSize>,
{
type StateSize: DimName;
type MeasurementSize: DimName;
fn observation(&self) -> VectorN<f64, Self::MeasurementSize>
where
DefaultAllocator: Allocator<f64, Self::MeasurementSize>;
fn sensitivity(&self) -> MatrixMN<f64, Self::MeasurementSize, Self::StateSize>
where
DefaultAllocator: Allocator<f64, Self::StateSize, Self::MeasurementSize>;
fn visible(&self) -> bool;
fn at(&self) -> Epoch;
}
pub trait MeasurementDevice<N>
where
Self: Sized,
N: Measurement,
DefaultAllocator: Allocator<f64, N::StateSize>
+ Allocator<f64, N::StateSize, N::MeasurementSize>
+ Allocator<f64, N::MeasurementSize>
+ Allocator<f64, N::MeasurementSize, N::StateSize>,
{
type MeasurementInput;
fn measure(&self, state: &Self::MeasurementInput) -> Option<N>;
}
pub trait AutoDiffDynamics: Dynamics
where
Self: Sized,
{
type HyperStateSize: DimName;
type STMSize: DimName;
fn dual_eom(
&self,
t: f64,
state: &VectorN<Hyperdual<f64, Self::HyperStateSize>, Self::STMSize>,
) -> (
VectorN<f64, Self::STMSize>,
MatrixMN<f64, Self::STMSize, Self::STMSize>,
)
where
DefaultAllocator: Allocator<f64, Self::HyperStateSize>
+ Allocator<f64, Self::STMSize>
+ Allocator<f64, Self::STMSize, Self::STMSize>
+ Allocator<Hyperdual<f64, Self::HyperStateSize>, Self::STMSize>,
Owned<f64, Self::HyperStateSize>: Copy;
fn compute(
&self,
t: f64,
state: &VectorN<f64, Self::STMSize>,
) -> (
VectorN<f64, Self::STMSize>,
MatrixMN<f64, Self::STMSize, Self::STMSize>,
)
where
DefaultAllocator: Allocator<f64, Self::HyperStateSize>
+ Allocator<f64, Self::STMSize>
+ Allocator<f64, Self::STMSize, Self::STMSize>
+ Allocator<Hyperdual<f64, Self::HyperStateSize>, Self::STMSize>,
Owned<f64, Self::HyperStateSize>: Copy,
{
let hyperstate = hyperspace_from_vector(&state);
let (state, grad) = self.dual_eom(t, &hyperstate);
(state, grad)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum EpochFormat {
GregorianUtc,
GregorianTai,
MjdTai,
MjdTt,
MjdUtc,
JdeEt,
JdeTai,
JdeTt,
JdeUtc,
TaiSecs(f64),
TaiDays(f64),
}
impl fmt::Display for EpochFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
EpochFormat::GregorianUtc => write!(f, "Gregorian UTC"),
EpochFormat::GregorianTai => write!(f, "Gregorian TAI"),
EpochFormat::MjdTai => write!(f, "MJD TAI"),
EpochFormat::MjdTt => write!(f, "MJD TT"),
EpochFormat::MjdUtc => write!(f, "MJD UTC"),
EpochFormat::JdeEt => write!(f, "JDE ET"),
EpochFormat::JdeTai => write!(f, "JDE TAI"),
EpochFormat::JdeTt => write!(f, "JDE TT"),
EpochFormat::JdeUtc => write!(f, "JDE UTC"),
EpochFormat::TaiSecs(_) => write!(f, "TAI+ s"),
EpochFormat::TaiDays(_) => write!(f, "TAI+ days"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CovarFormat {
Sqrt,
Sigma1,
Sigma3,
MulSigma(f64),
}
impl fmt::Display for CovarFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
CovarFormat::Sqrt => write!(f, "exptd_val_"),
CovarFormat::Sigma1 => write!(f, "covar_"),
CovarFormat::Sigma3 => write!(f, "3sig_covar"),
CovarFormat::MulSigma(x) => write!(f, "{}sig_covar", x),
}
}
}