UnscentedKalmanEstimator.java

  1. /* Copyright 2002-2024 CS GROUP
  2.  * Licensed to CS GROUP (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.estimation.sequential;

  18. import java.util.List;

  19. import org.hipparchus.filtering.kalman.ProcessEstimate;
  20. import org.hipparchus.filtering.kalman.unscented.UnscentedKalmanFilter;
  21. import org.hipparchus.linear.MatrixDecomposer;
  22. import org.hipparchus.util.UnscentedTransformProvider;
  23. import org.orekit.estimation.measurements.ObservedMeasurement;
  24. import org.orekit.propagation.Propagator;
  25. import org.orekit.propagation.conversion.DSSTPropagatorBuilder;
  26. import org.orekit.propagation.conversion.PropagatorBuilder;
  27. import org.orekit.time.AbsoluteDate;
  28. import org.orekit.utils.ParameterDriver;
  29. import org.orekit.utils.ParameterDriversList;

  30. /**
  31.  * Implementation of an Unscented Kalman filter to perform orbit determination.
  32.  * <p>
  33.  * The filter uses a {@link PropagatorBuilder} to initialize its reference trajectory.
  34.  * </p>
  35.  * <p>
  36.  * The estimated parameters are driven by {@link ParameterDriver} objects. They are of 3 different types:<ol>
  37.  *   <li><b>Orbital parameters</b>:The position and velocity of the spacecraft, or, more generally, its orbit.<br>
  38.  *       These parameters are retrieved from the reference trajectory propagator builder when the filter is initialized.</li>
  39.  *   <li><b>Propagation parameters</b>: Some parameters modelling physical processes (SRP or drag coefficients etc...).<br>
  40.  *       They are also retrieved from the propagator builder during the initialization phase.</li>
  41.  *   <li><b>Measurements parameters</b>: Parameters related to measurements (station biases, positions etc...).<br>
  42.  *       They are passed down to the filter in its constructor.</li>
  43.  * </ol>
  44.  * <p>
  45.  * The total number of estimated parameters is m, the size of the state vector.
  46.  * </p>
  47.  * <p>
  48.  * The Kalman filter implementation used is provided by the underlying mathematical library Hipparchus.
  49.  * </p>
  50.  *
  51.  * <p>An {@link UnscentedKalmanEstimator} object is built using the {@link UnscentedKalmanEstimatorBuilder#build() build}
  52.  * method of a {@link UnscentedKalmanEstimatorBuilder}. The builder is generalized to accept any {@link PropagatorBuilder}.
  53.  * Howerver, it is absolutely not recommended to use a {@link DSSTPropagatorBuilder}.
  54.  * A specific {@link SemiAnalyticalUnscentedKalmanEstimatorBuilder semi-analytical unscented Kalman Filter} is implemented
  55.  * and shall be used.
  56.  * </p>
  57.  *
  58.  * @author GaĆ«tan Pierre
  59.  * @author Bryan Cazabonne
  60.  * @since 11.3
  61.  */
  62. public class UnscentedKalmanEstimator extends AbstractKalmanEstimator {

  63.     /** Reference date. */
  64.     private final AbsoluteDate referenceDate;

  65.     /** Unscented Kalman filter process model. */
  66.     private final UnscentedKalmanModel processModel;

  67.     /** Filter. */
  68.     private final UnscentedKalmanFilter<MeasurementDecorator> filter;

  69.     /** Observer to retrieve current estimation info. */
  70.     private KalmanObserver observer;

  71.     /** Unscented Kalman filter estimator constructor (package private).
  72.      * @param decomposer decomposer to use for the correction phase
  73.      * @param propagatorBuilders propagators builders used to evaluate the orbit.
  74.      * @param processNoiseMatricesProviders providers for process noise matrices
  75.      * @param estimatedMeasurementParameters measurement parameters to estimate
  76.      * @param measurementProcessNoiseMatrix provider for measurement process noise matrix
  77.      * @param utProvider provider for the unscented transform.
  78.      */
  79.     UnscentedKalmanEstimator(final MatrixDecomposer decomposer,
  80.                              final List<PropagatorBuilder> propagatorBuilders,
  81.                              final List<CovarianceMatrixProvider> processNoiseMatricesProviders,
  82.                              final ParameterDriversList estimatedMeasurementParameters,
  83.                              final CovarianceMatrixProvider measurementProcessNoiseMatrix,
  84.                              final UnscentedTransformProvider utProvider) {
  85.         super(propagatorBuilders);
  86.         this.referenceDate = propagatorBuilders.get(0).getInitialOrbitDate();
  87.         this.observer      = null;

  88.         // Build the process model and measurement model
  89.         this.processModel = new UnscentedKalmanModel(propagatorBuilders, processNoiseMatricesProviders,
  90.                                                      estimatedMeasurementParameters, measurementProcessNoiseMatrix);

  91.         this.filter = new UnscentedKalmanFilter<>(decomposer, processModel, processModel.getEstimate(), utProvider);

  92.     }

  93.     /** {@inheritDoc}. */
  94.     @Override
  95.     protected KalmanEstimation getKalmanEstimation() {
  96.         return processModel;
  97.     }

  98.     /** Set the observer.
  99.      * @param observer the observer
  100.      */
  101.     public void setObserver(final KalmanObserver observer) {
  102.         this.observer = observer;
  103.     }

  104.     /** Process a single measurement.
  105.      * <p>
  106.      * Update the filter with the new measurement by calling the estimate method.
  107.      * </p>
  108.      * @param observedMeasurement the measurement to process
  109.      * @return estimated propagator
  110.      */
  111.     public Propagator[] estimationStep(final ObservedMeasurement<?> observedMeasurement) {
  112.         final ProcessEstimate estimate = filter.estimationStep(KalmanEstimatorUtil.decorateUnscented(observedMeasurement, referenceDate));
  113.         processModel.finalizeEstimation(observedMeasurement, estimate);
  114.         if (observer != null) {
  115.             observer.evaluationPerformed(processModel);
  116.         }
  117.         return processModel.getEstimatedPropagators();
  118.     }

  119.     /** Process several measurements.
  120.      * @param observedMeasurements the measurements to process in <em>chronologically sorted</em> order
  121.      * @return estimated propagator
  122.      */
  123.     public Propagator[] processMeasurements(final Iterable<ObservedMeasurement<?>> observedMeasurements) {
  124.         Propagator[] propagators = null;
  125.         for (ObservedMeasurement<?> observedMeasurement : observedMeasurements) {
  126.             propagators = estimationStep(observedMeasurement);
  127.         }
  128.         return propagators;
  129.     }

  130. }