SGP4 differences with Python and NodeJS implementations


I’ve noticed differences between position in TEME as reported by (github):

and Orekit

and put results and codes used in repo:

While satellite.js and python-sgp4 differ by more than 1m for couple of sats, Orekit and python-sgp4 differ by more than 100m for only couple of sats while almoast all sats differ by more than 1 m.

My conclusion is I have something wrong in my code, probably related to parsing datetimes (i’ve used one datetime for all sats and libraries 2022-10-19T00:00:00Z). Could you help me where I’m wrong? My expectation was that different SGP4 implementations should yield very similar results for the same inputs (TLE and datetimes).

Hi @xmichaelx

Welcome to the Orekit forum! :slight_smile:

Is it possible to have an executable test to reproduce your issue?
It would be very helpful.

Thank you,

Thank you for warm welcome, Orekit is an amazing software.

How to generate that executable test? I’m not very proficient in Java - do you mean I should produce jar out of project in my repo?

Hi @xmichaelx

It could be a copy/paste of your Orekit program in the current forum thread in order to see if there is something wrong.
Because without seeing your code, it is difficult to find possible mistakes.

Thank you,

Code is fortunately short generate a list of SGP4 propagated positions in TEME in Skyfield/satellite.js and then for the same timestamp and TLE i generate the TLE positions in Orekit and I get a lot of >100 m differences for the same TLEs-timestamp pairs. Orekit code:

var s = new TLE(tle.get(0).toString(), tle.get(1).toString());
var propagator = TLEPropagator.selectExtrapolator(s);
var utc = TimeScalesFactory.getUTC();
var coords = propagator.getPVCoordinates(new AbsoluteDate(time, utc));

var orekit_x = coords.getPosition().getX()/1000;
var orekit_y = coords.getPosition().getY()/1000;
var orekit_z = coords.getPosition().getZ()/1000;

And for reference satellite.js code:

var satrec = satellite.twoline2satrec(sat.tle[0], sat.tle[1])
var positionAndVelocity = satellite.propagate(satrec, new Date(sat.time));
var sat_x = positionAndVelocity.position[0];
var sat_y = positionAndVelocity.position[1];
var sat_z = positionAndVelocity.position[2];

You can check it using:

1 25867U 99040B   22294.97725721  .00001118  00000-0  00000+0 0  9999
2 25867  41.9457 224.3371 8939761 241.1358   0.2074  0.37816312 23435

and input date parsed from string:


Hello there,

I think that skyfield returns positions in GCRF, not TEME.
So try outputting with orekit in the former (you can specify it in getpvcoordinates) and compare again.


General Kenobi,

Sorry my bad here, I’ve written Skyfield but it was python implementation of sgp4 by the same dev (Brandon Rhodes) hence the mistake - in Python I used:

satellite = Satrec.twoline2rv(*tle, WGS84)
sat_epoch = sat_epoch_datetime(satellite)
t = datetime(2022,10,19,tzinfo=timezone(timedelta()))
_, r, _ = satellite.sgp4(jd, fr)

Maybe it’s the matter of WGS used? Where can I check what Orekit uses by default WGS72 or WGS84?