I have a question on TLE propagation and specifically the A value.
Taking the TLEPropagatorTest as an example with the GPS satellite data (from the Orekit unittests).
The orbital period there is defined as period = 717.97 * 60.0 (43078.2 sec) or 2.00565440 in the TLE field.
If I do the A calculation myself using Mu = 3.986004418e14 and the defined period I get A = 2.656018572623494E7
When I use the TLEPropagator as TLEPropagator propagator = TLEPropagator.selectExtrapolator(tle); SpacecraftState initialState = propagator.getInitialState(); then initialState.getA() returns 2.6561853901682895E7 (~1.7km more) and subsequently the orbital period via initialState.getKeplerianPeriod() or initialState.getKeplerianMeanMotion() converted to seconds is 43082.248 (+4 seconds compared to the original TLE value).

And this is even without any propagation just the initial state.

Maybe I miss something but it looks pretty strange/inconsistent. Could you please advise me how to deal with this to get consistent results comparable to the original raw TLE data (if it’s possible)?

The difference you notice is expected. TLE is not really an orbit, it is a mean state that is meaningful only with respect to SGP4/SDP4 propagation models. The important word in the previous sentence is “mean”. TLE cannot be transformed into classical Keplerian parameters on one point only, which would correspond to osculating parameters. Converting TLE to something else requires fitting on a time span, with a recommended duration of at least two orbits, and using a propagation model that is consistent with TLE (i.e. first few zonal terms, luni-solar effects or drag depending on altitude). You can look at the conversion package to see how to transform TLEs.

Yes, I know it was mentioned many times that “TLE is not really an orbit” but was under impression that at least orbital period is the “true” orbital period. It’s understandable that the other parameters may have model-specific interpretations but the period. Interesting.

Also the test example where the original TLE period is used to simulate a full period for the satellite (finalState = propagator.propagate(initDate.shiftedBy(period))) shows another important (originally unexpected) property of the propagators. Just having a reference to a propagator you cannot really simulate a full period with it since in the TLEPropagator case propagator.propagate(initDate.shiftedBy(initialState.getKeplerianPeriod())) won’t give you what you want, right?

Or it’s only the case for the TLEPropagator (which should not be used then for any real propagation) and all other propagators should work fine (so need a conversion from TLE)?

Otherwise if I want to write a simple generic method for orbit simulation I need to manage and pass a set of parameters like a propagator + the orbital period value (+maybe something else), right?

I would say the period is almost the value that is most sensitive to model changes! When considering the bumpy Earth gravity field, the semi major axis exhibits harmonic effects (no secular drift as gravity is a conservative force). This implies the period computed by T = 2π√(a³/µ) will be different if you apply it near perigee or near apogee due to semi-major axis changes.

Period is known in advance with a simple computation only in the case or Keplerian propagation.
For all other cases, period (or getKeplerianPeriod) is just an approximation. When we propagate using
something like propagate(initDate.shiftedBy(period)), we are just pointing roughly to the next orbit, we may be off by a few seconds. We could adjust this a posteriori by stating that after one period, we want to be back at the same point as we are now, and using differential corrections to get there accurately, starting with a first propagation to next Keplerian period, then looking where we arrived, computing the differential correction, propagating again until we converge. This would usually converge in 2 or 3 iterations. One point to note however is how we define “same point”. When the propagation model is not Keplerian only, the orbit does not really close. So we could define “same point” as “same osculating true anomaly” or “crossing again the plane defined by current osculating position and normal to current osculating velocity”, or “crossing same latitude” or many other ways. Each of these definitions would lead to a different period (all close to each other, but different. Remember that astronomy defines both sidereal period, synodic period, draconitic period, anomalistic period, tropical period (for Earth).

The most generic method for orbit simulation we came up with in Orekit is the propagator interface. At the generic level, the only thing that is common to all implementation is to select the target date (the sole argument to propagate). Everything else depends on the propagation model, including how you specify the initial state, even if this is shared among several propagators).

Thank you so much @luc for so detailed explanation!
Now I need time to find how to apply this knowledge to my task.
I’m sure I’ll return back a little bit later with more questions.