1use 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
36mod ground_station;
38pub use ground_station::GroundStation;
39
40pub mod estimate;
42
43pub mod noise;
45
46pub mod msr;
48
49pub mod simulator;
51
52pub mod process;
54
55pub use simulator::TrackingDevice;
56
57pub mod snc;
59
60pub 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
70pub 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}