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.