vibe coding an orbital mechanics simulation to try out claude code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

15 KiB

Implementation Plan: Config-Based Spacecraft with Impulse Burn

Overview

Replace dynamic spacecraft spawning with config-based LEO spacecraft, implement patched conics impulse burn for Hohmann transfer, and add comprehensive test verification.

Date: January 18, 2026 Status: partially implemented Branch: mission-planning


Phase 1: Update Configuration File

Step 1.1: Add spacecraft to tests/configs/earth_mars_simple.toml

Add Spacecraft body to config with placeholder position/velocity (set at runtime by initialize_spacecraft_leo()).

Implementation: See tests/configs/earth_mars_simple.toml for full config

Key parameters:

  • mass = 1.0 kg (test particle)
  • radius = 1000.0 m
  • parent_index = 1 (Earth)
  • color = magenta (r=1.0, g=0.0, b=0.5)
  • position/velocity: Placeholders (0,0,0)

TODO: Future config format should support:

  • Earth-relative position: { altitude_km = 200.0 }
  • Earth-relative orbit: { orbit_type = "circular" }
  • More intuitive spacecraft mission parameters

Phase 2: Mission Planning Module - New Functions

Step 2.1: Add function declarations to src/mission_planning.h

Implementation: See src/mission_planning.h

Functions:

  • initialize_spacecraft_leo() - Initialize spacecraft in circular LEO around parent body
  • apply_transfer_burn() - Apply patched conics impulse burn for Hohmann transfer
  • calculate_phase_angle() - Calculate current phase angle between two bodies (in degrees)

Step 2.2: Implement initialize_spacecraft_leo() in src/mission_planning.cpp

Implementation: src/mission_planning.cpp:20-56

Algorithm:

  • Calculate orbital radius = parent radius + altitude
  • Position spacecraft radially outward from Sun (any angular position acceptable)
  • Calculate circular LEO velocity: v = sqrt(G * M_parent / r)
  • Set prograde orientation (tangential to Earth-Sun line)
  • Set both local and global coordinates correctly

Key Points:

  • LEO orbit is circular at 200km altitude (~7,788 m/s)
  • Spacecraft velocity = Earth velocity + LEO velocity
  • Local velocity = LEO velocity only (relative to Earth)

Step 2.3: Implement calculate_phase_angle() in src/mission_planning.cpp

Implementation: src/mission_planning.cpp:58-78

Algorithm:

  • Calculate angular positions of departure and arrival bodies relative to Sun
  • Compute phase difference: θ_arrival - θ_departure
  • Normalize to [0°, 360°) range
  • Return phase angle in degrees

Step 2.4: Implement apply_transfer_burn() in src/mission_planning.cpp

Implementation: src/mission_planning.cpp:80-116

Algorithm (Patched Conics Approach):

  • Calculate required heliocentric transfer velocity magnitude from params
  • Determine prograde direction (tangential to departure-Sun line)
  • Compute delta-v: Δv = v_transfer - v_current (vector subtraction)
  • Apply impulse to spacecraft velocity
  • Update local velocity relative to departure body
  • Print burn information for debugging

Note: Simplified single-impulse approximation. True patched conics would:

  1. Calculate Δv to reach SOI boundary
  2. Calculate velocity at SOI boundary
  3. Add transfer Δv at SOI boundary
  4. Combine into equivalent single impulse

Phase 3: Comprehensive Test Case

Step 3.1: Create new test in tests/test_hohmann_transfer.cpp

Implementation: tests/test_hohmann_transfer.cpp - See file for full test

Test: "Earth → Mars Hohmann Transfer with LEO Spacecraft"

Test Structure:

  1. Load config with 4 bodies (Sun, Earth, Mars, Spacecraft)
  2. Initialize spacecraft in 200km LEO around Earth
  3. Verify LEO orbit stability (parent, position, velocity, energy)
  4. Calculate Hohmann transfer parameters
  5. Wait for Earth-Mars launch window (within 1° tolerance)
  6. Verify phase angle accuracy
  7. Apply impulse burn for transfer
  8. Verify post-burn energy >= 0 (escape trajectory)
  9. Simulate transfer for 110% of expected duration
  10. Track SOI transitions (Earth→Sun→Mars)
  11. Verify final parent and energy conservation (<5% drift)
  12. If Mars SOI entry, verify distance (<2×SOI)

Key Assertions:

  • Config loading: 4 bodies loaded, spacecraft present
  • LEO stability: parent=Earth, position <1km error, velocity <10m/s error, energy <0
  • Launch window: opens in ~94 days, phase error <1°
  • Transfer: post-burn energy >= 0, Earth→Sun SOI transition, energy conservation

Current Issue Identified

Problem: Incorrect Delta-V Direction After Multi-Day Wait

FIXME: while running this simulation config graphically, I noticed that a larger problem is in simulation::find_dominant_body(). Earth's parent gets set to the satellite's index, which should never happen. I think the actual fix should be to have non-massive satellites in a different array than celestial bodies, and treat them differently. However, we should add more testing for the case that a comet or other massive celestial body gets close to another body. We do have tests/test_soi_transition.cpp, and tests/configs/soi_transition.toml so maybe it's an initialization problem because the new test config starts with both bodies in each others SOI?

Symptom:

  • Spacecraft enters LEO orbit correctly with negative energy (bound to Earth)
  • Waits 94 days for Earth-Mars launch window
  • During wait period, spacecraft completes ~6.3 LEO orbits
  • LEO orbit phase changes significantly over 94 days
  • After wait, apply_transfer_burn() applies delta-v assuming spacecraft is at Earth's current orbital phase
  • Result: Delta-v applied in wrong direction, resulting in retrograde burn
  • Post-burn energy remains negative (spacecraft still bound to Earth)

Root Cause Analysis:

The apply_transfer_burn() function calculates:

  1. Required heliocentric transfer velocity magnitude: v_transfer = 32,697 m/s
  2. Prograde direction based on Earth's current position: transfer_dir = prograde(t_current)
  3. Target velocity: v_target = v_transfer * transfer_dir

However, after 94 days:

  • Earth has moved to different orbital phase
  • Spacecraft in LEO is still orbiting Earth
  • Spacecraft's current heliocentric velocity includes Earth's motion + LEO motion
  • The calculated transfer direction is based on Earth's instantaneous position, not spacecraft's actual heliocentric velocity vector
  • This results in delta-v that doesn't account for spacecraft's phase in LEO

What Should Happen:

  1. Calculate spacecraft's current heliocentric velocity vector: v_current
  2. Calculate required heliocentric velocity for transfer orbit: v_transfer
  3. Apply delta-v: Δv = v_transfer - v_current (vector subtraction, not magnitude-based)

What Currently Happens:

  1. Assumes spacecraft starts at Earth's orbital position (ignores LEO phase)
  2. Calculates transfer direction based on Earth's current prograde vector
  3. Applies magnitude-based delta-v without considering spacecraft's actual velocity direction
  4. Results in incorrect burn direction

Solution Required

Modify apply_transfer_burn() to:

  1. Calculate spacecraft's actual heliocentric velocity:
Vec3 v_current_helio = spacecraft->velocity;  // Already in global frame
  1. Calculate required heliocentric transfer velocity:
double v_transfer_mag = params->departure_velocity;  // ~32,697 m/s

// Direction: prograde to Sun (same as Earth's orbital direction)
Vec3 sun_to_earth = vec3_sub(departure->position, sun->position);
Vec3 sun_to_earth_norm = vec3_normalize(sun_to_earth);
Vec3 transfer_dir = (Vec3){-sun_to_earth_norm.y, sun_to_earth_norm.x, 0.0};
Vec3 v_transfer_helio = vec3_scale(transfer_dir, v_transfer_mag);
  1. Calculate delta-v as vector difference:
Vec3 delta_v = vec3_sub(v_transfer_helio, v_current_helio);
  1. Apply impulse:
spacecraft->velocity = vec3_add(spacecraft->velocity, delta_v);
spacecraft->local_velocity = vec3_sub(spacecraft->velocity, departure->velocity);

This approach:

  • Accounts for spacecraft's actual heliocentric velocity (includes LEO phase)
  • Uses vector subtraction instead of magnitude-based calculation
  • Produces correct delta-v direction regardless of LEO phase
  • Should result in positive post-burn energy (escape trajectory)

Potential Issues and Mitigation

Issue 1: LEO Orbit Position Sensitivity

Spacecraft LEO phase may affect optimal launch window timing.

Mitigation: Test shows we wait for Earth-Mars phase angle, not spacecraft-LEO phase. This should be acceptable.

Issue 2: Impulse Burn Accuracy

Single-impulse approximation may not match true patched conics trajectory.

Mitigation: Initial test focuses on Earth→Sun transition and energy conservation. If needed, can refine to two-impulse burn in future.

Issue 3: Mars SOI Entry

Spacecraft may not enter Mars SOI due to:

  • Phase angle tolerance (1°)
  • Transfer time approximation
  • Impulse burn simplifications

Mitigation: Test includes explicit INFO messages and requires only Earth→Sun transition, not Mars arrival.


Timeline Estimate

  • Phase 0 (Git workflow): 10 minutes
  • Phase 1 (Config update): 5 minutes
  • Phase 2 (Mission planning): 1-2 hours
  • Phase 3 (Comprehensive test): 30 minutes
  • Phase 4 (Build and test): 20 minutes
  • Phase 5 (Cleanup): 20 minutes

Total: 2-3 hours


Test Configuration Reference

earth_mars_simple.toml

Implementation: tests/configs/earth_mars_simple.toml

Bodies:

  • Sun (index 0): Root body, 1.989e30 kg
  • Earth (index 1): 5.972e24 kg, 1.496e11 m from Sun
  • Mars (index 2): 6.39e23 kg, 2.279e11 m from Sun
  • Spacecraft (index 3): 1.0 kg, parent=Earth (position/velocity set at runtime)

Spacecraft parameters:

  • mass = 1.0 kg
  • radius = 1000.0 m
  • parent_index = 1 (Earth)
  • color = magenta (r=1.0, g=0.0, b=0.5)
  • position/velocity: Placeholders (0,0,0) - set by initialize_spacecraft_leo()

Future Work (Post-Implementation)

Immediate Next Steps

1. Config Format Improvements

  • Support Earth-relative position specification (e.g., { altitude_km = 200.0 })
  • Support Earth-relative orbit specification (e.g., { orbit_type = "circular" })
  • More intuitive spacecraft mission parameters in TOML config
  • Support multiple spacecraft in single config file

2. Improved Patched Conics Implementation

  • Calculate Δv to reach SOI boundary (escape trajectory)
  • Calculate velocity at SOI boundary
  • Add transfer Δv at SOI boundary
  • Combine into equivalent single impulse
  • Test accuracy of two-impulse vs single-impulse approach

3. Inclination Support

  • Extend to 3D transfers
  • Need 3D angular position calculations
  • Longitude of ascending node, inclination, argument of periapsis
  • Phase angle calculations in 3D
  • Out-of-plane maneuver calculations

4. Capture Burns

  • Simulate retrograde burns for orbital capture at destination
  • Calculate Δv needed for circularization
  • Support parking orbits at arrival body
  • Validate Mars capture burns (~1.4 km/s for Mars)

5. Adaptive Timestepping

Problem: Fixed 60s timestep is:

  • Too coarse for fast orbital phases (moon capture, close approaches)
  • Too slow for deep-space phases (interplanetary transfers)

Solution: Adaptive timestep based on orbital period

Implementation:

double calculate_adaptive_timestep(CelestialBody* body, CelestialBody* parent) {
    if (parent == NULL || body->semi_major_axis <= 0.0) {
        return 60.0;  // Default timestep
    }

    // Calculate orbital period using Kepler's third law
    double T = 2.0 * M_PI * sqrt(pow(body->semi_major_axis, 3) / (G * parent->mass));

    // Use 1/1000 of orbital period as timestep
    double adaptive_dt = T / 1000.0;

    // Clamp to reasonable bounds
    adaptive_dt = fmax(adaptive_dt, 10.0);   // Minimum 10s
    adaptive_dt = fmin(adaptive_dt, 600.0);  // Maximum 600s

    return adaptive_dt;
}

Changes required:

  • Add per-body timesteps to SimulationState
  • Update update_simulation() to use adaptive timesteps
  • Add synchronization mechanism for multiple timesteps

Expected outcome:

  • Better accuracy for fast orbits (moon capture)
  • Faster simulation for deep-space phases
  • Energy conserved across SOI transitions

Tests:

  • Verify energy drift with adaptive timesteps
  • Verify orbital period accuracy with adaptive timesteps
  • Test stability across SOI transitions

Visualization Features

6. Mission GUI

  • Interactive departure window visualization
  • Show current phase angle vs. required phase angle
  • Countdown to launch window
  • Transfer trajectory preview (predicted path)
  • Delta-v budget display

7. Multiple Burns Support

  • Mid-course corrections
  • Gravity assist maneuvers
  • Powered flybys
  • Multi-stage missions

8. SOI Visualization

  • Render SOI boundaries as wireframe spheres
  • Color-coded by mass
  • Toggle with keyboard shortcut
  • Show SOI transitions in real-time

Advanced Features

9. Mission Planner

  • Complete mission design tool
  • Multi-leg missions (Earth→Mars→Phobos)
  • Optimization algorithms (minimum Δv, minimum time)
  • Launch date search across windows
  • Mission timeline visualization

10. Real Ephemeris Integration

  • Use actual planetary positions (JPL Horizons API)
  • Date-based initialization
  • Real mission planning with actual ephemeris data
  • Compare simulation to historical missions

11. Enhanced Trajectory Analysis

  • Lambert solver for general transfers
  • Not just Hohmann transfers
  • Arbitrary departure/arrival positions and times
  • Non-planar transfers

Notes

Coordinate System

  • All calculations assume planar motion (z = 0) for initial implementation
  • Angular positions measured in XY plane
  • Future work: Extend to 3D with inclination

Timekeeping

  • Simulation time in seconds, conversions to days for display
  • Fast-forward uses 1-day steps for efficiency during launch window wait
  • Timestep remains 60s during fast-forward

Mass Strategy

  • Spacecraft mass = 1.0 kg (negligible but non-zero)
  • Physics engine handles test particles correctly (mass cancels in acceleration)
  • No N-body perturbations from spacecraft on planetary bodies

Validation Strategy

  • Compare against NASA reference missions (Viking, Curiosity, Perseverance)
  • Energy conservation tracking during transfer
  • Transfer time accuracy (±10% tolerance)
  • SOI transition verification (Earth→Sun→Mars)

Testing Approach

  • Unit tests for each function (formulas, calculations)
  • Integration tests for full missions (LEO initialization, impulse burn, transfer)
  • Regression tests against expected Hohmann transfer parameters

LEO Orbit Considerations

  • LEO orbit at 200 km altitude (r = 6.571×10⁶ m)
  • LEO velocity: ~7,788 m/s at 200 km
  • LEO period: ~88.5 minutes
  • Spacecraft LEO phase changes significantly during multi-day wait periods
  • Transfer burn must account for spacecraft's actual heliocentric velocity (not just Earth's)

References

  • docs/implementation_plan.md - Overall system architecture
  • NASA Technical Memorandum "Hohmann Transfer Calculations"
  • Orbital Mechanics for Engineering Students (Curtis)
  • Fundamentals of Astrodynamics (Bate, Mueller, White)