Getting Access to KalmanEstimation from Kalman Filter results

I am trying to get the predicted/corrected measurements/spacecraft states out of the results of a Kalman Filter but cannot seem to figure out how. Specifically I am trying to get a way to pull out the measurement residuals from the Kalman Estimation. I have been using the KalmanODTest.java as a reference to build the kalman, and am also writing in python. Below is my abridged process for setting and running the kalman:

  • build ‘int_builder’ with an IntegratorBuilder
  • build ‘prop_builder’ with a NumericalPropagatorBuilder
  • add mass and forces to ‘prop_builder’
  • turn on estimation for Cr and Cd through PropagationParametersDrivers
  • build ‘filt’ with a KalmanEstimatorBuilder.build()
  • run the Kalman Filter using filt.estimateStep on each measurement

This outputs a list of AbstractIntegratedPropagators which I can use to grab the estimated state, but no way to get the prediction/correction at each discrete measurement.

It would also be helpful to get some insight into how the KalmanEstimator, KalmanObserver, and KalmanEstimation interface with eachother (does the observer take a function?).

Thanks!

Hi @aerow610,

Welcome to the Orekit community !

The KalmanObserver interface and its method evaluationPerformed has to be implemented if you want to get the residuals.
There is a Java example here, in the AbstractOrbitDetermination class, in the Orekit test directory.

To do this in Python you’ll have to use the PythonKalmanObserver class.
I’m not an expert in Python but there are examples on how to use Orekit interfaces with Python in the test directory made by @petrus.hyvonen; see here.

Once your KalmanObserver is set up, you just have to call the method setKalmanObserver in your Kalman estimator and its method evaluationPerformed will be called after each estimation step.

I hope this will help you.

Maxime

Hi @MaximeJ,

Thanks for the quick response and all the info.

I don’t know much about java, but from the AbstractOrbitDetermination example it looks like the kalman.setObserver is being fed a new KalmanObserver which is defined by that following function evaluationPerformed (which takes a KalmanEstimation as input). So KalmanObserver.estimationPerformed needs a function to be instantiated? Or do I need to build a KalmanEstimation somehow and pass that in as input?

It seems like the estimationPerformed method is empty and needs to be defined by something so that it can be run in the filter estimation step.

What is the easiest way to set up a new KalmanObserver and define the estimationPerformed?

I did try to use the PythonKalmanObserver, but it looks like it has the same thing with the empty method.

Hi @aerow610,

I’ve seen you posted on the “Orekit Python Wrapper” Gitlab forge too.
So I don’t know if my answer will be redundant with Petrus’ one, or if you’ve solved your issue already.

As I said earlier I’m not an expert in Python so I’ll try my best :wink:

As Petrus suggested, I think you need to subclass the PythonKalmanObserver class.
Suppose you call it “MyKalmanObserver”.

In this class you define the function “evaluationPerformed” where you extract or print the data you need (spacecraft states, residuals etc.).

You should look up the examples on the forge, like the OrekitStepHandlerTest. You need to reproduce the sub-classing done at line 99 or line 148.

Once you’ve written “MyKalmanObserver”, you must instantiate it and pass it to the Kalman with “setObserver”.

Below is an example that I haven’t tested… It supposes you have a “KalmanEstimator” object defined in variable “my_filter”.

class MyObserver(PythonKalmanObserver):
    def evaluationPerformed(self, kalmanEstimation):
        print(kalmanEstimation.getCorrectedMeasurement().getObservedValue())

my_filter.setObserver(MyObserver())

I hope this will help you.
Maxime

Hi @MaximeJ,

I hadn’t realized that it needed to be subclassed, but that makes perfect sense. I tried out your example in my code and it was exactly what I needed to get the KalmanEstimation out!

Thanks so much for your quick replies and all the help!