Browse Source

Fix true anomaly trigger at periapsis

Swap order in update_simulation() to check maneuvers before physics update.
This ensures triggers fire at the correct position instead of after the
spacecraft has moved past the trigger point.

Also fix test config to avoid interference between time-based and true
anomaly triggers.
main
cinnaboot 5 months ago
parent
commit
4b77ad6ff7
  1. 2
      src/simulation.cpp
  2. 3
      tests/test_maneuver_planning.toml
  3. 18
      tests/test_periapsis_burn.cpp

2
src/simulation.cpp

@ -165,8 +165,8 @@ void update_soi(CelestialBody* body, CelestialBody* parent, double semi_major_ax
void update_simulation(SimulationState* sim) { void update_simulation(SimulationState* sim) {
update_bodies_physics(sim); update_bodies_physics(sim);
compute_global_coordinates(sim); compute_global_coordinates(sim);
update_spacecraft_physics(sim);
execute_pending_maneuvers(sim); execute_pending_maneuvers(sim);
update_spacecraft_physics(sim);
compute_spacecraft_globals(sim); compute_spacecraft_globals(sim);
sim->time += sim->dt; sim->time += sim->dt;
} }

3
tests/test_maneuver_planning.toml

@ -33,9 +33,10 @@ parent_index = 1
orbit = { orbit = {
semi_major_axis = 6.771e6, semi_major_axis = 6.771e6,
eccentricity = 0.0, eccentricity = 0.0,
true_anomaly = 0.0 true_anomaly = 1.57
} }
# LEO orbit: 400 km altitude (Earth radius 6.371e6 m + 400e3 m) # LEO orbit: 400 km altitude (Earth radius 6.371e6 m + 400e3 m)
# Start at true_anomaly = 1.57 (90 degrees) to avoid triggering immediately
[[maneuvers]] [[maneuvers]]
name = "orbit_raise_1" name = "orbit_raise_1"

18
tests/test_periapsis_burn.cpp

@ -8,11 +8,9 @@
#include "../src/orbital_mechanics.h" #include "../src/orbital_mechanics.h"
#include <cmath> #include <cmath>
// This test documents a bug: when a true anomaly trigger is set to 0 (periapsis), // Test prograde burn at periapsis (true anomaly = 0)
// the maneuver doesn't execute because the spacecraft moves past periapsis before // Verifies that the maneuver executes correctly when starting at periapsis
// the trigger check happens (trigger check occurs after physics update). TEST_CASE("Prograde burn at periapsis preserves periapsis distance", "[maneuver][periapsis]") {
// The expected behavior is that the maneuver should execute when at periapsis.
TEST_CASE("Prograde burn at periapsis preserves periapsis distance", "[maneuver][periapsis][bug]") {
const double TIME_STEP = 60.0; const double TIME_STEP = 60.0;
SimulationState* sim = create_simulation(10, 10, 100, TIME_STEP); SimulationState* sim = create_simulation(10, 10, 100, TIME_STEP);
@ -76,11 +74,6 @@ TEST_CASE("Prograde burn at periapsis raises apoapsis not periapsis", "[maneuver
update_simulation(sim); update_simulation(sim);
// Skip verification if bug not fixed
if (!sim->maneuvers[0].executed) {
SKIP("Maneuver didn't execute - known bug");
}
double final_sma = craft->orbit.semi_major_axis; double final_sma = craft->orbit.semi_major_axis;
double final_ecc = craft->orbit.eccentricity; double final_ecc = craft->orbit.eccentricity;
double final_periapsis = final_sma * (1.0 - final_ecc); double final_periapsis = final_sma * (1.0 - final_ecc);
@ -107,11 +100,6 @@ TEST_CASE("Burn location equals new periapsis after prograde burn", "[maneuver][
update_simulation(sim); update_simulation(sim);
// Skip verification if bug not fixed
if (!sim->maneuvers[0].executed) {
SKIP("Maneuver didn't execute - known bug");
}
double final_periapsis = craft->orbit.semi_major_axis * (1.0 - craft->orbit.eccentricity); double final_periapsis = craft->orbit.semi_major_axis * (1.0 - craft->orbit.eccentricity);
INFO("Burn radius: " << burn_radius); INFO("Burn radius: " << burn_radius);

Loading…
Cancel
Save