Skip to content

Overview & Extraction Notes

This paper represents the most significant effort to reconcile 25 years of divergent SGP4 implementations. It documents the bugs, provides corrected C++ and FORTRAN 90 source code, supplies 518 test vectors across 29 satellites, and formally defines the TEME coordinate frame that SGP4 output occupies.

Spacetrack Report No. 3 (1980) contained the canonical SGP4/SDP4 algorithms, but no authoritative digital source files were ever distributed. Over the following quarter century, independent reimplementations introduced divergent bugs, and compensating fixes were applied without coordination. By the early 2000s, multiple organizations ran code that all claimed to be “SGP4” but produced materially different results.

The divergence was partly a consequence of the transcription problem — the invisible column 72 boundary in FORTRAN IV fixed-format source, combined with the absence of any authoritative digital distribution.

Rev-1 was the first comprehensive effort to:

  1. Document the specific bugs and their orbital effects
  2. Provide corrected source code in both FORTRAN 90 and C++
  3. Supply extensive test cases covering edge cases and failure modes
  4. Define the TEME coordinate frame precisely enough for interoperability
  5. Establish a baseline that the broader community could synchronize against

The “Official” vs. “Unofficial” Problem

Section titled “The “Official” vs. “Unofficial” Problem”

By 2006, three major public versions were in circulation:

VersionOriginKey Differences
STR#3 (1980)AFSPC standaloneMixed precision, original bugs
GSFC (1996)NASA Goddard / SeaWiFSSome fixes from 1990 standalone
Dundee (Crawford)Independent researcherMost comprehensive external fix history

These differed in their handling of the secular integrator, Kepler convergence criteria, Lyddane singularity, and negative inclination values. Rev-1 synthesized insights from all three into a single non-proprietary version believed to be compatible with the operational code.

The original STR#3 FORTRAN mixed single-precision and double-precision arithmetic. Rev-1 uses full double precision throughout, eliminating an entire class of precision-related discrepancies. This is the primary cause of the 1—2 km differences observed when comparing Rev-1 output against the original test vectors.

Rev-1 documents five categories of bugs, each demonstrated by specific satellite numbers that triggered the failure:

Affected satellites: 04632, 14128, 20413, 23177, 23599

The Lyddane modification to Brouwer’s theory introduces a singularity at low inclination that the original code did not guard against. These satellites, with near-equatorial orbits, caused division-by-zero or catastrophic cancellation in the short-period corrections.

Affected satellites: 25954, 28626

The TLE fitting process occasionally produces slightly negative inclination values. The original code assumed I0I \geq 0 and computed sin(I)\sin(I) and cos(I)\cos(I) without bounds checking, leading to sign errors that propagated through the perturbation calculations.

Affected satellite: 09880

The deep-space secular integrator uses a 720-minute step size and must save its state between calls. The original code had a state-saving bug where the integrator’s accumulated perturbations were not properly preserved across propagation calls, producing discontinuous jumps for deep-space objects.

Affected satellite: 23333

For high-eccentricity orbits (e>0.9e > 0.9), the Newton-Raphson iteration in the original code could fail to converge within 10 iterations. Rev-1 improved the convergence logic and increased the iteration limit for these cases. Satellite 23333 is a Molniya-type orbit with e0.74e \approx 0.74 that exposed the boundary of the original solver.

The original code used three perigee height thresholds (98, 156, and 220 km) to select different atmospheric drag treatments. The threshold logic contained off-by-one comparisons that could select the wrong drag regime for satellites near these boundaries.

Before Rev-1, SGP4 output was loosely described as “ECI” (Earth-Centered Inertial) without specifying which of several possible inertial frames was meant. Rev-1 formally defined the output frame as TEME — True Equator, Mean Equinox — characterized by:

  • True equator: the instantaneous Earth equatorial plane including nutation
  • Mean equinox: a simplified equinox direction using only 4 of the 106 IAU-80 nutation terms
  • Not J2000: TEME is a “of date” frame that rotates slowly relative to J2000
  • Not TOD: TOD uses all 106 nutation terms; TEME uses only 4

The Appendix C provides the complete transformation matrices for converting TEME to J2000 and ITRF, including worked numerical examples.

Nutation at Propagation Time vs. TLE Epoch

Section titled “Nutation at Propagation Time vs. TLE Epoch”

A subtle question: when computing the TEME-to-J2000 transformation, should the nutation matrix be evaluated at the propagation time or at the TLE epoch? Rev-1 demonstrates that this choice produces a 23.6 m position difference over just 3 days. The “of date” approach (nutation at propagation time) is the correct one.

Rev-1 provides 29 test satellites (expanded from STR#3’s single near-earth and single deep-space test case) covering the full range of orbital regimes:

CategoryCountWhat It Tests
Near-earth normal8Standard LEO propagation
Low perigee4Atmospheric drag regime selection
Decaying orbits3Orbital decay and re-entry handling
12-hour resonance4Molniya-type deep-space resonance
24-hour resonance3GEO-type resonance
Low inclination3Lyddane singularity region
High eccentricity2Kepler convergence stress
Sub-orbital2Below 100 km perigee

The complete test case data (518 vectors) is provided in Appendix D and Appendix E.

AspectSTR#3 (1980)Rev-1 (2006/2008)
LanguageFORTRAN IV (fixed format)FORTRAN 90 + C++
PrecisionMixed single/doubleFull double precision
Test cases25 vectors, 2 satellites518 vectors, 29 satellites
ConstantsWGS-72 hardcodedWGS-72 and WGS-84 selectable
Output frameUndefined “ECI”TEME (formally defined)
Integrator720-min step, state bug720-min step, state bug fixed
Kepler iteration10 max, no ee guardImproved convergence for high ee
Lyddane fixNoneSingularity guard for I0I \approx 0
ComponentFilesContent
Main body9Sections I—VII (590 lines of transcribed text)
Appendix A1Organization comparison table
Appendix B1TLE format specification
Appendix C1TEME coordinate frame definition and transformations
Appendix D129 test satellite TLEs with metadata
Appendix E1518 test vectors (position and velocity)