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 19 import java.util.Arrays; 20 21 import org.hipparchus.exception.LocalizedCoreFormats; 22 import org.hipparchus.geometry.euclidean.threed.Vector3D; 23 import org.hipparchus.util.FastMath; 24 import org.orekit.errors.OrekitException; 25 import org.orekit.propagation.SpacecraftState; 26 import org.orekit.time.AbsoluteDate; 27 import org.orekit.utils.TimeStampedPVCoordinates; 28 29 /** Class modeling a position only measurement. 30 * <p> 31 * For position-velocity measurement see {@link PV}. 32 * </p> 33 * @see PV 34 * @author Luc Maisonobe 35 * @since 9.3 36 */ 37 public class Position extends AbstractMeasurement<Position> { 38 39 /** Identity matrix, for states derivatives. */ 40 private static final double[][] IDENTITY = new double[][] { 41 { 42 1, 0, 0, 0, 0, 0 43 }, { 44 0, 1, 0, 0, 0, 0 45 }, { 46 0, 0, 1, 0, 0, 0 47 } 48 }; 49 50 /** Covariance matrix of the PV measurement (size 3x3). */ 51 private final double[][] covarianceMatrix; 52 53 /** Constructor with one double for the standard deviation. 54 * <p>The double is the position's standard deviation, common to the 3 position's components.</p> 55 * <p> 56 * The measurement must be in the orbit propagation frame. 57 * </p> 58 * <p>This constructor uses 0 as the index of the propagator related 59 * to this measurement, thus being well suited for mono-satellite 60 * orbit determination.</p> 61 * @param date date of the measurement 62 * @param position position 63 * @param sigmaPosition theoretical standard deviation on position components 64 * @param baseWeight base weight 65 * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D, 66 * double, double, ObservableSatellite)} 67 */ 68 @Deprecated 69 public Position(final AbsoluteDate date, final Vector3D position, 70 final double sigmaPosition, final double baseWeight) { 71 this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(0)); 72 } 73 74 /** Constructor with one double for the standard deviation. 75 * <p>The double is the position's standard deviation, common to the 3 position's components.</p> 76 * <p> 77 * The measurement must be in the orbit propagation frame. 78 * </p> 79 * @param date date of the measurement 80 * @param position position 81 * @param sigmaPosition theoretical standard deviation on position components 82 * @param baseWeight base weight 83 * @param propagatorIndex index of the propagator related to this measurement 84 * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D, 85 * double, double, ObservableSatellite)} 86 */ 87 @Deprecated 88 public Position(final AbsoluteDate date, final Vector3D position, 89 final double sigmaPosition, final double baseWeight, 90 final int propagatorIndex) { 91 this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(propagatorIndex)); 92 } 93 94 /** Constructor with one double for the standard deviation. 95 * <p>The double is the position's standard deviation, common to the 3 position's components.</p> 96 * <p> 97 * The measurement must be in the orbit propagation frame. 98 * </p> 99 * @param date date of the measurement 100 * @param position position 101 * @param sigmaPosition theoretical standard deviation on position components 102 * @param baseWeight base weight 103 * @param satellite satellite related to this measurement 104 * @since 9.3 105 */ 106 public Position(final AbsoluteDate date, final Vector3D position, 107 final double sigmaPosition, final double baseWeight, 108 final ObservableSatellite satellite) { 109 this(date, position, 110 new double[] { 111 sigmaPosition, 112 sigmaPosition, 113 sigmaPosition 114 }, baseWeight, satellite); 115 } 116 117 /** Constructor with one vector for the standard deviation and default value for propagator index.. 118 * <p>The 3-sized vector represents the square root of the diagonal elements of the covariance matrix.</p> 119 * <p>The measurement must be in the orbit propagation frame.</p> 120 * <p>This constructor uses 0 as the index of the propagator related 121 * to this measurement, thus being well suited for mono-satellite 122 * orbit determination.</p> 123 * @param date date of the measurement 124 * @param position position 125 * @param sigmaPosition 3-sized vector of the standard deviations of the position 126 * @param baseWeight base weight 127 * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D, 128 * double[], double, ObservableSatellite)} 129 */ 130 @Deprecated 131 public Position(final AbsoluteDate date, final Vector3D position, 132 final double[] sigmaPosition, final double baseWeight) { 133 this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(0)); 134 } 135 136 /** Constructor with one vector for the standard deviation. 137 * <p>The 3-sized vector represents the square root of the diagonal elements of the covariance matrix.</p> 138 * <p>The measurement must be in the orbit propagation frame.</p> 139 * @param date date of the measurement 140 * @param position position 141 * @param sigmaPosition 3-sized vector of the standard deviations of the position 142 * @param baseWeight base weight 143 * @param propagatorIndex index of the propagator related to this measurement 144 * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D, 145 * double[], double, ObservableSatellite)} 146 */ 147 @Deprecated 148 public Position(final AbsoluteDate date, final Vector3D position, 149 final double[] sigmaPosition, final double baseWeight, final int propagatorIndex) { 150 this(date, position, sigmaPosition, baseWeight, new ObservableSatellite(propagatorIndex)); 151 } 152 153 /** Constructor with one vector for the standard deviation. 154 * <p>The 3-sized vector represents the square root of the diagonal elements of the covariance matrix.</p> 155 * <p>The measurement must be in the orbit propagation frame.</p> 156 * @param date date of the measurement 157 * @param position position 158 * @param sigmaPosition 3-sized vector of the standard deviations of the position 159 * @param baseWeight base weight 160 * @param satellite satellite related to this measurement 161 * @since 9.3 162 */ 163 public Position(final AbsoluteDate date, final Vector3D position, 164 final double[] sigmaPosition, final double baseWeight, final ObservableSatellite satellite) { 165 this(date, position, buildPvCovarianceMatrix(sigmaPosition), baseWeight, satellite); 166 } 167 168 /** 169 * Constructor with a covariance matrix and default value for propagator index. 170 * <p>The fact that the covariance matrices are symmetric and positive definite is not checked.</p> 171 * <p>The measurement must be in the orbit propagation frame.</p> 172 * <p>This constructor uses 0 as the index of the propagator related 173 * to this measurement, thus being well suited for mono-satellite 174 * orbit determination.</p> 175 * @param date date of the measurement 176 * @param position position 177 * @param positionCovarianceMatrix 3x3 covariance matrix of the position 178 * @param baseWeight base weight 179 * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D, 180 * double[][], double, ObservableSatellite)} 181 */ 182 @Deprecated 183 public Position(final AbsoluteDate date, final Vector3D position, 184 final double[][] positionCovarianceMatrix, final double baseWeight) { 185 this(date, position, positionCovarianceMatrix, baseWeight, new ObservableSatellite(0)); 186 } 187 188 /** Constructor with full covariance matrix and all inputs. 189 * <p>The fact that the covariance matrix is symmetric and positive definite is not checked.</p> 190 * <p>The measurement must be in the orbit propagation frame.</p> 191 * @param date date of the measurement 192 * @param position position 193 * @param covarianceMatrix 6x6 covariance matrix of the PV measurement 194 * @param baseWeight base weight 195 * @param propagatorIndex index of the propagator related to this measurement 196 * @deprecated as of 9.3, replaced by {@link #Position(AbsoluteDate, Vector3D, 197 * double[][], double, ObservableSatellite)} 198 */ 199 @Deprecated 200 public Position(final AbsoluteDate date, final Vector3D position, 201 final double[][] covarianceMatrix, final double baseWeight, 202 final int propagatorIndex) { 203 this(date, position, covarianceMatrix, baseWeight, new ObservableSatellite(propagatorIndex)); 204 } 205 206 /** Constructor with full covariance matrix and all inputs. 207 * <p>The fact that the covariance matrix is symmetric and positive definite is not checked.</p> 208 * <p>The measurement must be in the orbit propagation frame.</p> 209 * @param date date of the measurement 210 * @param position position 211 * @param covarianceMatrix 6x6 covariance matrix of the PV measurement 212 * @param baseWeight base weight 213 * @param satellite satellite related to this measurement 214 * @since 9.3 215 */ 216 public Position(final AbsoluteDate date, final Vector3D position, 217 final double[][] covarianceMatrix, final double baseWeight, 218 final ObservableSatellite satellite) { 219 super(date, 220 new double[] { 221 position.getX(), position.getY(), position.getZ() 222 }, extractSigmas(covarianceMatrix), 223 new double[] { 224 baseWeight, baseWeight, baseWeight 225 }, Arrays.asList(satellite)); 226 this.covarianceMatrix = covarianceMatrix; 227 } 228 229 /** Get the position. 230 * @return position 231 */ 232 public Vector3D getPosition() { 233 final double[] pv = getObservedValue(); 234 return new Vector3D(pv[0], pv[1], pv[2]); 235 } 236 237 /** Get the covariance matrix. 238 * @return the covariance matrix 239 */ 240 public double[][] getCovarianceMatrix() { 241 return covarianceMatrix; 242 } 243 244 /** Get the correlation coefficients matrix. 245 * <br>This is the 3x3 matrix M such that:</br> 246 * <br>Mij = Pij/(σi.σj)</br> 247 * <br>Where: <ul> 248 * <li> P is the covariance matrix 249 * <li> σi is the i-th standard deviation (σi² = Pii) 250 * </ul> 251 * @return the correlation coefficient matrix (3x3) 252 */ 253 public double[][] getCorrelationCoefficientsMatrix() { 254 255 // Get the standard deviations 256 final double[] sigmas = getTheoreticalStandardDeviation(); 257 258 // Initialize the correlation coefficients matric to the covariance matrix 259 final double[][] corrCoefMatrix = new double[sigmas.length][sigmas.length]; 260 261 // Divide by the standard deviations 262 for (int i = 0; i < sigmas.length; i++) { 263 for (int j = 0; j < sigmas.length; j++) { 264 corrCoefMatrix[i][j] = covarianceMatrix[i][j] / (sigmas[i] * sigmas[j]); 265 } 266 } 267 return corrCoefMatrix; 268 } 269 270 /** {@inheritDoc} */ 271 @Override 272 protected EstimatedMeasurement<Position> theoreticalEvaluation(final int iteration, final int evaluation, 273 final SpacecraftState[] states) { 274 275 // PV value 276 final ObservableSatellite satellite = getSatellites().get(0); 277 final SpacecraftState state = states[satellite.getPropagatorIndex()]; 278 final TimeStampedPVCoordinates pv = state.getPVCoordinates(); 279 280 // prepare the evaluation 281 final EstimatedMeasurement<Position> estimated = 282 new EstimatedMeasurement<>(this, iteration, evaluation, states, 283 new TimeStampedPVCoordinates[] { 284 pv 285 }); 286 287 estimated.setEstimatedValue(new double[] { 288 pv.getPosition().getX(), pv.getPosition().getY(), pv.getPosition().getZ() 289 }); 290 291 // partial derivatives with respect to state 292 estimated.setStateDerivatives(0, IDENTITY); 293 294 return estimated; 295 } 296 297 /** Extract standard deviations from a 3x3 position covariance matrix. 298 * Check the size of the position covariance matrix first. 299 * @param pCovarianceMatrix the 3x" possition covariance matrix 300 * @return the standard deviations (3-sized vector), they are 301 * the square roots of the diagonal elements of the covariance matrix in input. 302 */ 303 private static double[] extractSigmas(final double[][] pCovarianceMatrix) { 304 305 // Check the size of the covariance matrix, should be 3x3 306 if (pCovarianceMatrix.length != 3 || pCovarianceMatrix[0].length != 3) { 307 throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2, 308 pCovarianceMatrix.length, pCovarianceMatrix[0], 309 3, 3); 310 } 311 312 // Extract the standard deviations (square roots of the diagonal elements) 313 final double[] sigmas = new double[3]; 314 for (int i = 0; i < sigmas.length; i++) { 315 sigmas[i] = FastMath.sqrt(pCovarianceMatrix[i][i]); 316 } 317 return sigmas; 318 } 319 320 /** Build a 3x3 position covariance matrix from a 3-sized vector (position standard deviations). 321 * Check the size of the vector first. 322 * @param sigmaP 3-sized vector with position standard deviations 323 * @return the 3x3 position covariance matrix 324 */ 325 private static double[][] buildPvCovarianceMatrix(final double[] sigmaP) { 326 // Check the size of the vector first 327 if (sigmaP.length != 3) { 328 throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH, sigmaP.length, 3); 329 330 } 331 332 // Build the 3x3 position covariance matrix 333 final double[][] pvCovarianceMatrix = new double[3][3]; 334 for (int i = 0; i < sigmaP.length; i++) { 335 pvCovarianceMatrix[i][i] = sigmaP[i] * sigmaP[i]; 336 } 337 return pvCovarianceMatrix; 338 } 339 340 }