Cross-validation against Orekit and GMAT¶
LuPNT’s time-scale conversions, sidereal angles, reference-frame conversions (Earth and Moon), Sun/Moon ephemerides, and orbit propagation are cross-validated against two independent, widely used astrodynamics tools:
This page summarizes how the comparison works, the measured differences per category, and the known modeling differences the comparison uncovered.
Methodology¶
Neither tool is a build, run, or test dependency of LuPNT. Instead:
A developer-only generator script drives the external tool once and stores its outputs in a checked-in JSON fixture:
cpp/test/orekit/gen_orekit_reference.py(run via the optionaldevpixi environment) writescpp/test/orekit/data/orekit_reference.json.cpp/test/gmat/gen_gmat_reference.py(requires a local GMAT desktop install) generates and runs a GMAT script and writescpp/test/gmat/data/gmat_reference.json(the exact GMAT script is checked in alongside asgmat_reference.script).
Regular Catch2 tests under
cpp/test/orekit/andcpp/test/gmat/load the fixtures and compare LuPNT’s own computations against them. They run as part ofpixi run test-cppon every machine, with no external-tool dependency.
Both fixtures use LuPNT’s physical constants
(GM_EARTH = 398600.435507e9, GM_MOON = 4902.800118e9,
R_EARTH = 6378137, J2_EARTH = 1.08262668e-3; see
cpp/lupnt/core/constants.h) on both sides of the comparison, so the
observed differences are algorithmic/data differences, not differences in
adopted constants. Where the comparisons overlap (frame-conversion input
states, orbit cases, epochs), the two fixtures use identical inputs, so the
Orekit and GMAT columns below are directly comparable.
The test tolerances are calibrated: each tolerance is set a small factor (typically 2-20x) above the measured difference, with a comment in the test file explaining the difference’s origin. A tolerance that merely “passes” is not the goal – the point is that each residual difference is understood.
What is compared¶
Category |
vs Orekit |
vs GMAT |
|---|---|---|
Time scales |
TAI-UTC, TT-TAI, TDB-TAI, GPS-TAI, UT1-UTC at 6 epochs bracketing the 2012/2016 leap seconds |
TAI-UTC, TT-TAI, TDB-TAI at the same epochs (GMAT exposes no UT1/GPS) |
Sidereal angles |
GMST (IAU-82 / IERS 1996) and Earth Rotation Angle (IAU 2000) |
– |
Earth frames |
GCRF <-> EME2000, GCRF <-> ITRF for LEO/MEO/GEO/trans-lunar states at 3 epochs |
same states/epochs via GMAT’s ICRF / MJ2000Eq / BodyFixed systems |
Moon frames |
GCRF <-> MOON_CI (DE440 translation); MOON_ME vs the analytical IAU pole model |
GCRF <-> MOON_CI (DE421); MOON_PA vs GMAT’s SPICE-kernel Luna BodyFixed (a principal-axes frame) |
Ephemerides |
Earth->Moon and Earth->Sun position/velocity (DE440) at 3 epochs |
(implicit in the Moon-frame translations) |
Kepler propagation |
6 orbits – Earth MEO-HEO/LEO/GEO/Molniya + lunar LLO/ELFO –
propagated 0.25/0.5/0.75/1.5 periods (analytical
|
same 6 orbits (numerical RK89 point-mass propagation) |
J2 acceleration |
formula-level check at 5 positions
( |
– |
J2 propagation |
3 orbits, J2 about the inertial Z axis (same model as LuPNT) – isolates integrator differences |
2 orbits, J2 in the body-fixed frame – exposes the modeling difference |
Measured differences¶
The numbers below were measured when the fixtures were generated (June 2026); regenerate the fixtures and re-derive them if the comparison data changes. “Tolerance” is the value asserted by the tests.
Time scales and sidereal angles¶
Quantity |
vs Orekit (max) |
vs GMAT (max) |
Tolerance / origin of difference |
|---|---|---|---|
TAI-UTC, TT-TAI, GPS-TAI |
~2e-8 s |
~6e-7 s |
1e-6 s. Exactly defined offsets; the residuals are floating-point representation artifacts (LuPNT stores epochs as seconds-since-J2000 doubles; GMAT reports ~30000-day Modified Julian dates whose subtraction amplifies the ULP). |
TDB-TAI |
~4e-8 s |
~5e-7 s |
1e-6 s (Orekit) / 1e-5 s (GMAT). The ~1.7 ms periodic relativistic term is implemented with different truncated series. |
UT1-UTC |
<= 0.024 s (away from leap seconds) |
– |
0.1 s. EOP-table vintage difference (different IERS bulletin snapshots). See the leap-second note below. |
GMST, ERA |
<= 1.8e-6 rad |
– |
1e-5 rad. Identical formulas on both sides (IAU-82 GMST, IAU-2000 ERA); the residual is the UT1 difference times the Earth rotation rate. |
Frames¶
Conversion |
vs Orekit (max) |
vs GMAT (max) |
Tolerance / origin of difference |
|---|---|---|---|
GCRF <-> EME2000 |
1.8e-4 m (trans-lunar), i.e. ~5e-13 * |r| |
54 m (trans-lunar), i.e. ~1.6e-7 * |r| |
1e-3 m (Orekit); max(5 m, 3e-7 * |r|) (GMAT). LuPNT and Orekit implement the same IERS frame-bias matrix; GMAT’s ICRF <-> MJ2000Eq rotation differs by ~1e-7 rad (slightly epoch-dependent). |
GCRF <-> ITRF |
4.4 km @ trans-lunar 2025 epoch (~1.3e-5 * |r|); 14-98 m @ LEO |
1.6 km @ trans-lunar (~4.5e-6 * |r|); 34-36 m @ LEO |
max(100 m, 2e-5 * |r|), velocity 1 m/s. Earth-orientation (UT1/polar-motion) table vintage: a ~tens-of-ms UT1 difference rotates positions by ~1e-6..1e-5 rad about the polar axis, scaling with radius. Differences grow toward 2025 epochs where one or both tables are predictions. |
GCRF -> MOON_CI |
0.33 m |
80 m |
1 m (Orekit) / 200 m (GMAT). Pure DE-ephemeris translation: LuPNT and Orekit both evaluate DE440 (residual = distribution/reader differences, ~5e-11 relative); GMAT shipped DE421, so its column measures the DE421-vs-DE440 lunar ephemeris offset. |
Moon body-fixed |
MOON_ME vs IAU model: 57-200 m (~3e-5 * |r|) |
MOON_PA vs Luna BodyFixed: 56-86 m (translation-dominated) |
3e-4 * |r| (Orekit) / 300 m (GMAT). Orekit’s body-oriented Moon frame is the analytical IAU pole model, which approximates the DE mean-Earth axes to ~3e-5 rad. GMAT loads a SPICE Luna principal-axes kernel, validating LuPNT’s MOON_PA: after removing the DE421-vs-DE440 translation, the PA orientations agree at the sub-arcsecond level. Cross-check: swapping the frames (PA vs IAU, or ME vs GMAT) increases the differences 10-40x (0.6-3.4 km), confirming each identification. |
Ephemerides (Earth->Moon, Earth->Sun) |
Moon 0.33 m / Sun 7.2 m (both ~5e-11 relative) |
– |
max(1 m, 1e-10 * |r|), velocity 1e-5 m/s. Same DE440 data, independently distributed and independently interpolated. |
Orbit propagation¶
Quantity |
vs Orekit (max) |
vs GMAT (max) |
Tolerance / origin of difference |
|---|---|---|---|
Kepler: initial COE -> Cartesian |
1.5e-8 m |
1.3e-8 m |
1e-3 m. Pure conversion math; machine precision. |
Kepler: propagated Cartesian |
5.7e-8 m / 5e-12 m/s |
1.8e-2 m / 8e-6 m/s |
1e-2 m (Orekit) / 0.1 m (GMAT). Orekit’s propagator is analytical (like LuPNT’s), so agreement is machine precision; GMAT numerically integrates the point-mass problem (RK89, accuracy 1e-13), so its column shows integrator drift. |
Kepler: propagated angles (M/E/nu) |
<= 3e-15 rad |
<= 5e-8 rad |
1e-9 rad (Orekit) / 1e-6 rad (GMAT). Same analytical-vs-numerical distinction. |
J2 acceleration |
<= 1e-15 m/s^2 (vs 1e-12 tolerance) |
– |
Identical closed-form J2 formula. |
J2 propagation (inertial-axis J2) |
2.2e-5 m / 1.9e-9 m/s over 1.5 orbits |
– |
1e-3 m / 1e-6 m/s. Same force model on both sides (J2 about the inertial Z axis); the residual is LuPNT’s fixed-step RK4 (1 s) vs Orekit’s adaptive DP853. |
J2 propagation (body-fixed J2) |
– |
22-182 m / 0.005-0.099 m/s over 0.25-1.5 orbits |
300 m / 0.15 m/s. Modeling difference: LuPNT’s
|
Known modeling differences and limitations¶
The cross-validation surfaced three noteworthy items, all documented in the corresponding test files:
UT1 interpolation across leap seconds (LuPNT limitation).
LuPNT’s EOP table stores daily UT1-UTC values and linearly interpolates
across the 1 s leap-second jump. For epochs within ~1 day of an
insertion this produces spurious UT1-UTC: measured +0.938 s one hour
before the 2016-12-31 leap and +0.094 s six hours after the 2012-06-30
leap. Orekit interpolates the continuous UT1-TAI and is unaffected. The
fixtures flag such epochs (near_leap_second) and the tests skip the
UT1-dependent checks (UT1-UTC, GMST, ERA) there; TAI/TT/TDB/GPS are still
verified at those epochs.
J2 symmetry axis (intentional simplification).
JToCartTwoBodyDynamics applies the J2 acceleration about the inertial
Z axis rather than the body-fixed pole. The GMAT comparison quantifies the
effect of this choice for Earth orbits: tens to ~200 m over up to 1.5
orbits for the tested LEO/MEO-HEO cases. Use the full gravity-field
dynamics when this matters.
GMAT’s ICRF/MJ2000Eq frame bias. GMAT’s ICRF <-> MJ2000Eq rotation differs from the IERS frame-bias matrix used by LuPNT and Orekit (which agree to sub-mm) by ~1e-7 rad. This is a GMAT-side convention difference, visible only at trans-lunar ranges (~50 m).
Regenerating the fixtures¶
See cpp/test/orekit/README.md
and cpp/test/gmat/README.md
for the per-tool regeneration workflows (optional dev pixi environment
for Orekit; a local GMAT R2022a desktop install for GMAT) and the full JSON
data dictionaries.