SGP4 TLE propagation from TLE seems inaccurate

Hi Orekit Team,
I am trying to convert TLEs collected over the past 6 months into x,y,z positions in order to observe “ground truth” x,y,z positions. I try to extract the ground truths via the following code logic

mytle= TLE(tle_line1_str, tle_line2_str)
propagator = TLEPropagator.selectExtrapolator(mytle)
pv_truth = propagator.propagate(mytle.getDate().shiftedBy(0.0)).getPVCoordinates(frame=FramesFactory.getEME2000())

and from pv_truth.getPosition, I can extract x,y,z

PROBLEM: however, the extracted “ground truth x,y,z” seems to be very wrong when plotted. Because for satellite such as IRIDIUM id#=42807, we can see there is inclination of 86.4 °, but the extracted “ground truth x,y,z” shows ~0 degree inclination (shown as blue in attached ipynb picture)

Please see python notebook here:
convert-tle-to-ephemeris-truth-vs-propagates-FORUM-SUBMISSION.ipynb (67.1 KB)

Please see past 6 months TLEs here:
past6months_tles.txt (621.2 KB)

Please let me know if I am using TLEPropagator incorrectly? and how am I using it incorrectly?


Without going into your example (some external dependencies that are not readily available), I could recommend you tried a smaller test with just that Iridium TLE and the TLE propagation notebook example at:

Note also that you are only getting the coordinates from the time of the epoch of the TLE (maybe there is a mistake in the .shiftBy(0.0)?)



I made a small Java code to calculate the keplerian elements based on the first TLE of IRIDIUM.

public static void main(String[] args)  {

    // Initialize Orekit
    final File home       = new File(System.getProperty("user.home"));
    final File orekitData = new File(home, "orekit-data");
    final DataProvidersManager manager = DataContext.getDefault().getDataProvidersManager();
    manager.addProvider(new DirectoryCrawler(orekitData));

    // TLE
    final String line1 = "1 42807U 17039E   21032.21352857  .00000081  00000-0  21984-4 0  9999";
    final String line2 = "2 42807  86.3951  93.5661 0002498  92.7212 267.4270 14.34217473188743";
    final TLE tle = new TLE(line1, line2);

    // Propagator
    final TLEPropagator propagator = TLEPropagator.selectExtrapolator(tle);

    // Extract the orbit
    final SpacecraftState finalState = propagator.propagate(tle.getDate());
    final PVCoordinates pvECI = finalState.getPVCoordinates(FramesFactory.getEME2000());
    final KeplerianOrbit kepOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(finalState.getOrbit());

    // Print
    System.out.println("PV EME2000:" + pvECI);


The output is:

SpacecraftState{orbit=Cartesian parameters: {P(-445286.17044032563, 7145074.863214257, 3.8191719204909695), V(-467.4569435600412, -38.807271277088404, 7448.645419187451)}, attitude=org.orekit.attitudes.Attitude@439f5b3d, mass=1000.0, additional={}}
PV EME2000: {2021-02-01T05:07:28.868, P(-411587.9082939392, 7147095.167906658, 793.2008453674401), V(-452.59107933642565, -36.55895397728144, 7449.574823129494), A(0.4471519983929933, -7.764654985239574, -8.6174071867045E-4)}
Keplerian parameters: {a: 7161968.392685218; e: 0.0013607999899432305; i: 86.3974212550252; pa: 71.95036237682125; raan: 93.56610000248601; v: -71.95033174996804;}

As you can see, the inclination is about 86.4 degrees, as expected.
Maybe there is a error in your example?


Hi Bryan,
Thank you for your Java code. I agree with you that the Loaded TLE does yield appropriate inclination calculation value 86.4. I also checked that this holds true in my python code (and it does).

However, There is a discrepancy between inclination and x,y,z positions extracted/propagated by delta T=0 over many TLEs (span of past 6 months). In other words, if there were 1TLE collected per month, then we would have 6 TLEs collected over the past 6 months. from those 6TLEs we could convert them to 6 <x,y,z> and plot those 6 positions on a 3D plot. And hopefully we would get an ellipse that shows inclination of 86.4?

these extracted x,y,z positions plotted (in blue) on a 3D graph show inclinations of ~ 0degrees even though the SpacecraftState indicates inclination:86.4 (as you have shown in your java code)

Hi Petrus,

I am using .shiftBy(0.0) because I am trying to extract the x,y,z position from each historic TLE. Is there a better alternative way to extracting historic x,y,z positions?

You’re seeing aliasing. Change the “delta T” to other values and watch the blue circle move up and down.

Upon further inspection, the TLEs for IRIDIUM id#=42807 are sampled at intervals when the satellite repeatedly returns to roughly the same x,y,z positions,

thus not showing the obvious inclinations of an elliptical orbit

1 Like