# OrbitTracker 3D Fix Plan ## Problem `update_orbit_tracker()` only uses `atan2(y, x)` which calculates the angle in the x-y plane. For 3D inclined orbits, this doesn't track the true orbital angular position because: 1. The spacecraft moves in an inclined orbital plane (not the x-y plane) 2. The x-y projection doesn't represent the true angular progress around the orbit ## Current Implementation (Failing) ```cpp Vec3 relative_pos = vec3_sub(body->global_position, parent->global_position); double current_angle = atan2(relative_pos.y, relative_pos.x); // Only works for 2D orbits in x-y plane ``` ## Solution Track the orbital angular position by projecting the 3D position onto the orbital plane and calculating the true anomaly. ## Implementation Approach ### Option 1: Store Orbital Plane Normal (Recommended) Add fields to `OrbitTracker` to store the orbital plane orientation: - `Vec3 orbital_plane_normal` - Normal vector to the orbital plane - `Vec3 reference_direction` - Reference direction in the orbital plane (periapsis direction) Calculation steps: 1. Compute orbital plane normal from inclination (i) and RAAN (Ω): ``` n_x = sin(i) * sin(Ω) n_y = -sin(i) * cos(Ω) n_z = cos(i) ``` 2. Compute periapsis direction in 3D space: ``` R_z(Ω) · R_x(i) · R_z(ω) transforms (1, 0, 0) to periapsis direction ``` 3. Project position onto orbital plane and calculate angle from periapsis ### Option 2: Use Existing Rotation Matrix Reuse `mat3_rotation_orbital()` to transform position back to orbital plane coordinates: 1. Apply inverse rotation: `R_orbital^T · r_3D = r_orbital_plane` 2. Calculate angle in orbital plane: `atan2(y_orbital, x_orbital)` This is simpler and reuses existing code. ## Changes Required ### test_utilities.h - Add `double inclination` field to `OrbitTracker` struct - Add `double longitude_of_ascending_node` field - Add `double argument_of_periapsis` field ### test_utilities.cpp - Modify `create_orbit_tracker_with_min_time()` to accept orbital elements - Modify `update_orbit_tracker()` to: 1. Build inverse rotation matrix from stored orbital elements 2. Transform 3D position back to orbital plane 3. Calculate angle in orbital plane ### test_inclined_orbits.cpp - Update `create_orbit_tracker_with_min_time()` calls to pass orbital elements ## Test - Molniya orbital period test should pass (12 hours ± tolerance) - All other orbit tests should continue to pass ## Notes - Backward compatibility: Planar orbits (i=0) should work exactly as before - The inverse rotation is just the transpose of the rotation matrix (orthogonal) - Performance: Minimal impact, only called during tests ## Files to Modify 1. `src/test_utilities.h` - Add orbital element fields to OrbitTracker 2. `src/test_utilities.cpp` - Implement 3D angle calculation 3. `tests/test_inclined_orbits.cpp` - Update tracker creation calls 4. `tests/test_orbital_period.cpp` - May need updates if using tracker 5. `tests/test_moon_orbits.cpp` - May need updates if using tracker