Skip to main content

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::prelude::SpacecraftDynamics;
25use crate::md::trajectory::TrajError;
26use crate::propagators::PropagationError;
27use crate::time::Epoch;
28pub use crate::{State, TimeTagged};
29use anise::almanac::planetary::PlanetaryDataError;
30use anise::errors::AlmanacError;
31use hifitime::Duration;
32use snafu::prelude::Snafu;
33use std::sync::Arc;
34
35pub mod kalman;
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/// Provides the Batch least squares initial state solver.
62pub mod blse;
63
64/// Provides Position, Navigation, and Timing capabilities for spacecraft assets
65#[cfg(feature = "premium")]
66pub mod interlink;
67
68/// Provides Position, Navigation, and Timing capabilities for assets on the surface of celestial objects
69#[cfg(feature = "premium")]
70pub mod groundpnt;
71
72/// Provides post-filtering for GNSS/GPS devices
73#[cfg(feature = "premium")]
74pub mod position;
75
76/// A helper type for spacecraft orbit determination.
77pub type SpacecraftKalmanOD = self::process::KalmanODProcess<
78    SpacecraftDynamics,
79    nalgebra::Const<2>,
80    nalgebra::Const<3>,
81    GroundStation,
82>;
83
84/// A helper type for spacecraft orbit determination sequentially processing measurements
85pub type SpacecraftKalmanScalarOD = self::process::KalmanODProcess<
86    SpacecraftDynamics,
87    nalgebra::Const<1>,
88    nalgebra::Const<3>,
89    GroundStation,
90>;
91
92/// A helper type for spacecraft to spacecraft orbit determination.
93#[cfg(feature = "premium")]
94pub type InterlinkKalmanOD = self::process::KalmanODProcess<
95    SpacecraftDynamics,
96    nalgebra::Const<2>,
97    nalgebra::Const<3>,
98    interlink::InterlinkTxSpacecraft,
99>;
100
101#[allow(unused_imports)]
102pub mod prelude {
103    pub use super::estimate::*;
104    pub use super::ground_station::*;
105    pub use super::kalman::KalmanVariant;
106    pub use super::kalman::*;
107    pub use super::msr::*;
108    pub use super::noise::{GaussMarkov, StochasticNoise, WhiteNoise};
109    pub use super::process::*;
110    pub use super::simulator::TrackingArcSim;
111    pub use super::simulator::*;
112    pub use super::snc::*;
113    pub use super::*;
114    pub use crate::od::process::NormalizedConsistency;
115
116    pub use crate::time::{Duration, Epoch, TimeUnits, Unit};
117}
118
119#[derive(Debug, PartialEq, Snafu)]
120#[snafu(visibility(pub(crate)))]
121pub enum ODError {
122    #[snafu(display("during an orbit determination, encountered {source}"))]
123    ODPropError {
124        #[snafu(source(from(PropagationError, Box::new)))]
125        source: Box<PropagationError>,
126    },
127    #[snafu(display("during an orbit determination, encountered {source}"))]
128    ODDynamicsError {
129        #[snafu(source(from(DynamicsError, Box::new)))]
130        source: Box<DynamicsError>,
131    },
132    #[snafu(display("at least {need} measurements required for {action}"))]
133    TooFewMeasurements { need: usize, action: &'static str },
134    #[snafu(display("invalid step size: {step}"))]
135    StepSizeError { step: Duration },
136    #[snafu(display("filter iteration did not converge in {loops} iterations"))]
137    Diverged { loops: usize },
138    #[snafu(display("STM is singular"))]
139    SingularStateTransitionMatrix,
140    #[snafu(display("invalid measurement @ {epoch} = {val}"))]
141    InvalidMeasurement { epoch: Epoch, val: f64 },
142    #[snafu(display("Kalman gain is singular"))]
143    SingularKalmanGain,
144    #[snafu(display("Information matrix is singular"))]
145    SingularInformationMatrix,
146    #[snafu(display("noise matrix is singular"))]
147    SingularNoiseRk,
148    #[snafu(display("{kind} noise not configured"))]
149    NoiseNotConfigured { kind: String },
150    #[snafu(display("measurement sim error: {details}"))]
151    MeasurementSimError { details: String },
152    #[snafu(display("during an OD encountered {source}: {details}"))]
153    ODTrajError { source: TrajError, details: String },
154    #[snafu(display("OD failed because {source}"))]
155    ODConfigError { source: ConfigError },
156    #[snafu(display("OD failed because of an I/O error: {source}"))]
157    ODIOError { source: InputOutputError },
158    #[snafu(display("OD failed due to Almanac: {action} {source}"))]
159    ODAlmanac {
160        #[snafu(source(from(AlmanacError, Box::new)))]
161        source: Box<AlmanacError>,
162        action: &'static str,
163    },
164    #[snafu(display("OD failed due to planetary data in Almanac: {action} {source}"))]
165    ODPlanetaryData {
166        #[snafu(source(from(PlanetaryDataError, Box::new)))]
167        source: Box<PlanetaryDataError>,
168        action: &'static str,
169    },
170    #[snafu(display("not enough residuals to {action}"))]
171    ODNoResiduals { action: &'static str },
172    #[snafu(display("could not {action} OD results: {source}"))]
173    ODStateError {
174        #[snafu(source(from(StateError, Box::new)))]
175        source: Box<StateError>,
176        action: &'static str,
177    },
178    #[snafu(display("Maximum iterations ({max_iter}) reached without convergence"))]
179    ODMaxIterations { max_iter: usize },
180    #[snafu(display("Nyx orbit determination limitation: {action}"))]
181    ODLimitation { action: &'static str },
182}