# Config Format Reference ## Overview Simulation configuration files use TOML format and are loaded via `load_system_config()` in config_loader.h. The config defines three main sections: - `[[bodies]]` - Celestial bodies (stars, planets, moons) - `[[spacecraft]]` - Spacecraft orbiting bodies - `[[maneuvers]]` - Impulsive burns for spacecraft ## Bodies Configuration Each body entry defines a celestial object with physical properties and orbital elements. ### Required Fields | Field | Type | Units | Description | |-------|------|-------|-------------| | `name` | string | - | Unique identifier for the body | | `mass` | float | kg | Mass of the body | | `radius` | float | m | Physical radius of the body | | `parent_index` | integer | - | Index of parent body (-1 for root/star) | | `color` | table | RGB | RGB color for rendering | ### Orbit Table (nested) | Field | Type | Units | Default | Description | |-------|------|-------|---------|-------------| | `semi_major_axis` | float | m | 0.0 | Semi-major axis (elliptical/hyperbolic orbits only) | | `semi_latus_rectum` | float | m | - | Semi-latus rectum (parabolic orbits only) | | `eccentricity` | float | - | 0.0 | Orbital eccentricity (0-1 for elliptical, ~1 for parabolic, >1 for hyperbolic) | | `true_anomaly` | float | rad | 0.0 | Initial true anomaly (position along orbit) | | `inclination` | float | rad | 0.0 | Orbital plane inclination | | `longitude_of_ascending_node` | float | rad | 0.0 | Longitude of ascending node | | `argument_of_periapsis` | float | rad | 0.0 | Argument of periapsis | ### Bodies Example ```toml # Root body (star) [[bodies]] name = "Sun" mass = 1.989e30 radius = 6.96e8 parent_index = -1 color = { r = 1.0, g = 1.0, b = 0.0 } orbit = { semi_major_axis = 0.0, eccentricity = 0.0, true_anomaly = 0.0 } # Planet orbiting the star [[bodies]] name = "Earth" mass = 5.972e24 radius = 6.371e6 parent_index = 0 color = { r = 0.0, g = 0.5, b = 1.0 } orbit = { semi_major_axis = 1.496e11, eccentricity = 0.0167, inclination = 0.0, longitude_of_ascending_node = 0.0, argument_of_periapsis = 0.0, true_anomaly = 0.0 } # Moon orbiting the planet [[bodies]] name = "Moon" mass = 7.342e22 radius = 1.737e6 parent_index = 1 color = { r = 0.7, g = 0.7, b = 0.7 } orbit = { semi_major_axis = 3.844e8, eccentricity = 0.0549, inclination = 0.089, true_anomaly = 0.0 } ``` ### Special Cases **Root Bodies:** Set `parent_index = -1`. Root bodies represent stars and have no parent. Their orbital elements should all be zero. **Parabolic Orbits:** When eccentricity ≈ 1.0 (within `PARABOLIC_TOLERANCE = 1e-3`), use `semi_latus_rectum` instead of `semi_major_axis`: ```toml [[bodies]] name = "Comet" mass = 1.0e14 radius = 5.0e3 parent_index = 0 color = { r = 0.7, g = 0.8, b = 0.9 } orbit = { semi_latus_rectum = 2.992e11, eccentricity = 1.0, true_anomaly = 0.0 } ``` **Hyperbolic Orbits:** Use negative `semi_major_axis` for hyperbolic trajectories: ```toml [[bodies]] name = "InterstellarComet" mass = 1.0e14 radius = 5.0e3 parent_index = 0 color = { r = 0.5, g = 1.0, b = 0.5 } orbit = { semi_major_axis = -1.496e11, eccentricity = 1.5, true_anomaly = 0.0 } ``` **3D Orbital Orientation:** Use inclination, longitude_of_ascending_node, and argument_of_periapsis for inclined orbits (Molniya example): ```toml [[spacecraft]] name = "Molniya_Satellite" mass = 1000.0 parent_index = 0 orbit = { semi_major_axis = 26540000.0, eccentricity = 0.74, true_anomaly = 0.0, inclination = 1.107, longitude_of_ascending_node = 0.0, argument_of_periapsis = 4.71 } ``` ## Spacecraft Configuration Spacecraft are similar to bodies but lack physical radius and sphere of influence. They must orbit an existing body. ### Required Fields | Field | Type | Units | Description | |-------|------|-------|-------------| | `name` | string | - | Unique identifier for the spacecraft | | `mass` | float | kg | Mass of the spacecraft | | `parent_index` | integer | - | Index of parent body (must reference a valid body) | ### Orbit Table (nested) Same as bodies - see orbital elements table above. ### Spacecraft Example ```toml [[spacecraft]] name = "LEO_Satellite" mass = 1000.0 parent_index = 1 orbit = { semi_major_axis = 6.771e6, eccentricity = 0.0, true_anomaly = 0.0 } ``` ### Differences from Bodies - No `radius` field - No `color` field - No sphere of influence (SOI) - `parent_index` must be a valid body index (cannot be -1) - Cannot be a parent to other bodies or spacecraft ## Maneuvers Configuration Maneuvers define impulsive burns that modify spacecraft velocity. Each maneuver specifies when and how to execute a burn. ### Required Fields | Field | Type | Units | Description | |-------|------|-------|-------------| | `name` | string | - | Unique identifier for the maneuver | | `spacecraft_name` | string | - | Name of the spacecraft to apply burn to | | `direction` | string | - | Burn direction (see valid values below) | | `delta_v` | float | m/s | Velocity change magnitude | | `trigger_type` | string | - | Trigger condition type | | `trigger_value` | float | varies | Trigger condition value | ### Valid Direction Values | Direction | Description | |-----------|-------------| | `"prograde"` | Along velocity vector (increases orbital energy) | | `"retrograde"` | Opposite velocity vector (decreases orbital energy) | | `"normal"` | Along angular momentum vector (orbit normal) | | `"antinormal"` | Opposite angular momentum vector | | `"radial_in"` | Toward parent body | | `"radial_out"` | Away from parent body | ### Valid Trigger Types | Trigger Type | trigger_value | Description | |--------------|----------------|-------------| | `"time"` | seconds | Execute when simulation time >= trigger_value | | `"true_anomaly"` | radians | Execute when spacecraft true anomaly within 0.01 rad of trigger_value | ### Maneuvers Example ```toml # Time-based burn at 1 hour [[maneuvers]] name = "orbit_raise_1" spacecraft_name = "LEO_Satellite" trigger_type = "time" trigger_value = 3600.0 direction = "prograde" delta_v = 500.0 # True anomaly-based burn at periapsis (ν = 0) [[maneuvers]] name = "periapsis_burn" spacecraft_name = "LEO_Satellite" trigger_type = "true_anomaly" trigger_value = 0.0 direction = "prograde" delta_v = 1000.0 # Retrograde burn at apogee for orbit circularization [[maneuvers]] name = "circularize" spacecraft_name = "LEO_Satellite" trigger_type = "true_anomaly" trigger_value = 3.14159 direction = "retrograde" delta_v = 500.0 ``` ## Parsing Details ### Parabolic vs Non-Parabolic Orbits The parser uses eccentricity to determine which orbit parameter is required: - **Parabolic (|e - 1.0| < 1e-3):** Requires `semi_latus_rectum`, `semi_major_axis` is ignored - **Non-parabolic (e ≠ 1.0):** Requires `semi_major_axis`, `semi_latus_rectum` is ignored ### Default Values Orbital elements default to 0.0 if not specified: - `true_anomaly = 0.0` - `inclination = 0.0` - `longitude_of_ascending_node = 0.0` - `argument_of_periapsis = 0.0` ### Parent Index Behavior The `parent_index` field defines orbital hierarchy: - `-1`: Root body (no parent, typically a star) - `0` to N: Index of parent body in the bodies array - Bodies must be ordered such that parents appear before children - Spacecraft `parent_index` must reference a valid body index ### Numeric Type Handling All numeric fields accept either integers or floating-point values: - `mass`, `radius`, `semi_major_axis`, etc.: Accept int or float - `parent_index`: Accepts int (preferred) or float (converted to int) - Color components: Accept int or float (0-1 range typical) ## Validation Rules The config validator (config_validator.cpp) runs automatically after loading. All validations must pass for the simulation to start. ### Validation Constants | Constant | Value | Description | |----------|-------|-------------| | `MIN_MASS_RATIO` | 1000.0 | Minimum parent/child mass ratio for large bodies | | `PARABOLIC_TOLERANCE` | 1e-3 | Tolerance for detecting parabolic orbits | | `NESTED_ORBIT_FRACTION` | 5.0 | Max orbit radius as fraction of parent SOI | ### Parent Index Ordering **Rule:** Body `parent_index` must be < body index or -1. **Purpose:** Ensures parents are defined before children in the config file. **Example Error:** ``` Body 'Moon' (index 3) has invalid parent_index 3 - must be < 3 or -1 ``` **Spacecraft Validation:** Spacecraft `parent_index` must be a valid body index (0 to body_count-1). ### Orbital Elements **Elliptical Orbits (e < 1):** - `semi_major_axis` must be > 0 **Parabolic Orbits (|e - 1.0| < 1e-3):** - `semi_latus_rectum` must be > 0 - `semi_major_axis` is not used **Hyperbolic Orbits (e > 1):** - `semi_major_axis` must be < 0 (negative for hyperbolic) - `semi_major_axis` must not be 0 **General:** - `eccentricity` must be >= 0 - `semi_major_axis` or `semi_latus_rectum` must not be 0 ### True Anomaly Ranges (Hyperbolic Orbits) **Rule:** For hyperbolic orbits (e > 1), true anomaly must be within valid asymptotic bounds. **Valid Range:** [0, arccos(-1/e)] ∪ [2π - arccos(-1/e), 2π] **Purpose:** Prevents specifying positions in the forbidden region of hyperbolic orbits. **Example Error:** ``` Spacecraft 'Test' has invalid true_anomaly for hyperbolic orbit Eccentricity: 1.5000 True anomaly: 2.0000 rad Valid range: [0, 2.3005] ∪ [3.9827, 2π] ``` ### Initial Positions **Rule:** Distance between body and parent must exceed combined radii. **Purpose:** Prevents objects from starting inside their parent. **Example Error:** ``` Body 'Satellite' (index 2) too close to parent 'Earth' (index 1) Distance: 6.37e6 m Minimum required: 6.47e6 m (parent radius + body radius) ``` **Spacecraft:** Distance must be >= parent radius (spacecraft has no radius). ### Mass Ratios **Rule:** For root children with radius > 50% of parent, mass ratio >= 1000. **Purpose:** Ensures hierarchical system stability for large bodies. **Example Error:** ``` Body 'LargeMoon' (mass=1.00e25 kg, radius=4.00e6 m) has insufficient mass ratio with root parent 'Earth' (mass=5.97e24 kg, radius=6.37e6 m) Mass ratio: 0.60 (minimum required: 1000.00) Radius ratio: 0.63 (triggers validation for radius > 50% of parent) ``` ### SOI Overlap **Rule:** Bodies sharing the same parent must not have overlapping spheres of influence. **Purpose:** Prevents ambiguous SOI boundaries that could cause numerical instability. **Example Error:** ``` Bodies 'MoonA' and 'MoonB' have overlapping SOIs while sharing same parent 'Planet' Separation: 1.00e8 m Combined SOI: 1.50e8 m (7.00e7 + 8.00e7) SOI overlap: 5.00e7 m ``` ### Nested Orbits **Rule:** Moon-like bodies must orbit within 5x of parent's SOI. **Applies to:** - Bodies with radius < 30% of parent radius - Bodies with eccentricity < 0.5 - Bodies with mass < 1e20 kg **Purpose:** Ensures moon orbits are stable within parent's sphere of influence. **Example Error:** ``` Body 'DistantMoon' orbit extends too far from parent 'Planet' Child orbit radius: 2.00e9 m Parent SOI radius: 1.00e9 m Maximum allowed: 5.00e9 m (500.0% of parent SOI) ``` ## Complete Example Config ```toml # Complete Solar System Example with Spacecraft and Maneuvers [[bodies]] name = "Sun" mass = 1.989e30 radius = 6.96e8 parent_index = -1 color = { r = 1.0, g = 1.0, b = 0.0 } orbit = { semi_major_axis = 0.0, eccentricity = 0.0, true_anomaly = 0.0 } [[bodies]] name = "Earth" mass = 5.972e24 radius = 6.371e6 parent_index = 0 color = { r = 0.0, g = 0.5, b = 1.0 } orbit = { semi_major_axis = 1.496e11, eccentricity = 0.0167, inclination = 0.0, longitude_of_ascending_node = 0.0, argument_of_periapsis = 0.0, true_anomaly = 0.0 } [[bodies]] name = "Moon" mass = 7.342e22 radius = 1.737e6 parent_index = 1 color = { r = 0.7, g = 0.7, b = 0.7 } orbit = { semi_major_axis = 3.844e8, eccentricity = 0.0549, inclination = 0.089, true_anomaly = 0.0 } [[spacecraft]] name = "LEO_Satellite" mass = 1000.0 parent_index = 1 orbit = { semi_major_axis = 6.771e6, eccentricity = 0.0, true_anomaly = 0.0 } [[spacecraft]] name = "Molniya_Satellite" mass = 1000.0 parent_index = 1 orbit = { semi_major_axis = 26540000.0, eccentricity = 0.74, true_anomaly = 0.0, inclination = 1.107, longitude_of_ascending_node = 0.0, argument_of_periapsis = 4.71 } [[maneuvers]] name = "orbit_raise" spacecraft_name = "LEO_Satellite" trigger_type = "time" trigger_value = 3600.0 direction = "prograde" delta_v = 500.0 [[maneuvers]] name = "periapsis_burn" spacecraft_name = "Molniya_Satellite" trigger_type = "true_anomaly" trigger_value = 0.0 direction = "prograde" delta_v = 1000.0 ``` ## Orbit Type Quick Reference | Eccentricity | Orbit Type | Parameter | Example | |--------------|------------|-----------|---------| | e = 0 | Circular | semi_major_axis | Planets, moons | | 0 < e < 1 | Elliptical | semi_major_axis (positive) | Typical satellites | | e ≈ 1 | Parabolic | semi_latus_rectum | Escape trajectories | | e > 1 | Hyperbolic | semi_major_axis (negative) | Interstellar objects | ## Tips 1. **Units:** Always use SI units (kg, meters, seconds, radians) 2. **Angles:** Use radians for all angular values (inclination, true_anomaly, etc.) 3. **Ordering:** List bodies from star -> planets -> moons in order 4. **Testing:** Start with circular orbits (e=0) before adding complexity 5. **Validation:** Read error messages carefully - they indicate specific violations 6. **Precision:** Use scientific notation for large/small values (e.g., 1.496e11) 7. **Colors:** Use RGB values in [0, 1] range for realistic rendering 8. **Hyperbolic:** Remember true_anomaly limits for hyperbolic orbits