@ -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_anomal y;
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: