Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions crates/astrodyn_verif_jeod/src/run_verification/sim_dyncomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,10 @@ fn build_run10a(init: &InitialConditions) -> SimulationBuilder {
build_run10(init, "run10a")
}

fn build_run10b(init: &InitialConditions) -> SimulationBuilder {
build_run10(init, "run10b")
}

fn build_run10c(init: &InitialConditions) -> SimulationBuilder {
build_run10(init, "run10c")
}
Expand Down Expand Up @@ -1338,6 +1342,36 @@ pub fn run10a_gravity_torque() -> VerificationCase {
}
}

/// SIM_dyncomp RUN_10B — gravity-gradient torque, circular orbit,
/// cylinder mass, with a small initial LVLH pitch rate.
///
/// Identical to RUN_10A (gravity-gradient libration of the 1000 kg
/// cylinder at 85° pitch / 1° yaw from LVLH) except JEOD's
/// `RUN_10B/input.py` adds `vehicle.lvlh_init.ang_velocity =
/// [0, 0.01, 0] deg/s` — a 0.01 deg/s rate on the LVLH pitch axis. That
/// rate is baked into the t=0 row of `dyncomp_run10b_state.csv` (read by
Comment thread
simnaut marked this conversation as resolved.
/// `rot_from`), so the scenario builder is shared with RUN_10A.
pub fn run10b_gravity_torque_circular_rate() -> VerificationCase {
VerificationCase {
name: "tier3_simulation_run10b_gravity_torque_circular_rate",
scenario: build_run10b,
reference: CsvReference::Dyncomp6Dof("dyncomp_run10b_state.csv"),
duration: Time::new::<second>(28800.0),
// 1.05× observed max per component (CLAUDE.md tolerance policy);
// the body-X rate is identically zero, so it keeps the 1e-15
// floor the RUN_10A/C/D siblings use for that axis.
tolerances: Tolerances {
position_m: [1.370e-6, 2.154e-6, 1.826e-6],
velocity_m_s: [1.446e-9, 2.389e-9, 1.814e-9],
quat_angle_rad: 1.088e-4,
ang_vel_rad_s: [1e-15, 1.808e-7, 1.195e-7],
extras: &[],
},
extras: None,
pre_step: None,
}
}

/// SIM_dyncomp RUN_10C — gravity-gradient torque, elliptical orbit,
/// zero initial body rate.
pub fn run10c_gravity_torque_elliptical() -> VerificationCase {
Expand Down Expand Up @@ -1627,6 +1661,10 @@ fn build_run9a(init: &InitialConditions) -> SimulationBuilder {
build_run9_scenario(init, "run9a_torque")
}

fn build_run9b(init: &InitialConditions) -> SimulationBuilder {
build_run9_scenario(init, "run9b_torque_initial_rate")
}

fn build_run9c(init: &InitialConditions) -> SimulationBuilder {
build_run9_scenario(init, "run9c_force_torque")
}
Expand Down Expand Up @@ -1758,3 +1796,32 @@ pub fn run9d_force_torque_rate() -> VerificationCase {
pre_step: Some((run9_force_torque_pre_step, PreStepCadence::PerTick)),
}
}

/// SIM_dyncomp RUN_9B — point-mass 6-DOF + scheduled external torque,
/// with a non-zero initial inertial angular rate.
///
/// JEOD's `RUN_9B/input.py` starts the ISS at the Docking Torque
/// Equilibrium Attitude *with orbit angular rate* (~0.065 deg/s) and
/// applies the same body-frame `[10, 0, 0] N·m` torque as RUN_9A during
/// `t ∈ [1000, 2000) s`, with no external force. The only difference
/// from RUN_9A is the non-zero initial rate, which the recipe picks up
/// from the t=0 row of `dyncomp_run9b_state.csv` via `rot_from`; the
/// scenario builder and torque pre-step are shared with RUN_9A.
pub fn run9b_torque_initial_rate() -> VerificationCase {
VerificationCase {
name: "tier3_simulation_run9b_torque_initial_rate",
scenario: build_run9b,
reference: CsvReference::Dyncomp6Dof("dyncomp_run9b_state.csv"),
duration: Time::new::<second>(0.0),
// 1.05× observed max per component (CLAUDE.md tolerance policy).
tolerances: Tolerances {
position_m: [1.370e-6, 2.154e-6, 1.826e-6],
velocity_m_s: [1.446e-9, 2.389e-9, 1.814e-9],
quat_angle_rad: 4.426e-8,
ang_vel_rad_s: [1.651e-18, 1.367e-18, 6.262e-19],
extras: &[],
},
extras: None,
pre_step: Some((run9a_pre_step, PreStepCadence::PerTick)),
}
}
7 changes: 6 additions & 1 deletion crates/astrodyn_verif_jeod/tests/tier3_sim_dyncomp_run10.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Tier 3: SIM_dyncomp RUN_10A/10C/10D — Gravity gradient torque
//! Tier 3: SIM_dyncomp RUN_10A/10B/10C/10D — Gravity gradient torque

#![allow(
clippy::float_cmp,
Expand Down Expand Up @@ -31,6 +31,11 @@ fn tier3_simulation_run10a_gravity_torque() {
sim_dyncomp::run10a_gravity_torque().run_and_assert();
}

#[test]
fn tier3_simulation_run10b_gravity_torque_circular_rate() {
sim_dyncomp::run10b_gravity_torque_circular_rate().run_and_assert();
}

#[test]
fn tier3_simulation_run10c_gravity_torque_elliptical() {
sim_dyncomp::run10c_gravity_torque_elliptical().run_and_assert();
Expand Down
7 changes: 6 additions & 1 deletion crates/astrodyn_verif_jeod/tests/tier3_sim_dyncomp_run9.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Tier 3: SIM_dyncomp RUN_9A / RUN_9C / RUN_9D.
//! Tier 3: SIM_dyncomp RUN_9A / RUN_9B / RUN_9C / RUN_9D.
//!
//! The recipe factories (`sim_dyncomp::run9{a,c,d}_*`) carry the JEOD
//! pulse-window schedule (`t ∈ [1000, 2000) s` with body-frame
Expand All @@ -18,6 +18,11 @@ fn tier3_simulation_run9a_torque() {
sim_dyncomp::run9a_torque().run_and_assert();
}

#[test]
fn tier3_simulation_run9b_torque_initial_rate() {
sim_dyncomp::run9b_torque_initial_rate().run_and_assert();
}

#[test]
fn tier3_simulation_run9c_force_torque() {
sim_dyncomp::run9c_force_torque().run_and_assert();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ fn bevy_parity_dyncomp_run10a_gravity_torque() {
sim_dyncomp::run10a_gravity_torque().run_and_assert_parity::<astrodyn::Earth>();
}

#[test]
fn bevy_parity_dyncomp_run10b_gravity_torque_circular_rate() {
sim_dyncomp::run10b_gravity_torque_circular_rate().run_and_assert_parity::<astrodyn::Earth>();
}

#[test]
fn bevy_parity_dyncomp_run10c_gravity_torque_elliptical() {
sim_dyncomp::run10c_gravity_torque_elliptical().run_and_assert_parity::<astrodyn::Earth>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Bevy ↔ runner parity for SIM_dyncomp RUN_9A / RUN_9C / RUN_9D —
//! Bevy ↔ runner parity for SIM_dyncomp RUN_9A / RUN_9B / RUN_9C / RUN_9D —
//! scheduled external force / torque pulses (`t ∈ [1000, 2000) s`) on
//! the 6-DOF ISS scenario, via the `VerificationCaseParityExt` trait
//! (issue #389).
Expand Down Expand Up @@ -26,6 +26,11 @@ fn bevy_parity_dyncomp_run9a_torque() {
sim_dyncomp::run9a_torque().run_and_assert_parity::<astrodyn::Earth>();
}

#[test]
fn bevy_parity_dyncomp_run9b_torque_initial_rate() {
sim_dyncomp::run9b_torque_initial_rate().run_and_assert_parity::<astrodyn::Earth>();
}

#[test]
fn bevy_parity_dyncomp_run9c_force_torque() {
sim_dyncomp::run9c_force_torque().run_and_assert_parity::<astrodyn::Earth>();
Expand Down
Loading