diff --git a/examples/01_orbit_prop/main.rs b/examples/01_orbit_prop/main.rs index aa95d6c1..1ad949d3 100644 --- a/examples/01_orbit_prop/main.rs +++ b/examples/01_orbit_prop/main.rs @@ -105,7 +105,7 @@ fn main() -> Result<(), Box> { // Set up the spacecraft dynamics. // Specify that the orbital dynamics must account for the graviational pull of the Moon and the Sun. - // The gravity of the Earth will also be accounted for since the spaceraft in an Earth orbit. + // The gravity of the Earth will also be accounted for since the spacecraft in an Earth orbit. let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]); // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud. diff --git a/examples/03_geo_analysis/drift.rs b/examples/03_geo_analysis/drift.rs index 3b500c42..0cb0002b 100644 --- a/examples/03_geo_analysis/drift.rs +++ b/examples/03_geo_analysis/drift.rs @@ -72,7 +72,7 @@ fn main() -> Result<(), Box> { // Set up the spacecraft dynamics. // Specify that the orbital dynamics must account for the graviational pull of the Moon and the Sun. - // The gravity of the Earth will also be accounted for since the spaceraft in an Earth orbit. + // The gravity of the Earth will also be accounted for since the spacecraft in an Earth orbit. let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]); // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud. diff --git a/examples/03_geo_analysis/raise.rs b/examples/03_geo_analysis/raise.rs index 62baa3ad..80c14e82 100644 --- a/examples/03_geo_analysis/raise.rs +++ b/examples/03_geo_analysis/raise.rs @@ -79,7 +79,7 @@ fn main() -> Result<(), Box> { // Set up the spacecraft dynamics. // Specify that the orbital dynamics must account for the graviational pull of the Moon and the Sun. - // The gravity of the Earth will also be accounted for since the spaceraft in an Earth orbit. + // The gravity of the Earth will also be accounted for since the spacecraft in an Earth orbit. let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]); // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud. diff --git a/examples/04_lro_od/main.rs b/examples/04_lro_od/main.rs index 3c2ba24e..40e607f4 100644 --- a/examples/04_lro_od/main.rs +++ b/examples/04_lro_od/main.rs @@ -109,7 +109,7 @@ fn main() -> Result<(), Box> { // Set up the spacecraft dynamics. // Specify that the orbital dynamics must account for the graviational pull of the Earth and the Sun. - // The gravity of the Moon will also be accounted for since the spaceraft in a lunar orbit. + // The gravity of the Moon will also be accounted for since the spacecraft in a lunar orbit. let mut orbital_dyn = OrbitalDynamics::point_masses(vec![EARTH, SUN, JUPITER_BARYCENTER]); // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud. diff --git a/src/dynamics/drag.rs b/src/dynamics/drag.rs index 1a32d238..a69c27b3 100644 --- a/src/dynamics/drag.rs +++ b/src/dynamics/drag.rs @@ -36,18 +36,18 @@ pub enum AtmDensity { StdAtm { max_alt_m: f64 }, } -/// `ConstantDrag` implements a constant drag model as defined in Vallado, 4th ed., page 551, with an important caveat. +/// Implements a constant drag model as defined in Vallado, 4th ed., page 551. /// -/// **WARNING:** This basic model assumes that the velocity of the spacecraft is identical to the velocity of the upper atmosphere, -/// This is a **bad** assumption and **should not** be used for high fidelity simulations. -/// This will be resolved after https://gitlab.com/chrisrabotin/nyx/issues/93 is implemented. +/// **WARNING:** This model assumes the spacecraft velocity is identical to the upper atmosphere velocity, +/// which is a significant simplification. Not for high-fidelity simulations. +/// This will be resolved after https://github.com/nyx-space/nyx/issues/93 is implemented. #[derive(Clone)] pub struct ConstantDrag { - /// atmospheric density in kg/m^3 + /// Atmospheric density in kg/m^3. pub rho: f64, - /// Geoid causing the drag + /// Geoid causing the drag. pub drag_frame: Frame, - /// Set to true to estimate the coefficient of drag + /// Set to true to estimate the coefficient of drag. pub estimate: bool, } @@ -78,7 +78,7 @@ impl ForceModel for ConstantDrag { })?; let velocity = osc.velocity_km_s; - // Note the 1e3 factor to convert drag units from ((kg * km^2 * s^-2) / m^1) to (kg * km * s^-2) + // A factor of 1e3 is needed to convert the acceleration to km/s^2. Ok(-0.5 * 1e3 * self.rho @@ -99,14 +99,14 @@ impl ForceModel for ConstantDrag { } } -/// `Drag` implements all three drag models. +/// Implements three drag models. #[derive(Clone)] pub struct Drag { - /// Density computation method + /// The density computation method. pub density: AtmDensity, - /// Frame to compute the drag in + /// The frame to compute the drag in. pub drag_frame: Frame, - /// Set to true to estimate the coefficient of drag + /// Set to true to estimate the coefficient of drag. pub estimate: bool, } @@ -175,7 +175,7 @@ impl ForceModel for Drag { match self.density { AtmDensity::Constant(rho) => { let velocity = osc_drag_frame.velocity_km_s; - // Note the 1e3 factor to convert drag units from ((kg * km^2 * s^-2) / m^1) to (kg * km * s^-2) + // A factor of 1e3 is needed to convert the acceleration to km/s^2. Ok(-0.5 * 1e3 * rho @@ -202,8 +202,8 @@ impl ForceModel for Drag { / ref_alt_m) .exp(); - // TODO: Drag modeling will be improved in https://github.com/nyx-space/nyx/issues/317 - // The frame will be double checked in this PR as well. + // TODO: Drag modeling will be improved in https://github.com/nyx-space/nyx/issues/317. + // The frame will be double-checked in this PR as well. let velocity_integr_frame = almanac .transform_to(osc_drag_frame, integration_frame, None) .context(DynamicsAlmanacSnafu { @@ -212,7 +212,7 @@ impl ForceModel for Drag { .velocity_km_s; let velocity = velocity_integr_frame - osc_drag_frame.velocity_km_s; - // Note the 1e3 factor to convert drag units from ((kg * km^2 * s^-2) / m^1) to (kg * km * s^-2) + // A factor of 1e3 is needed to convert the acceleration to km/s^2. Ok(-0.5 * 1e3 * rho @@ -230,11 +230,11 @@ impl ForceModel for Drag { .context(AstroPhysicsSnafu) .context(DynamicsAstroSnafu)?; let rho = if altitude_km > max_alt_m / 1_000.0 { - // Use a constant density + // Use a constant density. 10.0_f64.powf((-7e-5) * altitude_km - 14.464) } else { - // Code from AVS/Schaub's Basilisk - // Calculating the density based on a scaled 6th order polynomial fit to the log of density + // Code from AVS/Schaub's Basilisk. + // Calculating the density based on a scaled 6th order polynomial fit to the log of density. let scale = (altitude_km - 526.8000) / 292.8563; let logdensity = 0.34047 * scale.powi(6) - 0.5889 * scale.powi(5) - 0.5269 * scale.powi(4) @@ -243,7 +243,7 @@ impl ForceModel for Drag { - 2.3024 * scale - 12.575; - /* Calculating density by raising 10 to the log of density */ + // Calculating density by raising 10 to the log of density. 10.0_f64.powf(logdensity) }; @@ -255,7 +255,7 @@ impl ForceModel for Drag { .velocity_km_s; let velocity = velocity_integr_frame - osc_drag_frame.velocity_km_s; - // Note the 1e3 factor to convert drag units from ((kg * km^2 * s^-2) / m^1) to (kg * km * s^-2) + // A factor of 1e3 is needed to convert the acceleration to km/s^2. Ok(-0.5 * 1e3 * rho diff --git a/src/dynamics/mod.rs b/src/dynamics/mod.rs index 166bb6d7..6129e160 100644 --- a/src/dynamics/mod.rs +++ b/src/dynamics/mod.rs @@ -31,43 +31,42 @@ use std::sync::Arc; pub use crate::errors::NyxError; -/// The orbital module handles all Cartesian based orbital dynamics. +/// Cartesian-based orbital dynamics. /// -/// It is up to the engineer to ensure that the coordinate frames of the different dynamics borrowed -/// from this module match, or perform the appropriate coordinate transformations. +/// Ensure coordinate frames match or perform transformations when combining dynamics. pub mod orbital; use self::guidance::GuidanceError; pub use self::orbital::*; -/// The spacecraft module allows for simulation of spacecraft dynamics in general, including propulsion/maneuvers. +/// Spacecraft dynamics, including propulsion and maneuvers. pub mod spacecraft; pub use self::spacecraft::*; -/// Defines a few examples of guidance laws. +/// Guidance laws. pub mod guidance; -/// Defines some velocity change controllers. +/// Velocity change controllers. pub mod deltavctrl; -/// Defines solar radiation pressure models +/// Solar radiation pressure models. pub mod solarpressure; pub use self::solarpressure::*; -/// The drag module handles drag in a very basic fashion. Do not use for high fidelity dynamics. +/// Atmospheric drag models. pub mod drag; pub use self::drag::*; -/// Define the spherical harmonic models. -/// This module allows loading gravity models from [PDS](http://pds-geosciences.wustl.edu/), [EGM2008](http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008/) and GMAT's own COF files. +/// Spherical harmonic gravity models. +/// +/// Supports loading models from PDS, EGM2008, and GMAT's COF files. pub mod sph_harmonics; pub use self::sph_harmonics::*; -/// The `Dynamics` trait handles and stores any equation of motion *and* the state is integrated. +/// A trait for models with equations of motion that can be integrated. /// -/// Its design is such that several of the provided dynamics can be combined fairly easily. However, -/// when combining the dynamics (e.g. integrating both the attitude of a spaceraft and its orbital -/// parameters), it is up to the implementor to handle time and state organization correctly. -/// For time management, I highly recommend using `hifitime` which is thoroughly validated. +/// This trait is designed for composition, allowing different dynamics to be combined. +/// When combining dynamics, ensure that time and state are handled consistently. +/// `hifitime` is recommended for time management. #[allow(clippy::type_complexity)] pub trait Dynamics: Clone + Sync + Send where @@ -79,11 +78,11 @@ where type HyperdualSize: DimName; type StateType: State; - /// Defines the equations of motion for these dynamics, or a combination of provided dynamics. - /// The time delta_t is in **seconds** PAST the context epoch. The state vector is the state which - /// changes for every intermediate step of the integration. The state context is the state of - /// what is being propagated, it should allow rebuilding a new state context from the - /// provided state vector. + /// Defines the equations of motion. + /// + /// - `delta_t`: Time in seconds past the context epoch. + /// - `state_vec`: The state vector, which changes at each integration step. + /// - `state_ctx`: The state context, used to rebuild the state from the state vector. fn eom( &self, delta_t: f64, @@ -94,9 +93,9 @@ where where DefaultAllocator: Allocator<::VecLength>; - /// Defines the equations of motion for Dual numbers for these dynamics. - /// _All_ dynamics need to allow for automatic differentiation. However, if differentiation is not supported, - /// then the dynamics should prevent initialization with a context which has an STM defined. + /// Defines the equations of motion for dual numbers, enabling automatic differentiation. + /// + /// If differentiation is not supported, this function should prevent initialization with a context that has an STM defined. fn dual_eom( &self, _delta_t: f64, @@ -118,9 +117,9 @@ where Err(DynamicsError::StateTransitionMatrixUnset) } - /// Optionally performs some final changes after each successful integration of the equations of motion. - /// For example, this can be used to update the Guidance mode. - /// NOTE: This function is also called just prior to very first integration step in order to update the initial state if needed. + /// Performs final changes after each successful integration step. + /// + /// Also called before the first integration step to update the initial state if needed. fn finally( &self, next_state: Self::StateType, @@ -130,19 +129,19 @@ where } } -/// The `ForceModel` trait handles immutable dynamics which return a force. Those will be divided by the mass of the spacecraft to compute the acceleration (F = ma). +/// A trait for immutable dynamics that return a force (e.g., solar radiation pressure, drag). /// -/// Examples include Solar Radiation Pressure, drag, etc., i.e. forces which do not need to save the current state, only act on it. +/// The force is divided by the spacecraft's mass to compute acceleration (F=ma). pub trait ForceModel: Send + Sync + fmt::Display { - /// If a parameter of this force model is stored in the spacecraft state, then this function should return the index where this parameter is being affected + /// Returns the estimation index if a parameter of this force model is stored in the spacecraft state. fn estimation_index(&self) -> Option; - /// Defines the equations of motion for this force model from the provided osculating state. + /// Defines the equations of motion for this force model. fn eom(&self, ctx: &Spacecraft, almanac: Arc) -> Result, DynamicsError>; - /// Force models must implement their partials, although those will only be called if the propagation requires the - /// computation of the STM. The `osc_ctx` is the osculating context, i.e. it changes for each sub-step of the integrator. - /// The last row corresponds to the partials of the parameter of this force model wrt the position, i.e. this only applies to conservative forces. + /// Defines the partial derivatives of the equations of motion. + /// + /// The last row corresponds to the partials of the parameter of this force model with respect to position, which only applies to conservative forces. fn dual_eom( &self, osc_ctx: &Spacecraft, @@ -150,15 +149,12 @@ pub trait ForceModel: Send + Sync + fmt::Display { ) -> Result<(Vector3, Matrix4x3), DynamicsError>; } -/// The `AccelModel` trait handles immutable dynamics which return an acceleration. Those can be added directly to Orbital Dynamics for example. -/// -/// Examples include spherical harmonics, i.e. accelerations which do not need to save the current state, only act on it. +/// A trait for immutable dynamics that return an acceleration (e.g., spherical harmonics). pub trait AccelModel: Send + Sync + fmt::Display { - /// Defines the equations of motion for this force model from the provided osculating state in the integration frame. + /// Defines the equations of motion for this acceleration model. fn eom(&self, osc: &Orbit, almanac: Arc) -> Result, DynamicsError>; - /// Acceleration models must implement their partials, although those will only be called if the propagation requires the - /// computation of the STM. + /// Defines the partial derivatives of the equations of motion. fn dual_eom( &self, osc_ctx: &Orbit, @@ -166,25 +162,30 @@ pub trait AccelModel: Send + Sync + fmt::Display { ) -> Result<(Vector3, Matrix3), DynamicsError>; } -/// Stores dynamical model errors +/// Dynamical model errors. #[derive(Debug, PartialEq, Snafu)] #[snafu(visibility(pub(crate)))] pub enum DynamicsError { - /// Fuel exhausted at the provided spacecraft state + /// Fuel exhausted. #[snafu(display("fuel exhausted at {sc}"))] FuelExhausted { sc: Box }, + /// State Transition Matrix (STM) was expected but not set. #[snafu(display("expected STM to be set"))] StateTransitionMatrixUnset, + /// Astrodynamics error. #[snafu(display("dynamical model encountered an astro error: {source}"))] DynamicsAstro { source: AstroError }, + /// Guidance error. #[snafu(display("dynamical model encountered an issue with the guidance: {source}"))] DynamicsGuidance { source: GuidanceError }, + /// Almanac error. #[snafu(display("dynamical model issue due to Almanac: {action} {source}"))] DynamicsAlmanacError { action: &'static str, #[snafu(source(from(AlmanacError, Box::new)))] source: Box, }, + /// Planetary data error. #[snafu(display("dynamical model issue due to planetary data: {action} {source}"))] DynamicsPlanetaryError { action: &'static str, diff --git a/src/dynamics/orbital.rs b/src/dynamics/orbital.rs index e14ced9e..c67e79b5 100644 --- a/src/dynamics/orbital.rs +++ b/src/dynamics/orbital.rs @@ -33,31 +33,31 @@ use std::sync::Arc; pub use super::sph_harmonics::Harmonics; -/// `OrbitalDynamics` provides the equations of motion for any celestial dynamic, without state transition matrix computation. +/// Equations of motion for celestial dynamics. #[derive(Clone)] pub struct OrbitalDynamics { pub accel_models: Vec>, } impl OrbitalDynamics { - /// Initializes the point masses gravities with the provided list of bodies + /// Initializes the dynamics with point mass gravity from a list of celestial bodies. pub fn point_masses(celestial_objects: Vec) -> Self { - // Create the point masses Self::new(vec![PointMasses::new(celestial_objects)]) } - /// Initializes a OrbitalDynamics which does not simulate the gravity pull of other celestial objects but the primary one. + /// Initializes two-body dynamics, which only simulate the gravity of the primary body. pub fn two_body() -> Self { Self::new(vec![]) } - /// Initialize orbital dynamics with a list of acceleration models + /// Initializes orbital dynamics with a list of acceleration models. pub fn new(accel_models: Vec>) -> Self { Self { accel_models } } - /// Initialize new orbital mechanics with the provided model. - /// **Note:** Orbital dynamics _always_ include two body dynamics, these cannot be turned off. + /// Initializes orbital dynamics with a single acceleration model. + /// + /// **Note:** Two-body dynamics are always included and cannot be disabled. pub fn from_model(accel_model: Arc) -> Self { Self::new(vec![accel_model]) } @@ -166,15 +166,15 @@ impl OrbitalDynamics { } } -/// PointMasses model +/// A point mass gravity model. pub struct PointMasses { pub celestial_objects: Vec, - /// Light-time correction computation if extra point masses are needed + /// Light-time correction. pub correction: Option, } impl PointMasses { - /// Initializes the point masses gravities with the provided list of bodies + /// Initializes the point mass gravity model with a list of celestial bodies. pub fn new(celestial_objects: Vec) -> Arc { Arc::new(Self { celestial_objects, @@ -182,7 +182,7 @@ impl PointMasses { }) } - /// Initializes the point masses gravities with the provided list of bodies, and accounting for some light time correction + /// Initializes the point mass gravity model with a list of celestial bodies and a light-time correction. pub fn with_correction(celestial_objects: Vec, correction: Aberration) -> Self { Self { celestial_objects, diff --git a/src/dynamics/solarpressure.rs b/src/dynamics/solarpressure.rs index f6cdcad4..0f3b36ca 100644 --- a/src/dynamics/solarpressure.rs +++ b/src/dynamics/solarpressure.rs @@ -32,18 +32,18 @@ use std::sync::Arc; #[allow(non_upper_case_globals)] pub const SOLAR_FLUX_W_m2: f64 = 1367.0; -/// Computation of solar radiation pressure is based on STK: http://help.agi.com/stk/index.htm#gator/eq-solar.htm . +/// A solar radiation pressure model, based on the STK model. #[derive(Clone)] pub struct SolarPressure { - /// solar flux at 1 AU, in W/m^2 + /// Solar flux at 1 AU, in W/m^2. pub phi: f64, pub e_loc: EclipseLocator, - /// Set to true to estimate the coefficient of reflectivity + /// Set to true to estimate the coefficient of reflectivity. pub estimate: bool, } impl SolarPressure { - /// Will set the solar flux at 1 AU to: Phi = 1367.0 + /// Initializes the model with the default solar flux (1367.0 W/m^2). pub fn default_raw( shadow_bodies: Vec, almanac: Arc, @@ -72,12 +72,12 @@ impl SolarPressure { }) } - /// Accounts for the shadowing of only one body and will set the solar flux at 1 AU to: Phi = 1367.0 + /// Initializes the model with default settings, accounting for shadowing from a single celestial body. pub fn default(shadow_body: Frame, almanac: Arc) -> Result, DynamicsError> { Ok(Arc::new(Self::default_raw(vec![shadow_body], almanac)?)) } - /// Accounts for the shadowing of only one body and will set the solar flux at 1 AU to: Phi = 1367.0 + /// Initializes the model with default settings, with reflectivity estimation disabled. pub fn default_no_estimation( shadow_bodies: Vec, almanac: Arc, @@ -87,7 +87,7 @@ impl SolarPressure { Ok(Arc::new(srp)) } - /// Must provide the flux in W/m^2 + /// Initializes the model with a custom solar flux. pub fn with_flux( flux_w_m2: f64, shadow_bodies: Vec, @@ -98,7 +98,7 @@ impl SolarPressure { Ok(Arc::new(me)) } - /// Solar radiation pressure force model accounting for the provided shadow bodies. + /// Initializes the model, accounting for shadowing from a list of celestial bodies. pub fn new( shadow_bodies: Vec, almanac: Arc, diff --git a/src/dynamics/spacecraft.rs b/src/dynamics/spacecraft.rs index b838de3f..983b3ea4 100644 --- a/src/dynamics/spacecraft.rs +++ b/src/dynamics/spacecraft.rs @@ -37,9 +37,9 @@ use crate::cosmic::AstroError; const NORM_ERR: f64 = 1e-4; -/// A generic spacecraft dynamics with associated force models, guidance law, and flag specifying whether to decrement the prop mass or not. -/// Note: when developing new guidance laws, it is recommended to _not_ enable prop decrement until the guidance law seems to work without proper physics. -/// Note: if the spacecraft runs out of prop, the propagation segment will return an error. +/// A generic spacecraft dynamics model. +/// +/// **Note:** If the spacecraft runs out of propellant, the propagation will return an error. #[derive(Clone)] pub struct SpacecraftDynamics { pub orbital_dyn: OrbitalDynamics, @@ -50,8 +50,9 @@ pub struct SpacecraftDynamics { } impl SpacecraftDynamics { - /// Initialize a Spacecraft with a set of orbital dynamics and a propulsion subsystem. - /// By default, the mass of the vehicle will be decremented as propellant is consumed. + /// Initializes the dynamics with a guidance law. + /// + /// By default, the spacecraft's mass will be decremented as propellant is consumed. pub fn from_guidance_law(orbital_dyn: OrbitalDynamics, guid_law: Arc) -> Self { Self { orbital_dyn, @@ -61,8 +62,7 @@ impl SpacecraftDynamics { } } - /// Initialize a Spacecraft with a set of orbital dynamics and a propulsion subsystem. - /// Will _not_ decrement the prop mass as propellant is consumed. + /// Initializes the dynamics with a guidance law, but without mass decrement. pub fn from_guidance_law_no_decr( orbital_dyn: OrbitalDynamics, guid_law: Arc, @@ -75,7 +75,7 @@ impl SpacecraftDynamics { } } - /// Initialize a Spacecraft with a set of orbital dynamics and with SRP enabled. + /// Initializes the dynamics with orbital dynamics. pub fn new(orbital_dyn: OrbitalDynamics) -> Self { Self { orbital_dyn, @@ -85,7 +85,7 @@ impl SpacecraftDynamics { } } - /// Initialize new spacecraft dynamics with the provided orbital mechanics and with the provided force model. + /// Initializes the dynamics with a single force model. pub fn from_model(orbital_dyn: OrbitalDynamics, force_model: Arc) -> Self { Self { orbital_dyn, @@ -95,7 +95,7 @@ impl SpacecraftDynamics { } } - /// Initialize new spacecraft dynamics with a vector of force models. + /// Initializes the dynamics with a list of force models. pub fn from_models( orbital_dyn: OrbitalDynamics, force_models: Vec>, @@ -105,7 +105,7 @@ impl SpacecraftDynamics { me } - /// A shortcut to spacecraft.guid_law if a guidance law is defined for these dynamics + /// Returns whether the guidance objective has been achieved. pub fn guidance_achieved(&self, state: &Spacecraft) -> Result { match &self.guid_law { Some(guid_law) => guid_law.achieved(state), @@ -113,7 +113,7 @@ impl SpacecraftDynamics { } } - /// Clone these spacecraft dynamics and update the control to the one provided. + /// Clones these dynamics and sets the guidance law. pub fn with_guidance_law(&self, guid_law: Arc) -> Self { Self { orbital_dyn: self.orbital_dyn.clone(), diff --git a/src/dynamics/sph_harmonics.rs b/src/dynamics/sph_harmonics.rs index f070902b..ae07c282 100644 --- a/src/dynamics/sph_harmonics.rs +++ b/src/dynamics/sph_harmonics.rs @@ -32,6 +32,7 @@ use std::sync::Arc; use super::{DynamicsAlmanacSnafu, DynamicsAstroSnafu, DynamicsError}; +/// A spherical harmonics gravity model. #[derive(Clone)] pub struct Harmonics { compute_frame: Frame, @@ -49,7 +50,7 @@ pub struct Harmonics { } impl Harmonics { - /// Create a new Harmonics dynamical model from the provided gravity potential storage instance. + /// Creates a new harmonics model from a gravity potential storage instance. pub fn from_stor(compute_frame: Frame, stor: HarmonicsMem) -> Arc { let degree_np2 = stor.max_degree_n() + 2; let mut a_nm = DMatrix::from_element(degree_np2 + 1, degree_np2 + 1, 0.0); diff --git a/src/lib.rs b/src/lib.rs index 78abce9f..d5430b92 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,9 +18,9 @@ /*! # nyx-space -[Nyx](https://en.wikipedia.org/wiki/Nyx): Blazing fast high-fidelity astrodynamics for Monte Carlo analyzes of constellations, interplanetary missions, and deep space flight navigation. +[Nyx](https://en.wikipedia.org/wiki/Nyx): High-fidelity, fast astrodynamics toolkit for spacecraft navigation, mission design, and Monte Carlo analyses. -Refer to [nyxspace.com](https://nyxspace.com) for a user guide, a show case, the MathSpec, and the validation data. +Refer to the [user guide](https://nyxspace.com) for more information. */ // Allow confusable identifiers, as the code tries to use the literature's notation where possible. @@ -28,38 +28,38 @@ Refer to [nyxspace.com](https://nyxspace.com) for a user guide, a show case, the extern crate log; -/// Provides all the propagators / integrators available in `nyx`. +/// Numerical propagators and integrators. pub mod propagators; -/// Provides several dynamics used for orbital mechanics and attitude dynamics, which can be elegantly combined. +/// Orbital and attitude dynamics which can be elegantly combined. pub mod dynamics; -/// Provides the solar system planets, and state and ephemerides management. +/// Solar system bodies, state, and ephemerides management. pub mod cosmic; -/// Utility functions shared by different modules, and which may be useful to engineers. +/// Shared utilities. pub mod utils; pub mod errors; -/// Nyx will (almost) never panic and functions which may fail will return an error. +/// Nyx's error handling. pub use self::errors::NyxError; -/// All the input/output needs for this library, including loading of SPICE kernels, and gravity potential files. +/// I/O for SPICE kernels, gravity models, and more. pub mod io; -/// All the orbital determination and spacecraft navigation tools and functions. +/// Orbit determination and spacecraft navigation. pub mod od; -/// All of the mission design and mission analysis tools and functions +/// Mission design and analysis. pub mod md; -/// Simple tools (e.g. Lambert solver) +/// Standalone astrodynamics tools. pub mod tools; -/// Monte Carlo module +/// Monte Carlo simulations. pub mod mc; -/// Polynomial and fitting module +/// Polynomial fitting and interpolation. pub mod polyfit; /// Re-export of hifitime diff --git a/src/od/simulator/scheduler.rs b/src/od/simulator/scheduler.rs index e1977f15..96c09df8 100644 --- a/src/od/simulator/scheduler.rs +++ b/src/od/simulator/scheduler.rs @@ -43,7 +43,7 @@ impl Default for Handoff { } } -/// A scheduler allows building a scheduling of spaceraft tracking for a set of ground stations. +/// A scheduler allows building a scheduling of spacecraft tracking for a set of ground stations. #[derive(Copy, Clone, Debug, Default, Deserialize, PartialEq, Serialize, TypedBuilder)] #[builder(doc)] pub struct Scheduler { diff --git a/src/propagators/error_ctrl.rs b/src/propagators/error_ctrl.rs index d3c0b232..0137f7ad 100644 --- a/src/propagators/error_ctrl.rs +++ b/src/propagators/error_ctrl.rs @@ -25,56 +25,27 @@ use crate::linalg::{DefaultAllocator, DimName, OVector, U3}; // prevents dividing by too small of a number. const REL_ERR_THRESH: f64 = 0.1; -/// The Error Control manages how a propagator computes the error in the current step. +/// Manages how a propagator computes the error in the current step. #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum ErrorControl { - /// An RSS state error control which effectively for the provided vector composed of two vectors of the same unit, both of size 3 (e.g. position + velocity). + /// An RSS state error control for Cartesian states (e.g., position and velocity). RSSCartesianState, - /// An RSS step error control which effectively for the provided vector composed of two vectors of the same unit, both of size 3 (e.g. position + velocity). + /// An RSS step error control for Cartesian states (e.g., position and velocity). RSSCartesianStep, - /// An RSS state error control: when in doubt, use this error controller, especially for high accurracy. - /// - /// Here is the warning from GMAT R2016a on this error controller: - /// > This is a more stringent error control method than [`rss_step`] that is often used as the default in other software such as STK. - /// > If you set [the] accuracy to a very small number, 1e-13 for example, and set the error control to [`rss_step`], integrator - /// > performance will be poor, for little if any improvement in the accuracy of the orbit integration. - /// > For more best practices of these integrators (which clone those in GMAT), please refer to the - /// > [GMAT reference](https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/doc/help/src/Resource_NumericalIntegrators.xml#L1292). - /// > (Source)[https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/forcemodel/ODEModel.cpp#L3004] + /// An RSS state error control. Recommended for high-accuracy simulations. RSSState, - /// An RSS step error control which effectively computes the L2 norm of the provided Vector of size 3 - /// - /// Note that this error controller should be preferably be used only with slices of a state with the same units. - /// For example, one should probably use this for position independently of using it for the velocity. - /// (Source)[https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/forcemodel/ODEModel.cpp#L3045] + /// An RSS step error control. Should only be used with state slices that have the same units. RSSStep, - /// A largest error control which effectively computes the largest error at each component - /// - /// This is a standard error computation algorithm, but it's arguably bad if the state's components have different units. - /// It calculates the largest local estimate of the error from the integration (`error_est`) - /// given the difference in the candidate state and the previous state (`state_delta`). - /// This error estimator is from the physical model estimator of GMAT - /// (Source)[https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/forcemodel/PhysicalModel.cpp#L987] + /// Computes the largest error at each component. Not recommended for states with mixed units. LargestError, - /// A largest state error control - /// - /// (Source)[https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/forcemodel/ODEModel.cpp#L3018] + /// A largest state error control. LargestState, - - /// A largest step error control which effectively computes the L1 norm of the provided Vector of size 3 - /// - /// Note that this error controller should be preferably be used only with slices of a state with the same units. - /// For example, one should probably use this for position independently of using it for the velocity. - /// (Source)[https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/forcemodel/ODEModel.cpp#L3033] + /// A largest step error control. Should only be used with state slices that have the same units. LargestStep, } impl ErrorControl { - /// Computes the actual error of the current step. - /// - /// The `error_est` is the estimated error computed from the difference in the two stages of - /// of the RK propagator. The `candidate` variable is the candidate state, and `cur_state` is - /// the current state. This function must return the error. + /// Computes the error of the current step. pub fn estimate( self, error_est: &OVector, @@ -192,11 +163,6 @@ impl Default for ErrorControl { } } -/// An RSS step error control which effectively computes the L2 norm of the provided Vector of size 3 -/// -/// Note that this error controller should be preferably be used only with slices of a state with the same units. -/// For example, one should probably use this for position independently of using it for the velocity. -/// (Source)[https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/forcemodel/ODEModel.cpp#L3045] #[derive(Clone, Copy)] #[allow(clippy::upper_case_acronyms)] struct RSSStep; @@ -219,15 +185,6 @@ impl RSSStep { } } -/// An RSS state error control: when in doubt, use this error controller, especially for high accurracy. -/// -/// Here is the warning from GMAT R2016a on this error controller: -/// > This is a more stringent error control method than [`rss_step`] that is often used as the default in other software such as STK. -/// > If you set [the] accuracy to a very small number, 1e-13 for example, and set the error control to [`rss_step`], integrator -/// > performance will be poor, for little if any improvement in the accuracy of the orbit integration. -/// > For more best practices of these integrators (which clone those in GMAT), please refer to the -/// > [GMAT reference](https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/doc/help/src/Resource_NumericalIntegrators.xml#L1292). -/// > (Source)[https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/forcemodel/ODEModel.cpp#L3004] #[derive(Clone, Copy)] #[allow(clippy::upper_case_acronyms)] struct RSSState; diff --git a/src/propagators/mod.rs b/src/propagators/mod.rs index 4e21af41..90ab5167 100644 --- a/src/propagators/mod.rs +++ b/src/propagators/mod.rs @@ -20,7 +20,7 @@ use anise::errors::MathError; use snafu::prelude::*; use std::fmt; -/// Provides different methods for controlling the error computation of the integrator. +/// Integrator error control methods. pub mod error_ctrl; pub use self::error_ctrl::*; @@ -36,14 +36,14 @@ use crate::{dynamics::DynamicsError, errors::EventError, io::ConfigError, time:: pub use options::*; use serde::{Deserialize, Serialize}; -/// Stores the details of the previous integration step of a given propagator. Access as `my_prop.clone().latest_details()`. +/// Stores the details of the previous integration step. #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct IntegrationDetails { - /// step size used + /// The step size used. pub step: Duration, - /// error in the previous integration step + /// The error in the previous integration step. pub error: f64, - /// number of attempts needed by an adaptive step size to be within the tolerance + /// The number of attempts needed by an adaptive step size controller to meet the tolerance. pub attempts: u8, } @@ -57,16 +57,22 @@ impl fmt::Display for IntegrationDetails { } } +/// Propagation errors. #[derive(Debug, PartialEq, Snafu)] pub enum PropagationError { + /// A dynamics error was encountered. #[snafu(display("encountered a dynamics error {source}"))] Dynamics { source: DynamicsError }, + /// An error was encountered when propagating until an event. #[snafu(display("when propagating until an event: {source}"))] TrajectoryEventError { source: EventError }, + /// The requested event could not be found. #[snafu(display("requested propagation until event #{nth} but only {found} found"))] NthEventError { nth: usize, found: usize }, + /// A configuration error was encountered. #[snafu(display("propagation failed because {source}"))] PropConfigError { source: ConfigError }, + /// A math error was encountered. #[snafu(display("propagation encountered a math error {source}"))] PropMathError { source: MathError }, } diff --git a/tests/propagation/trajectory.rs b/tests/propagation/trajectory.rs index 4fb08da3..05d41e14 100644 --- a/tests/propagation/trajectory.rs +++ b/tests/propagation/trajectory.rs @@ -266,7 +266,7 @@ fn traj_ephem_forward_cov_test(almanac: Arc) { #[rstest] fn traj_spacecraft(almanac: Arc) { let _ = pretty_env_logger::try_init(); - // Test the interpolation of a spaceraft trajectory and of its prop. Includes a demo of checking what the guidance mode _should_ be provided the state. + // Test the interpolation of a spacecraft trajectory and of its prop. Includes a demo of checking what the guidance mode _should_ be provided the state. // Note that we _do not_ attempt to interpolate the Guidance Mode. // This is based on the Ruggiero AOP correction @@ -305,7 +305,7 @@ fn traj_spacecraft(almanac: Arc) { let mut prop = setup.with(start_state, almanac.clone()); let (end_state, traj) = prop.for_duration_with_traj(prop_time).unwrap(); - // Example of iterating through the spaceraft trajectory and checking what the guidance mode is at each time. + // Example of iterating through the spacecraft trajectory and checking what the guidance mode is at each time. let mut prev_mode = GuidanceMode::Coast; // But let's now iterate over the trajectory every day instead of every minute