1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
/*
Nyx, blazing fast astrodynamics
Copyright (C) 2021 Christopher Rabotin <christopher.rabotin@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
pub use crate::time::Errors as TimeErrors;
use crate::Spacecraft;
use std::convert::From;
use std::error::Error;
use std::fmt;
#[derive(Clone, PartialEq, Debug)]
pub enum NyxError {
/// STM is singular, check the automatic differentiation function and file a bug
SingularStateTransitionMatrix,
/// Fuel exhausted error, try running without fuel depletion, and then adding it.
/// Parameter is the state at which the fuel has exhaused
FuelExhausted(Box<Spacecraft>),
/// Propagation event not triggered withinin the max propagation time
ConditionNeverTriggered,
/// Propagation event not hit enough times (requested, found).
UnsufficientTriggers(usize, usize),
/// Maximum iterations reached, value corresponds to the number of iterations used
MaxIterReached(String),
/// Event not in braket
EventNotInEpochBraket(String, String),
/// The operation was expecting the state to have an STM, but it isn't present.
StateTransitionMatrixUnset,
/// The sensitivity matrix was not updated prior to requesting a filter measurement update
SensitivityNotUpdated,
/// Kalman gain is singular, file a bug if this is encountered
SingularKalmanGain,
/// Covariance is singular
SingularCovarianceMatrix,
/// Jacobian of some optimization problem is singular
SingularJacobian,
TargetsTooClose,
LambertNotReasonablePhi,
LambertMultiRevNotSupported,
/// Returns this error if the partials for this model are not defined, thereby preventing the computation of the STM
PartialsUndefined,
/// Returned if trying to set a parameter for something which does not have that parameter.
ParameterUnavailableForType,
LoadingError(String),
FileUnreadable(String),
ObjectNotFound(String),
NoInterpolationData(String),
InvalidInterpolationData(String),
OutOfInterpolationWindow(String),
NoStateData(String),
DisjointFrameOrientations(String, String),
/// When there is a controller but there isn't any thruster available
CtrlExistsButNoThrusterAvail,
/// The control vector returned by a controller must be a unit vector. Use the throttle() function to specify the amount.
CtrlNotAUnitVector(f64),
/// The control throttle range must be between 0.0 and 1.0 (both included) as it represents a percentage.
CtrlThrottleRangeErr(f64),
/// An objective based analysis or control was attempted, but no objective was defined.
NoObjectiveDefined,
/// Error when exporting data
ExportError(String),
/// This computation requires the orbit to be hyperbolic
NotHyperbolic(String),
/// Raised if a differential corrector is not decreasing the error
CorrectionIneffective(String),
/// When there is an error during a Monte Carlo or in the conditions starting a Monte Carlo run
MonteCarlo(String),
/// Raised if the variables to be adjusted lead to an over-determined of the problem for the targeter
TargetError(String),
/// Raised if the variables to be adjusted lead to an under-determined of the problem for the targeter
UnderdeterminedProblem,
/// Returned if CCSDS encountered an error
CCSDS(String),
/// Returned if the targeter for `node_no` has failed
MultipleShootingTargeter(usize, Box<NyxError>),
/// Returned when the trajectory could not be created
TrajectoryCreationError,
/// Some custom error for new dynamics
CustomError(String),
/// Hifitime errors that rose upward
TimeError(TimeErrors),
}
impl fmt::Display for NyxError {
// Prints the Keplerian orbital elements with units
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::SensitivityNotUpdated => write!(
f,
"The measurement matrix H_tilde was not updated prior to measurement update"
),
Self::SingularKalmanGain => write!(
f,
"Gain could not be computed because H*P_bar*H + R is singular"
),
Self::SingularStateTransitionMatrix => write!(
f,
"STM is singular, propagation or smoothing cannot proceed"
),
Self::SingularCovarianceMatrix => {
write!(f, "Covariance is singular, smoothing cannot proceed")
}
Self::FuelExhausted(sc) => write!(
f,
"Spacecraft fuel exhausted, disable fuel depletion and place maneuvers\n{}",
sc
),
Self::ConditionNeverTriggered => write!(
f,
"Try increasing the search space, i.e. increase the maximum propagation time"
),
Self::TargetsTooClose => write!(f, "Lambert too close: Δν ~=0 and A ~=0"),
Self::LambertMultiRevNotSupported => {
write!(f, "Use the Izzo algorithm for multi-rev transfers")
}
Self::LambertNotReasonablePhi => {
write!(f, "No reasonable phi found to connect both radii")
}
Self::MultipleShootingTargeter(n, e) => {
write!(f, "Multiple shooting failed on node {} with {}", n, e)
}
_ => write!(f, "{:?}", self),
}
}
}
impl Error for NyxError {}
impl From<TimeErrors> for NyxError {
fn from(e: TimeErrors) -> Self {
NyxError::TimeError(e)
}
}