Add BurnResult struct (position, velocity, true_anomaly) to Maneuver.
Capture pre-burn state in update_spacecraft_physics() before applying
delta-v, enabling tests to assert exact burn-time periapsis location
and true anomaly with tight tolerances (R_TOL, ANG_TOL) instead of
propagation-level tolerances inflated by post-burn state drift.
Refactor test_periapsis_burn.cpp to use burn_result:
- Burn radius now asserts exactly at periapsis (R_TOL)
- True anomaly now asserts exactly 0 (ANG_TOL)
- Both sequential burns confirmed at same periapsis location
- 822 assertions passing (up from 813)
Phase A: Extend sim_engine.py with maneuver trigger detection
- Add TriggerType enum, Maneuver dataclass
- Implement check_maneuver_trigger() matching C++ sub-step logic
- Integrate maneuver execution into update_spacecraft()
- Add maneuvers_from_config() for TOML parsing
- Create precalc_periapsis_burn.py for expected value generation
Phase B: Refactor test_periapsis_burn.cpp
- Merge 4 TEST_CASEs into 1 SCENARIO with 5 SECTIONs
- Shared fixture setup in SCENARIO body
- Replace Approx() with WithinAbs() using named tolerance constants
- Use precalculated expected values for quantitative assertions
- Integer comparisons use REQUIRE() not WithinAbs()
- Add BurnResult plan comment for future burn-time state capture
TOML config converted to TOML 1.0 inline table syntax.
- Rewrite precalc_moon_orbits.py to output orbit params as dotted keys
(orbit.semi_major_axis = ...) instead of nested tables, conforming
to TOML 1.0 spec for Python compatibility
- Add print_cpp_expected_values() helper to script output
- Add new test_moon_orbits.cpp replacing old_tests version:
* MoonData struct now carries int parent_index instead of pointer
* Eliminate opaque pointer arithmetic for parent index comparison
* Collect failures in vector during sim loops, assert once at end
(reduces assertions from 763,230 to 43 per test)
- Add test_moon_orbits.toml generated from precalc script
- Merge 5 SCENARIOs into 1 with shared fixture
- Reorganize 23 SECTIONs by test type (geometry → vis-viva → period → timestep → long-term)
- Add 2 missing timestep tests (apogee radius, velocity comparison)
- Replace all qualitative checks (a > b) with WithinAbs against precalculated values
- Use named tolerance constants everywhere — zero hardcoded numbers in WithinAbs
- Add VEL_CHANGE_SMALL_DT fixture constant
- Refactor precalc script to load from TOML via Simulator class
- Output matches new test ordering
Consolidate 9 TEST_CASEs into 5 SCENARIOs with 22 SECTIONs:
- Load orbital parameters from TOML config instead of hardcoded constants
- Use precomputed expected values via precalc_analytical_propagation.py
- Apply tight tolerance constants (REL_TOL, ANG_TOL, R_TOL, V_TOL)
- Remove decorative comment blocks and redundant SCENARIO title comments
- Fix propagate_orbital_elements/orbital_elements_to_cartesian API usage
(both take parent_mass, not mu)
- Add destroy_simulation cleanup to each SCENARIO
New files: precalc_analytical_propagation.py, test_analytical_propagation.toml
Move all shared tolerance constants to src/test_utilities.h with inline
comments. Update all test files to use header constants instead of local
definitions. Add DRIFT_TOL for parabolic orbit energy checks.
Key changes:
- test_utilities.h: consolidated constants with inline descriptions,
removed per-test doc comments, added DRIFT_TOL=1e-12
- test_cartesian_to_elements_advanced.cpp: use header E_TOL, ANG_TOL,
A_TOL; local A_TOL_LARGE=2e-4 for |a|=1e11 vis-viva error cases
- test_parabolic_orbit.cpp: use V_TOL, E_TOL, REL_TOL, R_TOL, DRIFT_TOL;
add precalculated initial velocity check; remove FIXME ratio test
- test_cartesian_to_elements_basic.cpp, test_extreme_eccentricity.cpp,
test_extreme_orientation_mixed.cpp, test_extreme_timescales.cpp:
migrate remaining local constants to header
- continue.md: update tolerance reference table to match header
- scripts/precalc_parabolic_orbit.py: remove velocity sampling loop
(no longer used by C++ test)
All 624 tests pass.
- Merge initial conditions check into single SCENARIO
- Tighten energy check to relative error (1e-10) vs KE
- Replace qualitative checks with quantitative WithinAbs assertions
- Use named tolerance constants throughout fixture
- Update precalc_parabolic_orbit.py to output SI units (m, m/s)
- Precalculate expected values with full precision from Python
- Python and C++ produce identical results in SI units
- Add semi_latus_rectum support in sim_engine.py for parabolic orbits
- Refactor old_tests/test_inclined_orbits.cpp into 4 SCENARIOs
- Replace broken OrbitTracker period test with propagation-to-apogee check
- Rewrite TOML config to TOML 1.0 inline table syntax
- Add precalc script using sim_engine.py
- Fix orbit tracker: use fabs() for accumulated_rotation threshold
- New test_energy.cpp: energy conservation (10-day drift < 1e-12) and
zero-inclination prograde direction verification
- Tighten energy assertion: replaced qualitative < 5% with WithinAbs(0.0, 1e-12)
(actual drift ~2e-16 for 10-day simulation)
- Remove direction test from test_orbital_period.cpp (semantic separation)
- All 16 assertions across 3 test files passing
Replace manual buffer management (malloc/free/snprintf) with a simple
stack-allocated TestOutput helper. Uses dump_simulation_state's 4-param
API with a single dump_state() method. Verification stays as individual
INFO() calls outside the loop.
Planning doc updates:
- Replace estimate table with actual measured values from DT sweep test
- Add 0.5s and 2.0s data points (69m and 228m respectively)
- Mark DT sweep tests as COMPLETED section
- Add analysis note about linear scaling with DT
New tests in test_maneuver_planning.cpp:
1. DT sweep: Hohmann transfer separation vs time step
- Runs full Hohmann transfer at DT = {0.1, 0.5, 1.0, 2.0, 5.0, 10.0}
- Verifies final separation matches expected ranges
- Confirms ecc < 0.01 for DT <= 1.0
2. DT sweep: quantization error is bounded by DT
- Tests 9 trigger offsets per DT value at DT = {1, 5, 10, 30}
- Verifies quantization error is always in [0, DT)
- Verifies execution time matches ceil-to-step-boundary
3. DT sweep: Hohmann arrival burn timing error
- Measures exact timing error at each DT
- Reports position error estimate (timing_error × velocity)
- Confirms timing error < DT
All 157 tests pass (240,742 assertions).
Previous: 154 tests, 240,445 assertions.
Rename src/rendezvous_hohmann.{h,cpp} to src/rendezvous.{h,cpp} and
tests/test_rendezvous_hohmann.{cpp,toml} to tests/test_rendezvous.{cpp,toml}.
This consolidates the rendezvous module under a simpler name since the
old CW-based rendezvous module was removed and only Hohmann transfer
functionality remains.
Update all includes, config paths, and Makefile references.
Reduce TIME_STEP from 10.0 to 0.1 and increase MAX_STEPS to 700000
to achieve sub-10m rendezvous accuracy. Update milestone dump timing
to correctly capture pre/post-burn states. Revert test config to
original values to match test expectations.
Remove src/rendezvous.h, src/rendezvous.cpp, tests/test_rendezvous.cpp,
and tests/test_rendezvous.toml. No other modules depend on these files.
Also remove RendezvousState enum, RendezvousTarget struct, and
rendezvous_target field from Spacecraft in orbital_objects.h.
For coplanar orbits (inclination < 0.01 rad), compute omega from the
eccentricity vector (longitude of periapsis) instead of forcing omega=0.
This is necessary for correct post-burn orbital element conversion,
critical for Hohmann transfer accuracy.
Update test_omega_debug to accept the new behavior: omega is computed
from the eccentricity vector direction for coplanar orbits.