Position.java

  1. /* Copyright 2002-2019 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 only measurement.
  27.  * <p>
  28.  * For position-velocity measurement see {@link PV}.
  29.  * </p>
  30.  * @see PV
  31.  * @author Luc Maisonobe
  32.  * @since 9.3
  33.  */
  34. public class Position extends AbstractMeasurement<Position> {

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

  45.     /** Covariance matrix of the PV measurement (size 3x3). */
  46.     private final double[][] covarianceMatrix;

  47.     /** Constructor with one double for the standard deviation.
  48.      * <p>The double is the position's standard deviation, common to the 3 position's components.</p>
  49.      * <p>
  50.      * The measurement must be in the orbit propagation frame.
  51.      * </p>
  52.      * <p>This constructor uses 0 as the index of the propagator related
  53.      * to this measurement, thus being well suited for mono-satellite
  54.      * orbit determination.</p>
  55.      * @param date date of the measurement
  56.      * @param position position
  57.      * @param sigmaPosition theoretical standard deviation on position components
  58.      * @param baseWeight base weight
  59.      * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D,
  60.      * double, double, ObservableSatellite)}
  61.      */
  62.     @Deprecated
  63.     public Position(final AbsoluteDate date, final Vector3D position,
  64.                     final double sigmaPosition, final double baseWeight) {
  65.         this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(0));
  66.     }

  67.     /** Constructor with one double for the standard deviation.
  68.      * <p>The double is the position's standard deviation, common to the 3 position's components.</p>
  69.      * <p>
  70.      * The measurement must be in the orbit propagation frame.
  71.      * </p>
  72.      * @param date date of the measurement
  73.      * @param position position
  74.      * @param sigmaPosition theoretical standard deviation on position components
  75.      * @param baseWeight base weight
  76.      * @param propagatorIndex index of the propagator related to this measurement
  77.      * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D,
  78.      * double, double, ObservableSatellite)}
  79.      */
  80.     @Deprecated
  81.     public Position(final AbsoluteDate date, final Vector3D position,
  82.                     final double sigmaPosition, final double baseWeight,
  83.                     final int propagatorIndex) {
  84.         this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(propagatorIndex));
  85.     }

  86.     /** Constructor with one double for the standard deviation.
  87.      * <p>The double is the position's standard deviation, common to the 3 position's components.</p>
  88.      * <p>
  89.      * The measurement must be in the orbit propagation frame.
  90.      * </p>
  91.      * @param date date of the measurement
  92.      * @param position position
  93.      * @param sigmaPosition theoretical standard deviation on position components
  94.      * @param baseWeight base weight
  95.      * @param satellite satellite related to this measurement
  96.      * @since 9.3
  97.      */
  98.     public Position(final AbsoluteDate date, final Vector3D position,
  99.                     final double sigmaPosition, final double baseWeight,
  100.                     final ObservableSatellite satellite) {
  101.         this(date, position,
  102.              new double[] {
  103.                  sigmaPosition,
  104.                  sigmaPosition,
  105.                  sigmaPosition
  106.              }, baseWeight, satellite);
  107.     }

  108.     /** Constructor with one vector for the standard deviation and default value for propagator index..
  109.      * <p>The 3-sized vector represents the square root of the diagonal elements of the covariance matrix.</p>
  110.      * <p>The measurement must be in the orbit propagation frame.</p>
  111.      * <p>This constructor uses 0 as the index of the propagator related
  112.      * to this measurement, thus being well suited for mono-satellite
  113.      * orbit determination.</p>
  114.      * @param date date of the measurement
  115.      * @param position position
  116.      * @param sigmaPosition 3-sized vector of the standard deviations of the position
  117.      * @param baseWeight base weight
  118.      * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D,
  119.      * double[], double, ObservableSatellite)}
  120.      */
  121.     @Deprecated
  122.     public Position(final AbsoluteDate date, final Vector3D position,
  123.                     final double[] sigmaPosition, final double baseWeight) {
  124.         this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(0));
  125.     }

  126.     /** Constructor with one vector for the standard deviation.
  127.      * <p>The 3-sized vector represents the square root of the diagonal elements of the covariance matrix.</p>
  128.      * <p>The measurement must be in the orbit propagation frame.</p>
  129.      * @param date date of the measurement
  130.      * @param position position
  131.      * @param sigmaPosition 3-sized vector of the standard deviations of the position
  132.      * @param baseWeight base weight
  133.      * @param propagatorIndex index of the propagator related to this measurement
  134.      * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D,
  135.      * double[], double, ObservableSatellite)}
  136.      */
  137.     @Deprecated
  138.     public Position(final AbsoluteDate date, final Vector3D position,
  139.                     final double[] sigmaPosition, final double baseWeight, final int propagatorIndex) {
  140.         this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(propagatorIndex));
  141.     }

  142.     /** Constructor with one vector for the standard deviation.
  143.      * <p>The 3-sized vector represents the square root of the diagonal elements of the covariance matrix.</p>
  144.      * <p>The measurement must be in the orbit propagation frame.</p>
  145.      * @param date date of the measurement
  146.      * @param position position
  147.      * @param sigmaPosition 3-sized vector of the standard deviations of the position
  148.      * @param baseWeight base weight
  149.      * @param satellite satellite related to this measurement
  150.      * @since 9.3
  151.      */
  152.     public Position(final AbsoluteDate date, final Vector3D position,
  153.                     final double[] sigmaPosition, final double baseWeight, final ObservableSatellite satellite) {
  154.         this(date, position, buildPvCovarianceMatrix(sigmaPosition), baseWeight, satellite);
  155.     }

  156.     /**
  157.      * Constructor with a covariance matrix and default value for propagator index.
  158.      * <p>The fact that the covariance matrices are symmetric and positive definite is not checked.</p>
  159.      * <p>The measurement must be in the orbit propagation frame.</p>
  160.      * <p>This constructor uses 0 as the index of the propagator related
  161.      * to this measurement, thus being well suited for mono-satellite
  162.      * orbit determination.</p>
  163.      * @param date date of the measurement
  164.      * @param position position
  165.      * @param positionCovarianceMatrix 3x3 covariance matrix of the position
  166.      * @param baseWeight base weight
  167.      * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D,
  168.      * double[][], double, ObservableSatellite)}
  169.      */
  170.     @Deprecated
  171.     public Position(final AbsoluteDate date, final Vector3D position,
  172.                     final double[][] positionCovarianceMatrix, final double baseWeight) {
  173.         this(date, position, positionCovarianceMatrix, baseWeight, new ObservableSatellite(0));
  174.     }

  175.     /** Constructor with full covariance matrix and all inputs.
  176.      * <p>The fact that the covariance matrix is symmetric and positive definite is not checked.</p>
  177.      * <p>The measurement must be in the orbit propagation frame.</p>
  178.      * @param date date of the measurement
  179.      * @param position position
  180.      * @param covarianceMatrix 6x6 covariance matrix of the PV measurement
  181.      * @param baseWeight base weight
  182.      * @param propagatorIndex index of the propagator related to this measurement
  183.      * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D,
  184.      * double[][], double, ObservableSatellite)}
  185.      */
  186.     @Deprecated
  187.     public Position(final AbsoluteDate date, final Vector3D position,
  188.                     final double[][] covarianceMatrix, final double baseWeight,
  189.                     final int propagatorIndex) {
  190.         this(date, position, covarianceMatrix, baseWeight, new ObservableSatellite(propagatorIndex));
  191.     }

  192.     /** Constructor with full covariance matrix and all inputs.
  193.      * <p>The fact that the covariance matrix is symmetric and positive definite is not checked.</p>
  194.      * <p>The measurement must be in the orbit propagation frame.</p>
  195.      * @param date date of the measurement
  196.      * @param position position
  197.      * @param covarianceMatrix 6x6 covariance matrix of the PV measurement
  198.      * @param baseWeight base weight
  199.      * @param satellite satellite related to this measurement
  200.      * @since 9.3
  201.      */
  202.     public Position(final AbsoluteDate date, final Vector3D position,
  203.                     final double[][] covarianceMatrix, final double baseWeight,
  204.                     final ObservableSatellite satellite) {
  205.         super(date,
  206.               new double[] {
  207.                   position.getX(), position.getY(), position.getZ()
  208.               }, extractSigmas(covarianceMatrix),
  209.               new double[] {
  210.                   baseWeight, baseWeight, baseWeight
  211.               }, Arrays.asList(satellite));
  212.         this.covarianceMatrix = covarianceMatrix;
  213.     }

  214.     /** Get the position.
  215.      * @return position
  216.      */
  217.     public Vector3D getPosition() {
  218.         final double[] pv = getObservedValue();
  219.         return new Vector3D(pv[0], pv[1], pv[2]);
  220.     }

  221.     /** Get the covariance matrix.
  222.      * @return the covariance matrix
  223.      */
  224.     public double[][] getCovarianceMatrix() {
  225.         return covarianceMatrix;
  226.     }

  227.     /** Get the correlation coefficients matrix.
  228.      * <br>This is the 3x3 matrix M such that:</br>
  229.      * <br>Mij = Pij/(σi.σj)</br>
  230.      * <br>Where: <ul>
  231.      * <li> P is the covariance matrix
  232.      * <li> σi is the i-th standard deviation (σi² = Pii)
  233.      * </ul>
  234.      * @return the correlation coefficient matrix (3x3)
  235.      */
  236.     public double[][] getCorrelationCoefficientsMatrix() {

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

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

  241.         // Divide by the standard deviations
  242.         for (int i = 0; i < sigmas.length; i++) {
  243.             for (int j = 0; j < sigmas.length; j++) {
  244.                 corrCoefMatrix[i][j] = covarianceMatrix[i][j] / (sigmas[i] * sigmas[j]);
  245.             }
  246.         }
  247.         return corrCoefMatrix;
  248.     }

  249.     /** {@inheritDoc} */
  250.     @Override
  251.     protected EstimatedMeasurement<Position> theoreticalEvaluation(final int iteration, final int evaluation,
  252.                                                                    final SpacecraftState[] states) {

  253.         // PV value
  254.         final ObservableSatellite      satellite = getSatellites().get(0);
  255.         final SpacecraftState          state     = states[satellite.getPropagatorIndex()];
  256.         final TimeStampedPVCoordinates pv        = state.getPVCoordinates();

  257.         // prepare the evaluation
  258.         final EstimatedMeasurement<Position> estimated =
  259.                         new EstimatedMeasurement<>(this, iteration, evaluation, states,
  260.                                                    new TimeStampedPVCoordinates[] {
  261.                                                        pv
  262.                                                    });

  263.         estimated.setEstimatedValue(new double[] {
  264.             pv.getPosition().getX(), pv.getPosition().getY(), pv.getPosition().getZ()
  265.         });

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

  268.         return estimated;
  269.     }

  270.     /** Extract standard deviations from a 3x3 position covariance matrix.
  271.      * Check the size of the position covariance matrix first.
  272.      * @param pCovarianceMatrix the 3x" possition covariance matrix
  273.      * @return the standard deviations (3-sized vector), they are
  274.      * the square roots of the diagonal elements of the covariance matrix in input.
  275.      */
  276.     private static double[] extractSigmas(final double[][] pCovarianceMatrix) {

  277.         // Check the size of the covariance matrix, should be 3x3
  278.         if (pCovarianceMatrix.length != 3 || pCovarianceMatrix[0].length != 3) {
  279.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
  280.                                       pCovarianceMatrix.length, pCovarianceMatrix[0],
  281.                                       3, 3);
  282.         }

  283.         // Extract the standard deviations (square roots of the diagonal elements)
  284.         final double[] sigmas = new double[3];
  285.         for (int i = 0; i < sigmas.length; i++) {
  286.             sigmas[i] = FastMath.sqrt(pCovarianceMatrix[i][i]);
  287.         }
  288.         return sigmas;
  289.     }

  290.     /** Build a 3x3 position covariance matrix from a 3-sized vector (position standard deviations).
  291.      * Check the size of the vector first.
  292.      * @param sigmaP 3-sized vector with position standard deviations
  293.      * @return the 3x3 position covariance matrix
  294.      */
  295.     private static double[][] buildPvCovarianceMatrix(final double[] sigmaP) {
  296.         // Check the size of the vector first
  297.         if (sigmaP.length != 3) {
  298.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH, sigmaP.length, 3);

  299.         }

  300.         // Build the 3x3 position covariance matrix
  301.         final double[][] pvCovarianceMatrix = new double[3][3];
  302.         for (int i = 0; i < sigmaP.length; i++) {
  303.             pvCovarianceMatrix[i][i] =  sigmaP[i] * sigmaP[i];
  304.         }
  305.         return pvCovarianceMatrix;
  306.     }

  307. }