Browse Source
- Updated technical_reference.md to reflect analytical propagation - Added docs/config_format.md with complete TOML format reference - Added docs/coding_standards.md with coding conventions - Simplified technical reference (removed ASCII diagrams, verbose sections)main
5 changed files with 1393 additions and 471 deletions
@ -0,0 +1,343 @@ |
|||||||
|
# Coding Standards - Orbital Mechanics Simulation |
||||||
|
|
||||||
|
## Code Style |
||||||
|
|
||||||
|
- **C-style C++**: structs and functions only, NO classes or templates |
||||||
|
- **File extensions**: Use `.cpp` extensions for all source files (for future C++ features if needed) |
||||||
|
- **Include guards**: All headers use include guards (e.g., `#ifndef MODULE_NAME_H`) |
||||||
|
- **Function design**: Small, focused functions with single responsibilities |
||||||
|
|
||||||
|
```cpp |
||||||
|
// Header file with include guard |
||||||
|
#ifndef ORBITAL_MECHANICS_H |
||||||
|
#define ORBITAL_MECHANICS_H |
||||||
|
|
||||||
|
struct OrbitalElements { |
||||||
|
double semi_major_axis; |
||||||
|
double eccentricity; |
||||||
|
double true_anomaly; |
||||||
|
}; |
||||||
|
|
||||||
|
OrbitalElements propagate_orbital_elements(OrbitalElements elements, double dt, double parent_mass); |
||||||
|
|
||||||
|
#endif |
||||||
|
``` |
||||||
|
|
||||||
|
## Naming Conventions |
||||||
|
|
||||||
|
**Struct names**: PascalCase |
||||||
|
```cpp |
||||||
|
struct CelestialBody { }; |
||||||
|
struct OrbitalElements { }; |
||||||
|
struct Spacecraft { }; |
||||||
|
``` |
||||||
|
|
||||||
|
**Function names**: snake_case |
||||||
|
```cpp |
||||||
|
propagate_orbital_elements() |
||||||
|
find_dominant_body() |
||||||
|
update_bodies_physics() |
||||||
|
``` |
||||||
|
|
||||||
|
**Member variables**: snake_case |
||||||
|
```cpp |
||||||
|
global_position |
||||||
|
local_velocity |
||||||
|
parent_index |
||||||
|
``` |
||||||
|
|
||||||
|
**Constants**: UPPER_CASE |
||||||
|
```cpp |
||||||
|
PARABOLIC_TOLERANCE |
||||||
|
MIN_MASS_RATIO |
||||||
|
``` |
||||||
|
|
||||||
|
**Enum values**: UPPER_CASE with prefix |
||||||
|
```cpp |
||||||
|
enum BurnDirection { BURN_PROGRADE, BURN_RETROGRADE }; |
||||||
|
enum TriggerType { TRIGGER_TIME, TRIGGER_TRUE_ANOMALY }; |
||||||
|
``` |
||||||
|
|
||||||
|
## Comments |
||||||
|
|
||||||
|
- **Minimal comments**: Code should be self-documenting |
||||||
|
- **Non-obvious logic only**: Comment only what cannot be inferred from the code |
||||||
|
- **No decorative blocks**: No `===`, `---`, or ASCII art comment blocks |
||||||
|
|
||||||
|
```cpp |
||||||
|
// Good: minimal comments |
||||||
|
if (vec3_distance(pos, parent_pos) > soi_radius) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
// Bad: excessive decoration |
||||||
|
// ======================================== |
||||||
|
// SOI Check Function |
||||||
|
// ======================================== |
||||||
|
// This function checks if we're in SOI |
||||||
|
// ======================================== |
||||||
|
``` |
||||||
|
|
||||||
|
## Whitespace |
||||||
|
|
||||||
|
- **No trailing whitespace**: All files (including markdown) must not have trailing whitespace |
||||||
|
- **Pre-commit hook**: Automatically strips trailing whitespace |
||||||
|
- **Markdown line breaks**: Use `<br>` tag instead of two trailing spaces |
||||||
|
|
||||||
|
```markdown |
||||||
|
Good: |
||||||
|
Line 1<br> |
||||||
|
Line 2 |
||||||
|
|
||||||
|
Bad: |
||||||
|
Line 2 |
||||||
|
Line 4 |
||||||
|
``` |
||||||
|
|
||||||
|
## Memory Management |
||||||
|
|
||||||
|
- **Dynamic arrays**: Use `malloc` and `free` |
||||||
|
- **Struct-based design**: No RAII or smart pointers |
||||||
|
- **Manual cleanup**: Destroy functions handle cleanup |
||||||
|
|
||||||
|
```cpp |
||||||
|
// Allocation |
||||||
|
SimulationState* sim = malloc(sizeof(SimulationState)); |
||||||
|
sim->bodies = malloc(max_bodies * sizeof(CelestialBody)); |
||||||
|
|
||||||
|
// Cleanup |
||||||
|
void destroy_simulation(SimulationState* sim) { |
||||||
|
free(sim->bodies); |
||||||
|
free(sim->spacecraft); |
||||||
|
free(sim); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## Code Organization |
||||||
|
|
||||||
|
**Layer separation**: Physics, Simulation, Configuration, Rendering layers |
||||||
|
|
||||||
|
**Physics module independence**: Physics functions use parameter-based signatures, no dependencies on simulation structures |
||||||
|
|
||||||
|
```cpp |
||||||
|
// Good: parameter-based, independent |
||||||
|
Vec3 vec3_add(Vec3 a, Vec3 b); |
||||||
|
Mat3 mat3_rotation_orbital(double omega, double i, double omega_upper); |
||||||
|
|
||||||
|
// Avoid: depends on specific structures |
||||||
|
Vec3 compute_global_position(CelestialBody* body); // Simulation layer |
||||||
|
``` |
||||||
|
|
||||||
|
**Headers vs implementation**: |
||||||
|
- Headers (`.h`): Declarations only |
||||||
|
- Implementation (`.cpp`): Function definitions |
||||||
|
|
||||||
|
## Floating-Point Comparisons (Testing) |
||||||
|
|
||||||
|
- **Use `WithinAbs()`**: Required for floating-point comparisons |
||||||
|
- **Avoid `Approx()`**: Deprecated in Catch2 |
||||||
|
- **Required header**: `<catch2/matchers/catch_matchers_floating_point.hpp>` |
||||||
|
|
||||||
|
```cpp |
||||||
|
#include <catch2/matchers/catch_matchers_floating_point.hpp> |
||||||
|
|
||||||
|
TEST_CASE("orbital energy conservation") { |
||||||
|
double energy = calculate_total_energy(sim); |
||||||
|
REQUIRE_THAT(energy, WithinAbs(expected, 1e-6)); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## Git Workflow |
||||||
|
|
||||||
|
- **Small commits**: Logical separation of changes |
||||||
|
- **Concise messages**: One-line commit messages preferred |
||||||
|
- **Build before commit**: Run `make && make test` before committing |
||||||
|
|
||||||
|
```bash |
||||||
|
# Verify build and tests pass |
||||||
|
make && make test |
||||||
|
|
||||||
|
# Commit with descriptive message |
||||||
|
git add . |
||||||
|
git commit -m "add parabolic orbit propagation" |
||||||
|
``` |
||||||
|
|
||||||
|
## Build System |
||||||
|
|
||||||
|
**Makefile targets**: |
||||||
|
- `make` or `make all`: Build simulation |
||||||
|
- `make test`: Build and run automated tests |
||||||
|
- `make clean`: Remove build artifacts |
||||||
|
- `make rebuild`: Clean and rebuild |
||||||
|
|
||||||
|
**Default configuration**: |
||||||
|
- Time step: 60 seconds for solar system scale |
||||||
|
- Physics steps per frame: 100 (default) |
||||||
|
- Simulation time per frame: 60s × 100 = 6000 seconds at 1× speed |
||||||
|
|
||||||
|
```bash |
||||||
|
# Full build |
||||||
|
make |
||||||
|
|
||||||
|
# Run tests |
||||||
|
make test |
||||||
|
|
||||||
|
# Clean and rebuild |
||||||
|
make rebuild |
||||||
|
``` |
||||||
|
|
||||||
|
## Physics Considerations |
||||||
|
|
||||||
|
**Time step**: 60 seconds for solar system scale |
||||||
|
|
||||||
|
**Circular orbit velocity**: |
||||||
|
```cpp |
||||||
|
v = sqrt(G * M / r) |
||||||
|
``` |
||||||
|
|
||||||
|
**Sphere of Influence (SOI)**: Hill sphere approximation |
||||||
|
```cpp |
||||||
|
r_soi = a * (m / M)^(2/5) |
||||||
|
``` |
||||||
|
|
||||||
|
**SOI transitions**: 0.5× distance hysteresis to prevent oscillation |
||||||
|
|
||||||
|
**Parabolic orbits**: Escape velocity |
||||||
|
```cpp |
||||||
|
v² = 2GM / r |
||||||
|
``` |
||||||
|
|
||||||
|
**Hyperbolic orbits**: Positive total energy with asymptotic velocity at infinity |
||||||
|
|
||||||
|
**Analytical propagation**: Uses Kepler equation solvers (not RK4 integration) |
||||||
|
- Elliptical: E - e·sin(E) = M |
||||||
|
- Parabolic: D + D³/3 = M (Barker's equation) |
||||||
|
- Hyperbolic: H - e·sinh(H) = M |
||||||
|
|
||||||
|
## Module Dependencies |
||||||
|
|
||||||
|
``` |
||||||
|
Physics (foundation, no dependencies) |
||||||
|
↓ |
||||||
|
Orbital Mechanics (depends only on Physics) |
||||||
|
↓ |
||||||
|
Spacecraft, Maneuver (depend on Physics) |
||||||
|
↓ |
||||||
|
Simulation (depends on Physics, Orbital Mechanics, Spacecraft, Maneuver) |
||||||
|
↓ |
||||||
|
Config Loader (depends on Simulation) |
||||||
|
Config Validator (depends on Simulation and Orbital Mechanics) |
||||||
|
Renderer (depends on Simulation) |
||||||
|
UI Renderer (depends on Renderer and Simulation) |
||||||
|
``` |
||||||
|
|
||||||
|
**Key principles**: |
||||||
|
- Physics is completely independent |
||||||
|
- Lower layers never depend on upper layers |
||||||
|
- Each module has clear, minimal dependencies |
||||||
|
|
||||||
|
## Testing Guidelines |
||||||
|
|
||||||
|
- **Framework**: Catch2 |
||||||
|
- **Run tests**: `make test` |
||||||
|
- **Test configs**: Located in `tests/configs/` |
||||||
|
- **Descriptive names**: Use clear test case names |
||||||
|
|
||||||
|
```bash |
||||||
|
# Run all tests |
||||||
|
make test |
||||||
|
|
||||||
|
# Run specific test config |
||||||
|
./orbit_test '[config_name]' |
||||||
|
|
||||||
|
# Test with debug output (shows INFO messages) |
||||||
|
./orbit_test -s '[config_name]' |
||||||
|
``` |
||||||
|
|
||||||
|
**Test structure**: |
||||||
|
```cpp |
||||||
|
TEST_CASE("elliptical orbit energy conservation", "[energy]") { |
||||||
|
SimulationState* sim = create_simulation(10, 1, 0, 60.0); |
||||||
|
load_system_config(sim, "tests/configs/elliptical.toml"); |
||||||
|
|
||||||
|
double initial_energy = calculate_system_total_energy(sim); |
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++) { |
||||||
|
update_simulation(sim); |
||||||
|
} |
||||||
|
|
||||||
|
double final_energy = calculate_system_total_energy(sim); |
||||||
|
REQUIRE_THAT(final_energy, WithinAbs(initial_energy, 1e-6)); |
||||||
|
|
||||||
|
destroy_simulation(sim); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## Common Patterns |
||||||
|
|
||||||
|
**Struct initialization**: |
||||||
|
```cpp |
||||||
|
CelestialBody earth = {0}; |
||||||
|
strcpy(earth.name, "Earth"); |
||||||
|
earth.mass = 5.972e24; |
||||||
|
earth.radius = 6.371e6; |
||||||
|
``` |
||||||
|
|
||||||
|
**Error handling**: Return codes or NULL pointers |
||||||
|
```cpp |
||||||
|
int result = some_function(); |
||||||
|
if (result != 0) { |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
CelestialBody* body = find_body(sim, "Earth"); |
||||||
|
if (body == NULL) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**Const correctness**: Use `const` for read-only parameters |
||||||
|
```cpp |
||||||
|
Vec3 vec3_add(const Vec3 a, const Vec3 b) { |
||||||
|
Vec3 result = { a.x + b.x, a.y + b.y, a.z + b.z }; |
||||||
|
return result; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## File Organization |
||||||
|
|
||||||
|
**Directory structure**: |
||||||
|
``` |
||||||
|
src/ |
||||||
|
physics.h/cpp |
||||||
|
orbital_mechanics.h/cpp |
||||||
|
simulation.h/cpp |
||||||
|
spacecraft.h/cpp |
||||||
|
maneuver.h/cpp |
||||||
|
config_loader.h/cpp |
||||||
|
config_validator.h/cpp |
||||||
|
renderer.h/cpp |
||||||
|
ui_renderer.h/cpp |
||||||
|
test_utilities.h/cpp |
||||||
|
|
||||||
|
tests/ |
||||||
|
test_*.cpp |
||||||
|
configs/ |
||||||
|
|
||||||
|
configs/ |
||||||
|
*.toml |
||||||
|
|
||||||
|
docs/ |
||||||
|
*.md |
||||||
|
``` |
||||||
|
|
||||||
|
## Pre-commit Hooks |
||||||
|
|
||||||
|
The project uses a pre-commit hook that: |
||||||
|
- Strips trailing whitespace from all files |
||||||
|
- Prevents commits with trailing whitespace |
||||||
|
|
||||||
|
**If you see a "trailing whitespace" error**: |
||||||
|
1. The hook has automatically fixed the files |
||||||
|
2. Review the changes |
||||||
|
3. Stage them again and retry the commit |
||||||
@ -0,0 +1,490 @@ |
|||||||
|
# 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 |
||||||
@ -0,0 +1,87 @@ |
|||||||
|
# Session Summary - Documentation Rewrite |
||||||
|
|
||||||
|
**Date:** 2026-02-04 |
||||||
|
|
||||||
|
## Session Overview |
||||||
|
This session focused on rewriting the technical documentation to reflect the current state of the codebase after switching to analytical propagation. |
||||||
|
|
||||||
|
## Changes Made |
||||||
|
|
||||||
|
### 1. Explored codebase |
||||||
|
Used @explore sub-agent to identify all critical data structures and functions across the codebase. |
||||||
|
|
||||||
|
### 2. Created new technical reference |
||||||
|
Rewrote `docs/technical_reference.md` from scratch: |
||||||
|
- Updated all references from RK4 to analytical propagation |
||||||
|
- Added comprehensive data structure documentation with file locations |
||||||
|
- Added detailed function signatures for critical functions |
||||||
|
- Added module dependency graph (later removed) |
||||||
|
- Added analytical propagation algorithm details for all orbit types |
||||||
|
- Added velocity deviation detection (1e-6 tolerance) |
||||||
|
- Added orbital element reconstruction after burns and SOI transitions |
||||||
|
- Kept coordinate frame strategy, orbit types, and data flow sections |
||||||
|
- Initially had line numbers, ASCII diagrams (later removed) |
||||||
|
- Initial version: 730 lines |
||||||
|
|
||||||
|
### 3. Created config format documentation |
||||||
|
New file `docs/config_format.md`: |
||||||
|
- Complete TOML format documentation for bodies, spacecraft, maneuvers |
||||||
|
- All field descriptions, types, units |
||||||
|
- Parsing details and default values |
||||||
|
- All 7 validation rules with constants |
||||||
|
- Complete working example config |
||||||
|
- 490 lines |
||||||
|
|
||||||
|
### 4. Created coding standards documentation |
||||||
|
New file `docs/coding_standards.md`: |
||||||
|
- Code style (C-style C++, no classes/templates) |
||||||
|
- Naming conventions |
||||||
|
- Comment guidelines |
||||||
|
- Whitespace rules (no trailing whitespace) |
||||||
|
- Memory management (malloc/free) |
||||||
|
- Code organization and layer separation |
||||||
|
- Floating-point comparisons for tests |
||||||
|
- Git workflow |
||||||
|
- Build system details |
||||||
|
- Physics considerations |
||||||
|
- Module dependencies |
||||||
|
- Testing guidelines |
||||||
|
|
||||||
|
### 5. Simplified technical reference |
||||||
|
- Moved verbose config section to config_format.md (replaced with brief summary) |
||||||
|
- Moved config validator section to config_format.md (replaced with brief summary) |
||||||
|
- Removed most line numbers (kept only 5 critical algorithm locations) |
||||||
|
- Reduced from 655 lines to 557 lines |
||||||
|
|
||||||
|
### 6. Removed ASCII diagrams |
||||||
|
- Removed module dependency graph (replaced with text) |
||||||
|
- Removed data flow diagrams (replaced with text) |
||||||
|
- Removed SOI mechanics flow chart (replaced with text) |
||||||
|
- Reduced from 557 lines to 557 lines (text descriptions were concise) |
||||||
|
|
||||||
|
### 7. Cleaned up |
||||||
|
- Removed `docs/technical_reference.md.backup` |
||||||
|
|
||||||
|
## Commits |
||||||
|
No commits were made during this session (all documentation changes). |
||||||
|
|
||||||
|
## Results |
||||||
|
- Created 2 new documentation files (config_format.md, coding_standards.md) |
||||||
|
- Completely rewrote technical reference (730 lines → 557 lines) |
||||||
|
- Documentation is now LLM-friendly (text-only, no ASCII diagrams) |
||||||
|
- All content from original reference preserved, reorganized, and updated |
||||||
|
|
||||||
|
## Files Modified |
||||||
|
- `docs/technical_reference.md` - Completely rewritten |
||||||
|
- `docs/config_format.md` - Created (490 lines) |
||||||
|
- `docs/coding_standards.md` - Created |
||||||
|
- `docs/technical_reference.md.backup` - Removed |
||||||
|
|
||||||
|
## Next Steps |
||||||
|
None - documentation rewrite is complete. |
||||||
|
|
||||||
|
## Notes |
||||||
|
- Technical reference is now optimized for LLM agents to understand the codebase |
||||||
|
- Line numbers kept only for 5 critical algorithms (unlikely to change) |
||||||
|
- Detailed config format is in separate doc for easy reference |
||||||
|
- Coding standards are documented for consistency |
||||||
Loading…
Reference in new issue