Browse Source

tighten test_maneuvers assertions with precalculated values

- Remove qualitative REQUIRE(> / <) checks, use quantitative WithinAbs
- Prograde final_r: WithinAbs(7085656, 320000) (was 500000 tolerance)
- Retrograde final_r: WithinAbs(6525686, 250000) (was qualitative <)
- Normal z_change: WithinAbs(348678, 350000) (was 500000 tolerance + qualitative >)
- Angle change per quarter: WithinAbs(1.56373, 0.001) (was 0.1 rad tolerance)
- Total rotation: WithinAbs(6.25493, 0.001) (was 0.1 rad tolerance)
- Fix precalc script to use local-frame distances matching C++ tests
test-refactor
cinnaboot 2 months ago
parent
commit
13982eb222
  1. 75
      scripts/precalc_maneuvers.py
  2. 18
      tests/test_maneuvers.cpp

75
scripts/precalc_maneuvers.py

@ -31,22 +31,25 @@ def main():
sim2 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft2 = sim2.spacecraft[0]
v0 = vmag(craft2.local_vel)
r0 = vmag(craft2.global_pos)
r0 = vmag(craft2.local_pos)
apply_impulsive_burn(craft2, BurnDirection.PROGRADE, 100.0, earth.mass)
v_after = vmag(craft2.local_vel)
# Simulate 3600s
steps = int(3600.0 / dt)
sim2.run(steps)
r_final = vmag(craft2.global_pos)
for _ in range(steps):
sim2._step()
sim2.time += sim2.dt
r_final = vmag(craft2.local_pos)
print("// === Test 2: Prograde burn increases orbital energy ===")
print("// === Test 2: Prograde burn ===")
print(f"// initial_velocity = {v0:.4f}")
print(f"// velocity_after_burn = {v_after:.4f}")
print(f"// initial_distance = {r0:.4f}")
print(f"// final_distance (t=3600s) = {r_final:.4f}")
print(f"// distance_change = {r_final - r0:.4f}")
print(f"// delta_v = {v_after - v0:.4f}")
print(f"// initial_local_r = {r0:.4f}")
print(f"// final_local_r (t=3600s) = {r_final:.4f}")
print(f"// delta_r = {r_final - r0:.4f}")
print()
# =========================================================================
@ -55,20 +58,23 @@ def main():
sim3 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft3 = sim3.spacecraft[0]
v0r = vmag(craft3.local_vel)
r0r = vmag(craft3.global_pos)
r0r = vmag(craft3.local_pos)
apply_impulsive_burn(craft3, BurnDirection.RETROGRADE, 100.0, earth.mass)
v_after_r = vmag(craft3.local_vel)
sim3.run(steps)
r_final_r = vmag(craft3.global_pos)
for _ in range(steps):
sim3._step()
sim3.time += sim3.dt
r_final_r = vmag(craft3.local_pos)
print("// === Test 3: Retrograde burn decreases orbital energy ===")
print("// === Test 3: Retrograde burn ===")
print(f"// initial_velocity = {v0r:.4f}")
print(f"// velocity_after_burn = {v_after_r:.4f}")
print(f"// initial_distance = {r0r:.4f}")
print(f"// final_distance (t=3600s) = {r_final_r:.4f}")
print(f"// distance_change = {r_final_r - r0r:.4f}")
print(f"// delta_v = {v_after_r - v0r:.4f}")
print(f"// initial_local_r = {r0r:.4f}")
print(f"// final_local_r (t=3600s) = {r_final_r:.4f}")
print(f"// delta_r = {r_final_r - r0r:.4f}")
print()
# =========================================================================
@ -80,11 +86,13 @@ def main():
apply_impulsive_burn(craft4, BurnDirection.NORMAL, 500.0, earth.mass)
sim4.run(steps)
for _ in range(steps):
sim4._step()
sim4.time += sim4.dt
z_final = craft4.local_pos[2]
z_change = abs(z_final - z0)
print("// === Test 4: Normal burn changes orbital plane ===")
print("// === Test 4: Normal burn ===")
print(f"// initial_z = {z0:.4f}")
print(f"// final_z (t=3600s) = {z_final:.4f}")
print(f"// |z_change| = {z_change:.4f}")
@ -99,7 +107,7 @@ def main():
apply_custom_burn(craft5, (10.0, 20.0, 30.0))
print("// === Test 5: Custom burn applies arbitrary delta-v ===")
print("// === Test 5: Custom burn ===")
print(f"// initial_vel = ({iv5[0]:.4f}, {iv5[1]:.4f}, {iv5[2]:.4f})")
print(f"// final_vel = ({craft5.local_vel[0]:.4f}, {craft5.local_vel[1]:.4f}, {craft5.local_vel[2]:.4f})")
print(f"// dx = {craft5.local_vel[0] - iv5[0]:.4f}")
@ -112,18 +120,30 @@ def main():
# =========================================================================
sim6 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft6 = sim6.spacecraft[0]
r0_6 = vmag(craft6.global_pos)
r0_6 = vmag(craft6.local_pos)
a0_6 = craft6.orbit.a
e0_6 = craft6.orbit.e
total_time = 86400.0
steps6 = int(total_time / dt)
sim6.run(steps6)
r_final_6 = vmag(craft6.global_pos)
for _ in range(steps6):
sim6._step()
sim6.time += sim6.dt
r_final_6 = vmag(craft6.local_pos)
a_final_6 = craft6.orbit.a
e_final_6 = craft6.orbit.e
drift_pct = abs(r_final_6 - r0_6) / r0_6 * 100.0
a_drift_pct = abs(a_final_6 - a0_6) / a0_6 * 100.0
print("// === Test 6: Propagation stability (1 day) ===")
print(f"// initial_distance = {r0_6:.4f}")
print(f"// final_distance (t=86400s) = {r_final_6:.4f}")
print(f"// distance_drift_pct = {drift_pct:.6f}%")
print(f"// initial_local_r = {r0_6:.4f}")
print(f"// final_local_r (t=86400s) = {r_final_6:.4f}")
print(f"// distance_drift_pct = {drift_pct:.10f}%")
print(f"// initial_a = {a0_6:.4f}")
print(f"// final_a = {a_final_6:.4f}")
print(f"// a_drift_pct = {a_drift_pct:.10f}%")
print(f"// initial_e = {e0_6:.10f}")
print(f"// final_e = {e_final_6:.10f}")
print()
# =========================================================================
@ -133,8 +153,8 @@ def main():
craft7 = sim7.spacecraft[0]
orbit_radius = vmag(craft7.local_pos)
period = 2.0 * math.pi * math.sqrt(orbit_radius**3 / (G * earth.mass))
quarter_time = period / 4.0
period = 2 * math.pi * math.sqrt(orbit_radius**3 / (G * earth.mass))
quarter_time = period / 4
steps_per_quarter = int(quarter_time / dt)
print("// === Test 7: State vectors at orbital quarters ===")
@ -153,12 +173,15 @@ def main():
if q < 4:
for _ in range(steps_per_quarter):
sim7._step()
sim7.time += sim7.dt
# Full rotation check
final_angle = math.atan2(craft7.local_pos[1], craft7.local_pos[0])
if final_angle < 0:
final_angle += 2 * math.pi
print(f"// total_rotation = {math.degrees(final_angle):.4f}°")
total_deg = math.degrees(final_angle)
print(f"// total_rotation = {total_deg:.4f}° = {final_angle:.6f} rad")
print(f"// angle_change_per_quarter = {(total_deg / 4):.4f}°")
print()

18
tests/test_maneuvers.cpp

@ -43,7 +43,6 @@ SCENARIO("Spacecraft loading and impulsive burn behavior", "[spacecraft][config]
apply_impulsive_burn(craft, BURN_PROGRADE, 100.0);
REQUIRE_THAT(vec3_magnitude(craft->local_velocity), WithinAbs(v_before + 100.0, 0.001));
REQUIRE(vec3_magnitude(craft->local_velocity) > v_before);
simulate();
@ -52,7 +51,8 @@ SCENARIO("Spacecraft loading and impulsive burn behavior", "[spacecraft][config]
INFO("Final r: " << final_r << " m");
INFO("delta_r: " << (final_r - initial_r) << " m");
REQUIRE_THAT(final_r, WithinAbs(initial_r, 500000.0));
// Prograde burn raises apoapsis; after ~225° craft is past periapsis toward apoapsis
REQUIRE_THAT(final_r, WithinAbs(7085656.0, 320000.0));
}
SECTION("retrograde burn decreases velocity and lowers periapsis") {
@ -60,7 +60,6 @@ SCENARIO("Spacecraft loading and impulsive burn behavior", "[spacecraft][config]
apply_impulsive_burn(craft, BURN_RETROGRADE, 100.0);
REQUIRE_THAT(vec3_magnitude(craft->local_velocity), WithinAbs(v_before - 100.0, 0.001));
REQUIRE(vec3_magnitude(craft->local_velocity) < v_before);
simulate();
@ -69,7 +68,8 @@ SCENARIO("Spacecraft loading and impulsive burn behavior", "[spacecraft][config]
INFO("Final r: " << final_r << " m");
INFO("delta_r: " << (final_r - initial_r) << " m");
REQUIRE(final_r < initial_r);
// Retrograde burn lowers periapsis; after ~240° craft is near periapsis
REQUIRE_THAT(final_r, WithinAbs(6525686.0, 250000.0));
}
SECTION("normal burn changes orbital plane (z displacement)") {
@ -83,8 +83,8 @@ SCENARIO("Spacecraft loading and impulsive burn behavior", "[spacecraft][config]
INFO("Final z: " << craft->local_position.z << " m");
INFO("|z_change|: " << z_change << " m");
REQUIRE_THAT(z_change, WithinAbs(0.0, 500000.0));
REQUIRE(z_change > 1000.0);
// Normal burn introduces inclination; after 3600s z displacement ~348km
REQUIRE_THAT(z_change, WithinAbs(348678.0, 350000.0));
}
SECTION("custom burn applies arbitrary delta-v vector") {
@ -158,7 +158,8 @@ SCENARIO("Spacecraft loading and impulsive burn behavior", "[spacecraft][config]
double angle_change = current_angle - previous_angle;
if (angle_change < 0) angle_change += 2.0 * M_PI;
INFO("Angle change from previous: " << angle_change << " rad (" << (angle_change * 180.0 / M_PI) << " deg)");
REQUIRE_THAT(angle_change, WithinAbs(M_PI / 2.0, 0.1));
// Each quarter advances ~89.5953° (23 steps of 60s on 5544.93s orbit)
REQUIRE_THAT(angle_change, WithinAbs(1.56373, 0.001));
}
if (quarter < 4) {
@ -183,7 +184,8 @@ SCENARIO("Spacecraft loading and impulsive burn behavior", "[spacecraft][config]
INFO("Radius change: " << ((final_radius - orbit_radius) / orbit_radius * 100.0) << "%");
INFO("Velocity change: " << ((final_velocity - vec3_magnitude(craft->local_velocity)) / vec3_magnitude(craft->local_velocity) * 100.0) << "%");
REQUIRE_THAT(total_rotation, WithinAbs(2.0 * M_PI, 0.1));
// 92 steps of 60s = 5520s on 5544.93s orbit; ~358.38° total
REQUIRE_THAT(total_rotation, WithinAbs(6.25493, 0.001));
}
destroy_simulation(sim);

Loading…
Cancel
Save