Position.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.estimation.measurements;

  18. import java.util.Collections;

  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.     /** Type of the measurement. */
  36.     public static final String MEASUREMENT_TYPE = "Position";

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

  47.     /** Covariance matrix of the position only measurement (size 3x3). */
  48.     private final double[][] covarianceMatrix;

  49.     /** Constructor with one double for the standard deviation.
  50.      * <p>The double is the position's standard deviation, common to the 3 position's components.</p>
  51.      * <p>
  52.      * The measurement must be in the orbit propagation frame.
  53.      * </p>
  54.      * @param date date of the measurement
  55.      * @param position position
  56.      * @param sigmaPosition theoretical standard deviation on position components
  57.      * @param baseWeight base weight
  58.      * @param satellite satellite related to this measurement
  59.      * @since 9.3
  60.      */
  61.     public Position(final AbsoluteDate date, final Vector3D position,
  62.                     final double sigmaPosition, final double baseWeight,
  63.                     final ObservableSatellite satellite) {
  64.         this(date, position,
  65.              new double[] {
  66.                  sigmaPosition,
  67.                  sigmaPosition,
  68.                  sigmaPosition
  69.              }, baseWeight, satellite);
  70.     }

  71.     /** Constructor with one vector for the standard deviation.
  72.      * <p>The 3-sized vector represents the square root of the diagonal elements of the covariance matrix.</p>
  73.      * <p>The measurement must be in the orbit propagation frame.</p>
  74.      * @param date date of the measurement
  75.      * @param position position
  76.      * @param sigmaPosition 3-sized vector of the standard deviations of the position
  77.      * @param baseWeight base weight
  78.      * @param satellite satellite related to this measurement
  79.      * @since 9.3
  80.      */
  81.     public Position(final AbsoluteDate date, final Vector3D position,
  82.                     final double[] sigmaPosition, final double baseWeight, final ObservableSatellite satellite) {
  83.         this(date, position, buildPvCovarianceMatrix(sigmaPosition), baseWeight, satellite);
  84.     }

  85.     /** Constructor with full covariance matrix and all inputs.
  86.      * <p>The fact that the covariance matrix is symmetric and positive definite is not checked.</p>
  87.      * <p>The measurement must be in the orbit propagation frame.</p>
  88.      * @param date date of the measurement
  89.      * @param position position
  90.      * @param covarianceMatrix 3x3 covariance matrix of the position only measurement
  91.      * @param baseWeight base weight
  92.      * @param satellite satellite related to this measurement
  93.      * @since 9.3
  94.      */
  95.     public Position(final AbsoluteDate date, final Vector3D position,
  96.                     final double[][] covarianceMatrix, final double baseWeight,
  97.                     final ObservableSatellite satellite) {
  98.         super(date,
  99.               new double[] {
  100.                   position.getX(), position.getY(), position.getZ()
  101.               }, extractSigmas(covarianceMatrix),
  102.               new double[] {
  103.                   baseWeight, baseWeight, baseWeight
  104.               }, Collections.singletonList(satellite));
  105.         this.covarianceMatrix = covarianceMatrix.clone();
  106.     }

  107.     /** Get the position.
  108.      * @return position
  109.      */
  110.     public Vector3D getPosition() {
  111.         final double[] pv = getObservedValue();
  112.         return new Vector3D(pv[0], pv[1], pv[2]);
  113.     }

  114.     /** Get the covariance matrix.
  115.      * @return the covariance matrix
  116.      */
  117.     public double[][] getCovarianceMatrix() {
  118.         return covarianceMatrix.clone();
  119.     }

  120.     /** Get the correlation coefficients matrix.
  121.      * <p>This is the 3x3 matrix M such that:
  122.      * <p>Mij = Pij/(σi.σj)
  123.      * <p>Where:
  124.      * <ul>
  125.      * <li>P is the covariance matrix
  126.      * <li>σi is the i-th standard deviation (σi² = Pii)
  127.      * </ul>
  128.      * @return the correlation coefficient matrix (3x3)
  129.      */
  130.     public double[][] getCorrelationCoefficientsMatrix() {

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

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

  135.         // Divide by the standard deviations
  136.         for (int i = 0; i < sigmas.length; i++) {
  137.             for (int j = 0; j < sigmas.length; j++) {
  138.                 corrCoefMatrix[i][j] = covarianceMatrix[i][j] / (sigmas[i] * sigmas[j]);
  139.             }
  140.         }
  141.         return corrCoefMatrix;
  142.     }

  143.     /** {@inheritDoc} */
  144.     @Override
  145.     protected EstimatedMeasurementBase<Position> theoreticalEvaluationWithoutDerivatives(final int iteration, final int evaluation,
  146.                                                                                          final SpacecraftState[] states) {

  147.         // PV value
  148.         final TimeStampedPVCoordinates pv = states[0].getPVCoordinates();

  149.         // prepare the evaluation
  150.         final EstimatedMeasurementBase<Position> estimated =
  151.                         new EstimatedMeasurementBase<>(this, iteration, evaluation, states,
  152.                                                        new TimeStampedPVCoordinates[] {
  153.                                                            pv
  154.                                                        });

  155.         estimated.setEstimatedValue(pv.getPosition().getX(), pv.getPosition().getY(), pv.getPosition().getZ());

  156.         return estimated;

  157.     }

  158.     /** {@inheritDoc} */
  159.     @Override
  160.     protected EstimatedMeasurement<Position> theoreticalEvaluation(final int iteration, final int evaluation,
  161.                                                                    final SpacecraftState[] states) {

  162.         final EstimatedMeasurement<Position> estimated = new EstimatedMeasurement<>(theoreticalEvaluationWithoutDerivatives(iteration, evaluation, states));

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

  165.         return estimated;
  166.     }

  167.     /** Extract standard deviations from a 3x3 position covariance matrix.
  168.      * Check the size of the position covariance matrix first.
  169.      * @param pCovarianceMatrix the 3x" position covariance matrix
  170.      * @return the standard deviations (3-sized vector), they are
  171.      * the square roots of the diagonal elements of the covariance matrix in input.
  172.      */
  173.     private static double[] extractSigmas(final double[][] pCovarianceMatrix) {

  174.         // Check the size of the covariance matrix, should be 3x3
  175.         if (pCovarianceMatrix.length != 3 || pCovarianceMatrix[0].length != 3) {
  176.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
  177.                                       pCovarianceMatrix.length, pCovarianceMatrix[0],
  178.                                       3, 3);
  179.         }

  180.         // Extract the standard deviations (square roots of the diagonal elements)
  181.         final double[] sigmas = new double[3];
  182.         for (int i = 0; i < sigmas.length; i++) {
  183.             sigmas[i] = FastMath.sqrt(pCovarianceMatrix[i][i]);
  184.         }
  185.         return sigmas;
  186.     }

  187.     /** Build a 3x3 position covariance matrix from a 3-sized vector (position standard deviations).
  188.      * Check the size of the vector first.
  189.      * @param sigmaP 3-sized vector with position standard deviations
  190.      * @return the 3x3 position covariance matrix
  191.      */
  192.     private static double[][] buildPvCovarianceMatrix(final double[] sigmaP) {
  193.         // Check the size of the vector first
  194.         if (sigmaP.length != 3) {
  195.             throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH, sigmaP.length, 3);

  196.         }

  197.         // Build the 3x3 position covariance matrix
  198.         final double[][] pvCovarianceMatrix = new double[3][3];
  199.         for (int i = 0; i < sigmaP.length; i++) {
  200.             pvCovarianceMatrix[i][i] =  sigmaP[i] * sigmaP[i];
  201.         }
  202.         return pvCovarianceMatrix;
  203.     }

  204. }