1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.sequential;
18
19 import org.hipparchus.filtering.kalman.ProcessEstimate;
20 import org.hipparchus.filtering.kalman.unscented.UnscentedEvolution;
21 import org.hipparchus.filtering.kalman.unscented.UnscentedProcess;
22 import org.hipparchus.linear.ArrayRealVector;
23 import org.hipparchus.linear.MatrixUtils;
24 import org.hipparchus.linear.RealMatrix;
25 import org.hipparchus.linear.RealVector;
26 import org.orekit.estimation.measurements.EstimatedMeasurement;
27 import org.orekit.estimation.measurements.EstimatedMeasurementBase;
28 import org.orekit.estimation.measurements.ObservedMeasurement;
29 import org.orekit.orbits.CartesianOrbit;
30 import org.orekit.orbits.Orbit;
31 import org.orekit.propagation.Propagator;
32 import org.orekit.propagation.SpacecraftState;
33 import org.orekit.propagation.conversion.AbstractPropagatorBuilder;
34 import org.orekit.propagation.conversion.PropagatorBuilder;
35 import org.orekit.time.AbsoluteDate;
36 import org.orekit.utils.ParameterDriver;
37 import org.orekit.utils.ParameterDriversList;
38 import org.orekit.utils.ParameterDriversList.DelegatingDriver;
39
40 import java.util.List;
41
42
43
44
45
46
47 public class UnscentedKalmanModel extends AbstractKalmanEstimationCommon implements UnscentedProcess<MeasurementDecorator> {
48
49
50 private final double[] referenceValues;
51
52
53
54
55
56
57
58 protected UnscentedKalmanModel(final List<PropagatorBuilder> propagatorBuilders,
59 final List<CovarianceMatrixProvider> covarianceMatricesProviders,
60 final ParameterDriversList estimatedMeasurementParameters,
61 final CovarianceMatrixProvider measurementProcessNoiseMatrix) {
62
63 super(propagatorBuilders, covarianceMatricesProviders, estimatedMeasurementParameters, measurementProcessNoiseMatrix);
64
65
66 int stateDimension = 0;
67 for (final ParameterDriver ignored : getEstimatedOrbitalParameters().getDrivers()) {
68 stateDimension += 1;
69 }
70 for (final ParameterDriver ignored : getEstimatedPropagationParameters().getDrivers()) {
71 stateDimension += 1;
72 }
73 for (final ParameterDriver ignored : getEstimatedMeasurementsParameters().getDrivers()) {
74 stateDimension += 1;
75 }
76
77 this.referenceValues = new double[stateDimension];
78 int index = 0;
79 for (final ParameterDriver driver : getEstimatedOrbitalParameters().getDrivers()) {
80 referenceValues[index++] = driver.getReferenceValue();
81 }
82 for (final ParameterDriver driver : getEstimatedPropagationParameters().getDrivers()) {
83 referenceValues[index++] = driver.getReferenceValue();
84 }
85 for (final ParameterDriver driver : getEstimatedMeasurementsParameters().getDrivers()) {
86 referenceValues[index++] = driver.getReferenceValue();
87 }
88 }
89
90
91 @Override
92 public UnscentedEvolution getEvolution(final double previousTime, final RealVector[] sigmaPoints,
93 final MeasurementDecorator measurement) {
94
95
96 final ObservedMeasurement<?> observedMeasurement = measurement.getObservedMeasurement();
97 for (final ParameterDriver driver : observedMeasurement.getParametersDrivers()) {
98 if (driver.getReferenceDate() == null) {
99 driver.setReferenceDate(getBuilders().getFirst().getOrbitalParameterFactory().getDate());
100 }
101 }
102
103
104 incrementCurrentMeasurementNumber();
105
106
107 setCurrentDate(measurement.getObservedMeasurement().getDate());
108
109
110 final RealVector[] predictedSigmaPoints = new RealVector[sigmaPoints.length];
111
112
113
114
115
116
117
118
119
120
121
122 for (int i = sigmaPoints.length - 1; i >= 0; i--) {
123
124
125 final RealVector sigmaPoint = sigmaPoints[i].copy();
126 updateParameters(sigmaPoint);
127
128
129 final Propagator[] propagators = getEstimatedPropagators();
130
131
132 predictedSigmaPoints[i] =
133 predictState(observedMeasurement.getDate(), sigmaPoint, propagators, i != 0);
134 }
135
136
137 int d = 0;
138 for (final DelegatingDriver driver : getEstimatedOrbitalParameters().getDrivers()) {
139 driver.setReferenceValue(referenceValues[d]);
140 driver.setNormalizedValue(predictedSigmaPoints[0].getEntry(d));
141 referenceValues[d] = driver.getValue();
142
143
144 for (int i = 1; i < predictedSigmaPoints.length; ++i) {
145 predictedSigmaPoints[i].setEntry(d, predictedSigmaPoints[i].getEntry(d) - predictedSigmaPoints[0].getEntry(d));
146 }
147 predictedSigmaPoints[0].setEntry(d, 0.0);
148
149 d += 1;
150 }
151
152
153 return new UnscentedEvolution(measurement.getTime(), predictedSigmaPoints);
154 }
155
156
157 @Override
158 public RealMatrix getProcessNoiseMatrix(final double previousTime, final RealVector predictedState,
159 final MeasurementDecorator measurement) {
160
161 final RealVector predictedStateCopy = predictedState.copy();
162 updateParameters(predictedStateCopy);
163
164
165 Propagator[] propagators = getEstimatedPropagators();
166
167
168 for (int k = 0; k < propagators.length; ++k) {
169 final SpacecraftState predicted = propagators[k].getInitialState();
170 final Orbit predictedOrbit = new CartesianOrbit(predicted.getPVCoordinates(),
171 predicted.getFrame(),
172 measurement.getObservedMeasurement().getDate(),
173 predicted.getOrbit().getMu());
174 getBuilders().get(k).resetOrbit(predictedOrbit);
175 }
176 propagators = getEstimatedPropagators();
177
178
179 for (int k = 0; k < propagators.length; ++k) {
180 setPredictedSpacecraftState(propagators[k].getInitialState(), k);
181 }
182
183 return getNormalizedProcessNoise(predictedState.getDimension());
184 }
185
186
187 @Override
188 public RealVector[] getPredictedMeasurements(final RealVector[] predictedSigmaPoints, final MeasurementDecorator measurement) {
189
190
191 final ObservedMeasurement<?> observedMeasurement = measurement.getObservedMeasurement();
192
193
194 final RealVector theoreticalStandardDeviation =
195 MatrixUtils.createRealVector(observedMeasurement.getTheoreticalStandardDeviation());
196
197
198 final RealVector[] predictedMeasurements = new RealVector[predictedSigmaPoints.length];
199
200
201 for (int i = 0; i < predictedSigmaPoints.length; ++i) {
202
203 final RealVector predictedSigmaPoint = predictedSigmaPoints[i].copy();
204 updateParameters(predictedSigmaPoint);
205
206
207 final Propagator[] propagators = getEstimatedPropagators();
208
209
210 final SpacecraftState[] predictedStates = new SpacecraftState[propagators.length];
211 for (int k = 0; k < propagators.length; ++k) {
212 predictedStates[k] = propagators[k].getInitialState();
213 }
214
215
216 final EstimatedMeasurement<?> estimated = estimateMeasurement(observedMeasurement, getCurrentMeasurementNumber(),
217 KalmanEstimatorUtil.filterRelevant(observedMeasurement,
218 predictedStates));
219 predictedMeasurements[i] = new ArrayRealVector(estimated.getEstimatedValue())
220 .ebeDivide(theoreticalStandardDeviation);
221 }
222
223
224 return predictedMeasurements;
225
226 }
227
228
229 @Override
230 public RealVector getInnovation(final MeasurementDecorator measurement, final RealVector predictedMeas,
231 final RealVector predictedState, final RealMatrix innovationCovarianceMatrix) {
232
233 final RealVector theoreticalStandardDeviation =
234 MatrixUtils.createRealVector(measurement.getObservedMeasurement().getTheoreticalStandardDeviation());
235
236
237 final Propagator[] propagators = getEstimatedPropagators();
238
239
240 for (int k = 0; k < propagators.length; ++k) {
241 setPredictedSpacecraftState(propagators[k].getInitialState(), k);
242 }
243
244
245 final EstimatedMeasurement<?> predictedMeasurement =
246 estimateMeasurement(measurement.getObservedMeasurement(), getCurrentMeasurementNumber(),
247 KalmanEstimatorUtil.filterRelevant(measurement.getObservedMeasurement(),
248 getPredictedSpacecraftStates()));
249 setPredictedMeasurement(predictedMeasurement);
250 predictedMeasurement.setEstimatedValue(predictedMeas.ebeMultiply(theoreticalStandardDeviation).toArray());
251
252
253 KalmanEstimatorUtil.applyDynamicOutlierFilter(predictedMeasurement, innovationCovarianceMatrix);
254
255
256 return KalmanEstimatorUtil.computeInnovationVector(predictedMeasurement,
257 predictedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
258 }
259
260
261 private RealVector predictState(final AbsoluteDate date,
262 final RealVector previousState,
263 final Propagator[] propagators,
264 final boolean resetState) {
265
266
267 final RealVector predictedState = previousState.copy();
268
269
270 int jOrb = 0;
271
272
273 for (int k = 0; k < propagators.length; ++k) {
274
275
276 final SpacecraftState originalState = propagators[k].getInitialState();
277
278
279 final SpacecraftState predicted = propagators[k].propagate(date);
280
281
282
283 getBuilders().get(k).resetOrbit(predicted.getOrbit());
284
285
286
287
288 if (getBuilders().get(k) instanceof AbstractPropagatorBuilder) {
289 ((AbstractPropagatorBuilder<?, ?, ?>) (getBuilders().get(k))).setMass(predicted.getMass());
290 }
291
292
293
294
295
296 final ParameterDriversList drivers = getBuilders().
297 get(k).
298 getOrbitalParameterFactory().
299 getOrbitalParametersDrivers();
300 for (DelegatingDriver orbitalDriver : drivers.getDrivers()) {
301 if (orbitalDriver.isSelected()) {
302 orbitalDriver.setReferenceValue(referenceValues[jOrb]);
303 predictedState.setEntry(jOrb, orbitalDriver.getNormalizedValue());
304
305 jOrb += 1;
306 }
307 }
308
309
310 if (resetState) {
311 getBuilders().get(k).resetOrbit(originalState.getOrbit());
312 }
313 }
314
315 return predictedState;
316 }
317
318
319
320
321
322
323 public void finalizeEstimation(final ObservedMeasurement<?> observedMeasurement,
324 final ProcessEstimate estimate) {
325
326
327 setCorrectedEstimate(estimate);
328 updateParameters(estimate.getState());
329
330
331
332 final Propagator[] estimatedPropagators = getEstimatedPropagators();
333 for (int k = 0; k < estimatedPropagators.length; ++k) {
334 setCorrectedSpacecraftState(estimatedPropagators[k].getInitialState(), k);
335 }
336
337
338 setCorrectedMeasurement(estimateMeasurement(observedMeasurement, getCurrentMeasurementNumber(),
339 KalmanEstimatorUtil.filterRelevant(observedMeasurement,
340 getCorrectedSpacecraftStates())));
341 }
342
343
344
345
346
347
348
349
350
351
352 private static <T extends ObservedMeasurement<T>> EstimatedMeasurement<T> estimateMeasurement(final ObservedMeasurement<T> observedMeasurement,
353 final int measurementNumber,
354 final SpacecraftState[] spacecraftStates) {
355 final EstimatedMeasurementBase<T> estimatedMeasurementBase = observedMeasurement.
356 estimateWithoutDerivatives(measurementNumber, measurementNumber,
357 KalmanEstimatorUtil.filterRelevant(observedMeasurement, spacecraftStates));
358 return new EstimatedMeasurement<>(estimatedMeasurementBase);
359 }
360
361
362
363
364
365 private void updateParameters(final RealVector normalizedState) {
366 int i = 0;
367 for (final DelegatingDriver driver : getEstimatedOrbitalParameters().getDrivers()) {
368
369 driver.setReferenceValue(referenceValues[i]);
370 driver.setNormalizedValue(normalizedState.getEntry(i));
371 normalizedState.setEntry(i++, driver.getNormalizedValue());
372 }
373 for (final DelegatingDriver driver : getEstimatedPropagationParameters().getDrivers()) {
374
375 driver.setNormalizedValue(normalizedState.getEntry(i));
376 normalizedState.setEntry(i++, driver.getNormalizedValue());
377 }
378 for (final DelegatingDriver driver : getEstimatedMeasurementsParameters().getDrivers()) {
379
380 driver.setNormalizedValue(normalizedState.getEntry(i));
381 normalizedState.setEntry(i++, driver.getNormalizedValue());
382 }
383 }
384 }