From 0548d864c46dff9e1e8ac3a2587aa7f338c387aa Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Sat, 21 Feb 2026 18:17:41 +0000 Subject: [PATCH] Document scheduled_dt field and exact position burn execution in technical reference --- docs/technical_reference.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/technical_reference.md b/docs/technical_reference.md index e8930bc..6d37429 100644 --- a/docs/technical_reference.md +++ b/docs/technical_reference.md @@ -90,6 +90,7 @@ struct Maneuver { double delta_v; TriggerType trigger_type; double trigger_value; + double scheduled_dt; // time to propagate before burn (for exact position) bool executed; double executed_time; }; @@ -425,7 +426,7 @@ Energy calculations and orbit tracking for testing. ### Orbital Element Reconstruction After Burns -**Location:** `execute_maneuver()` (maneuver.cpp:166-176) +**Location:** `execute_maneuver()` (maneuver.cpp:219) **Process:** 1. Apply impulsive burn to `craft->local_velocity` @@ -437,6 +438,23 @@ Energy calculations and orbit tracking for testing. - If exceeded: reconstruct elements from current state - This catches numerical drift and ensures consistency +### Exact Position Burn Execution + +**Purpose:** True anomaly triggers must execute burns at the exact orbital position, not at the current position when crossing is detected. + +**Mechanism:** +1. `check_maneuver_trigger()` calculates `scheduled_dt` (time to reach target anomaly) +2. If crossing will occur within current frame (`scheduled_dt < sim->dt`), trigger fires +3. `execute_pending_maneuvers()` propagates spacecraft by `scheduled_dt` to exact position +4. Burn executes at precise orbital location +5. Remaining frame time (`sim->dt - scheduled_dt`) is propagated after burn +6. Spacecraft marked as handled to skip redundant propagation in `update_spacecraft_physics()` + +**Wraparound Handling:** +- Special case for 2π→0 crossing at periapsis +- When current_nu > 5.0 and future_nu < 1.0, wraparound crossing is detected +- Prevents false "moving away" rejection near angle boundaries + ### 3D Orbital Orientation **Rotation:** z-x-z Euler angles via `mat3_rotation_orbital(omega, i, Omega)` @@ -492,7 +510,7 @@ Energy calculations and orbit tracking for testing. The simulation initializes in this sequence: create_simulation() is called first, then load_system_config() parses the TOML file and loads bodies, spacecraft, and maneuvers. Next, run_all_config_validations() performs system-level validation. Then initialize_orbital_objects() converts orbital elements to local position/velocity for all bodies and spacecraft, computes global coordinates, and calculates SOI radii. Finally, the main simulation loop begins. ### Main Simulation Loop -The main simulation loop executes in this order: update_bodies_physics(), compute_global_coordinates(), update_spacecraft_physics(), execute_pending_maneuvers(), compute_spacecraft_globals(), then increments simulation time. Within update_bodies_physics(), for each body: check SOI via find_dominant_body, handle transitions by computing global coordinates from old parent, updating parent_index, computing new local coordinates, and reconstructing orbital elements. Then check velocity deviation with 1e-6 tolerance and reconstruct elements if needed. Propagate elements via propagate_orbital_elements() and update local position/velocity. compute_global_coordinates() updates all body global positions from parent.global + local. update_spacecraft_physics() performs the same velocity deviation check and propagation for spacecraft. execute_pending_maneuvers() checks each unexecuted maneuver for time or true anomaly triggers; if triggered, applies burn to local_velocity, reconstructs orbital elements, and marks executed. compute_spacecraft_globals() updates all spacecraft global positions. +The main simulation loop executes in this order: update_bodies_physics(), compute_global_coordinates(), execute_pending_maneuvers(), update_spacecraft_physics(), compute_spacecraft_globals(), then increments simulation time. Within update_bodies_physics(), for each body: check SOI via find_dominant_body, handle transitions by computing global coordinates from old parent, updating parent_index, computing new local coordinates, and reconstructing orbital elements. Then check velocity deviation with 1e-6 tolerance and reconstruct elements if needed. Propagate elements via propagate_orbital_elements() and update local position/velocity. compute_global_coordinates() updates all body global positions from parent.global + local. execute_pending_maneuvers() checks each unexecuted maneuver for time or true anomaly triggers. For true anomaly triggers: if crossing detected, sets scheduled_dt to time needed to reach target. When triggered, propagates spacecraft by scheduled_dt to exact position, executes burn, propagates remaining frame time, and marks spacecraft as handled to skip in update_spacecraft_physics(). update_spacecraft_physics() propagates spacecraft not already handled this frame. compute_spacecraft_globals() updates all spacecraft global positions. ### SOI Mechanics SOI transitions are detected by calling find_dominant_body() before each physics update. If the parent changes, the body's global coordinates are computed in the old frame, the parent_index is updated, new local coordinates are computed, and orbital elements are reconstructed. Propagation then uses the new local frame. @@ -514,7 +532,7 @@ SOI transitions are detected by calling find_dominant_body() before each physics - `find_dominant_body()`: simulation.cpp:105-148 - `cartesian_to_orbital_elements()`: orbital_mechanics.cpp:186-299 - `orbital_elements_to_cartesian()`: orbital_mechanics.cpp:6-44 -- `execute_maneuver()`: maneuver.cpp:166-176 +- `execute_maneuver()`: maneuver.cpp:219 - Velocity deviation check: simulation.cpp:267-270 (bodies), 291-294 (spacecraft) ### Build System