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