From Osculating to Mean Elements with Brouwer-Lyddane Propagator

Hi Orekit community
I am trying to convert from my TLE SpacecraftState into mean Keplerian elements, using the BrouwerLyddanePropagator. It has an implemented method: computeMeanOrbit, that, according to my understanding, will give back the Orbit object, with mean Keplerian elements.
Unfortunately, I am encountering some issues: it fails the convergence if I give not the starting state from TLE, but a propagated one.

Here the example:

long start = 1613870730000L;

/* TLEs of the satellite */
TLE tleOrbit = new TLE
            "1 43196U 18015E   21055.59816856  .00000894  00000-0  38966-4 0  9996",
            "2 43196  97.4662 188.8169 0016935 299.6845  60.2706 15.24746686170319");
Propagator propagator = TLEPropagator.selectExtrapolator(tleOrbit);
    
//Get state at initial date and 3 days before
SpacecraftState tleState = propagator.getInitialState();
SpacecraftState tleStateAtDate = propagator.propagate(Time.getAbsoluteDateFromTimestamp(start));
    
//BL mean orbit
double epsilon = 1.0e-12;
int maxIter = 500;
UnnormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getUnnormalizedProvider(7, 7);
Orbit meanOrbitOK = BrouwerLyddanePropagator.computeMeanOrbit(tleState.getOrbit(), provider,
provider.onDate(tleState.getDate()), BrouwerLyddanePropagator.M2, epsilon, maxIter);
Orbit meanOrbitKO = BrouwerLyddanePropagator.computeMeanOrbit(tleStateAtDate.getOrbit(), provider,
provider.onDate(tleStateAtDate.getDate()), BrouwerLyddanePropagator.M2, epsilon, maxIter);

where

public static AbsoluteDate getAbsoluteDateFromTimestamp(long timestamp) {
    LocalDateTime utcDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), UTC_ZONE_ID);
    val year = utcDate.getYear();
    val month = utcDate.getMonthValue();
    val day = utcDate.getDayOfMonth();
    val hour = utcDate.getHour();
    val minute = utcDate.getMinute();
    val second = utcDate.getSecond();
    val millis = utcDate.getNano() / 1e9;
    return new AbsoluteDate(year, month, day, hour, minute, second, TimeScalesFactory.getUTC()).shiftedBy(millis);

Here the error:

invalid parameter eccentricity: -0 not in range [0, ∞]
org.orekit.errors.OrekitException: invalid parameter eccentricity: -0 not in range [0, ∞]
	at app//org.orekit.orbits.KeplerianOrbit.checkParameterRangeInclusive(KeplerianOrbit.java:1624)
	at app//org.orekit.orbits.KeplerianOrbit.<init>(KeplerianOrbit.java:206)

Do I make something wrong?
Thanks in advance!
Alberto

Hi @alberto-ferrero

That’s a strange behavior because we added a check in the method to prevent negative eccentricities.
Could you try using the computeMeanOrbit method of the EcksteinHechlerPropagator?
It should give you very close results.

I have to check for the Brouwer Lyddane method but unfortunately I don’t have my computer now :sweat_smile:

Best regards,
Bryan

Hi Brian
Thanks for coming back to me quickly.
I think the error I see is for the check on the eccentricity.

I do confirm indeed that the I don’t have any issue with same scenario but with EH propagator.

//EH mean orbit
double epsilon = 1.0e-12;
int maxIter = 500;
UnnormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getUnnormalizedProvider(7, 7);
Orbit meanEHOrbit = EcksteinHechlerPropagator.computeMeanOrbit(tleState.getOrbit(), provider,
provider.onDate(tleState.getDate()), epsilon, maxIter);
Orbit meanEHOrbitAtDate = EcksteinHechlerPropagator.computeMeanOrbit(tleStateAtDate.getOrbit(), provider,
provider.onDate(tleStateAtDate.getDate()), epsilon, maxIter);

Thanks
Alberto

Here another test, starting from a simple Keplerian orbit, same results:

  • EH OK
  • BL KO
long start = 1613870730000L;

double a = 6858137;
double e = 0.0;
double i = FastMath.toRadians(97.331);
double Om = FastMath.toRadians(138.05);
double om = 0.0;
double nu = 0.0;


KeplerianOrbit orb = new KeplerianOrbit(a, e, i, om, Om, nu, PositionAngle.TRUE, FramesFactory.getEME2000(),
        Time.getAbsoluteDateFromTimestamp(start), Constants.mu);

//BL mean orbit
double epsilon = 1.0e-12;
int maxIter = 200;
UnnormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getUnnormalizedProvider(7, 7);

Orbit meanEHOrbitOK = EcksteinHechlerPropagator.computeMeanOrbit(orb, provider,
   provider.onDate(orb.getDate()), epsilon, maxIter);

Orbit meanBLOrbitKO = BrouwerLyddanePropagator.computeMeanOrbit(orb, provider,
    provider.onDate(orb.getDate()), BrouwerLyddanePropagator.M2, epsilon, maxIter);

Hi @alberto-ferrero

I tried and it looks like a bug. I just have one question. Are you sure that your input orbit is an osculating orbit?

Best regards,
Bryan

Hi Bryan,
oh, do I need to open a bug ticket? It would be better I guess.

Regarding the Keplerian orbit, yes I am not really sure it corresponds to osculating elements. It might be not actually, but still the propagated state from the TLE should not cause issues as it is a ‘real’ case.
Thanks for the investigation
Alberto

I would like to perform more investigation of this issue. So, yes could you open an issue in our bug tracker? https://gitlab.orekit.org/orekit/orekit/-/issues
Also, could you put the link of this current forum discussion in the description of the issue?

Thank you,
Bryan

Ok, done :slight_smile:

Thanks!