Template orbit is confusing in propagator builders

I just encountered a problem with propagator builders.

AbstractPropagatorBuilder uses a template orbit to set up some metadata that will be used later on each time its build method is called for building the initial state for a new propagator. Currently, the AbstractPropagatorBuilder constructor extracts the date, frame, mu, orbit type and from the orbit type it extracts the parameter drivers. It also provides getters for these elements, as required by the PropagatorBuilder interface.

This does not work for GNSSPropagatorBuilder and GNSSPropagator. GNSSPropagator uses specific parameters which look a lot like KeplerianOrbit but are really not KeplerianOrbit as they are defined with respect to a rotating Earth frame (the ascending node is a longitude, not a right ascension). There are no OrbitType for these, and the orbital parameter drivers are specific. The solution I used when merging GNSSPropagatorBuilder into the PropagatorBuilder hierarchy (see issue 1850) was to use a first throw-away GNSSPropagator in GNSSPropagatorBuilder to get the template orbit from the initial orbit generated by GNSSPropagator. This doesn’t work in practice, because GNSSPropagator outputs CartesianOrbit (which are orbits, as required by AbstractPropagatorBuilder), but CartesianOrbit has nothing to do with the not-really-keplerian orbital parameters input (GNSSPropagator input and output are different types…).

So I was wondering if we could replace the template orbit in AbstractPropagatorBuilder constructor by a new OrbitBuilder interface that would have the getters for date, frame, mu and the mappers to and from arrays (but not orbit type) and use that in PropagatorBuilder getters and in AbstractPropagatorBuilder constructor. We could either have dedicated KeplerianOrbitBuilder, CircularOrbitBuilder… or have all orbit implement the builder for their own type. This way, existing code using a real template orbit for building a propagator builder would still work and GNSSPropagator could use a dedicated implementation that does not rely on Orbit and OrbitType. The only drawback would be the getOrbitType and getPositionAngleType would disappear from the PropagatorBuilder interface.

What do you think?

[edit] in fact, we could keep orbit type and position angle type in OrbitBuilder, I can think of a way to make it work with GNSSPropagator with some internal orbit conversion.

1 Like

Perhaps rather than a Builder pattern, a non-static factory?

I have something analogous to this in an application:

public abstract class OrbitFactory<O extends Orbit> {
    
    private final Frame frame;
    
    private final double mu;
    
    protected OrbitFactory(final Frame frame, final double mu) {
        this.frame = frame;
        this.mu = mu;
    }
    
    public abstract O toOrbit(final double[] orbElts);
    
    // etc.
}

The difference in this context is minimal, but I’ve found the factory impls. to be very convenient when my mu and Frame are effectively constant for some application.

Hi guys,

I’m late to the battle and what I’m going to say may be a bit off topic, but I’m gonna say it anyway lol

From a software architecture and code logic point of view, at the moment the (Field)Orbit class has two main responsibilities:

  • data container since it contains a date, a frame, a gravitational constant, a representation of positon and velocoty
  • functionality/algorithm with coordinates conversion, Jacobian computation, simple propagation

And it’s probably too much. Because it makes the code less clear and harder to unit test (and also less straightforward to use i think). Don’t get me wrong, I’ve participated to this, even though I’ve tried to use class composition more to delegate to other classes so that at least the code is less monolithic.

Now, with modern Java and the record object, we should be able to make something cleaner for the data container needs.
I strongly suggest that after the next patch release, we switch to Java 21 on the develop branch so that we can start making good use of these types of pattern

About the topic at hand, I offer no specific guidance beyond to keep what I’ve said in mind

Cheers,
Romain.

1 Like