nyx_space/cosmic/mod.rs
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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
/*
Nyx, blazing fast astrodynamics
Copyright (C) 2018-onwards 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/>.
*/
use anise::errors::{AlmanacError, PhysicsError};
pub use anise::prelude::*;
pub use crate::cosmic::{GuidanceMode, Spacecraft};
use crate::dynamics::DynamicsError;
pub use crate::errors::NyxError;
use crate::errors::StateError;
use crate::linalg::allocator::Allocator;
use crate::linalg::{DefaultAllocator, DimName, OMatrix, OVector};
use crate::md::StateParameter;
use snafu::Snafu;
use std::fmt;
/// A trait allowing for something to have an epoch
pub trait TimeTagged {
/// Retrieve the Epoch
fn epoch(&self) -> Epoch;
/// Set the Epoch
fn set_epoch(&mut self, epoch: Epoch);
}
/// A trait for generate propagation and estimation state.
/// The first parameter is the size of the state, the second is the size of the propagated state including STM and extra items.
pub trait State: Default + Copy + PartialEq + fmt::Display + fmt::LowerExp + Send + Sync
where
Self: Sized,
DefaultAllocator:
Allocator<Self::Size> + Allocator<Self::Size, Self::Size> + Allocator<Self::VecLength>,
{
/// Size of the state and its STM
type Size: DimName;
type VecLength: DimName;
/// Initialize an empty state
/// By default, this is not implemented. This function must be implemented when filtering on this state.
fn zeros() -> Self {
unimplemented!()
}
/// Return this state as a vector for the propagation/estimation
fn to_vector(&self) -> OVector<f64, Self::VecLength>;
/// Return this state as a vector for the propagation/estimation
/// By default, this is not implemented. This function must be implemented when filtering on this state.
fn stm(&self) -> Result<OMatrix<f64, Self::Size, Self::Size>, DynamicsError> {
Err(DynamicsError::StateTransitionMatrixUnset)
}
/// Return this state as a vector for the propagation/estimation
/// By default, this is not implemented. This function must be implemented when filtering on this state.
fn reset_stm(&mut self) {
unimplemented!()
}
/// Unsets the STM for this state
fn unset_stm(&mut self);
/// Set this state
fn set(&mut self, epoch: Epoch, vector: &OVector<f64, Self::VecLength>);
/// Reconstruct a new State from the provided delta time in seconds compared to the current state
/// and with the provided vector.
fn set_with_delta_seconds(
mut self,
delta_t_s: f64,
vector: &OVector<f64, Self::VecLength>,
) -> Self
where
DefaultAllocator: Allocator<Self::VecLength>,
{
self.set(self.epoch() + delta_t_s, vector);
self
}
/// Retrieve the Epoch
fn epoch(&self) -> Epoch;
/// Set the Epoch
fn set_epoch(&mut self, epoch: Epoch);
/// By default, this is not implemented. This function must be implemented when filtering on this state.
fn add(self, _other: OVector<f64, Self::Size>) -> Self {
unimplemented!()
}
/// Return the value of the parameter, returns an error by default
fn value(&self, param: StateParameter) -> Result<f64, StateError> {
Err(StateError::Unavailable { param })
}
/// Allows setting the value of the given parameter.
/// NOTE: Most parameters where the `value` is available CANNOT be also set for that parameter (it's a much harder problem!)
fn set_value(&mut self, param: StateParameter, _val: f64) -> Result<(), StateError> {
Err(StateError::Unavailable { param })
}
/// Returns a copy of the orbit
fn orbit(&self) -> Orbit;
/// Modifies this state's orbit
fn set_orbit(&mut self, _orbit: Orbit) {}
}
pub fn assert_orbit_eq_or_abs(left: &Orbit, right: &Orbit, epsilon: f64, msg: &str) {
if !left.eq_within(right, epsilon, epsilon) {
panic!(
r#"assertion failed: {}
left: `{:?}`,
right: `{:?}`"#,
msg, left, right
)
}
}
#[derive(Debug, PartialEq, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum AstroError {
#[snafu(display("B Plane jacobian invariant must be either VX, VY or VZ"))]
BPlaneInvariant,
#[snafu(display("operation requires a local frame"))]
NotLocalFrame,
#[snafu(display("partial derivatives not defined for this parameter"))]
PartialsUndefined,
#[snafu(display("Orbit is not hyperbolic so there is no hyperbolic anomaly."))]
NotHyperbolic,
#[snafu(display("physics error occured during astro computation: {source}"))]
AstroPhysics { source: PhysicsError },
#[snafu(display("ANISE Almanac error occured during astro computation: {source}"))]
AstroAlmanac {
#[snafu(source(from(AlmanacError, Box::new)))]
source: Box<AlmanacError>,
},
}
// Re-Export OrbitDual
mod orbitdual;
pub use self::orbitdual::*;
// Re-Export B Plane
mod bplane;
pub use self::bplane::*;
// Re-Export spacecraft
mod spacecraft;
pub use self::spacecraft::*;
/// The eclipse module allows finding eclipses and (conversely) visibility between a state and another one (e.g. a planet or the Sun).
pub mod eclipse;
/// Speed of light in meters per second
pub const SPEED_OF_LIGHT_M_S: f64 = SPEED_OF_LIGHT_KM_S * 1e3;
pub use anise::constants::SPEED_OF_LIGHT_KM_S;
/// Astronomical unit, in kilometers, according to the [IAU](https://www.iau.org/public/themes/measuring/).
pub const AU: f64 = 149_597_870.700;
/// From NIST special publication 330, 2008 edition, in meters per second squared
pub const STD_GRAVITY: f64 = 9.80665;