Hi all,
With my intern Gaëtan we are working on adding the Unscented Kalman Filter (UKF) and its semi-analytical version, the Unscented Semi-analytical Kalman Filter (USKF), in Orekit. We are very happy with the results of the two algorithms.
The first task of the internship was to add the mathematical algorithm of the UKF in Hipparchus. This task is completed and the algorithm available in Hipparchus 2.2.
The second task was the implementation of the two filters to perform satellite orbit determination in Orekit. The two filters are implemented and validated. The work is available in a merge request and can be introduced for a minor version.
The purpose of the last task is to reduce the code duplication and have more “generic” classes to initialize the Kalman Filters. Indeed, with this addition, Orekit has 4 differents Kalman filters.
However, we’re having some issues.
Context
In Orekit, a Kalman filter is implemented using 3 classes:
-
XxxModel
: The model which combines the mathematics and orbital mechanics point of views. -
XxxEstimator
: The object used by the user to perform the estimation. -
XxxEstimatorBuilder
: The builder for the estimator.
As the XxxModel
is specific for each Kalman filter, it is require to have one class per filter.
Currently, we are not thinking about having a generic XxxEstimator
class since the implementation is a bit different for the semi-analytical and non semi-analytical filter.
The class we have to optimize is the XxxEstimatorBuilder
. We want to optimize this class in order to have only one (i.e., not 4) and let the user initialize any Kalman filter using this single class.
Please find below some idea. We didn’t try them, they are just here to open discussions.
Proposal 1
-
Add an interface
SequentialEstimator
implemented by the 4 Kalman filters. It could contain the methodsestimationStep()
andprocessMeasurements()
-
Add a new parameter to the KalmanEstimatorBuilder class: utProvider (type UnscentedTransformProvider) and a new method to initialize it:
unscentedTransformProvider
/** Configure the unscented transform provider.
* @param transformProvider unscented transform to use for the prediction phase
* @return this object.
*/
public KalmanEstimatorBuilder unscentedTransformProvider(final UnscentedTransformProvider transformProvider) {
this.utProvider = transformProvider;
return this;
}
- Add a type generic to the
KalmanEstimatorBuilder
class.
The class could be something like:
public class KalmanEstimatorBuilder<K extends SequentialEstimator> {
...
public K build() {
...
}
Advantage: Easy to implement and extendable if a user implements its own filter.
Drawback: Can be done only for a major release.
Proposal 2
-
Add an interface
SequentialEstimator
implemented by the 4 Kalman filters. It could contain the methodsestimationStep()
andprocessMeasurements()
-
Add a new parameter to the
KalmanEstimatorBuilder
class:utProvider
(typeUnscentedTransformProvider
) and a new method to initialize it:unscentedTransformProvider
/** Configure the unscented transform provider.
* @param transformProvider unscented transform to use for the prediction phase
* @return this object.
*/
public KalmanEstimatorBuilder unscentedTransformProvider(final UnscentedTransformProvider transformProvider) {
this.utProvider = transformProvider;
return this;
}
-
Add an enumerate
KalmanType
containing the method build(…) (implemented for each filter) and 4 entries:EXTENDED
,EXTENDED_SEMI_ANALYTICAL
,UNSCENTED
, andUNSCENTED_SEMI_ANALYTICAL
. -
Add a new parameter to the
KalmanEstimatorBuilder
:kalmanType
. It could be set by default toKalmanType.EXTENDED
(to be compatible with a minor version) and modifiable using
public KalmanEstimatorBuilder kalmanType(final KalmanType type) {
this.kalmanType= type;
return this;
}
- Call the
build(...)
method of thekalmanType
inside thebuild(...)
method of the estimator builder.
public SequentialEstimator build() {
return kalmanType.build(decomposer, propagatorBuilders, processNoiseMatrixProviders,
estimatedMeasurementsParameters, measurementProcessNoiseMatrix,
utProvider);
}
Advantage: Easy to implement and can be done for a minor release.
Drawback: Not extendable for a user having its own filter
Proposal 3
Imagine something with a single XxxEstimator
too.
Advantage: Reduce a lot of code (i.e., two factorizations), could include user-specific Kalman Filter, could be done for a minor release.
Drawback: Probably difficult to implement.
Conclusion
We would be very happy to have your comments on the different proposals and tell us if you think that one is interesting to implement.
Also, I somebody has a fourth idea, we would be very happy too.
Thank you for your help,
Bryan