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