Browse Source

Remove [!mayfail] tags from now-passing inclined orbit tests

- Molniya position tests now pass with 3D rotation implementation
- Generic inclined orbit test passes with proper argument_of_periapsis
- Only orbital period test still fails (orbit tracker needs 3D fix)
- Add plan document for fixing update_orbit_tracker()
main
cinnaboot 5 months ago
parent
commit
217ca7a618
  1. 78
      docs/planning/orbit-tracker-3d-fix-plan.md
  2. 4
      tests/test_inclined_orbits.cpp

78
docs/planning/orbit-tracker-3d-fix-plan.md

@ -0,0 +1,78 @@
# 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

4
tests/test_inclined_orbits.cpp

@ -9,7 +9,7 @@
const double POSITION_TOLERANCE_METERS = 10000.0; const double POSITION_TOLERANCE_METERS = 10000.0;
const double PERIOD_TOLERANCE_SECONDS = 600.0; const double PERIOD_TOLERANCE_SECONDS = 600.0;
TEST_CASE("Molniya orbit - position verification at multiple true anomalies", "[inclined][molniya][!mayfail]") { TEST_CASE("Molniya orbit - position verification at multiple true anomalies", "[inclined][molniya]") {
const double TIME_STEP = 60.0; const double TIME_STEP = 60.0;
const double SECONDS_PER_DAY = 86400.0; const double SECONDS_PER_DAY = 86400.0;
const double SEMI_MAJOR_AXIS = 26540000.0; const double SEMI_MAJOR_AXIS = 26540000.0;
@ -138,7 +138,7 @@ TEST_CASE("Molniya orbit - orbital period verification", "[inclined][molniya][pe
destroy_simulation(sim); destroy_simulation(sim);
} }
TEST_CASE("Generic inclined orbit - moderate inclination", "[inclined][generic][!mayfail]") { TEST_CASE("Generic inclined orbit - moderate inclination", "[inclined][generic]") {
const double TIME_STEP = 60.0; const double TIME_STEP = 60.0;
const double SEMI_MAJOR_AXIS = 10000000.0; const double SEMI_MAJOR_AXIS = 10000000.0;
const double ECCENTRICITY = 0.5; const double ECCENTRICITY = 0.5;

Loading…
Cancel
Save