UnivariateProcessNoise.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 org.hipparchus.analysis.UnivariateFunction;
  19. import org.hipparchus.linear.MatrixUtils;
  20. import org.hipparchus.linear.RealMatrix;
  21. import org.orekit.frames.LOFType;
  22. import org.orekit.orbits.PositionAngleType;
  23. import org.orekit.propagation.SpacecraftState;
  24. import org.orekit.propagation.StateCovariance;

  25. /** Provider for a temporal evolution of the process noise matrix.
  26.  * All parameters (orbital or propagation) are time dependent and provided as {@link UnivariateFunction}.
  27.  * The argument of the functions is a duration in seconds (between current and previous spacecraft state).
  28.  * The output of the functions must be of the dimension of a standard deviation.
  29.  * The method {@link #getProcessNoiseMatrix} then square the values so that they are consistent with a covariance matrix.
  30.  * <p>
  31.  * The orbital parameters evolutions are provided in LOF frame and Cartesian (PV);
  32.  * then converted in inertial frame and current {@link org.orekit.orbits.OrbitType} and {@link PositionAngleType}
  33.  * when method {@link #getProcessNoiseMatrix} is called.
  34.  * </p>
  35.  * <p>
  36.  * The time-dependent functions define a process noise matrix that is diagonal
  37.  * <em>in the Local Orbital Frame</em>, corresponds to Cartesian elements, abd represents
  38.  * the temporal evolution of (the standard deviation of) the process noise model. The
  39.  * first function is therefore the standard deviation along the LOF X axis, the second
  40.  * function represents the standard deviation along the LOF Y axis...
  41.  * This allows to set up simply a process noise representing an uncertainty that grows
  42.  * mainly along the track. The 6x6 upper left part of output matrix will however not be
  43.  * diagonal as it will be converted to the same inertial frame and orbit type as the
  44.  * {@link SpacecraftState state} used by the {@link KalmanEstimator Kalman estimator}.
  45.  * </p>
  46.  * <p>
  47.  * The propagation and measurements parameters are not associated to a specific frame and
  48.  * are appended as is in the lower right part diagonal of the output matrix. This implies
  49.  * this simplified model does not include correlation between the parameters and the orbit,
  50.  * but only evolution of the parameters themselves. If such correlations are needed, users
  51.  * must set up a custom {@link CovarianceMatrixProvider covariance matrix provider}. In most
  52.  * cases, the parameters are constant and their evolution noise is always 0, so the
  53.  * functions can be set to {@code x -> 0}.
  54.  * </p>
  55.  * <p>
  56.  * This class always provides one initial noise matrix or initial covariance matrix and one process noise matrix.
  57.  * </p>
  58.  * @author Luc Maisonobe
  59.  * @author Maxime Journot
  60.  * @since 9.2
  61.  */
  62. public class UnivariateProcessNoise extends AbstractCovarianceMatrixProvider {

  63.     /** Local Orbital Frame (LOF) type used. */
  64.     private final LOFType lofType;

  65.     /** Position angle for the orbital process noise matrix. */
  66.     private final PositionAngleType positionAngleType;

  67.     /** Array of univariate functions for the six orbital parameters process noise evolution in LOF frame and Cartesian formalism. */
  68.     private final UnivariateFunction[] lofCartesianOrbitalParametersEvolution;

  69.     /** Array of univariate functions for the propagation parameters process noise evolution. */
  70.     private final UnivariateFunction[] propagationParametersEvolution;

  71.     /** Array of univariate functions for the measurements parameters process noise evolution. */
  72.     private final UnivariateFunction[] measurementsParametersEvolution;

  73.     /** Simple constructor.
  74.      * @param initialCovarianceMatrix initial covariance matrix
  75.      * @param lofType the LOF type used
  76.      * @param positionAngleType the position angle used for the computation of the process noise
  77.      * @param lofCartesianOrbitalParametersEvolution Array of univariate functions for the six orbital parameters process noise evolution in LOF frame and Cartesian orbit type
  78.      * @param propagationParametersEvolution Array of univariate functions for the propagation parameters process noise evolution
  79.      */
  80.     public UnivariateProcessNoise(final RealMatrix initialCovarianceMatrix,
  81.                                   final LOFType lofType,
  82.                                   final PositionAngleType positionAngleType,
  83.                                   final UnivariateFunction[] lofCartesianOrbitalParametersEvolution,
  84.                                   final UnivariateFunction[] propagationParametersEvolution) {

  85.         // Call the new constructor with an empty array for measurements parameters
  86.         this(initialCovarianceMatrix, lofType, positionAngleType, lofCartesianOrbitalParametersEvolution, propagationParametersEvolution, new UnivariateFunction[0]);
  87.     }

  88.     /** Simple constructor.
  89.      * @param initialCovarianceMatrix initial covariance matrix
  90.      * @param lofType the LOF type used
  91.      * @param positionAngleType the position angle used for the computation of the process noise
  92.      * @param lofCartesianOrbitalParametersEvolution Array of univariate functions for the six orbital parameters process noise evolution in LOF frame and Cartesian orbit type
  93.      * @param propagationParametersEvolution Array of univariate functions for the propagation parameters process noise evolution
  94.      * @param measurementsParametersEvolution Array of univariate functions for the measurements parameters process noise evolution
  95.      * @since 10.3
  96.      */
  97.     public UnivariateProcessNoise(final RealMatrix initialCovarianceMatrix,
  98.                                   final LOFType lofType,
  99.                                   final PositionAngleType positionAngleType,
  100.                                   final UnivariateFunction[] lofCartesianOrbitalParametersEvolution,
  101.                                   final UnivariateFunction[] propagationParametersEvolution,
  102.                                   final UnivariateFunction[] measurementsParametersEvolution) {

  103.         super(initialCovarianceMatrix);
  104.         this.lofType = lofType;
  105.         this.positionAngleType = positionAngleType;
  106.         this.lofCartesianOrbitalParametersEvolution  = lofCartesianOrbitalParametersEvolution.clone();
  107.         this.propagationParametersEvolution = propagationParametersEvolution.clone();
  108.         this.measurementsParametersEvolution = measurementsParametersEvolution.clone();
  109.     }

  110.     /** Getter for the lofType.
  111.      * @return the lofType
  112.      */
  113.     public LOFType getLofType() {
  114.         return lofType;
  115.     }

  116.     /** Getter for the positionAngle.
  117.      * @return the positionAngle
  118.      */
  119.     public PositionAngleType getPositionAngleType() {
  120.         return positionAngleType;
  121.     }

  122.     /** Getter for the lofCartesianOrbitalParametersEvolution.
  123.      * @return the lofCartesianOrbitalParametersEvolution
  124.      */
  125.     public UnivariateFunction[] getLofCartesianOrbitalParametersEvolution() {
  126.         return lofCartesianOrbitalParametersEvolution.clone();
  127.     }

  128.     /** Getter for the propagationParametersEvolution.
  129.      * @return the propagationParametersEvolution
  130.      */
  131.     public UnivariateFunction[] getPropagationParametersEvolution() {
  132.         return propagationParametersEvolution.clone();
  133.     }

  134.     /** Getter for the measurementsParametersEvolution.
  135.      * @return the measurementsParametersEvolution
  136.      */
  137.     public UnivariateFunction[] getMeasurementsParametersEvolution() {
  138.         return measurementsParametersEvolution.clone();
  139.     }

  140.     /** {@inheritDoc} */
  141.     @Override
  142.     public RealMatrix getProcessNoiseMatrix(final SpacecraftState previous,
  143.                                             final SpacecraftState current) {

  144.         // Number of estimated parameters
  145.         final int nbOrb    = lofCartesianOrbitalParametersEvolution.length;
  146.         final int nbPropag = propagationParametersEvolution.length;
  147.         final int nbMeas   = measurementsParametersEvolution.length;

  148.         // Initialize process noise matrix
  149.         final RealMatrix processNoiseMatrix = MatrixUtils.createRealMatrix(nbOrb + nbPropag + nbMeas,
  150.                                                                            nbOrb + nbPropag + nbMeas);

  151.         // Orbital parameters
  152.         if (nbOrb != 0) {
  153.             // Orbital parameters process noise matrix in inertial frame and current orbit type
  154.             final RealMatrix inertialOrbitalProcessNoiseMatrix = getInertialOrbitalProcessNoiseMatrix(previous, current);
  155.             processNoiseMatrix.setSubMatrix(inertialOrbitalProcessNoiseMatrix.getData(), 0, 0);
  156.         }

  157.         // Propagation parameters
  158.         if (nbPropag != 0) {
  159.             // Propagation parameters process noise matrix
  160.             final RealMatrix propagationProcessNoiseMatrix = getPropagationProcessNoiseMatrix(previous, current);
  161.             processNoiseMatrix.setSubMatrix(propagationProcessNoiseMatrix.getData(), nbOrb, nbOrb);
  162.         }

  163.         // Measurement parameters
  164.         if (nbMeas != 0) {
  165.             // Measurement parameters process noise matrix
  166.             final RealMatrix measurementsProcessNoiseMatrix = getMeasurementsProcessNoiseMatrix(previous, current);
  167.             processNoiseMatrix.setSubMatrix(measurementsProcessNoiseMatrix.getData(), nbOrb + nbPropag, nbOrb + nbPropag);
  168.         }

  169.         return processNoiseMatrix;
  170.     }

  171.     /** Get the process noise for the six orbital parameters in current spacecraft inertial frame and current orbit type.
  172.      * @param previous previous state
  173.      * @param current current state
  174.      * @return physical (i.e. non normalized) orbital process noise matrix in inertial frame
  175.      */
  176.     private RealMatrix getInertialOrbitalProcessNoiseMatrix(final SpacecraftState previous,
  177.                                                             final SpacecraftState current) {

  178.         // ΔT = duration in seconds from previous to current spacecraft state
  179.         final double deltaT = current.getDate().durationFrom(previous.getDate());

  180.         // Evaluate the functions, using ΔT as argument
  181.         final int      lofOrbitalProcessNoiseLength = lofCartesianOrbitalParametersEvolution.length;
  182.         final double[] lofOrbitalProcessNoiseValues = new double[lofOrbitalProcessNoiseLength];

  183.         // The function return a value which dimension is that of a standard deviation
  184.         // It needs to be squared before being put in the process noise covariance matrix
  185.         for (int i = 0; i < lofOrbitalProcessNoiseLength; i++) {
  186.             final double functionValue =  lofCartesianOrbitalParametersEvolution[i].value(deltaT);
  187.             lofOrbitalProcessNoiseValues[i] = functionValue * functionValue;
  188.         }

  189.         // Form the diagonal matrix in LOF frame and Cartesian formalism
  190.         final RealMatrix lofCartesianProcessNoiseMatrix = MatrixUtils.createRealDiagonalMatrix(lofOrbitalProcessNoiseValues);

  191.         // Create state covariance object in LOF
  192.         final StateCovariance lofCartesianProcessNoiseCov =
  193.                         new StateCovariance(lofCartesianProcessNoiseMatrix, current.getDate(), lofType);

  194.         // Convert to Cartesian in orbital frame
  195.         final StateCovariance inertialCartesianProcessNoiseCov =
  196.                         lofCartesianProcessNoiseCov.changeCovarianceFrame(current.getOrbit(), current.getFrame());

  197.         // Convert to current orbit type and position angle
  198.         final StateCovariance inertialOrbitalProcessNoiseCov =
  199.                         inertialCartesianProcessNoiseCov.changeCovarianceType(current.getOrbit(),
  200.                                                                               current.getOrbit().getType(), positionAngleType);
  201.         // Return inertial orbital covariance matrix
  202.         return inertialOrbitalProcessNoiseCov.getMatrix();
  203.     }

  204.     /** Get the process noise for the propagation parameters.
  205.      * @param previous previous state
  206.      * @param current current state
  207.      * @return physical (i.e. non normalized) propagation process noise matrix
  208.      */
  209.     private RealMatrix getPropagationProcessNoiseMatrix(final SpacecraftState previous,
  210.                                                         final SpacecraftState current) {

  211.         // ΔT = duration from previous to current spacecraft state (in seconds)
  212.         final double deltaT = current.getDate().durationFrom(previous.getDate());

  213.         // Evaluate the functions, using ΔT as argument
  214.         final int      propagationProcessNoiseLength = propagationParametersEvolution.length;
  215.         final double[] propagationProcessNoiseValues = new double[propagationProcessNoiseLength];

  216.         // The function return a value which dimension is that of a standard deviation
  217.         // It needs to be squared before being put in the process noise covariance matrix
  218.         for (int i = 0; i < propagationProcessNoiseLength; i++) {
  219.             final double functionValue =  propagationParametersEvolution[i].value(deltaT);
  220.             propagationProcessNoiseValues[i] = functionValue * functionValue;
  221.         }

  222.         // Form the diagonal matrix corresponding to propagation parameters process noise
  223.         return MatrixUtils.createRealDiagonalMatrix(propagationProcessNoiseValues);
  224.     }

  225.     /** Get the process noise for the measurements parameters.
  226.      * @param previous previous state
  227.      * @param current current state
  228.      * @return physical (i.e. non normalized) measurements process noise matrix
  229.      */
  230.     private RealMatrix getMeasurementsProcessNoiseMatrix(final SpacecraftState previous,
  231.                                                          final SpacecraftState current) {

  232.         // ΔT = duration from previous to current spacecraft state (in seconds)
  233.         final double deltaT = current.getDate().durationFrom(previous.getDate());

  234.         // Evaluate the functions, using ΔT as argument
  235.         final int      measurementsProcessNoiseLength = measurementsParametersEvolution.length;
  236.         final double[] measurementsProcessNoiseValues = new double[measurementsProcessNoiseLength];

  237.         // The function return a value which dimension is that of a standard deviation
  238.         // It needs to be squared before being put in the process noise covariance matrix
  239.         for (int i = 0; i < measurementsProcessNoiseLength; i++) {
  240.             final double functionValue =  measurementsParametersEvolution[i].value(deltaT);
  241.             measurementsProcessNoiseValues[i] = functionValue * functionValue;
  242.         }

  243.         // Form the diagonal matrix corresponding to propagation parameters process noise
  244.         return MatrixUtils.createRealDiagonalMatrix(measurementsProcessNoiseValues);
  245.     }

  246. }