From f5a1fdd24557804de58e07a6a5ede2dc2367db43 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Thu, 22 Jan 2026 08:38:27 -0500 Subject: [PATCH] Refactor: Integrate spacecraft into SimulationState Merge spacecraft management into simulation module: - Move Spacecraft struct from maneuver.h to spacecraft.h - Add spacecraft array to SimulationState (spacecraft, craft_count, max_craft) - Remove separate SpacecraftState struct and related functions - Update create_simulation() to require max_craft parameter - Move spacecraft update logic into update_simulation() - Make load_spacecraft_config() internal helper, called by load_system_config() - Update all test files to use new API with 3-parameter create_simulation() - Handle max_craft=0 case gracefully (no spacecraft allocation) Test results: 26/27 passing (1 pre-existing SOI test unrelated to changes) --- src/config_loader.cpp | 115 +++++++++++------------ src/config_loader.h | 1 - src/main.cpp | 3 +- src/maneuver.cpp | 1 + src/maneuver.h | 11 +-- src/simulation.cpp | 59 +++++++++++- src/simulation.h | 16 +++- src/spacecraft.cpp | 68 +------------- src/spacecraft.h | 21 ++--- tests/test_energy.cpp | 2 +- tests/test_hyperbolic_orbit.cpp | 6 +- tests/test_invalid_parent_assignment.cpp | 8 +- tests/test_maneuvers.cpp | 50 +++------- tests/test_moon_orbits.cpp | 8 +- tests/test_orbital_period.cpp | 4 +- tests/test_parabolic_orbit.cpp | 4 +- tests/test_root_body_transitions.cpp | 4 +- tests/test_soi_transition.cpp | 4 +- 18 files changed, 173 insertions(+), 212 deletions(-) diff --git a/src/config_loader.cpp b/src/config_loader.cpp index 909c9a1..452a18c 100644 --- a/src/config_loader.cpp +++ b/src/config_loader.cpp @@ -3,7 +3,9 @@ #include #include #include "simulation.h" -#include "spacecraft.h" + +static bool parse_toml_spacecraft(toml_datum_t craft_table, Spacecraft* craft); +static bool load_spacecraft_from_toml(SimulationState* sim, toml_result_t result); static bool extract_vec3_from_table(toml_datum_t table, Vec3* pos) { toml_datum_t x = toml_get(table, "x"); @@ -157,80 +159,40 @@ bool load_system_config(SimulationState* sim, const char* filepath) { } sim->body_count = body_count; - toml_free(result); - - initialize_bodies(sim); strncpy(sim->config_name, filepath, sizeof(sim->config_name) - 1); sim->config_name[sizeof(sim->config_name) - 1] = '\0'; - printf("Loaded %d bodies from %s\n", body_count, filepath); - return true; -} - -static bool parse_toml_spacecraft(toml_datum_t craft_table, Spacecraft* craft) { - toml_datum_t name = toml_get(craft_table, "name"); - if (name.type != TOML_STRING) { - return false; - } - strncpy(craft->name, name.u.s, 63); - craft->name[63] = '\0'; - - toml_datum_t mass = toml_get(craft_table, "mass"); - toml_datum_t parent_idx = toml_get(craft_table, "parent_index"); - - if (mass.type != TOML_FP64 || parent_idx.type != TOML_INT64) { + // Load spacecraft from the same config file (before freeing TOML data) + if (!load_spacecraft_from_toml(sim, result)) { + toml_free(result); return false; } - craft->mass = mass.u.fp64; - craft->parent_index = (int)(parent_idx.type == TOML_INT64 ? parent_idx.u.int64 : (int)parent_idx.u.fp64); - - toml_datum_t position = toml_get(craft_table, "position"); - if (position.type != TOML_TABLE || !extract_vec3_from_table(position, &craft->local_position)) { - return false; - } - craft->position = craft->local_position; + toml_free(result); - toml_datum_t velocity = toml_get(craft_table, "velocity"); - if (velocity.type == TOML_TABLE) { - if (!extract_vec3_from_table(velocity, &craft->local_velocity)) { - return false; - } - } else { - craft->local_velocity = {0.0, 0.0, 0.0}; - } - craft->velocity = craft->local_velocity; + initialize_bodies(sim); + printf("Loaded %d bodies from %s\n", body_count, filepath); return true; } -bool load_spacecraft_config(SpacecraftState* craft_state, SimulationState* sim, const char* filepath) { - toml_result_t result = toml_parse_file_ex(filepath); - if (!result.ok) { - printf("Error: Could not parse TOML config file: %s\n", filepath); - printf("TOML Error: %s\n", result.errmsg); - return false; - } - +static bool load_spacecraft_from_toml(SimulationState* sim, toml_result_t result) { toml_datum_t spacecraft = toml_get(result.toptab, "spacecraft"); if (spacecraft.type != TOML_ARRAY) { - printf("No spacecraft array found in config file: %s (optional)\n", filepath); - toml_free(result); + printf("No spacecraft array found in config file: %s (optional)\n", sim->config_name); return true; } int craft_count = spacecraft.u.arr.size; if (craft_count == 0) { - printf("No spacecraft found in config file: %s\n", filepath); - toml_free(result); + printf("No spacecraft found in config file: %s\n", sim->config_name); return true; } - if (craft_count > craft_state->max_craft) { - printf("Error: Too many spacecraft (%d) for state (max: %d)\n", - craft_count, craft_state->max_craft); - toml_free(result); + if (craft_count > sim->max_craft) { + printf("Error: Too many spacecraft (%d) for simulation (max: %d)\n", + craft_count, sim->max_craft); return false; } @@ -239,14 +201,12 @@ bool load_spacecraft_config(SpacecraftState* craft_state, SimulationState* sim, toml_datum_t craft_table = spacecraft.u.arr.elem[i]; if (!parse_toml_spacecraft(craft_table, &craft)) { printf("Error: Failed to parse spacecraft at index %d\n", i); - toml_free(result); return false; } if (craft.parent_index < 0 || craft.parent_index >= sim->body_count) { printf("Error: Spacecraft '%s' has invalid parent_index %d (valid: 0-%d)\n", craft.name, craft.parent_index, sim->body_count - 1); - toml_free(result); return false; } @@ -254,15 +214,50 @@ bool load_spacecraft_config(SpacecraftState* craft_state, SimulationState* sim, craft.position = vec3_add(parent->position, craft.local_position); craft.velocity = vec3_add(parent->velocity, craft.local_velocity); - int idx = add_spacecraft(craft_state, &craft); + int idx = add_spacecraft(sim, &craft); if (idx < 0) { - printf("Error: Failed to add spacecraft to state\n"); - toml_free(result); + printf("Error: Failed to add spacecraft to simulation\n"); return false; } } - printf("Loaded %d spacecraft from %s\n", craft_count, filepath); - toml_free(result); + printf("Loaded %d spacecraft from %s\n", craft_count, sim->config_name); return true; } + +static bool parse_toml_spacecraft(toml_datum_t craft_table, Spacecraft* craft) { + toml_datum_t name = toml_get(craft_table, "name"); + if (name.type != TOML_STRING) { + return false; + } + strncpy(craft->name, name.u.s, 63); + craft->name[63] = '\0'; + + toml_datum_t mass = toml_get(craft_table, "mass"); + toml_datum_t parent_idx = toml_get(craft_table, "parent_index"); + + if (mass.type != TOML_FP64 || parent_idx.type != TOML_INT64) { + return false; + } + + craft->mass = mass.u.fp64; + craft->parent_index = (int)(parent_idx.type == TOML_INT64 ? parent_idx.u.int64 : (int)parent_idx.u.fp64); + + toml_datum_t position = toml_get(craft_table, "position"); + if (position.type != TOML_TABLE || !extract_vec3_from_table(position, &craft->local_position)) { + return false; + } + craft->position = craft->local_position; + + toml_datum_t velocity = toml_get(craft_table, "velocity"); + if (velocity.type == TOML_TABLE) { + if (!extract_vec3_from_table(velocity, &craft->local_velocity)) { + return false; + } + } else { + craft->local_velocity = {0.0, 0.0, 0.0}; + } + craft->velocity = craft->local_velocity; + + return true; +} \ No newline at end of file diff --git a/src/config_loader.h b/src/config_loader.h index dda9ef4..0a5caa8 100644 --- a/src/config_loader.h +++ b/src/config_loader.h @@ -6,6 +6,5 @@ #include "../ext/tomlc17/src/tomlc17.h" bool load_system_config(SimulationState* sim, const char* filepath); -bool load_spacecraft_config(SpacecraftState* craft_state, SimulationState* sim, const char* filepath); #endif diff --git a/src/main.cpp b/src/main.cpp index 6a33426..88040df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -106,8 +106,9 @@ int main(int argc, char** argv) { // Create simulation with time step of 60 seconds const int MAX_BODIES = 100; + const int MAX_SPACECRAFT = 50; const double TIME_STEP = 60.0; // 60 seconds per step - SimulationState* sim = create_simulation(MAX_BODIES, TIME_STEP); + SimulationState* sim = create_simulation(MAX_BODIES, MAX_SPACECRAFT, TIME_STEP); // Load system configuration if (!load_system_config(sim, args.config_file)) { diff --git a/src/maneuver.cpp b/src/maneuver.cpp index ea5d79f..4f5fddb 100644 --- a/src/maneuver.cpp +++ b/src/maneuver.cpp @@ -1,5 +1,6 @@ #include "maneuver.h" #include "physics.h" +#include "spacecraft.h" #include Vec3 calculate_prograde_dir(Vec3 local_velocity) { diff --git a/src/maneuver.h b/src/maneuver.h index b844863..973e415 100644 --- a/src/maneuver.h +++ b/src/maneuver.h @@ -2,6 +2,7 @@ #define MANEUVER_H #include "physics.h" +#include "spacecraft.h" enum BurnDirection { BURN_PROGRADE, @@ -13,16 +14,6 @@ enum BurnDirection { BURN_CUSTOM }; -struct Spacecraft { - char name[64]; - double mass; - Vec3 local_position; - Vec3 local_velocity; - Vec3 position; - Vec3 velocity; - int parent_index; -}; - // Direction calculation functions (local frame) Vec3 calculate_prograde_dir(Vec3 local_velocity); Vec3 calculate_retrograde_dir(Vec3 local_velocity); diff --git a/src/simulation.cpp b/src/simulation.cpp index 2965554..7b89bdc 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -1,4 +1,5 @@ #include "simulation.h" +#include "spacecraft.h" #include #include #include @@ -6,11 +7,20 @@ #include // Create a new simulation -SimulationState* create_simulation(int max_bodies, double time_step) { +SimulationState* create_simulation(int max_bodies, int max_craft, double time_step) { SimulationState* sim = (SimulationState*)malloc(sizeof(SimulationState)); sim->bodies = (CelestialBody*)malloc(sizeof(CelestialBody) * max_bodies); + + if (max_craft > 0) { + sim->spacecraft = (Spacecraft*)malloc(sizeof(Spacecraft) * max_craft); + } else { + sim->spacecraft = NULL; + } + sim->body_count = 0; sim->max_bodies = max_bodies; + sim->craft_count = 0; + sim->max_craft = max_craft; sim->time = 0.0; sim->dt = time_step; sim->config_name[0] = '\0'; @@ -23,10 +33,28 @@ void destroy_simulation(SimulationState* sim) { if (sim->bodies) { free(sim->bodies); } + if (sim->max_craft > 0 && sim->spacecraft) { + free(sim->spacecraft); + } free(sim); } } +// Add a spacecraft to the simulation +int add_spacecraft(SimulationState* sim, Spacecraft* craft) { + if (sim->craft_count >= sim->max_craft) { + printf("Error: Cannot add spacecraft - simulation full (%d/%d)\n", + sim->craft_count, sim->max_craft); + return -1; + } + + int new_idx = sim->craft_count; + sim->spacecraft[new_idx] = *craft; + sim->craft_count++; + + return new_idx; +} + // Add a body to the simulation at runtime int add_body_to_simulation(SimulationState* sim, CelestialBody* body) { if (sim->body_count >= sim->max_bodies) { @@ -163,6 +191,35 @@ void update_simulation(SimulationState* sim) { } compute_global_coordinates(sim); + + // Update spacecraft + for (int i = 0; i < sim->craft_count; i++) { + Spacecraft* craft = &sim->spacecraft[i]; + + if (craft->parent_index < 0 || craft->parent_index >= sim->body_count) { + continue; + } + + CelestialBody* parent = &sim->bodies[craft->parent_index]; + + rk4_step(&craft->local_position, &craft->local_velocity, + sim->dt, craft->mass, parent->mass); + } + + // Compute spacecraft global coordinates + for (int i = 0; i < sim->craft_count; i++) { + Spacecraft* craft = &sim->spacecraft[i]; + + if (craft->parent_index >= 0 && craft->parent_index < sim->body_count) { + CelestialBody* parent = &sim->bodies[craft->parent_index]; + craft->position = vec3_add(parent->position, craft->local_position); + craft->velocity = vec3_add(parent->velocity, craft->local_velocity); + } else { + craft->position = craft->local_position; + craft->velocity = craft->local_velocity; + } + } + sim->time += sim->dt; } diff --git a/src/simulation.h b/src/simulation.h index ac365b7..fc3c8d1 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -3,6 +3,8 @@ #include "physics.h" +struct Spacecraft; + // Celestial body structure struct CelestialBody { char name[64]; @@ -24,17 +26,23 @@ struct SimulationState { CelestialBody* bodies; int body_count; int max_bodies; - double time; // simulation time (seconds) - double dt; // time step (seconds) - char config_name[256]; // name of the config file loaded + + Spacecraft* spacecraft; + int craft_count; + int max_craft; + + double time; + double dt; + char config_name[256]; }; // Simulation management functions -SimulationState* create_simulation(int max_bodies, double time_step); +SimulationState* create_simulation(int max_bodies, int max_craft, double time_step); void destroy_simulation(SimulationState* sim); // Dynamic body management int add_body_to_simulation(SimulationState* sim, CelestialBody* body); +int add_spacecraft(SimulationState* sim, Spacecraft* craft); // SOI and simulation update functions int find_dominant_body(SimulationState* sim, int body_index); diff --git a/src/spacecraft.cpp b/src/spacecraft.cpp index 8c1ffe5..c535a4c 100644 --- a/src/spacecraft.cpp +++ b/src/spacecraft.cpp @@ -1,71 +1,5 @@ #include "spacecraft.h" -#include "physics.h" +#include "simulation.h" #include #include #include - -SpacecraftState* create_spacecraft_state(int max_craft) { - SpacecraftState* state = (SpacecraftState*)malloc(sizeof(SpacecraftState)); - state->spacecraft = (Spacecraft*)malloc(sizeof(Spacecraft) * max_craft); - state->craft_count = 0; - state->max_craft = max_craft; - return state; -} - -void destroy_spacecraft_state(SpacecraftState* state) { - if (state) { - if (state->spacecraft) { - free(state->spacecraft); - } - free(state); - } -} - -int add_spacecraft(SpacecraftState* state, Spacecraft* craft) { - if (state->craft_count >= state->max_craft) { - printf("Error: Cannot add spacecraft - state full (%d/%d)\n", - state->craft_count, state->max_craft); - return -1; - } - - int new_idx = state->craft_count; - state->spacecraft[new_idx] = *craft; - state->craft_count++; - - return new_idx; -} - -void compute_spacecraft_globals(SpacecraftState* craft_state, SimulationState* sim) { - for (int i = 0; i < craft_state->craft_count; i++) { - Spacecraft* craft = &craft_state->spacecraft[i]; - - if (craft->parent_index >= 0 && craft->parent_index < sim->body_count) { - CelestialBody* parent = &sim->bodies[craft->parent_index]; - craft->position = vec3_add(parent->position, craft->local_position); - craft->velocity = vec3_add(parent->velocity, craft->local_velocity); - } else { - craft->position = craft->local_position; - craft->velocity = craft->local_velocity; - } - } -} - -void update_spacecraft(SpacecraftState* craft_state, SimulationState* sim) { - for (int i = 0; i < craft_state->craft_count; i++) { - Spacecraft* craft = &craft_state->spacecraft[i]; - - if (craft->parent_index < 0 || craft->parent_index >= sim->body_count) { - continue; - } - - CelestialBody* parent = &sim->bodies[craft->parent_index]; - - double parent_mass = parent->mass; - double craft_mass = craft->mass; - - rk4_step(&craft->local_position, &craft->local_velocity, - sim->dt, craft_mass, parent_mass); - } - - compute_spacecraft_globals(craft_state, sim); -} diff --git a/src/spacecraft.h b/src/spacecraft.h index 8fca919..d7ac8bf 100644 --- a/src/spacecraft.h +++ b/src/spacecraft.h @@ -1,19 +1,16 @@ #ifndef SPACECRAFT_H #define SPACECRAFT_H -#include "maneuver.h" -#include "simulation.h" +#include "physics.h" -struct SpacecraftState { - Spacecraft* spacecraft; - int craft_count; - int max_craft; +struct Spacecraft { + char name[64]; + double mass; + Vec3 local_position; + Vec3 local_velocity; + Vec3 position; + Vec3 velocity; + int parent_index; }; -SpacecraftState* create_spacecraft_state(int max_craft); -void destroy_spacecraft_state(SpacecraftState* state); -void update_spacecraft(SpacecraftState* craft_state, SimulationState* sim); -void compute_spacecraft_globals(SpacecraftState* craft_state, SimulationState* sim); -int add_spacecraft(SpacecraftState* state, Spacecraft* craft); - #endif diff --git a/tests/test_energy.cpp b/tests/test_energy.cpp index a773374..f510091 100644 --- a/tests/test_energy.cpp +++ b/tests/test_energy.cpp @@ -10,7 +10,7 @@ TEST_CASE("Energy conservation - Earth circular orbit", "[energy][rk4]") { const double DAYS_TO_SIMULATE = 10.0; const double SECONDS_PER_DAY = 86400.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/earth_circular.toml")); diff --git a/tests/test_hyperbolic_orbit.cpp b/tests/test_hyperbolic_orbit.cpp index f4c9481..844a181 100644 --- a/tests/test_hyperbolic_orbit.cpp +++ b/tests/test_hyperbolic_orbit.cpp @@ -12,7 +12,7 @@ TEST_CASE("Hyperbolic orbit - energy and escape trajectory", "[hyperbolic][energ const double SECONDS_PER_DAY = 86400.0; const double AU = 1.496e11; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/hyperbolic_comet.toml")); @@ -111,7 +111,7 @@ TEST_CASE("Hyperbolic orbit - energy and escape trajectory", "[hyperbolic][energ TEST_CASE("Hyperbolic orbit initial conditions", "[hyperbolic][initial]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/hyperbolic_comet.toml")); @@ -174,7 +174,7 @@ TEST_CASE("Hyperbolic orbit asymptotic velocity", "[hyperbolic][asymptotic]") { const double SECONDS_PER_DAY = 86400.0; const double AU = 1.496e11; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/hyperbolic_comet.toml")); diff --git a/tests/test_invalid_parent_assignment.cpp b/tests/test_invalid_parent_assignment.cpp index 76372fb..1248a9d 100644 --- a/tests/test_invalid_parent_assignment.cpp +++ b/tests/test_invalid_parent_assignment.cpp @@ -14,7 +14,7 @@ TEST_CASE("Invalid parent: Earth should not become child of spacecraft", "[init][parent][bug]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/earth_mars_simple.toml")); const int EARTH_IDX = 1; @@ -43,7 +43,7 @@ TEST_CASE("Invalid parent: massive bodies never become children of small bodies" const double TIME_STEP = 60.0; const double MASS_THRESHOLD_RATIO = 1000.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/earth_mars_simple.toml")); for (int i = 0; i < sim->body_count; i++) { @@ -89,7 +89,7 @@ TEST_CASE("Invalid parent: detect placeholder config values", "[init][config][validation]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/earth_mars_simple.toml")); const int EARTH_IDX = 1; @@ -117,7 +117,7 @@ TEST_CASE("Mutual SOI: similar mass planets within SOI boundary", "[init][soi][mutual][edge_case]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/mutual_soi_close.toml")); const int PLANET_A_IDX = 1; diff --git a/tests/test_maneuvers.cpp b/tests/test_maneuvers.cpp index d96bf2e..9f97f99 100644 --- a/tests/test_maneuvers.cpp +++ b/tests/test_maneuvers.cpp @@ -10,30 +10,25 @@ TEST_CASE("Spacecraft loading from config", "[spacecraft][config]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); - SpacecraftState* craft_state = create_spacecraft_state(10); + SimulationState* sim = create_simulation(10, 10, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); - REQUIRE(load_spacecraft_config(craft_state, sim, "tests/configs/spacecraft_test.toml")); - REQUIRE(craft_state->craft_count == 1); - REQUIRE(std::string(craft_state->spacecraft[0].name) == "LEO_Satellite"); - REQUIRE(craft_state->spacecraft[0].parent_index == 1); + REQUIRE(sim->craft_count == 1); + REQUIRE(std::string(sim->spacecraft[0].name) == "LEO_Satellite"); + REQUIRE(sim->spacecraft[0].parent_index == 1); - destroy_spacecraft_state(craft_state); destroy_simulation(sim); } TEST_CASE("Prograde burn increases orbital energy", "[spacecraft][burn][prograde]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); - SpacecraftState* craft_state = create_spacecraft_state(10); + SimulationState* sim = create_simulation(10, 10, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); - REQUIRE(load_spacecraft_config(craft_state, sim, "tests/configs/spacecraft_test.toml")); - Spacecraft* craft = &craft_state->spacecraft[0]; + Spacecraft* craft = &sim->spacecraft[0]; CelestialBody* earth = &sim->bodies[1]; double initial_distance = vec3_distance(craft->position, earth->position); @@ -47,27 +42,23 @@ TEST_CASE("Prograde burn increases orbital energy", "[spacecraft][burn][prograde double sim_time = 0.0; while (sim_time < SECONDS_TO_SIMULATE) { update_simulation(sim); - update_spacecraft(craft_state, sim); sim_time += TIME_STEP; } double final_distance = vec3_distance(craft->position, earth->position); REQUIRE(final_distance > initial_distance); - destroy_spacecraft_state(craft_state); destroy_simulation(sim); } TEST_CASE("Retrograde burn decreases orbital energy", "[spacecraft][burn][retrograde]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); - SpacecraftState* craft_state = create_spacecraft_state(10); + SimulationState* sim = create_simulation(10, 10, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); - REQUIRE(load_spacecraft_config(craft_state, sim, "tests/configs/spacecraft_test.toml")); - Spacecraft* craft = &craft_state->spacecraft[0]; + Spacecraft* craft = &sim->spacecraft[0]; CelestialBody* earth = &sim->bodies[1]; double initial_distance = vec3_distance(craft->position, earth->position); @@ -81,27 +72,23 @@ TEST_CASE("Retrograde burn decreases orbital energy", "[spacecraft][burn][retrog double sim_time = 0.0; while (sim_time < SECONDS_TO_SIMULATE) { update_simulation(sim); - update_spacecraft(craft_state, sim); sim_time += TIME_STEP; } double final_distance = vec3_distance(craft->position, earth->position); REQUIRE(final_distance < initial_distance); - destroy_spacecraft_state(craft_state); destroy_simulation(sim); } TEST_CASE("Normal burn changes orbital plane", "[spacecraft][burn][normal]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); - SpacecraftState* craft_state = create_spacecraft_state(10); + SimulationState* sim = create_simulation(10, 10, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); - REQUIRE(load_spacecraft_config(craft_state, sim, "tests/configs/spacecraft_test.toml")); - Spacecraft* craft = &craft_state->spacecraft[0]; + Spacecraft* craft = &sim->spacecraft[0]; double initial_z = craft->local_position.z; @@ -111,26 +98,22 @@ TEST_CASE("Normal burn changes orbital plane", "[spacecraft][burn][normal]") { double sim_time = 0.0; while (sim_time < SECONDS_TO_SIMULATE) { update_simulation(sim); - update_spacecraft(craft_state, sim); sim_time += TIME_STEP; } REQUIRE(fabs(craft->local_position.z - initial_z) > 1000.0); - destroy_spacecraft_state(craft_state); 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, TIME_STEP); - SpacecraftState* craft_state = create_spacecraft_state(10); + SimulationState* sim = create_simulation(10, 10, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); - REQUIRE(load_spacecraft_config(craft_state, sim, "tests/configs/spacecraft_test.toml")); - Spacecraft* craft = &craft_state->spacecraft[0]; + Spacecraft* craft = &sim->spacecraft[0]; Vec3 initial_vel = craft->local_velocity; Vec3 delta_v = {10.0, 20.0, 30.0}; @@ -141,7 +124,6 @@ TEST_CASE("Custom burn applies arbitrary delta-v", "[spacecraft][burn][custom]") 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_spacecraft_state(craft_state); destroy_simulation(sim); } @@ -150,13 +132,11 @@ TEST_CASE("Spacecraft propagation maintains stability", "[spacecraft][propagatio const double DAYS_TO_SIMULATE = 1.0; const double SECONDS_PER_DAY = 86400.0; - SimulationState* sim = create_simulation(10, TIME_STEP); - SpacecraftState* craft_state = create_spacecraft_state(10); + SimulationState* sim = create_simulation(10, 10, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/spacecraft_test.toml")); - REQUIRE(load_spacecraft_config(craft_state, sim, "tests/configs/spacecraft_test.toml")); - Spacecraft* craft = &craft_state->spacecraft[0]; + Spacecraft* craft = &sim->spacecraft[0]; CelestialBody* earth = &sim->bodies[1]; double initial_distance = vec3_distance(craft->position, earth->position); @@ -165,7 +145,6 @@ TEST_CASE("Spacecraft propagation maintains stability", "[spacecraft][propagatio double sim_time = 0.0; while (sim_time < total_time) { update_simulation(sim); - update_spacecraft(craft_state, sim); sim_time += TIME_STEP; } @@ -178,6 +157,5 @@ TEST_CASE("Spacecraft propagation maintains stability", "[spacecraft][propagatio REQUIRE(distance_drift_percent < 1.0); - destroy_spacecraft_state(craft_state); destroy_simulation(sim); } diff --git a/tests/test_moon_orbits.cpp b/tests/test_moon_orbits.cpp index 6950979..d640856 100644 --- a/tests/test_moon_orbits.cpp +++ b/tests/test_moon_orbits.cpp @@ -13,7 +13,7 @@ TEST_CASE("Moon orbital stability around Earth", "[moon][earth]") { const double MAX_SIMULATION_DAYS = 35.0; const double MOON_DISTANCE_FROM_EARTH = 384400000.0; - SimulationState* sim = create_simulation(20, TIME_STEP); + SimulationState* sim = create_simulation(20, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/solar_system.toml")); @@ -98,7 +98,7 @@ TEST_CASE("Galilean moons orbital stability around Jupiter", "[moon][jupiter]") const double GANYMEDE_PERIOD_DAYS = 7.15; const double CALLISTO_PERIOD_DAYS = 16.69; - SimulationState* sim = create_simulation(20, TIME_STEP); + SimulationState* sim = create_simulation(20, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/solar_system.toml")); @@ -162,7 +162,7 @@ TEST_CASE("Titan orbital stability around Saturn", "[moon][saturn]") { const double SECONDS_PER_DAY = 86400.0; const double MAX_SIMULATION_DAYS = 25.0; - SimulationState* sim = create_simulation(20, TIME_STEP); + SimulationState* sim = create_simulation(20, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/solar_system.toml")); @@ -216,7 +216,7 @@ TEST_CASE("Combined solar system with all moons - parent stability", "[moon][int const double SECONDS_PER_DAY = 86400.0; const double MAX_SIMULATION_DAYS = 60.0; - SimulationState* sim = create_simulation(20, TIME_STEP); + SimulationState* sim = create_simulation(20, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/solar_system.toml")); diff --git a/tests/test_orbital_period.cpp b/tests/test_orbital_period.cpp index 7ebf2f7..dac8216 100644 --- a/tests/test_orbital_period.cpp +++ b/tests/test_orbital_period.cpp @@ -11,7 +11,7 @@ TEST_CASE("Orbital period - Earth (RK4)", "[period][rk4]") { const double SECONDS_PER_DAY = 86400.0; const double MAX_SIMULATION_DAYS = 400.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/earth_circular.toml")); @@ -44,7 +44,7 @@ TEST_CASE("Orbital period - Mars (RK4)", "[period][rk4]") { const double SECONDS_PER_DAY = 86400.0; const double MAX_SIMULATION_DAYS = 750.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/mars_circular.toml")); diff --git a/tests/test_parabolic_orbit.cpp b/tests/test_parabolic_orbit.cpp index 14e9819..31c6402 100644 --- a/tests/test_parabolic_orbit.cpp +++ b/tests/test_parabolic_orbit.cpp @@ -12,7 +12,7 @@ TEST_CASE("Parabolic orbit - energy and escape trajectory", "[parabolic][energy] const double SECONDS_PER_DAY = 86400.0; const double AU = 1.496e11; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/parabolic_comet.toml")); @@ -104,7 +104,7 @@ TEST_CASE("Parabolic orbit - energy and escape trajectory", "[parabolic][energy] TEST_CASE("Parabolic orbit initial conditions", "[parabolic][initial]") { const double TIME_STEP = 60.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/parabolic_comet.toml")); diff --git a/tests/test_root_body_transitions.cpp b/tests/test_root_body_transitions.cpp index 62c13f2..db05cd1 100644 --- a/tests/test_root_body_transitions.cpp +++ b/tests/test_root_body_transitions.cpp @@ -23,7 +23,7 @@ TEST_CASE("Root body transition - Earth to Sun", "[root][transition]") { const double SECONDS_PER_DAY = 86400.0; const double AU = 1.496e11; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/manual_root_transition.toml")); @@ -97,7 +97,7 @@ TEST_CASE("Root body round-trip - Earth -> Sun -> Mars -> Sun", "[root][round-tr const double DAYS_TO_SIMULATE = 1000.0; const double SECONDS_PER_DAY = 86400.0; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/manual_root_transition.toml")); diff --git a/tests/test_soi_transition.cpp b/tests/test_soi_transition.cpp index 4891887..aaf92ec 100644 --- a/tests/test_soi_transition.cpp +++ b/tests/test_soi_transition.cpp @@ -22,7 +22,7 @@ TEST_CASE("SOI transition - Sun to Mars", "[soi][transition]") { INFO("Note: SOI transitions use simple model (no hysteresis)"); - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/soi_transition.toml")); @@ -100,7 +100,7 @@ TEST_CASE("SOI transition - verify SOI radii", "[soi][radii]") { const double TIME_STEP = 60.0; const double AU = 1.496e11; - SimulationState* sim = create_simulation(10, TIME_STEP); + SimulationState* sim = create_simulation(10, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/configs/soi_transition.toml"));