Convert orbit to Keplerian

Hi everyone,

I was propagating with the following code:

orbit = KeplerianOrbit(
altitude,
ecc,
inc,
float(np.radians(180)),
float(np.radians(261)),
float(np.radians(0)),
PositionAngle.MEAN,
frame,
initial_date,
Constants.EIGEN5C_EARTH_MU,
)
initialState = SpacecraftState(orbit, float(sat_mass))
orbitType = OrbitType.EQUINOCTIAL
tol = NumericalPropagator.tolerances(1.0, orbit, orbitType)
integrator = DormandPrince853Integrator(
float(0.0000000000001),
float(1000),
orekit.JArray(“double”).cast_(tol[0]),
orekit.JArray(“double”).cast_(tol[1]),
)
integrator.setInitialStepSize(float(60))
propagator = NumericalPropagator(integrator)
propagator.setOrbitType(orbitType)
propagator.setInitialState(initialState)
propagator.setAttitudeProvider(LofOffset(frame, LOFType.VNC))

I was then trying to retrieve the keplerian parameters using:

    currentState = propagator.propagate(time)
    orbit = OrbitType.KEPLERIAN.convertType(currentState.getOrbit())
    print(orbit.getA())
    print(orbit.getPerigeeArgument())

Now getA() is working but getPerigeeArgument() is not. The error is

   AttributeError: 'Orbit' object has no attribute 'getPerigeeArgument'

Any thoughts on this would be greatly appreciated!

Hi Ben,

Just a quick, what is the type of your orbit? ( type(orbit) )

Sometimes one needs to cast types in the python version of orekit, this canin this case be done by:
orbit = KeplerianOrbit.cast_(orbit)

It is easier to troubleshoot if you post a cut-n-pastable test code / link to code.

Greetings,

Hi Petrus,

Thank you for your response, this did indeed solve the problem. Perhaps I misunderstood, but I thought

orbit = OrbitType.KEPLERIAN.convertType(currentState.getOrbit())

would be sufficient?

Thanks again,
Ben

I am not sure about the Python side, but on the Java side there is already a glitch here which is due to a limitation in Java.
The OrbitType is an enumerate and its fixed elements (CARTESIAN, CIRCULAR, EQUINOCTIAL and KEPLERIAN) all override the convertType method. The return value of convertType is declared as a generic Orbit at the OrbitType enumerate level, and is specialized for each element (for example the return type of CARTESIAN.convertType is declared to be CartesianOrbit, the return type of KEPLERIAN.convertType is declared to be KeplerianOrbit). Despite this, it seems that when someone calls the method, the compiler sometimes does not sees the specialization and still considers the return type is only the generic Orbit. The generic Orbit class does have getA, getDate, getE and many other methods because they can be implemented for all orbit types, but not for example getPerigeeArgument() because it would not be defined for CircularOrbit.

So despite it seems odd, you may sometime have to cast the return by yourself, because you are assured that KEPLERIAN.convertType will return a KeplerianOrbit, but the compiler does not understands it.

2 Likes

Thank you for this clear explanation, it’s really appreciated!

On the Java side that oddity is addressed by Sealed Classes in Java 17. But it will probably be a while until we can use it because support for Java 8 runs through 2030.