use crate::RotationModel;
use astrodyn_planet::PlanetShape;
use astrodyn_quantities::dims::GravParam;
use astrodyn_quantities::ext::F64Ext;
use astrodyn_quantities::frame::SelfPlanet;
use uom::si::f64::{AngularVelocity, Length};
#[derive(Debug, Clone, Copy)]
pub struct PlanetConfig {
pub shape: PlanetShape,
pub rotation_model: RotationModel,
pub omega: f64,
pub shadow_radius: f64,
}
impl PlanetConfig {
#[inline]
pub fn mu_typed(&self) -> GravParam<SelfPlanet> {
self.shape.mu_typed()
}
#[inline]
pub fn omega_typed(&self) -> AngularVelocity {
self.omega.rad_per_s()
}
#[inline]
pub fn shadow_radius_typed(&self) -> Length {
use uom::si::length::meter;
Length::new::<meter>(self.shadow_radius)
}
}
pub const EARTH: PlanetConfig = PlanetConfig {
shape: astrodyn_planet::presets::EARTH,
rotation_model: RotationModel::EarthRNP,
omega: 7.292_115_146_706_388e-5,
shadow_radius: 6_378_137.0,
};
pub const MOON: PlanetConfig = PlanetConfig {
shape: astrodyn_planet::presets::MOON,
rotation_model: RotationModel::MoonIAU,
omega: 0.0,
shadow_radius: 1_738_140.0,
};
pub const SUN: PlanetConfig = PlanetConfig {
shape: astrodyn_planet::presets::SUN,
rotation_model: RotationModel::None,
omega: 0.0,
shadow_radius: 696_000_000.0,
};
pub const MARS: PlanetConfig = PlanetConfig {
shape: astrodyn_planet::presets::MARS,
rotation_model: RotationModel::MarsIAU,
omega: 7.088_218e-5,
shadow_radius: 3_396_000.0,
};
pub const JUPITER: PlanetConfig = PlanetConfig {
shape: astrodyn_planet::presets::JUPITER,
rotation_model: RotationModel::None,
omega: 0.0,
shadow_radius: 71_492_000.0,
};
pub const SATURN: PlanetConfig = PlanetConfig {
shape: astrodyn_planet::presets::SATURN,
rotation_model: RotationModel::None,
omega: 0.0,
shadow_radius: 60_268_000.0,
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn earth_shadow_radius_matches_r_eq() {
assert_eq!(EARTH.shadow_radius, EARTH.shape.r_eq());
}
#[test]
fn sun_no_rotation() {
assert_eq!(SUN.rotation_model, RotationModel::None);
}
#[test]
fn all_configs_positive_radii() {
for config in [EARTH, MOON, SUN, MARS, JUPITER, SATURN] {
assert!(
config.shadow_radius > 0.0,
"{}: shadow_radius must be positive",
config.shape.name
);
assert!(
config.omega >= 0.0,
"{}: omega must be non-negative",
config.shape.name
);
assert!(
config.shape.r_pol() <= config.shape.r_eq(),
"{}: r_pol must not exceed r_eq (oblate only)",
config.shape.name
);
}
}
#[test]
fn jupiter_saturn_geometry_matches_jeod() {
assert_eq!(JUPITER.shape.r_eq().to_bits(), 71_492_000.0_f64.to_bits());
assert_eq!(JUPITER.shape.flat_coeff.to_bits(), 0.06487_f64.to_bits());
assert_eq!(
JUPITER.shape.r_pol().to_bits(),
(71_492_000.0_f64 * (1.0 - 0.06487)).to_bits()
);
assert_eq!(JUPITER.shape.mu.to_bits(), 1.267_312_29e17_f64.to_bits());
assert_eq!(SATURN.shape.r_eq().to_bits(), 60_268_000.0_f64.to_bits());
assert_eq!(SATURN.shape.flat_coeff.to_bits(), 0.09796_f64.to_bits());
assert_eq!(
SATURN.shape.r_pol().to_bits(),
(60_268_000.0_f64 * (1.0 - 0.09796)).to_bits()
);
assert_eq!(SATURN.shape.mu.to_bits(), 3.793_118_7e16_f64.to_bits());
}
}