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  
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.hipparchus.exception.MathRuntimeException;
23  import org.hipparchus.filtering.kalman.extended.ExtendedKalmanFilter;
24  import org.hipparchus.linear.MatrixDecomposer;
25  import org.orekit.errors.OrekitException;
26  import org.orekit.estimation.measurements.ObservedMeasurement;
27  import org.orekit.propagation.conversion.DSSTPropagatorBuilder;
28  import org.orekit.propagation.semianalytical.dsst.DSSTPropagator;
29  import org.orekit.utils.ParameterDriver;
30  import org.orekit.utils.ParameterDriversList;
31  
32  /**
33   * Implementation of an Extended Semi-analytical Kalman Filter (ESKF) to perform orbit determination.
34   * <p>
35   * The filter uses a {@link DSSTPropagatorBuilder}.
36   * </p>
37   * <p>
38   * The estimated parameters are driven by {@link ParameterDriver} objects. They are of 3 different types:<ol>
39   *   <li><b>Orbital parameters</b>:The position and velocity of the spacecraft, or, more generally, its orbit.<br>
40   *       These parameters are retrieved from the reference trajectory propagator builder when the filter is initialized.</li>
41   *   <li><b>Propagation parameters</b>: Some parameters modelling physical processes (SRP or drag coefficients).<br>
42   *       They are also retrieved from the propagator builder during the initialization phase.</li>
43   *   <li><b>Measurements parameters</b>: Parameters related to measurements (station biases, positions etc...).<br>
44   *       They are passed down to the filter in its constructor.</li>
45   * </ol>
46   * <p>
47   * The Kalman filter implementation used is provided by the underlying mathematical library Hipparchus.
48   * All the variables seen by Hipparchus (states, covariances, measurement matrices...) are normalized
49   * using a specific scale for each estimated parameters or standard deviation noise for each measurement components.
50   * </p>
51   *
52   * @see "Folcik Z., Orbit Determination Using Modern Filters/Smoothers and Continuous Thrust Modeling,
53   *       Master of Science Thesis, Department of Aeronautics and Astronautics, MIT, June, 2008."
54   *
55   * @see "Cazabonne B., Bayard J., Journot M., and Cefola P. J., A Semi-analytical Approach for Orbit
56   *       Determination based on Extended Kalman Filter, AAS Paper 21-614, AAS/AIAA Astrodynamics
57   *       Specialist Conference, Big Sky, August 2021."
58   *
59   * @author Julie Bayard
60   * @author Bryan Cazabonne
61   * @author Maxime Journot
62   * @since 11.1
63   */
64  public class SemiAnalyticalKalmanEstimator extends AbstractKalmanEstimator {
65  
66      /** Kalman filter process model. */
67      private final SemiAnalyticalKalmanModel processModel;
68  
69      /** Filter. */
70      private final ExtendedKalmanFilter<MeasurementDecorator> filter;
71  
72      /** Kalman filter estimator constructor (package private).
73       * @param decomposer decomposer to use for the correction phase
74       * @param propagatorBuilder propagator builder used to evaluate the orbit.
75       * @param covarianceMatrixProvider provider for process noise matrix
76       * @param estimatedMeasurementParameters measurement parameters to estimate
77       * @param measurementProcessNoiseMatrix provider for measurement process noise matrix
78       */
79      public SemiAnalyticalKalmanEstimator(final MatrixDecomposer decomposer,
80                                           final DSSTPropagatorBuilder propagatorBuilder,
81                                           final CovarianceMatrixProvider covarianceMatrixProvider,
82                                           final ParameterDriversList estimatedMeasurementParameters,
83                                           final CovarianceMatrixProvider measurementProcessNoiseMatrix) {
84          super(Collections.singletonList(propagatorBuilder));
85          // Build the process model and measurement model
86          this.processModel = new SemiAnalyticalKalmanModel(propagatorBuilder, covarianceMatrixProvider,
87                                                            estimatedMeasurementParameters,  measurementProcessNoiseMatrix);
88  
89          // Extended Kalman Filter of Hipparchus
90          this.filter = new ExtendedKalmanFilter<>(decomposer, processModel, processModel.getEstimate());
91  
92      }
93  
94      /** {@inheritDoc}. */
95      @Override
96      protected KalmanEstimation getKalmanEstimation() {
97          return processModel;
98      }
99  
100     /** Set the observer.
101      * @param observer the observer
102      */
103     public void setObserver(final KalmanObserver observer) {
104         processModel.setObserver(observer);
105     }
106 
107     /** Process a single measurement.
108      * <p>
109      * Update the filter with the new measurement by calling the estimate method.
110      * </p>
111      * @param observedMeasurements the list of measurements to process
112      * @return estimated propagators
113      */
114     public DSSTPropagator processMeasurements(final List<ObservedMeasurement<?>> observedMeasurements) {
115         try {
116             return processModel.processMeasurements(observedMeasurements, filter);
117         } catch (MathRuntimeException mrte) {
118             throw new OrekitException(mrte);
119         }
120     }
121 
122 }
123