Keplerian propagation: unexpected behaviour after frame transformation

Hi all,

I experienced some unexpected behaviour when using Keplerian propagation and would like to hear your thoughts on it.

I created a state in the ITRF Earth fixed frame and transformed it to the EME2000 inertial frame. Then I propagated the orbit using the KeplerianOrbit.shiftedBy function. To my surprise I found that the Keplerian elements had changed. This is the code example:

    double mu = 3.986004415E14;
    Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, false);
    Frame eme2000 = FramesFactory.getEME2000();

    TimeStampedPVCoordinates pvEcef =
        new TimeStampedPVCoordinates(
            new AbsoluteDate("2023-01-14T22:42:30.237", TimeScalesFactory.getUTC()),
            new Vector3D(-2357.775009e3, -1925.20993e3, -6189.552496e3),
            new Vector3D(3.458605866e3, 6.038439177e3, -3.199247621e3));

    TimeStampedPVCoordinates pvEme2000 =
        itrf.getTransformTo(eme2000, pvEcef.getDate()).transformPVCoordinates(pvEcef);

    // FIX: remove accelerations
    // pvEme2000 = new TimeStampedPVCoordinates(pvEme2000.getDate(), pvEme2000.getPosition(), pvEme2000.getVelocity());

    KeplerianOrbit initialKeplerianOrbit = new KeplerianOrbit(pvEme2000, eme2000, mu);
    KeplerianOrbit finalKeplerianOrbit = initialKeplerianOrbit.shiftedBy(120.);

These are the different initial and final Keplerian elements:

Initial: {a: 6875544.249458295; e: 0.0032270965468105955; i: 97.64328622028128; pa: -287.56208413055316; raan: 149.4091198503696; v: 172.5301089927054;}
Final:   {a: 6875849.201941159; e: 0.13424979381815902; i: 97.97354421887381; pa: -210.1994735314524; raan: 150.26917669507833; v: 102.7825955787309;}

I figured that the Keplerian propagation (shiftedBy) considers non-Keplerian accelerations if those are defined in the PVCoordinates of the orbit. This was the case due to the reference frame transformation that I had applied from Earth-fixed to inertial frame. The transformation introduced accelerations in the TimeStampedPVCoordinates instance. These accelerations were then considered during the Keplerian propagation, such the propagation was no longer Keplerian and the orbital elements changed.

I was able to fix it by setting pvEme2000 without any accelerations, see code block.
Possibly a better solution would be to use a KinematicTransform as discussed on this forum before (Improve Performance of Transform).
Or is there another better way to handle this issue?

For me this behaviour was unexpected. I’m curious to hear whether you think the behaviour is expected or not.

Best wishes,


I think one needs to be very careful when using shiftedBy methods. Their behaviour is different depending on the object (Orbit, TimestampedPVCoordinates, Covariance).
For Keplerian propagation, you should use KeplerianPropagator which wraps up the correct use of Orbit's shiftedBy.


1 Like

Hi @Serrof,

Ok, thanks for pointing this out. I’ll be more careful with the use of shiftedBy then and make use of the KeplerianPropagator.


1 Like

Just for completion, the documentation of the shiftedBy method states:

The shifting model is a Keplerian one if no derivatives are available in the orbit, or Keplerian plus quadratic effect of the non-Keplerian acceleration if derivatives are available. Shifting is not intended as a replacement for proper orbit propagation but should be sufficient for small time shifts or coarse accuracy.


I agree that given the documentation I should not have used the shiftedBy in the first place, my mistake.

I was mainly surprised because initially I used inertial vectors (without transformations) and the code worked fine. Then when I applied a transformation from ECEF to ECI first, the results were not as I expected. I did not expect that the transformation would add accelerations to the PVCoordinates (and that shiftedBy would consider these). I normally do not use the accelerations part of PVCoordinates, so I didn’t consider this aspect. Possibly the documentation of transformPVCoordinates can be more explicit about this.