From 9fd6b2565853a2c1640fb661dea47ed0d7fe65da Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Sun, 25 Jan 2026 13:39:15 -0500 Subject: [PATCH] add parabolic orbit enhancements to future work and clarify altitude parameter docs --- docs/future_work.md | 4 + docs/parabolic_union_implementation.md | 152 ------------------------- docs/technical_reference.md | 2 +- 3 files changed, 5 insertions(+), 153 deletions(-) delete mode 100644 docs/parabolic_union_implementation.md diff --git a/docs/future_work.md b/docs/future_work.md index 79f379d..c381a74 100644 --- a/docs/future_work.md +++ b/docs/future_work.md @@ -188,6 +188,10 @@ This document outlines planned enhancements and future development areas for the - Asteroid flyby simulations - Gravity assist maneuvers +### Parabolic Orbit Enhancements +- Altitude parameter support for parabolic orbits: parse `altitude` and convert to `semi_latus_rectum = parent_radius + altitude` +- Explicit perihelion parameter: add `perihelion` to config file, derive `semi_latus_rectum = 2 * perihelion` for parabolic orbits + ## Performance Optimizations ### Adaptive Timestepping diff --git a/docs/parabolic_union_implementation.md b/docs/parabolic_union_implementation.md deleted file mode 100644 index 8d94027..0000000 --- a/docs/parabolic_union_implementation.md +++ /dev/null @@ -1,152 +0,0 @@ -# Parabolic Orbit Union Implementation Plan - -## Overview -Add support for parabolic orbits (e≈1.0) using semi-latus rectum parameter `p` instead of the current hacky `semi_major_axis = 1.0e30` infinity approximation. - -## Problem -Current implementation uses `semi_major_axis = 1.0e30` to approximate infinity for parabolic orbits, causing: -1. Numerical precision issues with extremely large distances (~6.68e18 AU) -2. Velocities approaching zero (1.6e-08 km/s instead of ~42 km/s escape velocity) -3. Test failures due to floating-point equality (final_distance ≈ initial_distance) - -## Solution -Use a union in `OrbitalElements` struct to support both `semi_major_axis` (for elliptical/hyperbolic) and `semi_latus_rectum` (for parabolic). - -## Mathematical Background -For parabolic orbits (e=1.0), the semi-major axis is theoretically infinity. Using semi-latus rectum `p` is mathematically correct: - -Position: `r = p / (1 + cos(ν))` -Velocity: `v = √(2μ / r)` - -Where: -- `p` = semi-latus rectum -- `ν` = true anomaly -- `μ` = GM (gravitational parameter) - -For parabolic orbits: `p = 2q` where `q` is perihelion distance - -## Implementation Steps - -### Phase 1: Update OrbitalElements Struct -**File: `src/orbital_mechanics.h`** - -```cpp -struct OrbitalElements { - union { - double semi_major_axis; // for elliptical (e<1) and hyperbolic (e>1) - double semi_latus_rectum; // for parabolic (e≈1) - }; - double eccentricity; - double true_anomaly; - double inclination; - double longitude_of_ascending_node; - double argument_of_periapsis; -}; -``` - -### Phase 2: Update Config Loader -**File: `src/config_loader.cpp`** - -Add to `parse_toml_body()` and `parse_toml_spacecraft()`: - -1. Parse both `semi_major_axis` and `semi_latus_rectum` from orbit table -2. Initialize union field based on which is specified -3. Validate exactly one is present per eccentricity range - -**Validation Logic:** -```cpp -bool has_semi_major = (semi_major.type == TOML_FP64); -bool has_semi_latus = (semi_latus.type == TOML_FP64); - -if (fabs(elements.eccentricity - 1.0) < 0.005) { - // Parabolic orbit - requires semi_latus_rectum - if (!has_semi_latus) { - printf("Error: Parabolic orbit requires 'semi_latus_rectum'\n"); - return false; - } - if (has_semi_major) { - printf("Error: Parabolic orbit cannot have 'semi_major_axis'\n"); - return false; - } - elements.semi_latus_rectum = semi_latus.u.fp64; -} else { - // Elliptical or hyperbolic - requires semi_major_axis - if (!has_semi_major) { - printf("Error: Elliptical/hyperbolic orbit requires 'semi_major_axis'\n"); - return false; - } - if (has_semi_latus) { - printf("Error: Elliptical/hyperbolic orbit cannot have 'semi_latus_rectum'\n"); - return false; - } - elements.semi_major_axis = semi_major.u.fp64; -} -``` - -### Phase 3: Update orbital_mechanics.cpp -**File: `src/orbital_mechanics.cpp`** - -Update parabolic case (line 21-23): - -```cpp -} else if (fabs(e - 1.0) < 0.005) { - double p = elements.semi_latus_rectum; - r = p / (1.0 + cos(nu)); - v_mag = sqrt(2.0 * mu / r); -} -``` - -Remove the `2.0 * a` approximation that requires `a=1.0e30`. - -### Phase 4: Update Test Configs -**File: `tests/configs/parabolic_comet.toml`** - -Replace `semi_major_axis = 1.0e30` with `semi_latus_rectum = 1.496e11` (p = 1 AU): - -```toml -[[bodies]] -name = "ParabolicComet" -mass = 1.0e14 -radius = 5.0e3 -parent_index = 0 -color = { r = 0.7, g = 0.8, b = 0.9 } -orbit = { - semi_latus_rectum = 1.496e11, - eccentricity = 1.0, - true_anomaly = 0.0 -} -``` - -### Phase 5: Update Documentation -**File: `docs/technical_reference.md`** - -1. Update `OrbitalElements` struct documentation to show union -2. Add note about `semi_latus_rectum` being required for parabolic orbits (e≈1.0) -3. Document `semi_latus_rectum` in config format section - -**File: `docs/unified_orbital_elements_plan.md`** - -Mark union implementation as complete in Phase 7 status. - -## Validation Steps - -1. Build: `make clean && make` -2. Run parabolic test: `./orbit_test '[parabolic]'` -3. Verify velocity is correct: should be ~42,127 m/s escape velocity at 1 AU -4. Verify energy is ~0 (parabolic orbits have total energy = 0) - -## Decisions Made - -### Default Behavior -No backward compatibility for `semi_major_axis` on parabolic orbits - require explicit `semi_latus_rectum` for all parabolic configs. This is cleaner than trying to auto-convert `p = 2*a`. - -### Spacecraft Altitude Parameter -Spacecraft `altitude` parameter is not supported for parabolic orbits in this implementation. If user specifies `altitude` with `eccentricity ≈ 1.0`, the config loader will require `semi_latus_rectum` instead and reject `altitude` or `semi_major_axis`. Added to future todos for Phase 8+. - -### Parabolic Detection Tolerance -Using `|e - 1.0| < 0.005` as threshold for detecting parabolic orbits. This matches tolerance used elsewhere in the codebase. - -## Future Enhancements (TODO) - -- Spacecraft `altitude` parameter for parabolic orbits: parse `altitude` and convert to `semi_latus_rectum = parent_radius + altitude` when eccentricity is parabolic -- Consider adding explicit `perihelion` parameter to config file, then derive `semi_latus_rectum = 2 * perihelion` for parabolic orbits diff --git a/docs/technical_reference.md b/docs/technical_reference.md index ec32da4..d8c8aab 100644 --- a/docs/technical_reference.md +++ b/docs/technical_reference.md @@ -298,7 +298,7 @@ orbit = { } ``` - Uses `orbit` table for orbital elements (same as bodies) -- Altitude can be used instead of `semi_major_axis` (convenience feature, added to parent radius) +- Altitude can be used instead of `semi_major_axis` for non-parabolic orbits (convenience feature, added to parent radius) **Config format (TOML) - Maneuvers:** ```toml