Estimating drag in a batch least squares estimator

I am using the BatchLSEstimator with the GaussNewtonOptimizer and I would like to include drag as one of the quantities to be estimated. Is it possible to do this? If so, could you point me to some sample code or resources to get started? Thanks!

Hi @knkiers , welcome to the forum

Yes, it is a classical feature.
You can look at the code of the AbstractOrbitDetermination abstract class and the NumericalOrbitDetermination class that extends it in the tutorials. You will see that for many force models that can be used (including drag), the force can be added to the propagator, which will make the propagator aware it must add the corresponding acceleration, and its specific ParameterDriver instances can be added to the estimator, making it aware it may include them in the list of estimated parameters.

The fact a ParameterDriver is estimated or not depends on a flag in it that can be set using its setSelected method. By default, the parameters drivers corresponding to the orbit are all estimated, and none of the parameters drivers corresponding to the force models are estimated. If you want to estimate a drag coefficient, you therefore have to recover the parameter driver using its name, and select it. You have to know its name, but they are public constants, so are easy to find.

In the tutorials, this is driven by specific logic with a boolean in the input file (the cdEstimated variable that appears in AbstractOrbitDetermination class). In your code, one way to do it would be use

  ParameterDriver dragDriver = propagatorBuilder.

This must be done before the estimation is started, of course.

Once the estimation finishes, you can retrieve the value by calling dragDriver.getValue(), this will give you the last value that was assigned to it. You could also retrieve it by retrivieng again the parameter driver in the force model, or in the propagator builder, or in the estimator, they will all finally point to the same driver. Youn could even monitor it during estimation by registering a ParameterObserver (calling dragDriver.addObserver()before the estimation, and your observervalueChanged` method will be called each time the estimator attempts to set a new value to the drag coefficient, even during the estimation.

Hi @luc – thank you for the helpful reply! My colleague and I have attempted to implement the approach that you outlined, but the dragDriver that gets returned appears to be of None type (we are using the python wrapper). We suspect that the propagator that we are using might not support adding the drag force. My colleague (@separnell) will be posting a message as well with more details. Thanks so much for your help!

Hey @luc,

I am working with @knkiers on this project and am attempting to implement the Drag Coefficient you discussed. However, when I attempt the .setSelected(true) function on the dragDriver it returns the error

AttributeError: 'NoneType' object has no attribute 'setSelected'.

We are using the numerical propagator builder with the DormandPrince853IntegratorBuilder, might there be a problem with our particular propagator builder not including this? Or is there a package we need to import to access the Drag Coefficient?

In addition, we are using the IOD Gibbs method to create an initial orbit guess. Is there a way to add air resistance to this as well?



Did you added a DragForce to your numerical propagator builder?
If not, what you have is a normal behavior because it can’t find the drag driver if no drag force model is added to the propagator. So, you shall add one.

Best regards,

You could also try findByName(DragSensitive.DRAG_COEFFICIENT)
(i.e., without the " ")


Thanks for the quick response!

Is that this thing from the Numerical orbit determination link provided by Luc?

I did attempt to implement this but had issues with defining the drag sensitive spacecraft. I have spacecraft state objects, but in reading the documentation I was unable to find where to define a dragSensitive spacecraft.


DragSensitive is an interface used to represent the geometry of the spacecraft for the drag perturbation. It has two implementations: IsotropicDrag assuming that the spacecraft is spherical and BoxAndSolarArraySpacecraft assuming the spacecraft is a box with solar panels. For a first use, I strongly recommend to use the IsotropicDrag implementation. Please find an example below showing how to initialize a DragForce.

final double       cd          = 2.0; // Use your value
final double       area        = 1.0; // Use your value
final boolean      cdEstimated = true; // You want to estimate it

// Atmosphere model
final MarshallSolarActivityFutureEstimation msafe =
                            new MarshallSolarActivityFutureEstimation(MarshallSolarActivityFutureEstimation.DEFAULT_SUPPORTED_NAMES,
final DataProvidersManager manager = DataContext.getDefault().getDataProvidersManager();
manager.feed(msafe.getSupportedNames(), msafe);
final Atmosphere atmosphere = new NRLMSISE00(msafe, CelestialBodyFactory.getSun(), centralBody);

final DragForce drag = new DragForce(atmosphere, new IsotropicDrag(area, cd)), Constants.WGS84_EARTH_MU);

for (final ParameterDriver driver : drag.getParametersDrivers()) {
    if (driver.getName().equals(DragSensitive.DRAG_COEFFICIENT)) {
        if (cdEstimated) {

You can find additional information on the following discussion:

Best regards,

Thanks again for your response! I have another question/ comment about a potential bug.

When I try the function

from org.orekit.forces.drag import MarshallSolarActivityFutureEstimation

I get a cannot import error. This is the module that the documentation says this package is from, though I have also tried a few other similar modules like


to which I get an error that the module doesn’t exist.

MarshallSolarActivityFutureEstimation is in package

Thanks for all of your help! Much appreciated!