Skip to content

Fix AFSPC gsto: use IAU/gstime polynomial to match Vallado C++ reference#22

Open
neilberkman wants to merge 1 commit into
neuromorphicsystems:masterfrom
neilberkman:fix-gsto-sidereal-time
Open

Fix AFSPC gsto: use IAU/gstime polynomial to match Vallado C++ reference#22
neilberkman wants to merge 1 commit into
neuromorphicsystems:masterfrom
neilberkman:fix-gsto-sidereal-time

Conversation

@neilberkman
Copy link
Copy Markdown

Summary

from_elements_afspc_compatibility_mode uses afspc_epoch_to_sidereal_time for gsto (Greenwich Sidereal Time at epoch). However, the Vallado C++ reference implementation never actually uses that formula.

In SGP4.cpp initl(), gsto is computed twice:

  1. Lines 1261–1270: The AFSPC d₁₉₇₀ polynomial (stored in gsto1)
  2. Line 1273: gsto = gstime_SGP4(epoch + 2433281.5);

The second assignment unconditionally overwrites the first. The AFSPC sidereal time result is dead code — gstime_SGP4 (the IAU polynomial) is always used, regardless of opsmode.

This PR changes the sidereal time function passed by from_elements_afspc_compatibility_mode from afspc_epoch_to_sidereal_time to iau_epoch_to_sidereal_time, matching the C++ behavior.

Impact

The gsto difference is ~1e-10 rad — negligible for short propagations but accumulates over time. For a GEO-resonant satellite propagated ~1 year (500,000 min), the position error drops from ~3.7 mm to < 0.13 mm vs the C++ reference.

Test plan

  • Regression test: GEO satellite 29238 at t=500,000 min with 1 mm tolerance — fails on master (2.2 mm error), passes with fix (0.13 mm error)
  • All existing tests pass unchanged

Vallado's initl() in SGP4.cpp computes gsto using two formulas:

1. Lines 1261-1270: the AFSPC d₁₉₇₀ polynomial (stored in gsto1)
2. Line 1273: gstime_SGP4(epoch + 2433281.5) — the IAU polynomial

The second assignment unconditionally overwrites the first, making the
AFSPC sidereal time formula dead code. The reference C++ always uses
gstime_SGP4 for gsto regardless of opsmode.

This crate's from_elements_afspc_compatibility_mode was passing
afspc_epoch_to_sidereal_time which implements the dead-code formula.
Changed to iau_epoch_to_sidereal_time which matches gstime_SGP4.

The difference is ~1e-10 rad in gsto, which accumulates during long
propagations. For a GEO satellite propagated ~1 year (500,000 min),
this reduces position error from 3.7 mm to < 1 mm vs the C++ reference.

Includes regression test that fails on master and passes with this fix.
Updated doc comment to reflect the change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant