Optimization of the Orbit Determination

Hi all,

I’m trying to use the orbit determination tutorial in order to see if Orekit could be used in place of other software (software from GMV in my case). I rewrote and reorganized the code in order to make it more understandable and maintainable but didn’t touch the core of the orbit determination.

My problem is that the OD takes a lot of time to compute : when it takes 30-60s max to compute in GMV, it can take up to 1800s in Orekit with the same data (1240 AzEl measurements distributed on 10 days).

I tested with different number of measurements (from 400 to 2000) and different distribution in time for the measurements (measurements distributed on 2 days or on 5 days).
What seems to matter is only the period of time : the computing time was of ~17s per evaluation for the 2 days period (~8.5s/evaluation/day) while it was of ~55s for the 5 days period (~11s/evaluation/day).

My question is : what can I do to optimize the OD computing time ? Do you have any idea of modifications in the code itself ? In the parameters ? Is it possible the use some parallelization ?

Annex question : how will the DSST OD work ? What will it use ?

Thanks in advance ! :slight_smile:

Hi @nrol

What do you mean by reorganized the code? Maybe your computation time issue comes from the code reorganization. I don’t know the privacy of what your have done but is it possible to have some examples of your reorganizations ?

For the DSST OD it will work in the same way as the Numerical OD but with the possibility to choose between return the mean elements or the osculating elements. This choice will be made by the user at the creation of the propagator used for the OD.

Bryan

We also have orbit determination examples where convergence is reached in a few seconds, so without
more information, we cannot guess what is wrong.
What you should look at are the force models (in particular for gravity field degree and order, or for surface forces modelling), propagator settings and convergence criterions.
If you have a few iterations that take a lot of time to compute, it is more likely to be force modelization or propagator settings that are the culprit, if you have a lot of iterations, it is more likely a problem of convergence criterion.

For propagation settings, let the integrator lots of freedom for selecting the step size (i.e. don’t put a max step too low as it would greatly reduce performances).

Beware that the criterion in the tutorial is based on a non-dimensional number computed by scaling values with respect to their expected standard deviation. This means that convergence to 1.0e-3 is generally very
accurate. A common mistake is to put a convergence criterion to something like 1.0e-10 or below.

To add to Luc and Bryan’s posts Orekit would welcome contributions in the area of measuring performance and improving it.

Concerning the reorganization, the two main modifications are :

  • I find the code in the OrbitDetermination class too “heavy” and difficult to understand : everything is in this class with many local interfaces and classes used. So I moved those parts of the code in proper classes and interfaces.
  • Regarding the parameters, it’s the same, everything was in a single file while the parameters were about the stations, the spacecraft, the estimator, the forces, etc. So I divided it in 5 files corresponding to 5 categories of parameters (spacecraft, stations, universe, measurements, estimator).

So what changed is only the structure of the code in the data loading at the beginning of the algorithm. The core of the algorithm (the line with “estimator.estimate()”) did not change and that core is the part that takes a long time to compute.

Here is an archive with my code and the data folder I use :
orekit_and_data.tar.gz (2.9 MB)

In this archive, you will find :

  • orekit/ : contains the sources
    • I deleted the test/ folder in order to reduce the size of the archive
    • arianegroup/ : contains the new classes (it is separated in order to identitfy those new classes, it could be integrated in the main/)
    • the orbit determination main class is “AGSOrbitDetermination”, still in the tutorial estimation example package
  • java_data/ : contains the data. This folder should be put somewhere in the user’s home (the path is a parameter in my code). It contains the following folders :
    • libs : all the libraries used by Orekit
    • obs : where to put the measurement files
    • orekit-data : usual orekit-data folder with some added files (for the parameters). I deleted some usuel data folders here in order to reduce the size of the archive, you may want to put them back if you want to try the algorithm.
    • output : where the algorithm will write the different output files
    • tle : where to put the input tle used to initialize the orbit (if chosen)

A few classes in orekit/main/ have been modified, especially in order to generate the OPM and the TLE files.

As you will see in the parameters files, I used in majority the default parameters for the forces as for the propagator.
I just tried to put a higher max step for the propagator and the algorithm takes more evaluations to converge than with the default max step (>10 while it takes only 4 with the default value).

Feel free to test the algorithm and to tell me what I may want to modify in it, be it for optimizing the code or just for the code to be better.

Nota : I didn’t provide new measurements in the archive as you may understand. I let you generate some based on the TLE given in the parameters. If you can’t, just tell me and I’ll see what I can do !

@evan.ward : what would you need for that ? I can provide you with an Excel with some computing time comparison if that’s what you refer to, for example.

Nicolas,

I would like to see a measurement of performance with the existing Orekit development code, a change that improves the performance significantly, and then a measurement of performance with the change included. That way we can have some data to decide if the change is worthwhile. The performance test should be written in a way that we can run it to verify your results and to test the change in other contexts (e.g. multi-threaded applications). It can be difficult to accurately measure performance with Java’s runtime optimizer, but I’ve had some success in the past with JMH [1], which seems to be what the JDK developers use. Usually the biggest performance improvements are algorithmic e.g. using a more efficient algorithm, not computing values that aren’t used, computing a value once and reusing it instead of recomputing.

[1] https://openjdk.java.net/projects/code-tools/jmh/

Well since I didn’t modify the core of the algorithm, there is no need for now to compare the performances with the existing Orekit development code.

My question is precisely on how the code could be modified, how the parameters could be optimized in order to speed the computation ! For example, I would like to know if the algorithm could be modified in order use multiple threads.
If someone has some ideas, I’ll implement it and compare the performances.

I have looked at your example, here are my findings.

My tests were run on an old (about 4-5 years old) laptop computer running Linux Debian with an Intel Core i5-3320M CPU, 8 gigabytes memory, running openJDK 11.0.1.

I generated azimuth-elevation data for the 5 stations Fucino, Kumsan, Uralla, Pretoria, Castlerock) starting from TLE. The generator configuration was 300s between each measurements when satellite was 5° above horizon, taking refraction into account and adding a Gaussian noise with zero mean and 0.02° standard deviation. There were 1243 measurements generated over 9.7 days.

With the same estimator configuration as in your archive, the computing time was about 334 seconds for 4 iterations, already far below 1800s.

Looking at the configuration, it appears you used an attitude mode defaulting to nadir pointing with yaw compensation. This attitude mode is probably the most computing intensive mode, due to yaw compensation (we have to take into account the Earth curvature along the sub satellite track and compute some derivatives there). At the same time, the force models for surface forces (here only radiation pressure) do not depend on attitude as an isotropic model is used, and there are no offset for on-board reflectors. This expensive attitude mode should therefore be replaced by a much simpler one without any effect on the results. I therefore added in your spacecraftConfiguration.in file the following line:

attitude.mode    = LOF_ALIGNED_LVLH

This single change reduced the computation time down to about 134 seconds and still 4 iterations.

You can reduce it further slightly by increasing propagation.position.error from 0.1 to 1.0, and reducing the
degree and order of gravity field from 20 to 15 or 12 for example. I did not investigate this because first I cannot dedicate to much time to this and second my measurements were generated from TLE which is a completely different model, therefore tuning the numerical propagator force model is irrelevant, it can only be done realistically when using real measurements.

So as a conclusion, I don’t get 1800s but rather 334s on an old laptop with a configuration roughly similar to yours (1243 measurement over 9.7 days for a geodesy satellite) and can reduce it to 134 s by using a more appropriate attitude mode.

2 Likes