Maneuvers package organization proposal

Dear all,

I wanted to propose a fitting organization for the forces.maneuvers package. This package is, in my opinion, currently a bit basic and lacking in Orekit.

This is not an enhancement I would think of adding to version 10.1 so there’s no rush and we have time to discuss it.

Motivations

  1. My first motivation is to implement a constant thrust maneuver where the thrust and direction can be estimated in orbit determination. With current maneuver package it would mean copy/pasting most of the code of ConstantThrustManeuver class (which for now can just estimate the thrust norm or the flow rate).

  2. @dorian wanted to contribute a variable thrust maneuver class. This implies adding a generic interface representing a thrust-based propulsion model (see the Variable Thrust Maneuver Model topic).

  3. @cbamann asked how to estimate and impulse maneuver (presumably ΔV based) in this topic. A proposed work around was to implement a very small thrust maneuver and do the conversion from ΔV to thrust by hand. But I guess we could do better, especially if the user wants to estimate the 3 components of the ΔV or retrieve the covariances associated with the ΔV.

  4. For now our unique maneuver force model (ConstantThrustManeuver) is based on built-in date detectors. For station keeping purpose a user could want to have detectors based on orbital events, with a thrust value, direction and duration that could be optimized with a batch least-square algorithm. Or a user could want to detect an impulse maneuver, estimating its ΔV and date through an orbit determination…

There are many use cases that we fail to cover with the current maneuvers’ package and I would like to propose an architecture that would attempt to correct this, or at least lay the first stone that will help improve this in the future.

Current maneuvers package architecture

For now the maneuvers package has the following classes:

  • ImpulseManeuver: this is actually a detector for impulse maneuver, not based on the ForceModel interface. It’s convenient but cannot be used to estimate maneuvers in orbit determination;

  • SmallManeuverAnalyticalModel: this is an analytical model for small maneuvers; it doesn’t implement the ForceModel interface;

  • ConstantThrustManeuver: a constant thrust maneuver with DateDetectors for start/end date and the possibility to estimate either the thrust norm or the flow rate. It implements the ForceModel interface.
    It is mainly that model that I’d like to enhance.

Draft architecture proposal

I would like to not introduce APIs changes so that we could release something in a minor version (say 10.2).
My idea would be to create a generic Maneuver class that has 3 attributes:

  1. An AttitudeProvider (may be null) that will override the current Spacecraft attitude to allow for a dedicated maneuver attitude. It is actually needed for compatibility reason with current ConstantThrustManeuver class.

  2. A PropulsionModel object that will hold everything that is propulsion related: thrust, deltaV, isp, flow rate etc. and the corresponding parameter drivers for estimation with a batch least-square or a Kalman filter.
    This will allow users to implement their own propulsion model, constant or variable, thrust or ΔV-based; and their own paramers for estimation.
    This PropulsionModel will help covering points 1, 2 and 3 in the Motivations part of this post.

  3. A ManeuverTriggers object that will contain the start and stop triggers for the maneuver. These triggers can be based on EventDetectors. They can also hold specific parameter drivers that would be used in estimation; for example to optimize a thrust duration, or estimate a maneuver date given satellites’ measurements.
    This ManeuverTriggers aims at covering point 4 in the Motivations part of this post.

The Maneuver class doesn’t hold any physical data, it is an orchestrator.
It provides generic implementations for the methods acceleration, addContribution, getEventDetectors and getParameterDrivers of the ForceModel interface.
These generic implementations calls dedicated methods in the PropulsionModel and ManeuverTriggers that will do the actual computations and have to be developed by the user.

I pushed a maneuver-package branch on the git repository to propose a first implementation of this architecture.
(It is not up to date with the latest commit on develop branch since it doesn’t contain the data-context enhancement written by Evan. But this won’t be an issue and I will do it later on).
It covers only point 1 for now… and is not tested.

The class diagram below illustrates its content. Sorry if it’s in a shambles but I struggled with PlantUml and since it’s not definitive I don’t want to spend hours making it super clean :wink:.
I added some variable thrust related classes to show where they would interface.
I removed the Field-based methods for readability but they exist.

This is just a draft. It is organized as follows:

  • Maneuver class is the orchestrator

  • The trigger package contain the maneuver triggers objects:

    • Interface ManeuverTriggers gives the methods needed to implement the triggers
    • Class DateBasedManeuverTriggers reproduces the existing behavior of ConstantThrustManeuver, i.e. the maneuver is defined by a start date and an end date. It does not contain any parameter driver.
      For now this is the only available maneuver triggers object.
  • The propulsion package contains the propulsion model objects:

    • Interface PropulsionModel gives the methods needed to implement a propulsion model
    • Interface ThrustPropulsionModel defines methods for a thrust-based propulsion model and computes the acceleration and mass derivatives given current thrust vector and flow rate
    • Class AbstractConstantThrustPropulsionModel specializes a ThrustPropulsionModel for a constant thrust. It mainly removes the dependency to current SpacecraftState in thrust vector and flow rate computations.
    • Class BasicConstantThrustPropulsionModel extends previous class and is used to reproduce the behavior of existing ConstantThrustManeuver. It can estimate the thrust norm or the flow rate.
    • Class ScaledConstantThrustPropulsionModel extends abstract class above and has 3 parameter drivers that are scale factors for the thrust on S/C X, Y and Z axis. It allows for a 3-D estimation of the thrust.
    • Class VariableThrustPropulsionModel implements interface ThrustPropulsionModel and holds the model for a variable thrust maneuver. It has to be implemented.
  • ConstantThrustManeuver class is a rewritten version of the existing class. It takes a DateBasedManeuverTriggers and an AbstractConstantThrustPropulsionModel as argument. With this it can have all the previously defined public method (for compatibility reasons) and the user can use its own custom constant thrust propulsion model.

  • VariableThrustManeuver class has to be implemented. It would take DateBasedManeuverTriggers and a VariableThrustPropulsionModel as arguments.

Once again, a draft implementation is available on the maneuver-package branch for those of you who want to check it out.

@dorian: would this architecture be ok for the variable thrust propulsion model you wanted to add ?

To all: what do you think of this ? Would you be interested in that feature ?
I’m very open to changing the architecture and/or the names of the classes. And I’m not an expert in class designing, so feel free to comment and criticize !

Maneuver triggers package is very small for now but it could grow in the future.
I had other classes ready for propulsion model package, mainly ΔV based models, but they made the UML diagram look so ugly that I just dropped them for this post.

I’m realizing I’ve started written a novel so I will stop my post here.
Thank you for reading all this, and sorry for its length.

Cheers,
Maxime

Dear Maxime,
I fully agree with your proposed architecture, as this is a way to organize several needed features. As a matter of fact I’m currently operationally using a variable thrust maneuver implementation (loosely based on ConstantThrustManeuver) to deal with GTO-GEO transfers with low thrust. A more systematic and general approach to maneuvers is for sure something I’m very interested in, and we (my team and myself) are willing to contribute as well.
Cheers - Glauco

Hi Maxime,

This new package organization looks very good. This is a great new feature for Orekit !
I quickly looked at the maneuver-package branch and the new package organization is easily understandable.

Bryan

Dear Maxime,

Thank you for your work on this problem. It looks very good to me. From our experience, may I suggest three modifications:

  • For the ScaledConstantThrustPropulsionModel, I am wondering if it would be more suitable to have one driver corresponding to a scale factor to the thrust norm, and two drivers corresponding to angles. That would solve the three axis of the thrust as well, but I assume a better behavior of the estimator as it is more linear, and as it corresponds to something we actually see in operations.
  • I think there is no need to have the acceleration and mass derivative computed in ThrustPropulsionModel. I think it is actually the role of the maneuver. Therefore, you do not really need to have the interface ThrustPropulsionModel. You could have an interface PropulsionModel with the methods init, getThrustVector, getFlowRate, getParameterDrivers and getName. The maneuver would then use these method to evaluate getAcceleration and addContribution.
  • With this architecture, there is no need to have a class VariableThrustManeuver as it would be a Maneuver with a specific PropulsionModel

Again, these are just suggestions, maybe there is something I did not understand in your design that makes my suggestions wrong.

Thanks again for your help on this subject.

Hi @dorian,

Thank you for your suggestions.

  • ScaledThrustPropulsionModel: I totally agree with you. I need these scale factors for a specific project, that’s why I proposed this one. But a factor for the thrust and 2 angles are indeed more physical.
  • ThrustPropulsionModel: My idea was that we could want to define maneuvers with something else than thrust and flow rate, ΔV for example. But I guess that whatever the model used it will get down to computing at some point the thrust and the flow rate…

I’ll wait a bit for other developers to give their opinion or suggestions and I’ll do the changes you propose in the maneuver-package branch.

Maxime