StateCovarianceMatrixProvider.java

  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.propagation;

  18. import org.hipparchus.linear.RealMatrix;
  19. import org.orekit.frames.Frame;
  20. import org.orekit.orbits.Orbit;
  21. import org.orekit.orbits.OrbitType;
  22. import org.orekit.orbits.PositionAngleType;
  23. import org.orekit.time.AbsoluteDate;

  24. /**
  25.  * Additional state provider for state covariance matrix.
  26.  * <p>
  27.  * This additional state provider allows computing a propagated covariance matrix based on a user defined input state
  28.  * covariance matrix. The computation of the propagated covariance matrix uses the State Transition Matrix between the
  29.  * propagated spacecraft state and the initial state. As a result, the user must define the name
  30.  * {@link #stmName of the provider for the State Transition Matrix}.
  31.  * <p>
  32.  * As the State Transition Matrix and the input state covariance matrix can be expressed in different orbit types, the
  33.  * user must specify both orbit types when building the covariance provider. In addition, the position angle used in
  34.  * both matrices must also be specified.
  35.  * <p>
  36.  * In order to add this additional state provider to an orbit propagator, user must use the
  37.  * {@link Propagator#addAdditionalDataProvider(AdditionalDataProvider)} method.
  38.  * <p>
  39.  * For a given propagated spacecraft {@code state}, the propagated state covariance matrix is accessible through the
  40.  * method {@link #getStateCovariance(SpacecraftState)}
  41.  *
  42.  * @author Bryan Cazabonne
  43.  * @author Vincent Cucchietti
  44.  * @since 11.3
  45.  */
  46. public class StateCovarianceMatrixProvider implements AdditionalDataProvider<RealMatrix> {

  47.     /** Dimension of the state. */
  48.     private static final int STATE_DIMENSION = 6;

  49.     /** Name of the state for State Transition Matrix. */
  50.     private final String stmName;

  51.     /** Matrix harvester to access the State Transition Matrix. */
  52.     private final MatricesHarvester harvester;

  53.     /** Name of the additional state. */
  54.     private final String additionalName;

  55.     /** Orbit type used for the State Transition Matrix. */
  56.     private final OrbitType stmOrbitType;

  57.     /** Position angle used for State Transition Matrix. */
  58.     private final PositionAngleType stmAngleType;

  59.     /** Orbit type for the covariance matrix. */
  60.     private final OrbitType covOrbitType;

  61.     /** Position angle used for the covariance matrix. */
  62.     private final PositionAngleType covAngleType;

  63.     /** Initial state covariance. */
  64.     private StateCovariance covInit;

  65.     /** Initial state covariance matrix. */
  66.     private RealMatrix covMatrixInit;

  67.     /**
  68.      * Constructor.
  69.      *
  70.      * @param additionalName name of the additional state
  71.      * @param stmName name of the state for State Transition Matrix
  72.      * @param harvester matrix harvester as returned by
  73.      * {@code propagator.setupMatricesComputation(stmName, null, null)}
  74.      * @param covInit initial state covariance
  75.      */
  76.     public StateCovarianceMatrixProvider(final String additionalName, final String stmName,
  77.                                          final MatricesHarvester harvester, final StateCovariance covInit) {
  78.         // Initialize fields
  79.         this.additionalName = additionalName;
  80.         this.stmName = stmName;
  81.         this.harvester = harvester;
  82.         this.covInit = covInit;
  83.         this.covOrbitType = covInit.getOrbitType();
  84.         this.covAngleType = covInit.getPositionAngleType();
  85.         this.stmOrbitType = harvester.getOrbitType();
  86.         this.stmAngleType = harvester.getPositionAngleType();
  87.     }

  88.     /** {@inheritDoc} */
  89.     @Override
  90.     public String getName() {
  91.         return additionalName;
  92.     }

  93.     /** {@inheritDoc} */
  94.     @Override
  95.     public void init(final SpacecraftState initialState, final AbsoluteDate target) {
  96.         // Convert the initial state covariance in the same orbit type as the STM
  97.         covInit = covInit.changeCovarianceType(initialState.getOrbit(), stmOrbitType, stmAngleType);

  98.         // Express covariance matrix in the same frame as the STM
  99.         final Orbit           initialOrbit      = initialState.getOrbit();
  100.         final StateCovariance covInitInSTMFrame = covInit.changeCovarianceFrame(initialOrbit, initialOrbit.getFrame());

  101.         covMatrixInit = covInitInSTMFrame.getMatrix();
  102.     }

  103.     /**
  104.      * {@inheritDoc}
  105.      * <p>
  106.      * The covariance matrix can be computed only if the State Transition Matrix state is available.
  107.      * </p>
  108.      */
  109.     @Override
  110.     public boolean yields(final SpacecraftState state) {
  111.         return !state.hasAdditionalData(stmName);
  112.     }

  113.     /** {@inheritDoc} */
  114.     @Override
  115.     public RealMatrix getAdditionalData(final SpacecraftState state) {

  116.         // State transition matrix for the input state
  117.         final RealMatrix dYdY0 = harvester.getStateTransitionMatrix(state);

  118.         // Compute the propagated covariance matrix
  119.         RealMatrix propCov = dYdY0.multiply(covMatrixInit.multiplyTransposed(dYdY0));
  120.         final StateCovariance propagated = new StateCovariance(propCov, state.getDate(), state.getFrame(), stmOrbitType, stmAngleType);

  121.         // Update to the user defined type
  122.         propCov = propagated.changeCovarianceType(state.getOrbit(), covOrbitType, covAngleType).getMatrix();

  123.         // Return the propagated covariance matrix
  124.         return propCov;

  125.     }

  126.     /**
  127.      * Get the orbit type in which the covariance matrix is expressed.
  128.      *
  129.      * @return the orbit type
  130.      */
  131.     public OrbitType getCovarianceOrbitType() {
  132.         return covOrbitType;
  133.     }

  134.     /**
  135.      * Get the state covariance in the same frame/local orbital frame, orbit type and position angle as the initial
  136.      * covariance.
  137.      *
  138.      * @param state spacecraft state to which the covariance matrix should correspond
  139.      * @return the state covariance
  140.      * @see #getStateCovariance(SpacecraftState, Frame)
  141.      * @see #getStateCovariance(SpacecraftState, OrbitType, PositionAngleType)
  142.      */
  143.     public StateCovariance getStateCovariance(final SpacecraftState state) {

  144.         // Get the current propagated covariance
  145.         final RealMatrix covarianceMatrix = getAdditionalData(state);

  146.         // Create associated state covariance
  147.         final StateCovariance covariance =
  148.                 new StateCovariance(covarianceMatrix, state.getDate(), state.getFrame(), covOrbitType, covAngleType);

  149.         // Return the state covariance in same frame/lof as initial covariance
  150.         if (covInit.getLOF() == null) {
  151.             return covariance;
  152.         }
  153.         else {
  154.             return covariance.changeCovarianceFrame(state.getOrbit(), covInit.getLOF());
  155.         }

  156.     }

  157.     /**
  158.      * Get the state covariance expressed in a given frame.
  159.      * <p>
  160.      * The output covariance matrix is expressed in the same orbit type as {@link #getCovarianceOrbitType()}.
  161.      *
  162.      * @param state spacecraft state to which the covariance matrix should correspond
  163.      * @param frame output frame for which the output covariance matrix must be expressed (must be inertial)
  164.      * @return the state covariance expressed in <code>frame</code>
  165.      * @see #getStateCovariance(SpacecraftState)
  166.      * @see #getStateCovariance(SpacecraftState, OrbitType, PositionAngleType)
  167.      */
  168.     public StateCovariance getStateCovariance(final SpacecraftState state, final Frame frame) {
  169.         // Return the converted covariance
  170.         return getStateCovariance(state).changeCovarianceFrame(state.getOrbit(), frame);
  171.     }

  172.     /**
  173.      * Get the state covariance expressed in a given orbit type.
  174.      *
  175.      * @param state spacecraft state to which the covariance matrix should correspond
  176.      * @param orbitType output orbit type
  177.      * @param angleType output position angle (not used if orbitType equals {@code CARTESIAN})
  178.      * @return the state covariance in <code>orbitType</code> and <code>angleType</code>
  179.      * @see #getStateCovariance(SpacecraftState)
  180.      * @see #getStateCovariance(SpacecraftState, Frame)
  181.      */
  182.     public StateCovariance getStateCovariance(final SpacecraftState state, final OrbitType orbitType,
  183.                                               final PositionAngleType angleType) {
  184.         // Return the converted covariance
  185.         return getStateCovariance(state).changeCovarianceType(state.getOrbit(), orbitType, angleType);
  186.     }
  187. }