use crate::recipes::scenarios;
use crate::SimulationBuilder;
use crate::SimulationTime;
pub struct Mission {
description: &'static str,
builder_fn: fn() -> SimulationBuilder,
time_override: Option<SimulationTime>,
}
impl Mission {
pub fn iss_leo() -> Self {
Self {
description: "ISS-class LEO; 3-DOF point-mass Earth gravity at J2000.",
builder_fn: scenarios::iss_leo::iss_leo,
time_override: None,
}
}
pub fn iss_leo_drag() -> Self {
Self {
description: "ISS-class LEO with MET solar-mean drag; 6-DOF identity attitude.",
builder_fn: scenarios::iss_leo::iss_leo_drag,
time_override: None,
}
}
pub fn apollo_translunar() -> Self {
Self {
description: "Apollo translunar trajectory; Earth + Moon + Sun gravity.",
builder_fn: scenarios::apollo::apollo_translunar,
time_override: None,
}
}
pub fn earth_moon_translunar() -> Self {
Self {
description: "Earth-Moon translunar trajectory; DE421 ephemeris.",
builder_fn: scenarios::earth_moon::earth_moon_translunar,
time_override: None,
}
}
pub fn geo() -> Self {
Self {
description: "Geostationary equatorial orbit at sidereal rate.",
builder_fn: scenarios::geostationary::geo,
time_override: None,
}
}
pub fn clementine_lunar() -> Self {
Self {
description: "Clementine lunar mission; 1994 launch epoch.",
builder_fn: scenarios::clementine_lunar::clementine_lunar,
time_override: None,
}
}
pub fn mars_orbit() -> Self {
Self {
description: "Mars-centered orbit; Sun perturbation, Dawn 2009 epoch.",
builder_fn: scenarios::mars_orbit::mars_orbit,
time_override: None,
}
}
pub fn mercury_relativistic() -> Self {
Self {
description: "Mercury heliocentric orbit; PPN relativistic corrections.",
builder_fn: scenarios::mercury::mercury_relativistic,
time_override: None,
}
}
pub fn description(&self) -> &'static str {
self.description
}
pub fn with_time(mut self, time: SimulationTime) -> Self {
self.time_override = Some(time);
self
}
pub fn into_builder(self) -> SimulationBuilder {
let mut sb = (self.builder_fn)();
if let Some(time) = self.time_override {
sb.time = time;
}
sb
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::recipes::epoch;
#[test]
fn each_constructor_returns_a_buildable_scenario() {
let _ = Mission::iss_leo().into_builder();
let _ = Mission::iss_leo_drag().into_builder();
let _ = Mission::apollo_translunar().into_builder();
let _ = Mission::earth_moon_translunar().into_builder();
let _ = Mission::geo().into_builder();
let _ = Mission::clementine_lunar().into_builder();
let _ = Mission::mars_orbit().into_builder();
let _ = Mission::mercury_relativistic().into_builder();
}
#[test]
fn description_is_non_empty() {
assert!(!Mission::iss_leo().description().is_empty());
assert!(!Mission::apollo_translunar().description().is_empty());
}
#[test]
fn with_time_overrides_simulation_epoch() {
let custom = epoch::clementine_1994();
let sb = Mission::iss_leo().with_time(custom).into_builder();
let default = Mission::iss_leo().into_builder();
assert_ne!(sb.time.tai_tjt_at_epoch, default.time.tai_tjt_at_epoch);
}
}