Browse Source

Add config validation for parent-child distances

Added validation in config_loader to prevent bodies from starting too close
to their parent bodies (distance must be >= parent.radius + body.radius).

Changes:
- src/config_loader.cpp: Add parent-child distance validation before initialization
- tests/configs/earth_mars_simple.toml: Fix spacecraft position to LEO altitude
  (Earth position + 6.571e6 m offset = 1.49606571e11 m)
- tests/test_invalid_parent_assignment.cpp: Update test 3 to use radius-based validation
- docs/mission_planning.md: Add TODO about spacecraft config pattern changes

Test results:
- Test 1:  PASS (Earth no longer becomes child of spacecraft)
- Test 2:  PASS (Mass hierarchy preserved)
- Test 3:  PASS (Spacecraft at valid LEO position)
- Test 4:  FAIL (mutual SOI bug, as expected)

This prevents the spacecraft initialization bug where Earth would incorrectly
become a child of the spacecraft due to distance=0.
main
cinnaboot 6 months ago
parent
commit
899fa3bae6
  1. 13
      docs/mission_planning.md
  2. 20
      src/config_loader.cpp
  3. 9
      tests/configs/earth_mars_simple.toml
  4. 6
      tests/test_invalid_parent_assignment.cpp

13
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" }`)

20
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);

9
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

6
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);
}

Loading…
Cancel
Save