use astrodyn_gravity::{GravityControl, GravityGradient};
use astrodyn_quantities::ext::Vec3Ext;
use glam::DVec3;
use crate::recipes::{constants, earth, epoch, moon, sun, vehicle};
use crate::vehicle_builder::VehicleBuilder;
use crate::SimulationBuilder;
pub const EARTH_IDX: usize = 0;
pub const MOON_IDX: usize = 1;
pub const SUN_IDX: usize = 2;
pub fn apollo_translunar() -> SimulationBuilder {
let mut sb = SimulationBuilder::new(epoch::j2000(), 60.0);
let earth_idx = sb.add_source("Earth", earth::point_mass());
debug_assert_eq!(earth_idx, EARTH_IDX);
let moon_idx = sb.add_source(
"Moon",
moon::third_body(
DVec3::new(3.85e8, 0.0, 0.0).m_at::<astrodyn_quantities::frame::RootInertial>(),
),
);
debug_assert_eq!(moon_idx, MOON_IDX);
let sun_idx = sb.add_source(
"Sun",
sun::third_body(
DVec3::new(1.496e11, 0.0, 0.0).m_at::<astrodyn_quantities::frame::RootInertial>(),
),
);
debug_assert_eq!(sun_idx, SUN_IDX);
sb = sb.sun(sun_idx).moon(moon_idx);
let r = 6_578_137.0; let v = (constants::mu_ggm05c().value / r).sqrt();
use astrodyn_dynamics::state::TranslationalStateTyped;
use astrodyn_quantities::frame::RootInertial;
let csm_state = TranslationalStateTyped::<RootInertial> {
position: DVec3::new(r, 0.0, 0.0).m_at::<RootInertial>(),
velocity: DVec3::new(0.0, v, 0.0).m_per_s_at::<RootInertial>(),
};
let csm = VehicleBuilder::new()
.with_translational(csm_state)
.three_dof_point_mass(vehicle::apollo_csm_mass())
.rk4()
.gravity(GravityControl::new_spherical(
earth_idx,
GravityGradient::Skip,
))
.gravity(GravityControl::new_third_body(moon_idx))
.gravity(GravityControl::new_third_body(sun_idx))
.build();
sb.add_body(csm);
sb
}