Additional information in Orbit object to know the type (mean or osculating)

Hi all!

Currently, there is no information in Orbit object to know if the orbit is a mean one or an osculating. However, there is a lot of area in Orekit where a model is able to generate both:

  • DSST
  • Eckstein-Hechler
  • Brouwer-Lyddanne

Therefore, I think it could be useful to add this information in Orbit object. What do you think?

I don’t know what’s the better solution between a boolean or a new enumerate.
I like the enumerate solution, but there is already an enumerate about the orbit type (i.e., circular, cartesian, etc.).
So, I think having a boolean isMeanOrbit is maybe the better solution

Thanks!
Bryan

Hi Bryan,

I also think it would be a worthwhile addition and i like the enumerate idea. We could maybe create an OrbitPropagationType instead ? This way we would be able to differentiate several kind of mean orbit type if we wanted to and even implement the “isMeanOrbit” method you are suggesting.

Cheers,
Vincent

There is already an enumerate for that: org.orekit.propagation.PropagationType, which was created by some random guy named… Bryan :rofl:

1 Like

Hello,

We do already have the enumerate PropagationType so we should probably use it. What do you think?
The name is not very meaningful in the “orbit” case but we can change that in a major release.

The advantage of the enum compared to the boolean is that if we do extend it with say a “SECULAR” propagation type then we won’t have to change everything.
That being said, new propagation types are not planned yet, so if you prefer a boolean then I’m not against it.

Cheers,
Maxime

Hi all,

I think we need to be extra careful here. “Mean” orbit means nothing specific, as there are many possible theories behind this word, which can be single or double averages by the way. Moreover, a “mean” CartesianOrbit is a complete heresy. Actually, changing frame or coordinates on a mean orbit is not rigorous: they’re both usually linked to the theory. Converting a single orbit between theories should be done via osculating sets.

In my opinion, the enum PropagationType already does the job and should not be put into the (Field)Orbit class. When it’s used by a propagator, there is no ambiguity as to which theory it refers too, thanks to the propagator itself. It’s the responsibility of the user to keep track of what kind of things he’s giving and getting.

We could go further and want to handle definition and conversions between averaging theories. But that’s a real endeavour and should be done at higher level than (Field)Orbit and its inheritors, which are already classes with too many responsibilities from an architecture point of view

Best,
Romain.

1 Like

That’s a good observation :rofl:
In fact, I don’t like the name of this class because it is used for both defining the propagation type of DSST and the initial state type of the DSST… At that time, I was a young Orekit developer :sweat_smile:
To my mind, having 2 different enumerates can improve the understanding.

+1 For instance Brouwer-Lyddane can propagate in 3 different modes : secular, mean or osculating.
I hope that one day we will be able to have these 3 different modes…
Do we have an issue open about that?

I 100% agree. The advantage of the enum is that we can have different entries for mean orbits BROUWER-LYDDANE_MEAN, ECKSTEIN_HECHLER_MEAN, DSST_MEAN

Yes, but I hope that people doing flight dynamics are aware about that thing. In other words, It is, to my mind, it is the responsibility of the user to use this feature carefully with CartesianOrbit.

Implementing a converter could be an interesting feature. This is even something we can add in the enum with a method getOsculatingOrbit(Orbit meanState) implemented by all the entries.
For instance, for DSST_MEAN we can have:

DSST_MEAN() {
   public Orbit getOsculatingOrbit(Orbit meanDsstOrbit, ...) {
        return DSSTPropagator.computeOsculatingOrbit(meanDsstOrbit, ...);
}

I agree that a user can call the method with a different mean orbit. That’s why we have to take care of the JavaDoc.
Or, we can add a check:

if (MeanElementsTheory.DSST_MEAN != meanDsstOrbit.getMeanElementsTheory()) {
   throw ...
}

I actually think that it’s a perfectly fine and natural behaviour.

Such an enum cannot reasonably be an attribute of Orbit from a design point of view. For example, DDST averaging works only with equinoctial elements and mean anomaly. But an Orbit can be of any OrbitType (or PositionAngleType if applicable). We cannot possibly check for that there. Remember that Orbit is used in propagation, it cannot afford to do more checks and computations that necessary. So again, I strongly advocate that we should keep it at a higher level.

We can probably trust people on that one. However, I think in general, the notion of mean orbit is somewhat intuitive by analogy, making people overconfident of their understanding of it. It’s actually very involved mathematically and full of subtilities. It’s basically a field within the field of orbit propagation.

That’s something we’ve been thinking about doing at Exotrail as a layer over Orekit. Since it is relatively low level, maybe we can formalize it and contribute.

Best,
Romain.

Hi all,

I think I agree with @Serrof on not adding mean/osculating info to the Orbit class.

I would say that Orbit represents a state in a dynamical system. This state can be represented using different coordinates or orbital element sets (they all represent the same state). Currently, Orbit does not contain any information on the dynamics, e.g. force model (except for mu). I think this is good, because it keeps the Orbit separate from the dynamics.

Introducing mean/osculating information would link the Orbit to the dynamics. The transformation from mean to osculating (and vice versa) depends on the averaging theory and on the forces considered in the transformation (for example SGP4 consider J2-J4 for propagation but only J2 for mean-osculating conversion).
If such dynamics information is desired in Orbit, it would make sense to add all force model and mean-osc conversion information. But I’m not sure if that is desired.

Best regards,
David

+1 for anything that lets me get both mean and osculating states out of a single propagation. Then I can stop propagating the same state twice and hoping all the integration steps line up. That would be a big improvement.

I agree with Romain and David that mean elements are specific to the model, and I’m -1 for any “automatic” conversions.

A small improvement would be including in SpacecraftState or Orbit whether it is mean or osculating so that I don’t have to keep passing around a isMean boolean with the SpacecraftState. I know there are complexities, but I’ve hit bugs in my code several times because I lost track of whether a specific SpacecraftState was mean or osculating elements. Though one could argue that I have poor code design to have that issue in the first place…

Hi Evan,

beyond the fact that a simple boolean is very ambiguous when it comes to the “mean” property of orbital elements, putting such an attribute in SpacecraftState would lead to even more problems: this class does not require an Orbit object to work, it can use an AbsolutePVCoordinates, which is astrange to the notion of averaging. That actually brings up another issue in my opinion: SpacecraftState should probably be abstract and have two inheritors. But that’s another debate…

At the moment, I believe only the DSST propagator can output orbits that are not osculating. Analytical models like Brouwer-Lyddane use mean orbits under the hood, but they remain unaccessible. So a nice feature would be the possibility to output them. Again, for me, it’s up to the user to know where their Orbit comes from in Orekit. If it’s from propagate of (Field)AbstractIntegratedPropagator, it’s easy to know if it is mean (in the sense of that very object) or not, via getPropagationType, which we could generalize.

Best,
Romain.

Yes, but not any more ambiguous than SpacecraftState already is. When I add a step handler to DSST the step handler can’t tell whether it’s getting mean states or osculating states from the propagator. That’s extra information that needs to be passed in. It would be nice if I didn’t have to pass isMean to the step handler for it to figure out whether it has a mean or osculating state. But, like I said, that is fairly minor.