1   /* Copyright 2002-2025 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.ArrayList;
20  import java.util.List;
21  
22  import org.hipparchus.linear.MatrixDecomposer;
23  import org.hipparchus.linear.QRDecomposer;
24  import org.orekit.errors.OrekitException;
25  import org.orekit.errors.OrekitMessages;
26  import org.orekit.propagation.conversion.EphemerisPropagatorBuilder;
27  import org.orekit.propagation.conversion.PropagatorBuilder;
28  import org.orekit.utils.ParameterDriversList;
29  
30  /** Builder for a Kalman filter estimator.
31   * @author Romain Gerbaud
32   * @author Maxime Journot
33   * @since 9.2
34   */
35  public class KalmanEstimatorBuilder {
36  
37      /** Decomposer to use for the correction phase. */
38      private MatrixDecomposer decomposer;
39  
40      /** Builders for propagators. */
41      private List<PropagatorBuilder> propagatorBuilders;
42  
43      /** Estimated measurements parameters. */
44      private ParameterDriversList estimatedMeasurementsParameters;
45  
46      /** Process noise matrices providers. */
47      private List<CovarianceMatrixProvider> processNoiseMatricesProviders;
48  
49      /** Process noise matrix provider for measurement parameters. */
50      private CovarianceMatrixProvider measurementProcessNoiseMatrix;
51  
52      /** Default constructor.
53       *  Set an extended Kalman filter, with linearized covariance prediction.
54       */
55      public KalmanEstimatorBuilder() {
56          this.decomposer                      = new QRDecomposer(1.0e-15);
57          this.propagatorBuilders              = new ArrayList<>();
58          this.estimatedMeasurementsParameters = new ParameterDriversList();
59          this.processNoiseMatricesProviders   = new ArrayList<>();
60          this.measurementProcessNoiseMatrix   = null;
61      }
62  
63      /** Construct a {@link KalmanEstimator} from the data in this builder.
64       * <p>
65       * Before this method is called, {@link #addPropagationConfiguration(PropagatorBuilder,
66       * CovarianceMatrixProvider) addPropagationConfiguration()} must have been called
67       * at least once, otherwise configuration is incomplete and an exception will be raised.
68       * </p>
69       * @return a new {@link KalmanEstimator}.
70       */
71      public KalmanEstimator build() {
72          final int n = propagatorBuilders.size();
73          if (n == 0) {
74              throw new OrekitException(OrekitMessages.NO_PROPAGATOR_CONFIGURED);
75          }
76          return new KalmanEstimator(decomposer, propagatorBuilders, processNoiseMatricesProviders,
77                                     estimatedMeasurementsParameters, measurementProcessNoiseMatrix);
78      }
79  
80      /** Configure the matrix decomposer.
81       * @param matrixDecomposer decomposer to use for the correction phase
82       * @return this object.
83       */
84      public KalmanEstimatorBuilder decomposer(final MatrixDecomposer matrixDecomposer) {
85          decomposer = matrixDecomposer;
86          return this;
87      }
88  
89      /** Add a propagation configuration.
90       * <p>
91       * This method must be called once for each propagator to managed with the
92       * {@link KalmanEstimator Kalman estimator}. The propagators order in the
93       * Kalman filter will be the call order.
94       * </p>
95       * <p>
96       * The {@code provider} should return a matrix with dimensions and ordering
97       * consistent with the {@code builder} configuration. The first 6 rows/columns
98       * correspond to the 6 orbital parameters. The remaining elements correspond
99       * to the subset of propagation parameters that are estimated, in the
100      * same order as propagatorBuilder.{@link
101      * org.orekit.propagation.conversion.PropagatorBuilder#getPropagationParametersDrivers()
102      * getPropagationParametersDrivers()}.{@link org.orekit.utils.ParameterDriversList#getDrivers()
103      * getDrivers()} (but filtering out the non selected drivers).
104      * </p>
105      * @param builder  The propagator builder to use in the Kalman filter.
106      * @param provider The process noise matrices provider to use, consistent with the builder.
107      *                 This parameter can be equal to {@code null} if the input builder is
108      *                 an {@link EphemerisPropagatorBuilder}. Indeed, for ephemeris based estimation
109      *                 only measurement parameters are estimated. Therefore, the covariance related
110      *                 to dynamical parameters can be null.
111      * @return this object.
112      * @see CovarianceMatrixProvider#getProcessNoiseMatrix(org.orekit.propagation.SpacecraftState,
113      * org.orekit.propagation.SpacecraftState) getProcessNoiseMatrix(previous, current)
114      */
115     public KalmanEstimatorBuilder addPropagationConfiguration(final PropagatorBuilder builder,
116                                                               final CovarianceMatrixProvider provider) {
117         propagatorBuilders.add(builder);
118         processNoiseMatricesProviders.add(provider);
119         return this;
120     }
121 
122     /** Configure the estimated measurement parameters.
123      * <p>
124      * If this method is not called, no measurement parameters will be estimated.
125      * </p>
126      * @param estimatedMeasurementsParams The estimated measurements' parameters list.
127      * @param provider covariance matrix provider for the estimated measurement parameters
128      * @return this object.
129      * @since 10.3
130      */
131     public KalmanEstimatorBuilder estimatedMeasurementsParameters(final ParameterDriversList estimatedMeasurementsParams,
132                                                                   final CovarianceMatrixProvider provider) {
133         estimatedMeasurementsParameters = estimatedMeasurementsParams;
134         measurementProcessNoiseMatrix   = provider;
135         return this;
136     }
137 
138 }