PV.java

  1. /* Copyright 2002-2018 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.measurements;

  18. import java.util.Arrays;

  19. import org.hipparchus.exception.LocalizedCoreFormats;
  20. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  21. import org.hipparchus.util.FastMath;
  22. import org.orekit.errors.OrekitException;
  23. import org.orekit.propagation.SpacecraftState;
  24. import org.orekit.time.AbsoluteDate;
  25. import org.orekit.utils.TimeStampedPVCoordinates;

  26. /** Class modeling a position-velocity state.
  27.  * @author Luc Maisonobe
  28.  * @since 8.0
  29.  */
  30. public class PV extends AbstractMeasurement<PV> {

  31.     /** Identity matrix, for states derivatives. */
  32.     private static final double[][] IDENTITY = new double[][] {
  33.         {
  34.             1, 0, 0, 0, 0, 0
  35.         }, {
  36.             0, 1, 0, 0, 0, 0
  37.         }, {
  38.             0, 0, 1, 0, 0, 0
  39.         }, {
  40.             0, 0, 0, 1, 0, 0
  41.         }, {
  42.             0, 0, 0, 0, 1, 0
  43.         }, {
  44.             0, 0, 0, 0, 0, 1
  45.         }
  46.     };

  47.     /** Covariance matrix of the PV measurement (size 6x6). */
  48.     private final double[][] covarianceMatrix;

  49.     /** Constructor with two double for the standard deviations.
  50.      * The first double is the position's standard deviation, common to the 3 position's components.
  51.      * The second double is the position's standard deviation, common to the 3 position's components.
  52.      * <p>
  53.      * The measurement must be in the orbit propagation frame.
  54.      * </p>
  55.      * This constructor uses 0 as the index of the propagator related
  56.      * to this measurement, thus being well suited for mono-satellite
  57.      * orbit determination.
  58.      * @param date date of the measurement
  59.      * @param position position
  60.      * @param velocity velocity
  61.      * @param sigmaPosition theoretical standard deviation on position components
  62.      * @param sigmaVelocity theoretical standard deviation on velocity components
  63.      * @param baseWeight base weight
  64.      * @throws OrekitException if the built inside covariance matrix does not have the proper size
  65.      */
  66.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  67.               final double sigmaPosition, final double sigmaVelocity, final double baseWeight) throws OrekitException {
  68.         this(date, position, velocity, sigmaPosition, sigmaVelocity, baseWeight, 0);
  69.     }

  70.     /** Constructor with two double for the standard deviations.
  71.      * The first double is the position's standard deviation, common to the 3 position's components.
  72.      * The second double is the position's standard deviation, common to the 3 position's components.
  73.      * <p>
  74.      * The measurement must be in the orbit propagation frame.
  75.      * </p>
  76.      * @param date date of the measurement
  77.      * @param position position
  78.      * @param velocity velocity
  79.      * @param sigmaPosition theoretical standard deviation on position components
  80.      * @param sigmaVelocity theoretical standard deviation on velocity components
  81.      * @param baseWeight base weight
  82.      * @param propagatorIndex index of the propagator related to this measurement
  83.      * @throws OrekitException if the built inside covariance matrix does not have the proper size
  84.      * @since 9.0
  85.      */
  86.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  87.               final double sigmaPosition, final double sigmaVelocity, final double baseWeight,
  88.               final int propagatorIndex) throws OrekitException {
  89.         this(date, position, velocity,
  90.              new double[] {
  91.                  sigmaPosition,
  92.                  sigmaPosition,
  93.                  sigmaPosition,
  94.                  sigmaVelocity,
  95.                  sigmaVelocity,
  96.                  sigmaVelocity
  97.              }, baseWeight, propagatorIndex);
  98.     }

  99.     /** Constructor with two vectors for the standard deviations and default value for propagator index..
  100.      * One 3-sized vectors for position standard deviations.
  101.      * One 3-sized vectors for velocity standard deviations.
  102.      * The 3-sized vectors are the square root of the diagonal elements of the covariance matrix.
  103.      * <p>The measurement must be in the orbit propagation frame.</p>
  104.      * This constructor uses 0 as the index of the propagator related
  105.      * to this measurement, thus being well suited for mono-satellite
  106.      * orbit determination.
  107.      * @param date date of the measurement
  108.      * @param position position
  109.      * @param velocity velocity
  110.      * @param sigmaPosition 3-sized vector of the standard deviations of the position
  111.      * @param sigmaVelocity 3-sized vector of the standard deviations of the velocity
  112.      * @param baseWeight base weight
  113.      * @throws OrekitException if input standard deviations vectors do not have the proper sizes
  114.      * @since 9.2
  115.      */
  116.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  117.               final double[] sigmaPosition, final double[] sigmaVelocity, final double baseWeight) throws OrekitException {
  118.         this(date, position, velocity, sigmaPosition, sigmaVelocity, baseWeight, 0);
  119.     }

  120.     /** Constructor with two vectors for the standard deviations.
  121.      * One 3-sized vectors for position standard deviations.
  122.      * One 3-sized vectors for velocity standard deviations.
  123.      * The 3-sized vectors are the square root of the diagonal elements of the covariance matrix.
  124.      * <p>The measurement must be in the orbit propagation frame.</p>
  125.      * @param date date of the measurement
  126.      * @param position position
  127.      * @param velocity velocity
  128.      * @param sigmaPosition 3-sized vector of the standard deviations of the position
  129.      * @param sigmaVelocity 3-sized vector of the standard deviations of the velocity
  130.      * @param baseWeight base weight
  131.      * @param propagatorIndex index of the propagator related to this measurement
  132.      * @throws OrekitException if input standard deviations vectors do not have the proper sizes
  133.      * @since 9.2
  134.      */
  135.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  136.               final double[] sigmaPosition, final double[] sigmaVelocity,
  137.               final double baseWeight, final int propagatorIndex) throws OrekitException {
  138.         this(date, position, velocity,
  139.              buildPvCovarianceMatrix(sigmaPosition, sigmaVelocity),
  140.              baseWeight, propagatorIndex);
  141.     }

  142.     /** Constructor with one vector for the standard deviations and default value for propagator index.
  143.      * The 6-sized vector is the square root of the diagonal elements of the covariance matrix.
  144.      * <p>The measurement must be in the orbit propagation frame.</p>
  145.      * This constructor uses 0 as the index of the propagator related
  146.      * to this measurement, thus being well suited for mono-satellite
  147.      * orbit determination.
  148.      * @param date date of the measurement
  149.      * @param position position
  150.      * @param velocity velocity
  151.      * @param sigmaPV 6-sized vector of the standard deviations
  152.      * @param baseWeight base weight
  153.      * @throws OrekitException if input standard deviations vector does not have the proper size
  154.      * @since 9.2
  155.      */
  156.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  157.               final double[] sigmaPV, final double baseWeight) throws OrekitException {
  158.         this(date, position, velocity, sigmaPV, baseWeight, 0);
  159.     }

  160.     /** Constructor with one vector for the standard deviations.
  161.      * The 6-sized vector is the square root of the diagonal elements of the covariance matrix.
  162.      * <p>The measurement must be in the orbit propagation frame.</p>
  163.      * @param date date of the measurement
  164.      * @param position position
  165.      * @param velocity velocity
  166.      * @param sigmaPV 6-sized vector of the standard deviations
  167.      * @param baseWeight base weight
  168.      * @param propagatorIndex index of the propagator related to this measurement
  169.      * @throws OrekitException if input standard deviations vector does not have the proper size
  170.      * @since 9.2
  171.      */
  172.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  173.               final double[] sigmaPV, final double baseWeight, final int propagatorIndex) throws OrekitException {
  174.         this(date, position, velocity,
  175.              buildPvCovarianceMatrix(sigmaPV),
  176.              baseWeight, propagatorIndex);
  177.     }

  178.     /**
  179.      * Constructor with 2 smaller covariance matrices and default value for propagator index.
  180.      * One 3x3 covariance matrix for position and one 3x3 covariance matrix for velocity.
  181.      * The fact that the covariance matrices are symmetric and positive definite is not checked.
  182.      * <p>The measurement must be in the orbit propagation frame.</p>
  183.      * This constructor uses 0 as the index of the propagator related
  184.      * to this measurement, thus being well suited for mono-satellite
  185.      * orbit determination.
  186.      * @param date date of the measurement
  187.      * @param position position
  188.      * @param velocity velocity
  189.      * @param positionCovarianceMatrix 3x3 covariance matrix of the position
  190.      * @param velocityCovarianceMatrix 3x3 covariance matrix of the velocity
  191.      * @param baseWeight base weight
  192.      * @throws OrekitException if input covariance matrices do not have the proper sizes
  193.      * @since 9.2
  194.      */
  195.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  196.               final double[][] positionCovarianceMatrix, final double[][] velocityCovarianceMatrix,
  197.               final double baseWeight) throws OrekitException {
  198.         this(date, position, velocity, positionCovarianceMatrix, velocityCovarianceMatrix, baseWeight, 0);
  199.     }

  200.     /**
  201.      * Constructor with 2 smaller covariance matrices.
  202.      * One 3x3 covariance matrix for position and one 3x3 covariance matrix for velocity.
  203.      * The fact that the covariance matrices are symmetric and positive definite is not checked.
  204.      * <p>The measurement must be in the orbit propagation frame.</p>
  205.      * @param date date of the measurement
  206.      * @param position position
  207.      * @param velocity velocity
  208.      * @param positionCovarianceMatrix 3x3 covariance matrix of the position
  209.      * @param velocityCovarianceMatrix 3x3 covariance matrix of the velocity
  210.      * @param baseWeight base weight
  211.      * @param propagatorIndex index of the propagator related to this measurement
  212.      * @throws OrekitException if input covariance matrices do not have the proper sizes
  213.      * @since 9.2
  214.      */
  215.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  216.               final double[][] positionCovarianceMatrix, final double[][] velocityCovarianceMatrix,
  217.               final double baseWeight, final int propagatorIndex) throws OrekitException {
  218.         this(date, position, velocity,
  219.              buildPvCovarianceMatrix(positionCovarianceMatrix, velocityCovarianceMatrix),
  220.              baseWeight, propagatorIndex);
  221.     }

  222.     /**
  223.      * Constructor with full covariance matrix but default index for propagator.
  224.      * The fact that the covariance matrix is symmetric and positive definite is not checked.
  225.      * <p>The measurement must be in the orbit propagation frame.</p>
  226.      * This constructor uses 0 as the index of the propagator related
  227.      * to this measurement, thus being well suited for mono-satellite
  228.      * orbit determination.
  229.      * @param date date of the measurement
  230.      * @param position position
  231.      * @param velocity velocity
  232.      * @param covarianceMatrix 6x6 covariance matrix of the PV measurement
  233.      * @param baseWeight base weight
  234.      * @throws OrekitException if input covariance matrix does not have the proper size
  235.      * @since 9.2
  236.      */
  237.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  238.               final double[][] covarianceMatrix, final double baseWeight) throws OrekitException {
  239.         this(date, position, velocity, covarianceMatrix, baseWeight, 0);
  240.     }

  241.     /** Constructor with full covariance matrix and all inputs.
  242.      * The fact that the covariance matrix is symmetric and positive definite is not checked.
  243.      * <p>The measurement must be in the orbit propagation frame.</p>
  244.      * @param date date of the measurement
  245.      * @param position position
  246.      * @param velocity velocity
  247.      * @param covarianceMatrix 6x6 covariance matrix of the PV measurement
  248.      * @param baseWeight base weight
  249.      * @param propagatorIndex index of the propagator related to this measurement
  250.      * @throws OrekitException if input covariance matrix does not have the proper size
  251.      * @since 9.2
  252.      */
  253.     public PV(final AbsoluteDate date, final Vector3D position, final Vector3D velocity,
  254.               final double[][] covarianceMatrix, final double baseWeight, final int propagatorIndex)
  255.         throws OrekitException {
  256.         super(date,
  257.               new double[] {
  258.                   position.getX(), position.getY(), position.getZ(),
  259.                   velocity.getX(), velocity.getY(), velocity.getZ()
  260.               }, extractSigmas(covarianceMatrix),
  261.               new double[] {
  262.                   baseWeight, baseWeight, baseWeight,
  263.                   baseWeight, baseWeight, baseWeight
  264.               }, Arrays.asList(propagatorIndex));
  265.         this.covarianceMatrix = covarianceMatrix;
  266.     }

  267.     /** Get the position.
  268.      * @return position
  269.      */
  270.     public Vector3D getPosition() {
  271.         final double[] pv = getObservedValue();
  272.         return new Vector3D(pv[0], pv[1], pv[2]);
  273.     }

  274.     /** Get the velocity.
  275.      * @return velocity
  276.      */
  277.     public Vector3D getVelocity() {
  278.         final double[] pv = getObservedValue();
  279.         return new Vector3D(pv[3], pv[4], pv[5]);
  280.     }

  281.     /** Get the covariance matrix.
  282.      * @return the covariance matrix
  283.      */
  284.     public double[][] getCovarianceMatrix() {
  285.         return covarianceMatrix;
  286.     }

  287.     /** Get the correlation coefficients matrix.
  288.      * <br>This is the 6x6 matrix M such that:</br>
  289.      * <br>Mij = Pij/(σi.σj)</br>
  290.      * <br>Where: <ul>
  291.      * <li> P is the covariance matrix
  292.      * <li> σi is the i-th standard deviation (σi² = Pii)
  293.      * </ul>
  294.      * @return the correlation coefficient matrix (6x6)
  295.      */
  296.     public double[][] getCorrelationCoefficientsMatrix() {

  297.         // Get the standard deviations
  298.         final double[] sigmas = getTheoreticalStandardDeviation();

  299.         // Initialize the correlation coefficients matric to the covariance matrix
  300.         final double[][] corrCoefMatrix = new double[sigmas.length][sigmas.length];

  301.         // Divide by the standard deviations
  302.         for (int i = 0; i < sigmas.length; i++) {
  303.             for (int j = 0; j < sigmas.length; j++) {
  304.                 corrCoefMatrix[i][j] = covarianceMatrix[i][j] / (sigmas[i] * sigmas[j]);
  305.             }
  306.         }
  307.         return corrCoefMatrix;
  308.     }

  309.     /** {@inheritDoc} */
  310.     @Override
  311.     protected EstimatedMeasurement<PV> theoreticalEvaluation(final int iteration, final int evaluation,
  312.                                                              final SpacecraftState[] states)
  313.         throws OrekitException {

  314.         // PV value
  315.         final TimeStampedPVCoordinates pv = states[getPropagatorsIndices().get(0)].getPVCoordinates();

  316.         // prepare the evaluation
  317.         final EstimatedMeasurement<PV> estimated =
  318.                         new EstimatedMeasurement<>(this, iteration, evaluation, states,
  319.                                                    new TimeStampedPVCoordinates[] {
  320.                                                        pv
  321.                                                    });

  322.         estimated.setEstimatedValue(new double[] {
  323.             pv.getPosition().getX(), pv.getPosition().getY(), pv.getPosition().getZ(),
  324.             pv.getVelocity().getX(), pv.getVelocity().getY(), pv.getVelocity().getZ()
  325.         });

  326.         // partial derivatives with respect to state
  327.         estimated.setStateDerivatives(0, IDENTITY);

  328.         return estimated;
  329.     }

  330.     /** Extract standard deviations from a 6x6 PV covariance matrix.
  331.      * Check the size of the PV covariance matrix first.
  332.      * @param pvCovarianceMatrix the 6x6 PV covariance matrix
  333.      * @return the standard deviations (6-sized vector), they are
  334.      * the square roots of the diagonal elements of the covariance matrix in input.
  335.      * @throws OrekitException if the PV covariance matrix is not a 6x6 matrix
  336.      */
  337.     private static double[] extractSigmas(final double[][] pvCovarianceMatrix) throws OrekitException {

  338.         // Check the size of the covariance matrix, should be 6x6
  339.         if (pvCovarianceMatrix[0].length != 6 || pvCovarianceMatrix[1].length != 6) {
  340.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
  341.                                       pvCovarianceMatrix[0].length, pvCovarianceMatrix[1],
  342.                                       6, 6);
  343.         }

  344.         // Extract the standard deviations (square roots of the diagonal elements)
  345.         final double[] sigmas = new double[6];
  346.         for (int i = 0; i < sigmas.length; i++) {
  347.             sigmas[i] = FastMath.sqrt(pvCovarianceMatrix[i][i]);
  348.         }
  349.         return sigmas;
  350.     }

  351.     /** Build a 6x6 PV covariance matrix from two 3x3 matrices (covariances in position and velocity).
  352.      * Check the size of the matrices first.
  353.      * @param positionCovarianceMatrix the 3x3 covariance matrix in position
  354.      * @param velocityCovarianceMatrix the 3x3 covariance matrix in velocity
  355.      * @return the 6x6 PV covariance matrix
  356.      * @throws OrekitException if the matrices do not have the proper size
  357.      */
  358.     private static double[][] buildPvCovarianceMatrix(final double[][] positionCovarianceMatrix,
  359.                                                       final double[][] velocityCovarianceMatrix)
  360.         throws OrekitException {
  361.         // Check the sizes of the matrices first
  362.         if (positionCovarianceMatrix[0].length != 3 || positionCovarianceMatrix[1].length != 3) {
  363.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
  364.                                       positionCovarianceMatrix[0].length, positionCovarianceMatrix[1],
  365.                                       3, 3);
  366.         }
  367.         if (velocityCovarianceMatrix[0].length != 3 || velocityCovarianceMatrix[1].length != 3) {
  368.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
  369.                                       velocityCovarianceMatrix[0].length, velocityCovarianceMatrix[1],
  370.                                       3, 3);
  371.         }

  372.         // Build the PV 6x6 covariance matrix
  373.         final double[][] pvCovarianceMatrix = new double[6][6];
  374.         for (int i = 0; i < 3; i++) {
  375.             for (int j = 0; j < 3; j++) {
  376.                 pvCovarianceMatrix[i][j]         = positionCovarianceMatrix[i][j];
  377.                 pvCovarianceMatrix[i + 3][j + 3] = velocityCovarianceMatrix[i][j];
  378.             }
  379.         }
  380.         return pvCovarianceMatrix;
  381.     }

  382.     /** Build a 6x6 PV covariance matrix from a 6-sized vector (position and velocity standard deviations).
  383.      * Check the size of the vector first.
  384.      * @param sigmaPV 6-sized vector with position standard deviations on the first 3 elements
  385.      * and velocity standard deviations on the last 3 elements
  386.      * @return the 6x6 PV covariance matrix
  387.      * @throws OrekitException if the size of the vector is different from 6
  388.      */
  389.     private static double[][] buildPvCovarianceMatrix(final double[] sigmaPV) throws OrekitException {
  390.         // Check the size of the vector first
  391.         if (sigmaPV.length != 6) {
  392.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH, sigmaPV.length, 6);

  393.         }

  394.         // Build the PV 6x6 covariance matrix
  395.         final double[][] pvCovarianceMatrix = new double[6][6];
  396.         for (int i = 0; i < sigmaPV.length; i++) {
  397.             pvCovarianceMatrix[i][i] =  sigmaPV[i] * sigmaPV[i];
  398.         }
  399.         return pvCovarianceMatrix;
  400.     }

  401.     /** Build a 6x6 PV covariance matrix from two 3-sized vectors (position and velocity standard deviations).
  402.      * Check the sizes of the vectors first.
  403.      * @param sigmaPosition standard deviations of the position (3-size vector)
  404.      * @param sigmaVelocity standard deviations of the velocity (3-size vector)
  405.      * @return the 6x6 PV covariance matrix
  406.      * @throws OrekitException if the vectors do not have the proper sizes
  407.      */
  408.     private static double[][] buildPvCovarianceMatrix(final double[] sigmaPosition,
  409.                                                       final double[] sigmaVelocity)
  410.         throws OrekitException {

  411.         // Check the sizes of the vectors first
  412.         if (sigmaPosition.length != 3) {
  413.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH, sigmaPosition.length, 3);

  414.         }
  415.         if (sigmaVelocity.length != 3) {
  416.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH, sigmaVelocity.length, 3);

  417.         }

  418.         // Build the PV 6x6 covariance matrix
  419.         final double[][] pvCovarianceMatrix = new double[6][6];
  420.         for (int i = 0; i < sigmaPosition.length; i++) {
  421.             pvCovarianceMatrix[i][i]         =  sigmaPosition[i] * sigmaPosition[i];
  422.             pvCovarianceMatrix[i + 3][i + 3] =  sigmaVelocity[i] * sigmaVelocity[i];
  423.         }
  424.         return pvCovarianceMatrix;
  425.     }
  426. }