diff --git a/docs/mission_planning.md b/docs/mission_planning.md index 1d311d9..f3f1b28 100644 --- a/docs/mission_planning.md +++ b/docs/mission_planning.md @@ -265,6 +265,19 @@ Spacecraft may not enter Mars SOI due to: ### Immediate Next Steps +**TODO: Spacecraft Config Pattern Changes** + +Spacecraft now requires full position specification in config files: +- Removed placeholder pattern that expected `initialize_spacecraft_leo()` to set position at runtime +- Position must be: parent position + orbital altitude offset +- Example: Earth LEO at 200km = Earth radius (6.371e6 m) + 200,000 m = 6.571e6 m offset +- Velocity is calculated by `initialize_bodies()` using `semi_major_axis` parameter + +**Impact on `initialize_spacecraft_leo()`:** +- Currently sets position relative to parent +- May need to be deprecated or updated to validate/override config-based positions +- Consider keeping function for dynamic scenarios (e.g., multi-burn missions) + #### 1. Config Format Improvements - Support Earth-relative position specification (e.g., `{ altitude_km = 200.0 }`) - Support Earth-relative orbit specification (e.g., `{ orbit_type = "circular" }`) diff --git a/src/config_loader.cpp b/src/config_loader.cpp index 37ee95f..aa09d6a 100644 --- a/src/config_loader.cpp +++ b/src/config_loader.cpp @@ -135,6 +135,26 @@ bool load_system_config(SimulationState* sim, const char* filepath) { } } + // Validate parent-child distances + for (int i = 0; i < body_count; i++) { + if (sim->bodies[i].parent_index >= 0) { + CelestialBody* body = &sim->bodies[i]; + CelestialBody* parent = &sim->bodies[body->parent_index]; + + double distance = vec3_distance(body->position, parent->position); + double min_distance = parent->radius + body->radius; + + if (distance < min_distance) { + printf("Error: Body '%s' (index %d) too close to parent '%s' (index %d)\n", + body->name, i, parent->name, body->parent_index); + printf(" Distance: %.2e m\n", distance); + printf(" Minimum required: %.2e m (parent radius + body radius)\n", min_distance); + toml_free(result); + return false; + } + } + } + sim->body_count = body_count; toml_free(result); diff --git a/tests/configs/earth_mars_simple.toml b/tests/configs/earth_mars_simple.toml index a4a28a2..50988bf 100644 --- a/tests/configs/earth_mars_simple.toml +++ b/tests/configs/earth_mars_simple.toml @@ -32,11 +32,12 @@ semi_major_axis = 2.279e11 name = "Spacecraft" mass = 1.0 radius = 1000.0 -# Position and velocity will be initialized at runtime for LEO orbit -position = { x = 1.496e11, y = 0.0, z = 0.0 } +# Position at LEO altitude: Earth position + (Earth radius + 200km altitude) +# Earth: 1.496e11, LEO offset: 6.571e6, Total: 1.49606571e11 +position = { x = 1.49606571e11, y = 0.0, z = 0.0 } velocity = { x = 0.0, y = 0.0, z = 0.0 } parent_index = 1 color = { r = 1.0, g = 0.0, b = 0.5 } eccentricity = 0.0 -# Semi-major axis will be: Earth radius + 200km -semi_major_axis = 6.571e6 # Placeholder, will be set during initialization +# Semi-major axis: Earth radius + 200km LEO altitude +semi_major_axis = 6.571e6 diff --git a/tests/test_invalid_parent_assignment.cpp b/tests/test_invalid_parent_assignment.cpp index e1f8769..76372fb 100644 --- a/tests/test_invalid_parent_assignment.cpp +++ b/tests/test_invalid_parent_assignment.cpp @@ -99,12 +99,16 @@ TEST_CASE("Invalid parent: detect placeholder config values", Vec3 earth_pos = sim->bodies[EARTH_IDX].position; double distance = vec3_distance(craft_pos, earth_pos); + double min_distance = sim->bodies[EARTH_IDX].radius + sim->bodies[SPACECRAFT_IDX].radius; INFO("Distance Earth <-> Spacecraft: " << distance << " m"); INFO("Earth position: (" << earth_pos.x << ", " << earth_pos.y << ", " << earth_pos.z << ")"); INFO("Spacecraft position: (" << craft_pos.x << ", " << craft_pos.y << ", " << craft_pos.z << ")"); + INFO("Earth radius: " << sim->bodies[EARTH_IDX].radius << " m"); + INFO("Spacecraft radius: " << sim->bodies[SPACECRAFT_IDX].radius << " m"); + INFO("Minimum required: " << min_distance << " m (parent radius + body radius)"); - REQUIRE(distance > 100000.0); + REQUIRE(distance >= min_distance); destroy_simulation(sim); }