|
|
|
@ -36,9 +36,8 @@ SCENARIO("Analytical propagation: apsides, periods, vis-viva, timestep accuracy, |
|
|
|
const double A2_V_PERI = 7874.183374942587e+00; // m/s at perigee
|
|
|
|
const double A2_V_PERI = 7874.183374942587e+00; // m/s at perigee
|
|
|
|
const double A2_V_APO = 3374.650017832537e+00; // m/s at apogee
|
|
|
|
const double A2_V_APO = 3374.650017832537e+00; // m/s at apogee
|
|
|
|
|
|
|
|
|
|
|
|
// Precalculated displacement for 0.1s timestep (from precalc script)
|
|
|
|
// 100-period propagation accumulates ~1.1e-12 rad anomaly error;
|
|
|
|
const double VEL_CHANGE_SMALL_DT = 0.4920854266; |
|
|
|
// ANG_TOL (1e-12) is too tight for long-term stability tests
|
|
|
|
|
|
|
|
|
|
|
|
const double LONG_TERM_ANG_TOL = 1e-10; |
|
|
|
const double LONG_TERM_ANG_TOL = 1e-10; |
|
|
|
|
|
|
|
|
|
|
|
// === Helper lambdas ===
|
|
|
|
// === Helper lambdas ===
|
|
|
|
@ -148,7 +147,7 @@ SCENARIO("Analytical propagation: apsides, periods, vis-viva, timestep accuracy, |
|
|
|
"Apsides spacecraft apogee"); |
|
|
|
"Apsides spacecraft apogee"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SECTION("apsides perigee velocity > apogee velocity") { |
|
|
|
SECTION("apsides perigee velocity matches precalculated value") { |
|
|
|
Vec3 pos_peri, vel_peri, pos_apo, vel_apo; |
|
|
|
Vec3 pos_peri, vel_peri, pos_apo, vel_apo; |
|
|
|
get_state(A1_A, A1_E, 0.0, pos_peri, vel_peri); |
|
|
|
get_state(A1_A, A1_E, 0.0, pos_peri, vel_peri); |
|
|
|
get_state(A1_A, A1_E, M_PI, pos_apo, vel_apo); |
|
|
|
get_state(A1_A, A1_E, M_PI, pos_apo, vel_apo); |
|
|
|
@ -160,7 +159,7 @@ SCENARIO("Analytical propagation: apsides, periods, vis-viva, timestep accuracy, |
|
|
|
REQUIRE_THAT(v_apo, WithinAbs(A1_V_APO, V_TOL)); |
|
|
|
REQUIRE_THAT(v_apo, WithinAbs(A1_V_APO, V_TOL)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SECTION("apsides perigee velocity > velocity at pi/4") { |
|
|
|
SECTION("apsides velocity at pi/4 matches precalculated value") { |
|
|
|
Vec3 pos_45, vel_45, pos_peri, vel_peri; |
|
|
|
Vec3 pos_45, vel_45, pos_peri, vel_peri; |
|
|
|
get_state(A1_A, A1_E, M_PI / 4.0, pos_45, vel_45); |
|
|
|
get_state(A1_A, A1_E, M_PI / 4.0, pos_45, vel_45); |
|
|
|
get_state(A1_A, A1_E, 0.0, pos_peri, vel_peri); |
|
|
|
get_state(A1_A, A1_E, 0.0, pos_peri, vel_peri); |
|
|
|
@ -182,7 +181,7 @@ SCENARIO("Analytical propagation: apsides, periods, vis-viva, timestep accuracy, |
|
|
|
"Timestep spacecraft apogee"); |
|
|
|
"Timestep spacecraft apogee"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SECTION("timestep perigee velocity > apogee velocity") { |
|
|
|
SECTION("timestep perigee velocity matches precalculated value") { |
|
|
|
Vec3 pos_peri, vel_peri, pos_apo, vel_apo; |
|
|
|
Vec3 pos_peri, vel_peri, pos_apo, vel_apo; |
|
|
|
get_state(A2_A, A2_E, 0.0, pos_peri, vel_peri); |
|
|
|
get_state(A2_A, A2_E, 0.0, pos_peri, vel_peri); |
|
|
|
get_state(A2_A, A2_E, M_PI, pos_apo, vel_apo); |
|
|
|
get_state(A2_A, A2_E, M_PI, pos_apo, vel_apo); |
|
|
|
@ -216,14 +215,9 @@ SCENARIO("Analytical propagation: apsides, periods, vis-viva, timestep accuracy, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// --- 3. Period return (both spacecraft) ---
|
|
|
|
// --- 3. Period return (both spacecraft) ---
|
|
|
|
SECTION("apsides position returns after one period") { |
|
|
|
SECTION("apsides position and velocity return after one period") { |
|
|
|
check_period_return(A1_A, A1_E, A1_PERIOD, |
|
|
|
|
|
|
|
"Apsides spacecraft position"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("apsides velocity returns after one period") { |
|
|
|
|
|
|
|
check_period_return(A1_A, A1_E, A1_PERIOD, |
|
|
|
check_period_return(A1_A, A1_E, A1_PERIOD, |
|
|
|
"Apsides spacecraft velocity"); |
|
|
|
"Apsides spacecraft"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SECTION("apsides true anomaly returns after one period") { |
|
|
|
SECTION("apsides true anomaly returns after one period") { |
|
|
|
@ -231,14 +225,9 @@ SCENARIO("Analytical propagation: apsides, periods, vis-viva, timestep accuracy, |
|
|
|
"Apsides spacecraft nu"); |
|
|
|
"Apsides spacecraft nu"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SECTION("timestep position returns after one period") { |
|
|
|
SECTION("timestep position and velocity return after one period") { |
|
|
|
check_period_return(A2_A, A2_E, A2_PERIOD, |
|
|
|
|
|
|
|
"Timestep spacecraft position"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("timestep velocity returns after one period") { |
|
|
|
|
|
|
|
check_period_return(A2_A, A2_E, A2_PERIOD, |
|
|
|
check_period_return(A2_A, A2_E, A2_PERIOD, |
|
|
|
"Timestep spacecraft velocity"); |
|
|
|
"Timestep spacecraft"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SECTION("timestep true anomaly returns after one period") { |
|
|
|
SECTION("timestep true anomaly returns after one period") { |
|
|
|
@ -287,7 +276,7 @@ SCENARIO("Analytical propagation: apsides, periods, vis-viva, timestep accuracy, |
|
|
|
INFO("vel_change: " << vel_change << " m/s"); |
|
|
|
INFO("vel_change: " << vel_change << " m/s"); |
|
|
|
|
|
|
|
|
|
|
|
REQUIRE_THAT(rel_pos_error, WithinAbs(0.0, REL_TOL * 100.0)); |
|
|
|
REQUIRE_THAT(rel_pos_error, WithinAbs(0.0, REL_TOL * 100.0)); |
|
|
|
REQUIRE_THAT(vel_change, WithinAbs(VEL_CHANGE_SMALL_DT, V_TOL)); |
|
|
|
REQUIRE_THAT(vel_change, WithinAbs(0.4920854266, V_TOL)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SECTION("accuracy at 1x period") { |
|
|
|
SECTION("accuracy at 1x period") { |
|
|
|
|