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::errors::StateError;
22use crate::io::{ConfigError, InputOutputError};
23use crate::linalg::OVector;
24use crate::md::trajectory::TrajError;
25use crate::propagators::PropagationError;
26use crate::time::Epoch;
27pub use crate::{State, TimeTagged};
28use anise::almanac::planetary::PlanetaryDataError;
29use anise::errors::AlmanacError;
30use hifitime::Duration;
31use snafu::prelude::Snafu;
32use std::sync::Arc;
33
34pub mod filter;
35pub use filter::Filter;
36
37/// Provides a range and range rate measuring models.
38mod ground_station;
39pub use ground_station::GroundStation;
40
41/// Provides Estimate handling functionalities.
42pub mod estimate;
43
44/// Provides noise modeling
45pub mod noise;
46
47/// Provides all of the support measurement models
48pub mod msr;
49
50/// Provides all of the functionality to simulate measurements from ground stations
51pub mod simulator;
52
53/// Provides the interfaces to the orbit determination process
54pub mod process;
55
56pub use simulator::TrackingDevice;
57
58/// Provides all state noise compensation functionality
59pub mod snc;
60
61/// A helper type for spacecraft orbit determination.
62pub type SpacecraftODProcess<'a> = self::process::ODProcess<
63    'a,
64    crate::md::prelude::SpacecraftDynamics,
65    nalgebra::Const<2>,
66    nalgebra::Const<3>,
67    filter::kalman::KF<crate::Spacecraft, nalgebra::Const<3>>,
68    GroundStation,
69>;
70
71/// A helper type for spacecraft orbit determination sequentially processing measurements
72pub type SpacecraftODProcessSeq<'a> = self::process::ODProcess<
73    'a,
74    crate::md::prelude::SpacecraftDynamics,
75    nalgebra::Const<1>,
76    nalgebra::Const<3>,
77    filter::kalman::KF<crate::Spacecraft, nalgebra::Const<3>>,
78    GroundStation,
79>;
80
81#[allow(unused_imports)]
82pub mod prelude {
83    pub use super::estimate::*;
84    pub use super::filter::kalman::*;
85    pub use super::ground_station::*;
86    pub use super::msr::*;
87    pub use super::noise::{GaussMarkov, StochasticNoise, WhiteNoise};
88    pub use super::process::*;
89    pub use super::simulator::TrackingArcSim;
90    pub use super::simulator::*;
91    pub use super::snc::*;
92    pub use super::*;
93
94    pub use crate::time::{Duration, Epoch, TimeUnits, Unit};
95}
96
97#[derive(Debug, PartialEq, Snafu)]
98#[snafu(visibility(pub(crate)))]
99pub enum ODError {
100    #[snafu(display("during an orbit determination, encountered {source}"))]
101    ODPropError { source: PropagationError },
102    #[snafu(display("during an orbit determination, encountered {source}"))]
103    ODDynamicsError { source: DynamicsError },
104    #[snafu(display("at least {need} measurements required for {action}"))]
105    TooFewMeasurements { need: usize, action: &'static str },
106    #[snafu(display("invalid step size: {step}"))]
107    StepSizeError { step: Duration },
108    #[snafu(display("filter iteration did not converge in {loops} iterations"))]
109    Diverged { loops: usize },
110    #[snafu(display("STM is singular"))]
111    SingularStateTransitionMatrix,
112    #[snafu(display("invalid measurement @ {epoch} = {val}"))]
113    InvalidMeasurement { epoch: Epoch, val: f64 },
114    #[snafu(display("Kalman gain is singular"))]
115    SingularKalmanGain,
116    #[snafu(display("noise matrix is singular"))]
117    SingularNoiseRk,
118    #[snafu(display("{kind} noise not configured"))]
119    NoiseNotConfigured { kind: String },
120    #[snafu(display("measurement sim error: {details}"))]
121    MeasurementSimError { details: String },
122    #[snafu(display("during an OD encountered {source}: {details}"))]
123    ODTrajError { source: TrajError, details: String },
124    #[snafu(display("OD failed because {source}"))]
125    ODConfigError { source: ConfigError },
126    #[snafu(display("OD failed because of an I/O error: {source}"))]
127    ODIOError { source: InputOutputError },
128    #[snafu(display("OD failed due to Almanac: {action} {source}"))]
129    ODAlmanac {
130        #[snafu(source(from(AlmanacError, Box::new)))]
131        source: Box<AlmanacError>,
132        action: &'static str,
133    },
134    #[snafu(display("OD failed due to planetary data in Almanac: {action} {source}"))]
135    ODPlanetaryData {
136        #[snafu(source(from(PlanetaryDataError, Box::new)))]
137        source: Box<PlanetaryDataError>,
138        action: &'static str,
139    },
140    #[snafu(display("not enough residuals to {action}"))]
141    ODNoResiduals { action: &'static str },
142    #[snafu(display("could not {action} OD results: {source}"))]
143    ODStateError {
144        #[snafu(source(from(StateError, Box::new)))]
145        source: Box<StateError>,
146        action: &'static str,
147    },
148    #[snafu(display("Nyx orbit determination limitation: {action}"))]
149    ODLimitation { action: &'static str },
150}