Using NRLMSISE-00 with numerical propagator

I’m new to orekit and I’m currently trying to add the NRLMSISE-00 atmospheric model to my drag force model so i can propagate an orbit.Not sure how to implement it so that the integrator automatically gets the atmospheric density at the integration step epoch and altitude. My current approach is shown below.

// Drag
NRLMSISE00 atm = new NRLMSISE00(null, sun, earth);
IsotropicDrag spacecraft = new IsotropicDrag(area,Cd);
DragForce drag = new DragForce(atm,spacecraft);

Hi @dl00718

Welcome to the Orekit forum! :slight_smile:

Your implementation is close to be perfect. However, you missed the initialization of the provider for solar activity data. This provider is mandatory because it is used to retrieve the needed parameters used to compute the atmosphere density.

Orekit has two providers: MarshallSolarActivityFutureEstimation and CssiSpaceWeatherData. Please find below an example showing how initializing the first one.

final MarshallSolarActivityFutureEstimation msafe =
                            new MarshallSolarActivityFutureEstimation(MarshallSolarActivityFutureEstimation.DEFAULT_SUPPORTED_NAMES,
            final DataProvidersManager manager = DataContext.getDefault().getDataProvidersManager();
            manager.feed(msafe.getSupportedNames(), msafe);

The initialization of the other one is very close. Like that you can replace your null parameter by msafe

An important information. These two provider use external data. They are available in the orekit-data folder available here The orekit-data can be updated with the last available values using the script available in the folder.

I hope this will help you.

Best regards,

Hi @bcazabonne

Thanks alot for the help. So this is how i went about it. Is it right?
File orekitData = new File(“path to orekit data folder”);
DataProvidersManager manager = DataContext.getDefault().getDataProvidersManager();
manager.addProvider(new DirectoryCrawler(orekitData));
// Initialize Solar Activity Provider Data Provider
final CssiSpaceWeatherData cssi = new CssiSpaceWeatherData(CssiSpaceWeatherData.DEFAULT_SUPPORTED_NAMES,manager,timescale);

    // Drag
    final NRLMSISE00 atm  = new NRLMSISE00(cssi,sun,earth);
    IsotropicDrag spacecraft = new IsotropicDrag(area,Cd);

    DragForce drag =   new DragForce(atm,spacecraft);

I have another question, although it might be a silly one. When i use the tlePropagator.getInitialState() method, does it give a state vector computed from the oscullating orbital elements or do i get that after converting the tlePropagator to a numericalPropagator and calling numericalPropagator.getInitialState()?

Thank you


Yes, it looks good!

That’s not a silly question. Calling tlePropagator.getInitialState() will give you the osculating orbital state of the satellite according to SGP4 model, which is the dynamical model used to convert TLE to orbital state. Calling numericalPropagator.getInitialState() gives you the initial state of the numerical propagator. Just be careful that after an orbit propagation, the numerical propagator updates its initial state.
Now, if you initialized the initial state of the numerical propagator using the the results of tlePropagator.getInitialState(), it should give you the same result at time t = t0.


Hi Bryan,
Thanks alot for the explanation. So if i want to propagate an orbit from a TLE epoch to re-entry, there’s no need to convert the TLe propagator to a numerical propagator. Instead I should set up a numerical propagator and use the initial state from

as my initial state, set up an event detector, then propagate forward. Is that the right approach to take?

Thank you

Hi @dl00718,

I think you will get a large error by doing so.
See this former answer from Luc for more insights on why “instantaneous position given by a TLE propagator cannot be used as an initial orbit for another propagator, regardless of the model you use”.

You need to first convert the TLEpropagator to a NumericalPropagator, and then use this converted propagator to propagate until re-entry.
See this post or this tutorial for converting a propagator…

Hi @MaximeJ

Thank you for the clarification Maxime. I’ll implement it that way.

Hi @MaximeJ @bcazabonne,

I was reading through the FramesFactory class and it recommends not propagating in the TEME frame unless using the SGP4 propagator. Should i retrieve the initial state of the converted numerical propagator and rotate it to another frame like EME2000, then create a new propagator with the rotated initial state? Or is it alright to use the converted numerical propagator in the TEME frame.

You don’t need to, just transform the initial state and use propagator.resetInitialState(myNewState)

As you read it it’s not recommended so I would avoid it.
I wasn’t aware of that, thank you for pointing it (the explanation is page 57 of the CCSDS ODM blue book mentioned in the Javadoc)
However, ince the frame is ambiguous, your initial state converted to EME2000 will still bear this ambiguity (since we’re not 100% sure how the original TEME frame you used should be defined). So this small uncertainty will be propagated through.
That being said, I would still follow CCSDS and Orekit recommendation of propagating in a non-ambiguous inertial frame like EME2000 or GCRF