nyx_space/
errors.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::md::trajectory::TrajError;
20use crate::md::StateParameter;
21pub use crate::md::TargetingError;
22use crate::{cosmic::AstroError, io::ConfigError};
23use anise::errors::{AlmanacError, PhysicsError};
24use hifitime::Epoch;
25use snafu::prelude::*;
26use std::convert::From;
27
28#[derive(Debug, Snafu)]
29#[snafu(visibility(pub(crate)))]
30pub enum NyxError {
31    #[snafu(display("Maximum iterations of {msg} reached"))]
32    MaxIterReached { msg: String },
33    #[snafu(display("Covariance is not positive semi definite"))]
34    CovarianceMatrixNotPsd,
35    #[snafu(display("Unavailable parameter {param:?}: {msg}"))]
36    StateParameterUnavailable { param: StateParameter, msg: String },
37    #[snafu(display("Could not load file: {msg}"))]
38    LoadingError { msg: String },
39    #[snafu(display("Could not read file: {msg}"))]
40    FileUnreadable { msg: String },
41    #[snafu(display("Cosm object not found: `{needle}` (available: {haystack:?})"))]
42    ObjectNotFound {
43        needle: String,
44        haystack: Vec<String>,
45    },
46    #[snafu(display("No interpolation data: {msg}"))]
47    NoInterpolationData { msg: String },
48    #[snafu(display("Invalid interpolation data: {msg}"))]
49    InvalidInterpolationData { msg: String },
50    #[snafu(display("No state data: {msg}"))]
51    NoStateData { msg: String },
52    #[snafu(display("Happens when trying to modify a polynomial's (error)-th error but the polynomial has less orders than that"))]
53    PolynomialOrderError { order: usize },
54    #[snafu(display(
55        "An objective based analysis or control was attempted, but no objective was defined"
56    ))]
57    NoObjectiveDefined,
58    #[snafu(display("This computation requires the orbit to be hyperbolic: {msg}"))]
59    NotHyperbolic { msg: String },
60    #[snafu(display("Monte Carlo error: {msg}"))]
61    MonteCarlo { msg: String },
62    #[snafu(display("CCSDS error: {msg}"))]
63    CCSDS { msg: String },
64    #[snafu(display("Error: {msg}"))]
65    CustomError { msg: String },
66    #[snafu(display("Trajectory error: {source}"))]
67    Trajectory { source: TrajError },
68    #[snafu(display("Math domain error: {msg}"))]
69    MathDomain { msg: String },
70    #[snafu(display("Guidance law config error: {msg}"))]
71    GuidanceConfigError { msg: String },
72    #[snafu(display("Config error: {source}"))]
73    ConfigError { source: ConfigError },
74    #[snafu(display("issue due to Almanac: {action} {source}"))]
75    FromAlmanacError {
76        #[snafu(source(from(AlmanacError, Box::new)))]
77        source: Box<AlmanacError>,
78        action: &'static str,
79    },
80}
81
82impl From<TrajError> for NyxError {
83    fn from(source: TrajError) -> Self {
84        NyxError::Trajectory { source }
85    }
86}
87
88impl From<ConfigError> for NyxError {
89    fn from(source: ConfigError) -> Self {
90        NyxError::ConfigError { source }
91    }
92}
93
94#[derive(Debug, PartialEq, Snafu)]
95#[snafu(visibility(pub(crate)))]
96pub enum StateError {
97    #[snafu(display("{param} is unavailable in this context"))]
98    Unavailable { param: StateParameter },
99    #[snafu(display("{param} is read only in this context"))]
100    ReadOnly { param: StateParameter },
101    #[snafu(display("{param} computation caused {source}"))]
102    StateAstroError {
103        param: StateParameter,
104        source: AstroError,
105    },
106    #[snafu(display("No thruster attached to spacecraft"))]
107    NoThrusterAvail,
108}
109
110#[derive(Debug, PartialEq, Snafu)]
111#[snafu(visibility(pub(crate)))]
112pub enum EventError {
113    #[snafu(display("during event computation: {source}"))]
114    EventAlmanacError {
115        #[snafu(source(from(AlmanacError, Box::new)))]
116        source: Box<AlmanacError>,
117    },
118    #[snafu(display("during event computation: {source}"))]
119    EventStateError {
120        param: StateParameter,
121        source: StateError,
122    },
123    #[snafu(display("during event computation: {source}"))]
124    EventPhysicsError { source: PhysicsError },
125    #[snafu(display("when computing an event in a trajectory {source}"))]
126    EventTrajError { source: TrajError },
127    #[snafu(display("Event {event} not found between {start} and {end}"))]
128    NotFound {
129        start: Epoch,
130        end: Epoch,
131        event: String,
132    },
133}
134
135#[derive(Debug, Snafu)]
136#[snafu(visibility(pub(crate)))]
137pub enum MonteCarloError {
138    #[snafu(display("Monte Carlo caused {source}"))]
139    StateError { source: StateError },
140    #[snafu(display("for {param}, expected percentage between 0.0 and 1.0 but got {prct}"))]
141    ParamPercentage { param: StateParameter, prct: f64 },
142    #[snafu(display(
143        "could {action} because none of the Monte Carlo {num_runs} runs were successful"
144    ))]
145    NoSuccessfulRuns {
146        action: &'static str,
147        num_runs: usize,
148    },
149}
150
151#[derive(Debug, PartialEq, Snafu)]
152#[snafu(visibility(pub(crate)))]
153pub enum LambertError {
154    #[snafu(display("Lambert too close: Δν ~=0 and A ~=0"))]
155    TargetsTooClose,
156    #[snafu(display("No reasonable phi found to connect both radii"))]
157    NotReasonablePhi,
158    #[snafu(display("Use the Izzo algorithm for multi-rev transfers"))]
159    MultiRevNotSupported,
160    #[snafu(display("no feasible solution in {m} revolutions, max is {m_max}"))]
161    MultiRevNotFeasible { m: u32, m_max: u32 },
162    #[snafu(display("Izzo method failed to converge after {maxiter} iterations"))]
163    SolverMaxIter { maxiter: usize },
164}