nyx_space/od/
mod.rs

1/*
2    Nyx, blazing fast astrodynamics
3    Copyright (C) 2018-onwards Christopher Rabotin <christopher.rabotin@gmail.com>
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU Affero General Public License as published
7    by the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU Affero General Public License for more details.
14
15    You should have received a copy of the GNU Affero General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.
17*/
18
19use crate::dynamics::DynamicsError;
20pub use crate::dynamics::{Dynamics, NyxError};
21use crate::io::{ConfigError, InputOutputError};
22use crate::linalg::OVector;
23use crate::md::trajectory::TrajError;
24use crate::propagators::PropagationError;
25use crate::time::Epoch;
26pub use crate::{State, TimeTagged};
27use anise::almanac::planetary::PlanetaryDataError;
28use anise::errors::AlmanacError;
29use hifitime::Duration;
30use snafu::prelude::Snafu;
31use std::sync::Arc;
32
33pub mod filter;
34pub use filter::Filter;
35
36/// Provides a range and range rate measuring models.
37mod ground_station;
38pub use ground_station::GroundStation;
39
40/// Provides Estimate handling functionalities.
41pub mod estimate;
42
43/// Provides noise modeling
44pub mod noise;
45
46/// Provides all of the support measurement models
47pub mod msr;
48
49/// Provides all of the functionality to simulate measurements from ground stations
50pub mod simulator;
51
52/// Provides the interfaces to the orbit determination process
53pub mod process;
54
55pub use simulator::TrackingDevice;
56
57/// Provides all state noise compensation functionality
58pub mod snc;
59
60/// A helper type for spacecraft orbit determination.
61pub type SpacecraftODProcess<'a> = self::process::ODProcess<
62    'a,
63    crate::md::prelude::SpacecraftDynamics,
64    nalgebra::Const<2>,
65    nalgebra::Const<3>,
66    filter::kalman::KF<crate::Spacecraft, nalgebra::Const<3>, nalgebra::Const<2>>,
67    GroundStation,
68>;
69
70/// A helper type for spacecraft orbit determination sequentially processing measurements
71pub type SpacecraftODProcessSeq<'a> = self::process::ODProcess<
72    'a,
73    crate::md::prelude::SpacecraftDynamics,
74    nalgebra::Const<1>,
75    nalgebra::Const<3>,
76    filter::kalman::KF<crate::Spacecraft, nalgebra::Const<3>, nalgebra::Const<1>>,
77    GroundStation,
78>;
79
80#[allow(unused_imports)]
81pub mod prelude {
82    pub use super::estimate::*;
83    pub use super::filter::kalman::*;
84    pub use super::ground_station::*;
85    pub use super::msr::*;
86    pub use super::noise::{GaussMarkov, StochasticNoise, WhiteNoise};
87    pub use super::process::*;
88    pub use super::simulator::TrackingArcSim;
89    pub use super::simulator::*;
90    pub use super::snc::*;
91    pub use super::*;
92
93    pub use crate::time::{Duration, Epoch, TimeUnits, Unit};
94}
95
96#[derive(Debug, PartialEq, Snafu)]
97#[snafu(visibility(pub(crate)))]
98pub enum ODError {
99    #[snafu(display("during an orbit determination, encountered {source}"))]
100    ODPropError { source: PropagationError },
101    #[snafu(display("during an orbit determination, encountered {source}"))]
102    ODDynamicsError { source: DynamicsError },
103    #[snafu(display("at least {need} measurements required for {action}"))]
104    TooFewMeasurements { need: usize, action: &'static str },
105    #[snafu(display("invalid step size: {step}"))]
106    StepSizeError { step: Duration },
107    #[snafu(display("filter iteration did not converge in {loops} iterations"))]
108    Diverged { loops: usize },
109    #[snafu(display("STM is singular"))]
110    SingularStateTransitionMatrix,
111    #[snafu(display("invalid measurement @ {epoch} = {val}"))]
112    InvalidMeasurement { epoch: Epoch, val: f64 },
113    #[snafu(display("sensitivity matrix must be updated before this call"))]
114    SensitivityNotUpdated,
115    #[snafu(display("Kalman gain is singular"))]
116    SingularKalmanGain,
117    #[snafu(display("noise matrix is singular"))]
118    SingularNoiseRk,
119    #[snafu(display("{kind} noise not configured"))]
120    NoiseNotConfigured { kind: String },
121    #[snafu(display("measurement sim error: {details}"))]
122    MeasurementSimError { details: String },
123    #[snafu(display("during an OD encountered {source}"))]
124    ODTrajError { source: TrajError },
125    #[snafu(display("OD failed because {source}"))]
126    ODConfigError { source: ConfigError },
127    #[snafu(display("OD failed because of an I/O error: {source}"))]
128    ODIOError { source: InputOutputError },
129    #[snafu(display("OD failed due to Almanac: {action} {source}"))]
130    ODAlmanac {
131        #[snafu(source(from(AlmanacError, Box::new)))]
132        source: Box<AlmanacError>,
133        action: &'static str,
134    },
135    #[snafu(display("OD failed due to planetary data in Almanac: {action} {source}"))]
136    ODPlanetaryData {
137        #[snafu(source(from(PlanetaryDataError, Box::new)))]
138        source: Box<PlanetaryDataError>,
139        action: &'static str,
140    },
141    #[snafu(display("not enough residuals to {action}"))]
142    ODNoResiduals { action: &'static str },
143}