diff --git a/docs/technical_reference.md b/docs/technical_reference.md index 51dc1d2..ec32da4 100644 --- a/docs/technical_reference.md +++ b/docs/technical_reference.md @@ -58,15 +58,21 @@ struct CelestialBody { char name[64]; double mass; // kg double radius; // meters - Vec3 local_position; // position relative to parent (meters) - Vec3 local_velocity; // velocity relative to parent (m/s) - Vec3 position; // global position (meters from origin) - Vec3 velocity; // global velocity (m/s) + int parent_index; // index of gravitational parent (-1 for root body like Sun) + float color[3]; // RGB color for rendering + + // Orbital elements from config (Keplerian elements) + OrbitalElements orbit; + + // Global frame (from origin) + Vec3 global_position; // meters from origin + Vec3 global_velocity; // m/s + + // Local frame (relative to parent) + Vec3 local_position; // meters from parent + Vec3 local_velocity; // m/s relative to parent + double soi_radius; // sphere of influence radius (meters) - int parent_index; // index of gravitational parent (-1 for root) - float color[3]; // RGB for rendering - double eccentricity; // orbital eccentricity (0 = circular) - double semi_major_axis; // meters }; ``` @@ -91,16 +97,18 @@ struct SimulationState { }; ``` -### OrbitalElements (simulation.h) +### OrbitalElements (orbital_mechanics.h) ```cpp struct OrbitalElements { - double time_days; - double semi_major_axis_au; + union { + double semi_major_axis; // for elliptical (e<1) and hyperbolic (e>1) + double semi_latus_rectum; // for parabolic (e≈1) + }; double eccentricity; - double specific_energy; - double distance_to_sun_au; - double distance_to_ref_body_au; - double velocity_magnitude; + double true_anomaly; + double inclination; + double longitude_of_ascending_node; + double argument_of_periapsis; }; ``` @@ -109,11 +117,18 @@ struct OrbitalElements { struct Spacecraft { char name[64]; double mass; + int parent_index; + + // Orbital elements from config + OrbitalElements orbit; + + // Global frame (from origin) + Vec3 global_position; + Vec3 global_velocity; + + // Local frame (relative to parent) Vec3 local_position; Vec3 local_velocity; - Vec3 position; - Vec3 velocity; - int parent_index; }; ``` @@ -225,7 +240,7 @@ Burn execution system for spacecraft orbital maneuvers. Supports multiple burn d - Maneuvers track execution state and timestamp ### Config Loader (config_loader.cpp/h) -TOML-based config parser using tomlc17 library. Auto-calculates circular orbit velocities and SOI radii. +TOML-based config parser using tomlc17 library. Auto-calculates circular orbit velocities from orbital elements and SOI radii. **Key functions:** - `load_system_config()` - main entry point, loads bodies/spacecraft/maneuvers from config file @@ -234,7 +249,6 @@ TOML-based config parser using tomlc17 library. Auto-calculates circular orbit v - `parse_toml_maneuver()` - parses maneuver entries - `load_spacecraft_from_toml()` - loads spacecraft array from config - `load_maneuvers_from_toml()` - loads maneuvers array from config -- `initialize_bodies()` - combined initialization: velocities, SOI radii, and local coordinates **Config format details:** - TOML arrays: `[[bodies]]`, `[[spacecraft]]`, `[[maneuvers]]` @@ -242,6 +256,7 @@ TOML-based config parser using tomlc17 library. Auto-calculates circular orbit v - `parent_index = -1` indicates root body (star) - Supports nested orbits (planets with moons) - All numeric values accept integers or floats +- Uses orbital elements table (Keplerian elements) instead of state vectors **Config format (TOML) - Bodies:** ```toml @@ -249,21 +264,25 @@ TOML-based config parser using tomlc17 library. Auto-calculates circular orbit v name = "Sun" mass = 1.989e30 radius = 6.96e8 -position = { x = 0.0, y = 0.0, z = 0.0 } parent_index = -1 color = { r = 1.0, g = 1.0, b = 0.0 } -eccentricity = 0.0 -semi_major_axis = 0.0 +orbit = { + semi_major_axis = 0.0, + eccentricity = 0.0, + true_anomaly = 0.0 +} [[bodies]] name = "Earth" mass = 5.972e24 radius = 6.371e6 -position = { x = 1.496e11, y = 0.0, z = 0.0 } parent_index = 0 color = { r = 0.0, g = 0.5, b = 1.0 } -eccentricity = 0.0 -semi_major_axis = 1.496e11 +orbit = { + semi_major_axis = 1.496e11, + eccentricity = 0.0, + true_anomaly = 0.0 +} ``` **Config format (TOML) - Spacecraft:** @@ -271,12 +290,15 @@ semi_major_axis = 1.496e11 [[spacecraft]] name = "LEO_Satellite" mass = 1000.0 -position = { x = 0.0, y = 6.771e6, z = 0.0 } -velocity = { x = 7660.0, y = 0.0, z = 0.0 } parent_index = 1 +orbit = { + semi_major_axis = 6.571e6, + eccentricity = 0.0, + true_anomaly = 0.0 +} ``` -- `position` and `velocity` are in local frame relative to parent -- `velocity` is optional (defaults to zero if omitted) +- Uses `orbit` table for orbital elements (same as bodies) +- Altitude can be used instead of `semi_major_axis` (convenience feature, added to parent radius) **Config format (TOML) - Maneuvers:** ```toml @@ -292,15 +314,36 @@ delta_v = 500.0 - `direction`: "prograde", "retrograde", "normal", "antinormal", "radial_in", "radial_out" - `delta_v`: velocity change magnitude in m/s +### Config Validator (config_validator.cpp/h) +Validation module that ensures config files define physically realistic systems. Called automatically after loading config and initializing orbital objects. + +**Key functions:** +- `run_all_config_validations()` - master validation function that calls all validators +- `validate_parent_index_ordering()` - ensures parent indices are properly ordered +- `validate_orbital_elements()` - checks orbital elements for valid values +- `validate_initial_positions()` - ensures bodies aren't inside their parent +- `validate_mass_ratios()` - checks parent-child mass ratios for hierarchical consistency +- `validate_soi_overlap()` - detects bodies with overlapping spheres of influence +- `validate_nested_orbits()` - ensures moons orbit within stable boundaries + **Validation rules:** - Body count must not exceed `max_bodies` - Spacecraft count must not exceed `max_craft` - Maneuver count must not exceed `max_maneuvers` - Body `parent_index` must be < body index or -1 (root) -- Parent-child distance must exceed combined radii - Spacecraft `parent_index` must reference valid body - Maneuver `spacecraft_name` must reference existing spacecraft - Maneuver names must be unique within config +- Eccentricity must be >= 0 +- Parabolic orbits (e≈1) require `semi_latus_rectum` (not `semi_major_axis`) +- Elliptical/hyperbolic orbits require `semi_major_axis` (not `semi_latus_rectum`) +- Elliptical orbits (e<1) require positive `semi_major_axis` +- Bodies with `eccentricity < 1` and `semi_major_axis <= 0` are rejected +- Parent-child distance must exceed combined radii +- Spacecraft must be at least parent's radius away +- **Mass ratio validation**: For root children with radius > 50% of parent, mass ratio >= 1000 +- **SOI overlap validation**: Bodies sharing same parent must not have overlapping SOIs +- **Nested orbit validation**: Moons (small radius, circular orbits) must orbit within 5x parent SOI ### Renderer (renderer.cpp/h) Raylib 3D visualization system. See **[docs/rendering.md](rendering.md)** for complete documentation including: @@ -418,11 +461,19 @@ GUI-only application with interactive 3D visualization. - Loads bodies array from `[[bodies]]` - Loads spacecraft array from `[[spacecraft]]` - Loads maneuvers array from `[[maneuvers]]` -2. `initialize_bodies()` → combined initialization: +2. `initialize_orbital_objects()` → combined initialization: + - Converts orbital elements to local position/velocity for all bodies - Calculates circular orbit velocities for all bodies (using vis-viva equation) - Computes sphere of influence radius for each body (Hill sphere) - - Sets local coordinates (position/velocity) for all bodies + - Sets local coordinates (position/velocity) for all bodies and spacecraft - Initializes spacecraft global coordinates +3. `run_all_config_validations()` → validates loaded configuration: + - Checks parent_index ordering + - Validates orbital elements + - Checks mass ratios between parent and child bodies + - Detects overlapping SOIs between bodies sharing same parent + - Validates nested orbit boundaries (moons within parent's SOI) + - Ensures initial positions don't collide with parent body ### Main Simulation Loop 1. `update_simulation()` → for each body: