UnivariateProcessNoise.java

  1. /* Copyright 2002-2020 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.PositionAngle;
  23. import org.orekit.propagation.SpacecraftState;
  24. import org.orekit.utils.CartesianDerivativesFilter;

  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 PositionAngle}
  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 PositionAngle positionAngle;

  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 positionAngle 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 PositionAngle positionAngle,
  83.                                   final UnivariateFunction[] lofCartesianOrbitalParametersEvolution,
  84.                                   final UnivariateFunction[] propagationParametersEvolution) {

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

  88.     /** Simple constructor.
  89.      * @param initialCovarianceMatrix initial covariance matrix
  90.      * @param lofType the LOF type used
  91.      * @param positionAngle 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 PositionAngle positionAngle,
  100.                                   final UnivariateFunction[] lofCartesianOrbitalParametersEvolution,
  101.                                   final UnivariateFunction[] propagationParametersEvolution,
  102.                                   final UnivariateFunction[] measurementsParametersEvolution) {

  103.         super(initialCovarianceMatrix);
  104.         this.lofType = lofType;
  105.         this.positionAngle = positionAngle;
  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 PositionAngle getPositionAngle() {
  120.         return positionAngle;
  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.         // Get the Jacobian from LOF to Inertial
  192.         final double[][] dLofdInertial = new double[6][6];
  193.         lofType.transformFromInertial(current.getDate(),
  194.                                       current.getPVCoordinates()).getInverse().getJacobian(CartesianDerivativesFilter.USE_PV,
  195.                                                                                            dLofdInertial);
  196.         final RealMatrix jacLofToInertial = MatrixUtils.createRealMatrix(dLofdInertial);

  197.         // Jacobian of orbit parameters with respect to Cartesian parameters
  198.         final double[][] dYdC = new double[6][6];
  199.         current.getOrbit().getJacobianWrtCartesian(positionAngle, dYdC);
  200.         final RealMatrix jacOrbitWrtCartesian = MatrixUtils.createRealMatrix(dYdC);

  201.         // Complete Jacobian of the transformation
  202.         final RealMatrix jacobian = jacOrbitWrtCartesian.multiply(jacLofToInertial);

  203.         // Return the orbital process noise matrix in inertial frame and proper orbit type
  204.         final RealMatrix inertialOrbitalProcessNoiseMatrix = jacobian.
  205.                          multiply(lofCartesianProcessNoiseMatrix).
  206.                          multiplyTransposed(jacobian);
  207.         return inertialOrbitalProcessNoiseMatrix;
  208.     }

  209.     /** Get the process noise for the propagation parameters.
  210.      * @param previous previous state
  211.      * @param current current state
  212.      * @return physical (i.e. non normalized) propagation process noise matrix
  213.      */
  214.     private RealMatrix getPropagationProcessNoiseMatrix(final SpacecraftState previous,
  215.                                                         final SpacecraftState current) {

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

  218.         // Evaluate the functions, using ΔT as argument
  219.         final int      propagationProcessNoiseLength = propagationParametersEvolution.length;
  220.         final double[] propagationProcessNoiseValues = new double[propagationProcessNoiseLength];

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

  227.         // Form the diagonal matrix corresponding to propagation parameters process noise
  228.         return MatrixUtils.createRealDiagonalMatrix(propagationProcessNoiseValues);
  229.     }

  230.     /** Get the process noise for the measurements parameters.
  231.      * @param previous previous state
  232.      * @param current current state
  233.      * @return physical (i.e. non normalized) measurements process noise matrix
  234.      */
  235.     private RealMatrix getMeasurementsProcessNoiseMatrix(final SpacecraftState previous,
  236.                                                          final SpacecraftState current) {

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

  239.         // Evaluate the functions, using ΔT as argument
  240.         final int      measurementsProcessNoiseLength = measurementsParametersEvolution.length;
  241.         final double[] measurementsProcessNoiseValues = new double[measurementsProcessNoiseLength];

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

  248.         // Form the diagonal matrix corresponding to propagation parameters process noise
  249.         return MatrixUtils.createRealDiagonalMatrix(measurementsProcessNoiseValues);
  250.     }

  251. }