How do i increase the accuracy of my Numerical Propagator?

Hey everyone, im new to orekit and i have been trying to develop a numerical propagator for a LEO with really accuracy ( within hundredths of meters) after around 4 days of propagation . The existing code i have developed so far , the error builds up to around 15kms. If there are any suggestions on how i can improve the accuracy and bring down the error i would really appreciate it .
Here’s the details along with code snippets .
Input Frame TOD & Orbit Type Cartesian Orbit :

        self.earth_frame = FramesFactory.getITRF(IERSConventions.IERS_2010, False)
        self.earth = OneAxisEllipsoid(Constants.IERS2010_EARTH_EQUATORIAL_RADIUS,Constants.IERS2010_EARTH_FLATTENING, self.earth_frame)
        
        self.tod_frame = FramesFactory.getTOD(IERSConventions.IERS_2010, True)
        #Orbit Type and sattelite initial state 
        self.init_orbit = CartesianOrbit(self.pv_coord, self.tod_frame, self.startDate, self.mu)
        self.init_state = SpacecraftState(self.init_orbit, self.mass)

        #Setting up Integrator : Dormand Prince 853 Integrator ,Rangge Kutta 8th order
        self.orbitType = OrbitType.CARTESIAN

Propagator Tolerances :

        self.minStep = 0.001
        self.maxstep = 60.0
        self.initStep = 30.0
        self.positionTolerance = 0.1e-3
        self.tol = NumericalPropagator.tolerances(self.positionTolerance, self.init_orbit, self.orbitType)
        self.integrator = DormandPrince853Integrator(self.minStep, self.maxstep, 
            JArray_double.cast_(self.tol[0]),  # Double array of doubles needs to be casted in Python
            JArray_double.cast_(self.tol[1]))
        self.integrator.setInitialStepSize(self.initStep)

        #Setting up Propagator
        self.propagator_num = NumericalPropagator(self.integrator)
        self.propagator_num.setOrbitType(self.orbitType)
        self.propagator_num.setInitialState(self.init_state)

Models :

  • Gravity Provider using Holmes Feather Stone (Deg 180, Oder 180)
  • Occulting Body for Moon
  • Third Body Attraction for Sun & Moon
  • Atmospheric Drag and Solar Radiation Pressure
        self.atmos = NRLMSISE00(self.cswl,self.sun,self.earth)
        drag = IsotropicDrag(self.atmos_area, self.atmos_coeff)
        self.atmos_drag = DragForce(self.atmos,drag)
        self.propagator_num.addForceModel(self.atmos_drag)

        #Solar Radiation Pressure
        self.umbra = ConicallyShadowedLightFluxModel(Constants.SUN_RADIUS,self.sun, Constants.IERS2010_EARTH_EQUATORIAL_RADIUS)
        self.srp_model = IsotropicRadiationSingleCoefficient(self.solar_area, self.solar_coeff)
        self.solar_radiation = SolarRadiationPressure(self.sun,self.earth, self.srp_model)
        self.propagator_num.addForceModel(self.solar_radiation)

        t = [self.startDate.shiftedBy(float(dt)) \
                    for dt in np.arange(0, self.duration, self.step_time)]
        self.prop_val = [self.propagator_num.propagate(tt) for tt in t]

Any Suggestions for improvements / Suggestions would really help.
Thanks in Advance.

From a quick glance, I don’t see obvious errors there.
What is your step_time? I would suggest that instead of performing by yourself a loop with step_time, you propagate just once from start to finish, using a step handler to pick up the intermediate states. It will be much faster, and maybe it will help with the accuracy, in case your step-time is too low (because there are some resets between separated propagations).

In your case, I would expect a few meter-level errors at most. 15km is huge.

Also check the frame, is it really TOD? This legacy frame is not used very often.

Hi @luc thank you for the response.
Yes the frame really is TOD.
My step time is 30 secs. Could you please give me an example on how to implement the step handler for a numerical propagator if you don’t mind as i wasn’t able to get it working .
Also i was looking towards adding the following to the propagator too but wasn’t able to find enough resources to implement them. Would really appreciate the help.

  • How do i add BoxAndSolarArraySpaceCraft ?
  • ConicallyShadowedLightFluxModel
  • How do i add fixed step handler
        self.umbra = ConicallyShadowedLightFluxModel(Constants.SUN_RADIUS,self.sun, Constants.IERS2010_EARTH_EQUATORIAL_RADIUS)
        # How do i add this to my Solar Radiation ??

Hi there,

What’s your reference when you say the error is 15km?

Cheers,
Romain.

Hi @Serrof
I have Leo sat data of around 4 days (TOD Frame) im propagating from its initial value and then finding the euclidean distance which is then plotted .

Ok so we’re talking real data here. Without parameter fitting, i thinks it’s plausible to have this type of differences over this timespan in LEO. Have you tried performing some orbit determination?

So does this mean the output is feasible ?
As for the orbit determination no i haven’t done any.
I still would like to implement the BoxAndSolarArray and other models mentioned earlier if possible.

About how to use some objects, you can check out the unit tests for these classes:

I see that you’re using Python. Which wrapper do you use? JCC or jpype ?

I’m making use of the jcc wrapper. Also i noticed that the error increases drastically after completing an orbit. Does this have to do with the way I’m propogating ? Will using the fixed step handler help?? I wasn’t able to find much resources regarding the handler.

Hi @Ashish,

Here’s a Java tutorial for StepHandler usage (implementation of a custom step handler is at the end of the file).

And here’s a Python example of how to subclass PythonOrekitFixedStepHandler with the wrapper (go to cell 14 in the Jupyter notebook).

Hope this helps,
Maxime

Note that using a step-handler to get the state every 30s won’t change anything to the propagation itself