#include #include "../src/physics.h" #include "../src/simulation.h" #include "../src/spacecraft.h" #include "../src/maneuver.h" #include "../src/config_loader.h" #include "../src/test_utilities.h" #include TEST_CASE("Spacecraft loading from config", "[spacecraft][config]") { const double TIME_STEP = 60.0; SimulationState* sim = create_simulation(10, 10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); REQUIRE(sim->craft_count == 1); REQUIRE(std::string(sim->spacecraft[0].name) == "LEO_Satellite"); REQUIRE(sim->spacecraft[0].parent_index == 1); destroy_simulation(sim); } TEST_CASE("Prograde burn increases orbital energy", "[spacecraft][burn][prograde]") { const double TIME_STEP = 60.0; SimulationState* sim = create_simulation(10, 10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); Spacecraft* craft = &sim->spacecraft[0]; CelestialBody* earth = &sim->bodies[1]; double initial_distance = vec3_distance(craft->global_position, earth->global_position); double initial_velocity = vec3_magnitude(craft->local_velocity); apply_impulsive_burn(craft, BURN_PROGRADE, 100.0); REQUIRE(vec3_magnitude(craft->local_velocity) > initial_velocity); const double SECONDS_TO_SIMULATE = 3600.0; double sim_time = 0.0; while (sim_time < SECONDS_TO_SIMULATE) { update_simulation(sim); sim_time += TIME_STEP; } double final_distance = vec3_distance(craft->global_position, earth->global_position); REQUIRE(final_distance > initial_distance); destroy_simulation(sim); } TEST_CASE("Retrograde burn decreases orbital energy", "[spacecraft][burn][retrograde]") { const double TIME_STEP = 60.0; SimulationState* sim = create_simulation(10, 10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); Spacecraft* craft = &sim->spacecraft[0]; CelestialBody* earth = &sim->bodies[1]; double initial_distance = vec3_distance(craft->global_position, earth->global_position); double initial_velocity = vec3_magnitude(craft->local_velocity); apply_impulsive_burn(craft, BURN_RETROGRADE, 100.0); REQUIRE(vec3_magnitude(craft->local_velocity) < initial_velocity); const double SECONDS_TO_SIMULATE = 3600.0; double sim_time = 0.0; while (sim_time < SECONDS_TO_SIMULATE) { update_simulation(sim); sim_time += TIME_STEP; } double final_distance = vec3_distance(craft->global_position, earth->global_position); REQUIRE(final_distance < initial_distance); destroy_simulation(sim); } TEST_CASE("Normal burn changes orbital plane", "[spacecraft][burn][normal]") { const double TIME_STEP = 60.0; SimulationState* sim = create_simulation(10, 10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); Spacecraft* craft = &sim->spacecraft[0]; double initial_z = craft->local_position.z; apply_impulsive_burn(craft, BURN_NORMAL, 500.0); const double SECONDS_TO_SIMULATE = 3600.0; double sim_time = 0.0; while (sim_time < SECONDS_TO_SIMULATE) { update_simulation(sim); sim_time += TIME_STEP; } REQUIRE(fabs(craft->local_position.z - initial_z) > 1000.0); destroy_simulation(sim); } TEST_CASE("Custom burn applies arbitrary delta-v", "[spacecraft][burn][custom]") { const double TIME_STEP = 60.0; SimulationState* sim = create_simulation(10, 10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); Spacecraft* craft = &sim->spacecraft[0]; Vec3 initial_vel = craft->local_velocity; Vec3 delta_v = {10.0, 20.0, 30.0}; apply_custom_burn(craft, delta_v); REQUIRE(fabs(craft->local_velocity.x - initial_vel.x - 10.0) < 0.001); REQUIRE(fabs(craft->local_velocity.y - initial_vel.y - 20.0) < 0.001); REQUIRE(fabs(craft->local_velocity.z - initial_vel.z - 30.0) < 0.001); destroy_simulation(sim); } TEST_CASE("Spacecraft propagation maintains stability", "[spacecraft][propagation]") { const double TIME_STEP = 60.0; const double DAYS_TO_SIMULATE = 1.0; const double SECONDS_PER_DAY = 86400.0; SimulationState* sim = create_simulation(10, 10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); Spacecraft* craft = &sim->spacecraft[0]; CelestialBody* earth = &sim->bodies[1]; double initial_distance = vec3_distance(craft->global_position, earth->global_position); double total_time = DAYS_TO_SIMULATE * SECONDS_PER_DAY; double sim_time = 0.0; while (sim_time < total_time) { update_simulation(sim); sim_time += TIME_STEP; } double final_distance = vec3_distance(craft->global_position, earth->global_position); double distance_drift_percent = fabs((final_distance - initial_distance) / initial_distance) * 100.0; INFO("Initial distance: " << initial_distance << " m"); INFO("Final distance: " << final_distance << " m"); INFO("Distance drift: " << distance_drift_percent << "%"); REQUIRE(distance_drift_percent < 1.0); destroy_simulation(sim); }