Possible SGP4 compatibility issues: e = 1e-4 boundary and THDT constant

Hi all,

I’ve been comparing Orekit’s SGP4/SDP4 output against Vallado/python-sgp4 and found two small differences that appear to explain the remaining residuals.

  1. At exactly e = 1e-4, Orekit keeps xmcof/omgcof, while Vallado/Spacetrack Report #3 drops them for e <= 1e-4. Changing the Orekit condition from < 1e-4 to <= 1e-4 restores parity for this boundary case.

  2. In deep-space propagation, Orekit uses:

THDT = 4.3752691e-3 rad/min

while Vallado uses:

4.37526908801129966e-3 rad/min

For GEO this produces a small accumulated difference. If I substitute Orekit’s rounded value into python-sgp4 at the corresponding locations, the 30-day GEO position matches Orekit to roughly 6e-9 km, so this seems to fully explain the discrepancy.

Would the maintainers consider:

  • fixing the e = 1e-4 boundary, and

  • making the deep-space Earth rotation constant/configuration selectable, even if the current Orekit value remains the default for compatibility?

Happy to put together a small MR with tests if this sounds reasonable.

Good catch!
Yes, you can open an issue and an associated merge request on the forge.
It may even end up in the next patch release.

Hi there,

thanks for reporting.

Can you provide the TLE behind your 6e-9km value?
We’ll add it to the tests.

Cheers

Hi,

Sure. The 6e-9 km figure came from a synthetic near-GEO element set, not a
catalogued object:

1 99999U          25001.00000000  .00000000  00000-0  10000-4 0    01
2 99999   0.0500  90.0000 0001000   0.0000   0.0000  1.00273790    01

Epoch 2025-01-01T00:00:00 UTC, propagated to epoch + 43200 min (30 days), TEME, km.
Orekit 13.1.3 selects DeepSDP4 for it. The reference is python-sgp4 2.27 (Vallado’s
code, pure-Python implementation, WGS72, opsmode ‘i’).

Position at +43200 min:

Vallado as published          -20974.134611934  36572.404003287  57.554005190
Orekit 13.1.3                 -20974.134455572  36572.404095167  57.554004784
Vallado with rptim = THDT     -20974.134455566  36572.404095171  57.554004784

Velocity at +43200 min (km/s):

Vallado as published          -2.667538381620  -1.529662878230  0.006928921098
Orekit 13.1.3                 -2.667538388139  -1.529662866722  0.006928921116

So Orekit differs from the published reference by 1.8e-4 km (0.18 m) at 30 days.
Replacing Vallado’s rptim = 4.37526908801129966e-3 with TLEConstants.THDT =
4.3752691E-3 in both places it is defined (dsinit and dspace) brings the two to
within about 7e-9 km (largest component 6e-9 km), so for this case the constant
accounts for the whole difference.

The gap grows with the resonance integration: the positions agree to 5e-9 km at
+1440 min, differ by 8e-7 km at +7200 min, and by 1.8e-4 km at +43200 min.

The same effect shows up in real element sets (CelesTrak, epochs 30 Sep – 1 Oct 2026),
same setup:

INTELSAT 10-02
1 28358U 04022A   26274.28586502 -.00000012  00000+0  00000+0 0  9993
2 28358   0.0188 244.4512 0000395  25.9670 201.5399  1.00271722 81621
GOES 16
1 41866U 16071A   26274.61451617 -.00000094  00000+0  00000+0 0  9994
2 41866   0.5976  84.0380 0002277 146.5604 256.3000  1.00270988 36179
TDRS 3
1 19548U 88091B   26273.95411941 -.00000297  00000+0  00000+0 0  9994
2 19548  12.5244 340.2927 0038904 350.6418 333.3814  1.00267688126445
MOLNIYA 2-10
1 07376U 74056A   26274.09180686 -.00000203  00000+0  00000+0 0  9998
2 07376  65.2296 289.8497 6674984 267.7805  20.5563  2.01201650381865
GPS BIIR-5 (PRN 22)
1 26407U 00040A   26274.63014552  .00000023  00000+0  00000+0 0  9993
2 26407  54.8348 210.9384 0117327 304.1901 154.9947  2.00558399192089

Position at +43200 min, Vallado as published / Orekit 13.1.3:

INTELSAT 10-02  -33114.373907564  26100.502023235    -24.272710665
                -33114.373796788  26100.502166895    -24.272710676   (1.81e-4 km apart)
GOES 16         -38613.886015897  16922.654786475    459.627441704
                -38613.886074104  16922.654649626    459.627442194   (1.49e-4 km)
TDRS 3           37385.602777505 -19116.396281757  -1154.331381244
                 37385.602763490 -19116.396309460  -1154.331388077   (3.2e-5 km)
MOLNIYA 2-10     19446.693409967  -2778.368915205  38517.132654297
                 19446.693391022  -2778.368706176  38517.132746445   (2.29e-4 km)
GPS BIIR-5       24487.779842619   7754.945643631   7691.872007344
                 24487.779842619   7754.945643630   7691.872007344   (agree to 1e-9 km)

With rptim replaced by THDT in the reference, the first four agree with Orekit to
7e-8, 2.7e-6, 3e-8 and 4e-8 km. The constant only enters the resonant branches
(24 h, and 12 h with e >= 0.5), so the GPS case is a useful control: it is
deep-space but not resonant, and the two already agree.

I’ll start work on the merge request now.

Cheers