Browse Source

clean: remove old_tests for test_periapsis_burn (refactored to tests/)

test-refactor
cinnaboot 2 months ago
parent
commit
23bde87960
  1. 266
      old_tests/test_periapsis_burn.cpp
  2. 74
      old_tests/test_periapsis_burn.toml

266
old_tests/test_periapsis_burn.cpp

@ -1,266 +0,0 @@
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>
#include "../src/physics.h"
#include "../src/simulation.h"
#include "../src/orbital_objects.h"
#include "../src/maneuver.h"
#include "../src/config_loader.h"
#include "../src/orbital_mechanics.h"
#include <cmath>
// NOTE: calculate_true_anomaly() was removed from the public API.
// It was redundant with cartesian_to_orbital_elements() which already
// computes true_anomaly as part of OrbitalElements.
//
// Suggested replacement for later refactor:
// OrbitalElements orbit = cartesian_to_orbital_elements(r, v, parent->mass);
// double true_anomaly = orbit.true_anomaly;
//
// Or even simpler — since the sim already calls cartesian_to_orbital_elements()
// each frame, just read craft->orbit.true_anomaly directly.
// Test prograde burn at periapsis (true anomaly = 0)
// Verifies that the maneuver executes correctly when starting at periapsis
TEST_CASE("Prograde burn at periapsis preserves periapsis distance", "[maneuver][periapsis]") {
const double TIME_STEP = 60.0;
SimulationState* sim = create_simulation(10, 10, 100, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_periapsis_burn.toml"));
Spacecraft* craft = &sim->spacecraft[0];
// Record initial state (at periapsis)
double initial_radius = vec3_magnitude(craft->local_position);
double initial_sma = craft->orbit.semi_major_axis;
double initial_ecc = craft->orbit.eccentricity;
double initial_periapsis = initial_sma * (1.0 - initial_ecc);
double initial_velocity = vec3_magnitude(craft->local_velocity);
INFO("Initial state:");
INFO(" Radius: " << initial_radius << " (should equal periapsis: " << initial_periapsis << ")");
INFO(" True anomaly: " << craft->orbit.true_anomaly);
INFO(" Velocity: " << initial_velocity);
INFO(" Maneuver trigger: true_anomaly = " << sim->maneuvers[0].trigger_value);
// Execute one step
update_simulation(sim);
// Check if maneuver executed
INFO("After 1 step:");
INFO(" Maneuver executed: " << sim->maneuvers[0].executed);
INFO(" Final radius: " << vec3_magnitude(craft->local_position));
INFO(" Final velocity: " << vec3_magnitude(craft->local_velocity));
// The maneuver should have executed since we started at periapsis
// This assertion will fail due to the bug - the trigger check happens
// after physics moves the spacecraft past periapsis
REQUIRE(sim->maneuvers[0].executed);
// If the maneuver executed, verify the physics:
double final_sma = craft->orbit.semi_major_axis;
double final_ecc = craft->orbit.eccentricity;
double final_periapsis = final_sma * (1.0 - final_ecc);
double final_velocity = vec3_magnitude(craft->local_velocity);
// Periapsis distance should be preserved
REQUIRE_THAT(final_periapsis, Catch::Matchers::WithinAbs(initial_periapsis, 1.0));
// Semi-major axis and velocity should increase
REQUIRE(final_sma > initial_sma);
REQUIRE(final_velocity > initial_velocity);
destroy_simulation(sim);
}
TEST_CASE("Two periapsis burns execute at same location", "[maneuver][periapsis][sequential]") {
const double TIME_STEP = 60.0;
const int ORBIT_STEPS = 300;
SimulationState* sim = create_simulation(10, 10, 100, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_periapsis_burn.toml"));
Spacecraft* craft = &sim->spacecraft[0];
CelestialBody* parent = &sim->bodies[craft->parent_index];
int maneuver_indices[2];
int maneuver_count_for_craft = 0;
for (int i = 0; i < sim->maneuver_count; i++) {
if (sim->maneuvers[i].craft_index == 0) {
maneuver_indices[maneuver_count_for_craft++] = i;
}
}
REQUIRE(maneuver_count_for_craft == 2);
double initial_periapsis = craft->orbit.semi_major_axis * (1.0 - craft->orbit.eccentricity);
double initial_apoapsis = craft->orbit.semi_major_axis * (1.0 + craft->orbit.eccentricity);
INFO("Initial orbit:");
INFO(" Periapsis: " << initial_periapsis);
INFO(" Apoapsis: " << initial_apoapsis);
INFO(" Eccentricity: " << craft->orbit.eccentricity);
double burn1_time = -1.0;
double burn1_radius = -1.0;
double burn1_true_anomaly = -10.0;
double burn1_period = -1.0;
double burn2_time = -1.0;
double burn2_radius = -1.0;
double burn2_true_anomaly = -10.0;
for (int i = 0; i < ORBIT_STEPS; i++) {
update_simulation(sim);
if (sim->maneuvers[maneuver_indices[0]].executed && burn1_time < 0) {
burn1_time = sim->time;
burn1_radius = vec3_magnitude(craft->local_position);
burn1_period = 2.0 * M_PI * sqrt(pow(craft->orbit.semi_major_axis, 3.0) / (G * parent->mass));
Vec3 r = craft->local_position;
Vec3 v = craft->local_velocity;
Vec3 h = vec3_cross(r, v);
Vec3 e_vec = calculate_eccentricity_vector(r, v, h, G * parent->mass);
double e_mag = vec3_magnitude(e_vec);
burn1_true_anomaly = calculate_true_anomaly(r, v, e_vec, e_mag, burn1_radius);
burn1_true_anomaly = normalize_angle(burn1_true_anomaly);
INFO("First burn executed at step " << i);
INFO(" Time: " << burn1_time);
INFO(" Radius: " << burn1_radius);
INFO(" True anomaly: " << burn1_true_anomaly << " rad (" << burn1_true_anomaly * 180.0 / M_PI << "°)");
INFO(" Periapsis: " << initial_periapsis);
INFO(" Apoapsis: " << initial_apoapsis);
INFO(" New period: " << burn1_period << " seconds");
}
if (sim->maneuvers[maneuver_indices[1]].executed && burn2_time < 0) {
burn2_time = sim->time;
burn2_radius = vec3_magnitude(craft->local_position);
Vec3 r = craft->local_position;
Vec3 v = craft->local_velocity;
Vec3 h = vec3_cross(r, v);
Vec3 e_vec = calculate_eccentricity_vector(r, v, h, G * parent->mass);
double e_mag = vec3_magnitude(e_vec);
burn2_true_anomaly = calculate_true_anomaly(r, v, e_vec, e_mag, burn2_radius);
burn2_true_anomaly = normalize_angle(burn2_true_anomaly);
INFO("Second burn executed at step " << i);
INFO(" Time: " << burn2_time);
INFO(" Radius: " << burn2_radius);
INFO(" True anomaly: " << burn2_true_anomaly << " rad (" << burn2_true_anomaly * 180.0 / M_PI << "°)");
}
}
REQUIRE(sim->maneuvers[maneuver_indices[0]].executed);
REQUIRE(sim->maneuvers[maneuver_indices[1]].executed);
INFO("Burn comparison:");
INFO(" Burn 1: time=" << burn1_time << ", radius=" << burn1_radius << ", true_anomaly=" << burn1_true_anomaly);
INFO(" Burn 2: time=" << burn2_time << ", radius=" << burn2_radius << ", true_anomaly=" << burn2_true_anomaly);
REQUIRE_THAT(burn1_radius, Catch::Matchers::WithinAbs(initial_periapsis, 10000.0));
REQUIRE_THAT(burn2_radius, Catch::Matchers::WithinAbs(initial_periapsis, 10000.0));
REQUIRE(fabs(burn1_true_anomaly) < 0.5);
REQUIRE(fabs(burn2_true_anomaly) < 0.5);
INFO("Expected orbital period (after burn 1): " << burn1_period << " seconds");
INFO("Actual time between burns: " << (burn2_time - burn1_time) << " seconds");
REQUIRE_THAT(burn2_time - burn1_time, Catch::Matchers::WithinAbs(burn1_period, TIME_STEP * 2.0));
destroy_simulation(sim);
}
TEST_CASE("Periapsis burn fires when crossing periapsis", "[maneuver][periapsis][crossing]") {
const double TIME_STEP = 60.0;
SimulationState* sim = create_simulation(10, 10, 100, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_periapsis_burn.toml"));
Spacecraft* craft = &sim->spacecraft[1]; // TestSatelliteCrossing
CelestialBody* parent = &sim->bodies[craft->parent_index];
int maneuver_index = -1;
for (int i = 0; i < sim->maneuver_count; i++) {
if (sim->maneuvers[i].craft_index == 1) {
maneuver_index = i;
break;
}
}
REQUIRE(maneuver_index >= 0);
double initial_periapsis = craft->orbit.semi_major_axis * (1.0 - craft->orbit.eccentricity);
double initial_apoapsis = craft->orbit.semi_major_axis * (1.0 + craft->orbit.eccentricity);
INFO("Initial orbit:");
INFO(" Periapsis: " << initial_periapsis);
INFO(" Apoapsis: " << initial_apoapsis);
INFO(" Initial true anomaly: " << craft->orbit.true_anomaly << " rad");
double burn_time = -1.0;
double burn_radius = -1.0;
double burn_true_anomaly = -10.0;
int max_steps = 1000;
for (int i = 0; i < max_steps && !sim->maneuvers[maneuver_index].executed; i++) {
update_simulation(sim);
if (sim->maneuvers[maneuver_index].executed) {
burn_time = sim->time;
burn_radius = vec3_magnitude(craft->local_position);
Vec3 r = craft->local_position;
Vec3 v = craft->local_velocity;
Vec3 h = vec3_cross(r, v);
Vec3 e_vec = calculate_eccentricity_vector(r, v, h, G * parent->mass);
double e_mag = vec3_magnitude(e_vec);
burn_true_anomaly = calculate_true_anomaly(r, v, e_vec, e_mag, burn_radius);
burn_true_anomaly = normalize_angle(burn_true_anomaly);
INFO("Burn executed at step " << i);
INFO(" Time: " << burn_time);
INFO(" Radius: " << burn_radius);
INFO(" True anomaly: " << burn_true_anomaly << " rad (" << burn_true_anomaly * 180.0 / M_PI << "°)");
INFO(" Periapsis: " << initial_periapsis);
INFO(" Apoapsis: " << initial_apoapsis);
}
}
REQUIRE(sim->maneuvers[maneuver_index].executed);
REQUIRE_THAT(burn_radius, Catch::Matchers::WithinAbs(initial_periapsis, 1000.0));
REQUIRE(fabs(burn_true_anomaly) < 0.5);
destroy_simulation(sim);
}
TEST_CASE("Burn location equals new periapsis after prograde burn", "[maneuver][periapsis][location]") {
const double TIME_STEP = 60.0;
SimulationState* sim = create_simulation(10, 10, 100, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_periapsis_burn.toml"));
Spacecraft* craft = &sim->spacecraft[0];
double initial_periapsis = craft->orbit.semi_major_axis * (1.0 - craft->orbit.eccentricity);
double initial_radius = vec3_magnitude(craft->local_position);
update_simulation(sim);
REQUIRE(sim->maneuvers[0].executed);
double final_periapsis = craft->orbit.semi_major_axis * (1.0 - craft->orbit.eccentricity);
INFO("Initial radius: " << initial_radius);
INFO("Initial periapsis: " << initial_periapsis);
INFO("Final periapsis: " << final_periapsis);
REQUIRE_THAT(initial_radius, Catch::Matchers::WithinAbs(initial_periapsis, 100.0));
REQUIRE_THAT(final_periapsis, Catch::Matchers::WithinAbs(initial_periapsis, 100.0));
destroy_simulation(sim);
}

74
old_tests/test_periapsis_burn.toml

@ -1,74 +0,0 @@
# Test Configuration: Prograde Burn at Periapsis
# Tests that periapsis distance is preserved during prograde burn
[[bodies]]
name = "Sun"
mass = 1.989e30
radius = 6.96e8
parent_index = -1
color = { r = 1.0, g = 1.0, b = 0.0 }
orbit = {
semi_major_axis = 0.0,
eccentricity = 0.0,
true_anomaly = 0.0
}
[[bodies]]
name = "Earth"
mass = 5.972e24
radius = 6.371e6
parent_index = 0
color = { r = 0.0, g = 0.5, b = 1.0 }
orbit = {
semi_major_axis = 1.496e11,
eccentricity = 0.0,
true_anomaly = 0.0
}
[[spacecraft]]
name = "TestSatellite"
mass = 1000.0
parent_index = 1
# Start at periapsis of an elliptical orbit
# a = 10,000 km, e = 0.3
# periapsis = 7,000 km, apoapsis = 13,000 km
orbit = {
semi_major_axis = 1.0371e7,
eccentricity = 0.3,
true_anomaly = 0.0
}
[[spacecraft]]
name = "TestSatelliteCrossing"
mass = 1000.0
parent_index = 1
# Start at 90 degrees from periapsis for crossing test
orbit = {
semi_major_axis = 1.0371e7,
eccentricity = 0.3,
true_anomaly = 1.57 # 90 degrees (pi/2)
}
[[maneuvers]]
name = "periapsis_prograde_burn"
spacecraft_name = "TestSatellite"
trigger_type = "true_anomaly"
trigger_value = 0.0
direction = "prograde"
delta_v = 500.0
[[maneuvers]]
name = "periapsis_prograde_burn_2"
spacecraft_name = "TestSatellite"
trigger_type = "true_anomaly"
trigger_value = 0.0
direction = "prograde"
delta_v = 500.0
[[maneuvers]]
name = "periapsis_prograde_burn_crossing"
spacecraft_name = "TestSatelliteCrossing"
trigger_type = "true_anomaly"
trigger_value = 0.0
direction = "prograde"
delta_v = 500.0
Loading…
Cancel
Save