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.sequential; 18 19 import org.hipparchus.analysis.UnivariateFunction; 20 import org.hipparchus.linear.MatrixUtils; 21 import org.hipparchus.linear.RealMatrix; 22 import org.orekit.frames.LOFType; 23 import org.orekit.orbits.PositionAngleType; 24 import org.orekit.propagation.SpacecraftState; 25 import org.orekit.propagation.StateCovariance; 26 27 /** Provider for a temporal evolution of the process noise matrix. 28 * All parameters (orbital or propagation) are time dependent and provided as {@link UnivariateFunction}. 29 * The argument of the functions is a duration in seconds (between current and previous spacecraft state). 30 * The output of the functions must be of the dimension of a standard deviation. 31 * The method {@link #getProcessNoiseMatrix} then square the values so that they are consistent with a covariance matrix. 32 * <p> 33 * The orbital parameters evolutions are provided in LOF frame and Cartesian (PV); 34 * then converted in inertial frame and current {@link org.orekit.orbits.OrbitType} and {@link PositionAngleType} 35 * when method {@link #getProcessNoiseMatrix} is called. 36 * </p> 37 * <p> 38 * The time-dependent functions define a process noise matrix that is diagonal 39 * <em>in the Local Orbital Frame</em>, corresponds to Cartesian elements, abd represents 40 * the temporal evolution of (the standard deviation of) the process noise model. The 41 * first function is therefore the standard deviation along the LOF X axis, the second 42 * function represents the standard deviation along the LOF Y axis... 43 * This allows to set up simply a process noise representing an uncertainty that grows 44 * mainly along the track. The 6x6 upper left part of output matrix will however not be 45 * diagonal as it will be converted to the same inertial frame and orbit type as the 46 * {@link SpacecraftState state} used by the {@link KalmanEstimator Kalman estimator}. 47 * </p> 48 * <p> 49 * The propagation and measurements parameters are not associated to a specific frame and 50 * are appended as is in the lower right part diagonal of the output matrix. This implies 51 * this simplified model does not include correlation between the parameters and the orbit, 52 * but only evolution of the parameters themselves. If such correlations are needed, users 53 * must set up a custom {@link CovarianceMatrixProvider covariance matrix provider}. In most 54 * cases, the parameters are constant and their evolution noise is always 0, so the 55 * functions can be set to {@code x -> 0}. 56 * </p> 57 * <p> 58 * This class always provides one initial noise matrix or initial covariance matrix and one process noise matrix. 59 * </p> 60 * @author Luc Maisonobe 61 * @author Maxime Journot 62 * @since 9.2 63 */ 64 public class UnivariateProcessNoise extends AbstractCovarianceMatrixProvider { 65 66 /** Local Orbital Frame (LOF) type used. */ 67 private final LOFType lofType; 68 69 /** Position angle for the orbital process noise matrix. */ 70 private final PositionAngleType positionAngleType; 71 72 /** Array of univariate functions for the six orbital parameters process noise evolution in LOF frame and Cartesian formalism. */ 73 private final UnivariateFunction[] lofCartesianOrbitalParametersEvolution; 74 75 /** Array of univariate functions for the propagation parameters process noise evolution. */ 76 private final UnivariateFunction[] propagationParametersEvolution; 77 78 /** Array of univariate functions for the measurements parameters process noise evolution. */ 79 private final UnivariateFunction[] measurementsParametersEvolution; 80 81 /** Simple constructor. 82 * @param initialCovarianceMatrix initial covariance matrix 83 * @param lofType the LOF type used 84 * @param positionAngleType the position angle used for the computation of the process noise 85 * @param lofCartesianOrbitalParametersEvolution Array of univariate functions for the six orbital parameters process noise evolution in LOF frame and Cartesian orbit type 86 * @param propagationParametersEvolution Array of univariate functions for the propagation parameters process noise evolution 87 */ 88 public UnivariateProcessNoise(final RealMatrix initialCovarianceMatrix, 89 final LOFType lofType, 90 final PositionAngleType positionAngleType, 91 final UnivariateFunction[] lofCartesianOrbitalParametersEvolution, 92 final UnivariateFunction[] propagationParametersEvolution) { 93 94 // Call the new constructor with an empty array for measurements parameters 95 this(initialCovarianceMatrix, lofType, positionAngleType, lofCartesianOrbitalParametersEvolution, propagationParametersEvolution, new UnivariateFunction[0]); 96 } 97 98 /** Simple constructor. 99 * @param initialCovarianceMatrix initial covariance matrix 100 * @param lofType the LOF type used 101 * @param positionAngleType the position angle used for the computation of the process noise 102 * @param lofCartesianOrbitalParametersEvolution Array of univariate functions for the six orbital parameters process noise evolution in LOF frame and Cartesian orbit type 103 * @param propagationParametersEvolution Array of univariate functions for the propagation parameters process noise evolution 104 * @param measurementsParametersEvolution Array of univariate functions for the measurements parameters process noise evolution 105 * @since 10.3 106 */ 107 public UnivariateProcessNoise(final RealMatrix initialCovarianceMatrix, 108 final LOFType lofType, 109 final PositionAngleType positionAngleType, 110 final UnivariateFunction[] lofCartesianOrbitalParametersEvolution, 111 final UnivariateFunction[] propagationParametersEvolution, 112 final UnivariateFunction[] measurementsParametersEvolution) { 113 114 super(initialCovarianceMatrix); 115 this.lofType = lofType; 116 this.positionAngleType = positionAngleType; 117 this.lofCartesianOrbitalParametersEvolution = lofCartesianOrbitalParametersEvolution.clone(); 118 this.propagationParametersEvolution = propagationParametersEvolution.clone(); 119 this.measurementsParametersEvolution = measurementsParametersEvolution.clone(); 120 } 121 122 /** Getter for the lofType. 123 * @return the lofType 124 */ 125 public LOFType getLofType() { 126 return lofType; 127 } 128 129 /** Getter for the positionAngle. 130 * @return the positionAngle 131 */ 132 public PositionAngleType getPositionAngleType() { 133 return positionAngleType; 134 } 135 136 /** Getter for the lofCartesianOrbitalParametersEvolution. 137 * @return the lofCartesianOrbitalParametersEvolution 138 */ 139 public UnivariateFunction[] getLofCartesianOrbitalParametersEvolution() { 140 return lofCartesianOrbitalParametersEvolution.clone(); 141 } 142 143 /** Getter for the propagationParametersEvolution. 144 * @return the propagationParametersEvolution 145 */ 146 public UnivariateFunction[] getPropagationParametersEvolution() { 147 return propagationParametersEvolution.clone(); 148 } 149 150 /** Getter for the measurementsParametersEvolution. 151 * @return the measurementsParametersEvolution 152 */ 153 public UnivariateFunction[] getMeasurementsParametersEvolution() { 154 return measurementsParametersEvolution.clone(); 155 } 156 157 /** {@inheritDoc} */ 158 @Override 159 public RealMatrix getProcessNoiseMatrix(final SpacecraftState previous, 160 final SpacecraftState current) { 161 162 // Number of estimated parameters 163 final int nbOrb = lofCartesianOrbitalParametersEvolution.length; 164 final int nbPropag = propagationParametersEvolution.length; 165 final int nbMeas = measurementsParametersEvolution.length; 166 167 // Initialize process noise matrix 168 final RealMatrix processNoiseMatrix = MatrixUtils.createRealMatrix(nbOrb + nbPropag + nbMeas, 169 nbOrb + nbPropag + nbMeas); 170 171 // Orbital parameters 172 if (nbOrb != 0) { 173 // Orbital parameters process noise matrix in inertial frame and current orbit type 174 final RealMatrix inertialOrbitalProcessNoiseMatrix = getInertialOrbitalProcessNoiseMatrix(previous, current); 175 processNoiseMatrix.setSubMatrix(inertialOrbitalProcessNoiseMatrix.getData(), 0, 0); 176 } 177 178 // Propagation parameters 179 if (nbPropag != 0) { 180 // Propagation parameters process noise matrix 181 final RealMatrix propagationProcessNoiseMatrix = getPropagationProcessNoiseMatrix(previous, current); 182 processNoiseMatrix.setSubMatrix(propagationProcessNoiseMatrix.getData(), nbOrb, nbOrb); 183 } 184 185 // Measurement parameters 186 if (nbMeas != 0) { 187 // Measurement parameters process noise matrix 188 final RealMatrix measurementsProcessNoiseMatrix = getMeasurementsProcessNoiseMatrix(previous, current); 189 processNoiseMatrix.setSubMatrix(measurementsProcessNoiseMatrix.getData(), nbOrb + nbPropag, nbOrb + nbPropag); 190 } 191 192 return processNoiseMatrix; 193 } 194 195 /** Get the process noise for the six orbital parameters in current spacecraft inertial frame and current orbit type. 196 * @param previous previous state 197 * @param current current state 198 * @return physical (i.e. non normalized) orbital process noise matrix in inertial frame 199 */ 200 private RealMatrix getInertialOrbitalProcessNoiseMatrix(final SpacecraftState previous, 201 final SpacecraftState current) { 202 203 // ΔT = duration in seconds from previous to current spacecraft state 204 final double deltaT = current.getDate().durationFrom(previous.getDate()); 205 206 // Evaluate the functions, using ΔT as argument 207 final int lofOrbitalProcessNoiseLength = lofCartesianOrbitalParametersEvolution.length; 208 final double[] lofOrbitalProcessNoiseValues = new double[lofOrbitalProcessNoiseLength]; 209 210 // The function return a value which dimension is that of a standard deviation 211 // It needs to be squared before being put in the process noise covariance matrix 212 for (int i = 0; i < lofOrbitalProcessNoiseLength; i++) { 213 final double functionValue = lofCartesianOrbitalParametersEvolution[i].value(deltaT); 214 lofOrbitalProcessNoiseValues[i] = functionValue * functionValue; 215 } 216 217 // Form the diagonal matrix in LOF frame and Cartesian formalism 218 final RealMatrix lofCartesianProcessNoiseMatrix = MatrixUtils.createRealDiagonalMatrix(lofOrbitalProcessNoiseValues); 219 220 // Create state covariance object in LOF 221 final StateCovariance lofCartesianProcessNoiseCov = 222 new StateCovariance(lofCartesianProcessNoiseMatrix, current.getDate(), lofType); 223 224 // Convert to Cartesian in orbital frame 225 final StateCovariance inertialCartesianProcessNoiseCov = 226 lofCartesianProcessNoiseCov.changeCovarianceFrame(current.getOrbit(), current.getFrame()); 227 228 // Convert to current orbit type and position angle 229 final StateCovariance inertialOrbitalProcessNoiseCov = 230 inertialCartesianProcessNoiseCov.changeCovarianceType(current.getOrbit(), 231 current.getOrbit().getType(), positionAngleType); 232 // Return inertial orbital covariance matrix 233 return inertialOrbitalProcessNoiseCov.getMatrix(); 234 } 235 236 /** Get the process noise for the propagation parameters. 237 * @param previous previous state 238 * @param current current state 239 * @return physical (i.e. non normalized) propagation process noise matrix 240 */ 241 private RealMatrix getPropagationProcessNoiseMatrix(final SpacecraftState previous, 242 final SpacecraftState current) { 243 244 // ΔT = duration from previous to current spacecraft state (in seconds) 245 final double deltaT = current.getDate().durationFrom(previous.getDate()); 246 247 // Evaluate the functions, using ΔT as argument 248 final int propagationProcessNoiseLength = propagationParametersEvolution.length; 249 final double[] propagationProcessNoiseValues = new double[propagationProcessNoiseLength]; 250 251 // The function return a value which dimension is that of a standard deviation 252 // It needs to be squared before being put in the process noise covariance matrix 253 for (int i = 0; i < propagationProcessNoiseLength; i++) { 254 final double functionValue = propagationParametersEvolution[i].value(deltaT); 255 propagationProcessNoiseValues[i] = functionValue * functionValue; 256 } 257 258 // Form the diagonal matrix corresponding to propagation parameters process noise 259 return MatrixUtils.createRealDiagonalMatrix(propagationProcessNoiseValues); 260 } 261 262 /** Get the process noise for the measurements parameters. 263 * @param previous previous state 264 * @param current current state 265 * @return physical (i.e. non normalized) measurements process noise matrix 266 */ 267 private RealMatrix getMeasurementsProcessNoiseMatrix(final SpacecraftState previous, 268 final SpacecraftState current) { 269 270 // ΔT = duration from previous to current spacecraft state (in seconds) 271 final double deltaT = current.getDate().durationFrom(previous.getDate()); 272 273 // Evaluate the functions, using ΔT as argument 274 final int measurementsProcessNoiseLength = measurementsParametersEvolution.length; 275 final double[] measurementsProcessNoiseValues = new double[measurementsProcessNoiseLength]; 276 277 // The function return a value which dimension is that of a standard deviation 278 // It needs to be squared before being put in the process noise covariance matrix 279 for (int i = 0; i < measurementsProcessNoiseLength; i++) { 280 final double functionValue = measurementsParametersEvolution[i].value(deltaT); 281 measurementsProcessNoiseValues[i] = functionValue * functionValue; 282 } 283 284 // Form the diagonal matrix corresponding to propagation parameters process noise 285 return MatrixUtils.createRealDiagonalMatrix(measurementsProcessNoiseValues); 286 } 287 288 }