1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements;
18
19 import java.util.List;
20
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.linear.MatrixUtils;
23 import org.hipparchus.stat.descriptive.StreamingStatistics;
24 import org.hipparchus.stat.descriptive.rank.Median;
25 import org.hipparchus.util.FastMath;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.api.Test;
28 import org.orekit.errors.OrekitException;
29 import org.orekit.estimation.Context;
30 import org.orekit.estimation.EstimationTestUtils;
31 import org.orekit.orbits.OrbitType;
32 import org.orekit.orbits.PositionAngleType;
33 import org.orekit.propagation.Propagator;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.propagation.conversion.NumericalPropagatorBuilder;
36 import org.orekit.time.AbsoluteDate;
37 import org.orekit.utils.Differentiation;
38 import org.orekit.utils.StateFunction;
39
40 public class PVTest {
41
42
43
44
45 @Test
46 public void testValues() {
47
48 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
49
50 final NumericalPropagatorBuilder propagatorBuilder =
51 context.createBuilder(OrbitType.EQUINOCTIAL, PositionAngleType.TRUE, false,
52 1.0e-6, 60.0, 0.001);
53
54
55 final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
56 propagatorBuilder);
57 final List<ObservedMeasurement<?>> measurements =
58 EstimationTestUtils.createMeasurements(propagator,
59 new PVMeasurementCreator(),
60 1.0, 3.0, 300.0);
61
62 propagator.clearStepHandlers();
63
64
65 final StreamingStatistics[] pvDiffStat = new StreamingStatistics[6];
66 for (int i = 0; i < 6; i++) {
67 pvDiffStat[i] = new StreamingStatistics();
68 }
69
70 for (final ObservedMeasurement<?> measurement : measurements) {
71
72
73 final AbsoluteDate datemeas = measurement.getDate();
74 SpacecraftState state = propagator.propagate(datemeas);
75
76
77 final EstimatedMeasurementBase<?> estimated = measurement.estimateWithoutDerivatives(0, 0, new SpacecraftState[] { state });
78
79
80 for (int i = 0; i < 6; i++) {
81 pvDiffStat[i].addValue(FastMath.abs(estimated.getEstimatedValue()[i] - measurement.getObservedValue()[i]));
82 }
83 }
84
85
86 for (int i = 0; i < 3; i++) {
87
88 Assertions.assertEquals(0.0, pvDiffStat[i].getMean(), 3.74e-7);
89 Assertions.assertEquals(0.0, pvDiffStat[i].getStandardDeviation(), 2.21e-7);
90
91
92 Assertions.assertEquals(0.0, pvDiffStat[i+3].getMean(), 1.29e-10);
93 Assertions.assertEquals(0.0, pvDiffStat[i+3].getStandardDeviation(), 7.82e-11);
94 }
95
96
97 Assertions.assertEquals(PV.MEASUREMENT_TYPE, measurements.get(0).getMeasurementType());
98 }
99
100
101
102
103 @Test
104 public void testStateDerivatives() {
105
106 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
107
108 final NumericalPropagatorBuilder propagatorBuilder =
109 context.createBuilder(OrbitType.KEPLERIAN, PositionAngleType.TRUE, true,
110 1.0e-6, 60.0, 0.001);
111
112
113 final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
114 propagatorBuilder);
115 final List<ObservedMeasurement<?>> measurements =
116 EstimationTestUtils.createMeasurements(propagator,
117 new PVMeasurementCreator(),
118 1.0, 3.0, 300.0);
119 propagator.clearStepHandlers();
120
121 double[] errorsP = new double[3 * 6 * measurements.size()];
122 double[] errorsV = new double[3 * 6 * measurements.size()];
123 int indexP = 0;
124 int indexV = 0;
125 for (final ObservedMeasurement<?> measurement : measurements) {
126
127 final AbsoluteDate date = measurement.getDate();
128 final SpacecraftState state = propagator.propagate(date);
129 final double[][] jacobian = measurement.estimate(0, 0, new SpacecraftState[] { state }).getStateDerivatives(0);
130
131
132 final double[][] finiteDifferencesJacobian =
133 Differentiation.differentiate(new StateFunction() {
134 public double[] value(final SpacecraftState state) {
135 return measurement.
136 estimateWithoutDerivatives(0, 0, new SpacecraftState[] { state }).
137 getEstimatedValue();
138 }
139 }, measurement.getDimension(),
140 propagator.getAttitudeProvider(), OrbitType.CARTESIAN,
141 PositionAngleType.TRUE, 1.0, 3).value(state);
142
143 Assertions.assertEquals(finiteDifferencesJacobian.length, jacobian.length);
144 Assertions.assertEquals(finiteDifferencesJacobian[0].length, jacobian[0].length);
145 for (int i = 0; i < jacobian.length; ++i) {
146 for (int j = 0; j < jacobian[i].length; ++j) {
147 final double relativeError = FastMath.abs((finiteDifferencesJacobian[i][j] - jacobian[i][j]) /
148 finiteDifferencesJacobian[i][j]);
149 if (j < 3) {
150 errorsP[indexP++] = relativeError;
151 } else {
152 errorsV[indexV++] = relativeError;
153 }
154 }
155 }
156
157 }
158
159
160 Assertions.assertEquals(0.0, new Median().evaluate(errorsP), 2.1e-10);
161 Assertions.assertEquals(0.0, new Median().evaluate(errorsV), 2.1e-10);
162
163 }
164
165
166
167 @Test
168 public void testPVWithSingleStandardDeviations() {
169
170
171 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
172
173
174 final Vector3D position = context.initialOrbit.getPosition();
175 final Vector3D velocity = context.initialOrbit.getPVCoordinates().getVelocity();
176 final AbsoluteDate date = context.initialOrbit.getDate();
177
178
179 final double sigmaP = 10.;
180 final double sigmaV = 0.1;
181 final double baseWeight = 0.5;
182
183
184 final double[][] Pref = new double[6][6];
185 for (int i = 0; i < 3; i++) {
186 Pref[i][i] = FastMath.pow(sigmaP, 2);
187 Pref[i+3][i+3] = FastMath.pow(sigmaV, 2);
188 }
189 final double[][] corrCoefRef = MatrixUtils.createRealIdentityMatrix(6).getData();
190
191
192 final ObservableSatellite[] sats = {
193 new ObservableSatellite(0),
194 new ObservableSatellite(2)
195 };
196
197
198 final PV[] pvs = new PV[2];
199 pvs[0] = new PV(date, position, velocity, sigmaP, sigmaV, baseWeight, sats[0]);
200 pvs[1] = new PV(date, position, velocity, sigmaP, sigmaV, baseWeight, sats[1]);
201
202
203 final double eps = 1e-20;
204
205
206 for (int k = 0; k < pvs.length; k++) {
207 final PV pv = pvs[k];
208
209
210 Assertions.assertEquals(sats[k].getPropagatorIndex(), pv.getSatellites().get(0).getPropagatorIndex());
211
212
213 for (int i = 0; i < 6; i++) {
214 Assertions.assertEquals(baseWeight, pv.getBaseWeight()[i], eps);
215 }
216
217 for (int i = 0; i < 3; i++) {
218 Assertions.assertEquals(sigmaP, pv.getTheoreticalStandardDeviation()[i] , eps);
219 Assertions.assertEquals(sigmaV, pv.getTheoreticalStandardDeviation()[i+3], eps);
220 }
221
222 final double[][] P = pv.getCovarianceMatrix();
223
224 final double normP = MatrixUtils.createRealMatrix(P).subtract(MatrixUtils.createRealMatrix(Pref)).getNorm1();
225 Assertions.assertEquals(0., normP, eps);
226
227
228 final double[][] corrCoef = pv.getCorrelationCoefficientsMatrix();
229
230 final double normCorrCoef = MatrixUtils.createRealMatrix(corrCoef).subtract(MatrixUtils.createRealMatrix(corrCoefRef)).getNorm1();
231 Assertions.assertEquals(0., normCorrCoef, eps);
232 }
233 }
234
235
236
237 @Test
238 public void testPVWithVectorStandardDeviations() {
239
240
241 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
242
243
244 final Vector3D position = context.initialOrbit.getPosition();
245 final Vector3D velocity = context.initialOrbit.getPVCoordinates().getVelocity();
246 final AbsoluteDate date = context.initialOrbit.getDate();
247
248
249 final double[] sigmaP = {10., 20., 30.};
250 final double[] sigmaV = {0.1, 0.2, 0.3};
251 final double[] sigmaPV = {10., 20., 30., 0.1, 0.2, 0.3};
252 final double baseWeight = 0.5;
253
254
255 final double[][] Pref = new double[6][6];
256 for (int i = 0; i < 3; i++) {
257 Pref[i][i] = FastMath.pow(sigmaP[i], 2);
258 Pref[i+3][i+3] = FastMath.pow(sigmaV[i], 2);
259 }
260 final double[][] corrCoefRef = MatrixUtils.createRealIdentityMatrix(6).getData();
261
262
263 final ObservableSatellite[] sats = {
264 new ObservableSatellite(0),
265 new ObservableSatellite(2),
266 new ObservableSatellite(0),
267 new ObservableSatellite(10)
268 };
269
270
271 final PV[] pvs = new PV[4];
272 pvs[0] = new PV(date, position, velocity, sigmaP, sigmaV, baseWeight, sats[0]);
273 pvs[1] = new PV(date, position, velocity, sigmaP, sigmaV, baseWeight, sats[1]);
274 pvs[2] = new PV(date, position, velocity, sigmaPV, baseWeight, sats[2]);
275 pvs[3] = new PV(date, position, velocity, sigmaPV, baseWeight, sats[3]);
276
277
278 final double eps = 1e-20;
279
280
281 for (int k = 0; k < pvs.length; k++) {
282 final PV pv = pvs[k];
283
284
285 Assertions.assertEquals(sats[k].getPropagatorIndex(), pv.getSatellites().get(0).getPropagatorIndex());
286
287
288 for (int i = 0; i < 6; i++) {
289 Assertions.assertEquals(baseWeight, pv.getBaseWeight()[i], eps);
290 }
291
292 for (int i = 0; i < 3; i++) {
293 Assertions.assertEquals(sigmaP[i], pv.getTheoreticalStandardDeviation()[i] , eps);
294 Assertions.assertEquals(sigmaV[i], pv.getTheoreticalStandardDeviation()[i+3], eps);
295 }
296
297 final double[][] P = pv.getCovarianceMatrix();
298
299 final double normP = MatrixUtils.createRealMatrix(P).subtract(MatrixUtils.createRealMatrix(Pref)).getNorm1();
300 Assertions.assertEquals(0., normP, eps);
301
302
303 final double[][] corrCoef = pv.getCorrelationCoefficientsMatrix();
304
305 final double normCorrCoef = MatrixUtils.createRealMatrix(corrCoef).subtract(MatrixUtils.createRealMatrix(corrCoefRef)).getNorm1();
306 Assertions.assertEquals(0., normCorrCoef, eps);
307 }
308 }
309
310
311
312 @Test
313 public void testPVWithTwoCovarianceMatrices() {
314
315 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
316
317
318 final Vector3D position = context.initialOrbit.getPosition();
319 final Vector3D velocity = context.initialOrbit.getPVCoordinates().getVelocity();
320 final AbsoluteDate date = context.initialOrbit.getDate();
321
322
323 final double[][] positionP = {{100., 400., 1200.}, {400., 400., 1800.}, {1200., 1800., 900.}};
324 final double[][] velocityP = {{0.01, 0.04, 0.12 }, {0.04, 0.04, 0.18 }, {0.12 , 0.18 , 0.09}};
325 final double baseWeight = 0.5;
326
327
328 final double[][] Pref = new double[6][6];
329 for (int i = 0; i < 3; i++) {
330 for (int j = i; j < 3; j++) {
331 Pref[i][j] = positionP[i][j];
332 Pref[j][i] = positionP[i][j];
333 Pref[i+3][j+3] = velocityP[i][j];
334 Pref[j+3][i+3] = velocityP[i][j];
335 }
336 }
337 final double[][] corrCoefRef3 = {{1., 2., 4.}, {2., 1., 3.}, {4., 3., 1.}};
338 final double[][] corrCoefRef = new double[6][6];
339 for (int i = 0; i < 3; i++) {
340 for (int j = i; j < 3; j++) {
341 corrCoefRef[i][j] = corrCoefRef3[i][j];
342 corrCoefRef[j][i] = corrCoefRef3[i][j];
343 corrCoefRef[i+3][j+3] = corrCoefRef3[i][j];
344 corrCoefRef[j+3][i+3] = corrCoefRef3[i][j];
345 }
346 }
347
348
349 final ObservableSatellite[] sats = {
350 new ObservableSatellite(0),
351 new ObservableSatellite(2)
352 };
353
354
355 final double[] sigmaP = {10., 20., 30.};
356 final double[] sigmaV = {0.1, 0.2, 0.3};
357
358
359 final PV[] pvs = new PV[2];
360 pvs[0] = new PV(date, position, velocity, positionP, velocityP, baseWeight, sats[0]);
361 pvs[1] = new PV(date, position, velocity, positionP, velocityP, baseWeight, sats[1]);
362
363
364 final double eps = 6.7e-16;
365
366
367 for (int k = 0; k < pvs.length; k++) {
368 final PV pv = pvs[k];
369
370
371 Assertions.assertEquals(sats[k].getPropagatorIndex(), pv.getSatellites().get(0).getPropagatorIndex());
372
373
374 for (int i = 0; i < 6; i++) {
375 Assertions.assertEquals(baseWeight, pv.getBaseWeight()[i], eps);
376 }
377
378 for (int i = 0; i < 3; i++) {
379 Assertions.assertEquals(sigmaP[i], pv.getTheoreticalStandardDeviation()[i] , eps);
380 Assertions.assertEquals(sigmaV[i], pv.getTheoreticalStandardDeviation()[i+3], eps);
381 }
382
383 final double[][] P = pv.getCovarianceMatrix();
384
385 final double normP = MatrixUtils.createRealMatrix(P).subtract(MatrixUtils.createRealMatrix(Pref)).getNorm1();
386 Assertions.assertEquals(0., normP, eps);
387
388
389 final double[][] corrCoef = pv.getCorrelationCoefficientsMatrix();
390
391 final double normCorrCoef = MatrixUtils.createRealMatrix(corrCoef).subtract(MatrixUtils.createRealMatrix(corrCoefRef)).getNorm1();
392 Assertions.assertEquals(0., normCorrCoef, eps);
393 }
394
395 }
396
397
398
399 @Test
400 public void testPVWithCovarianceMatrix() {
401
402 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
403
404
405 final Vector3D position = context.initialOrbit.getPosition();
406 final Vector3D velocity = context.initialOrbit.getPVCoordinates().getVelocity();
407 final AbsoluteDate date = context.initialOrbit.getDate();
408
409
410 final double[] sigmaPV = {10., 20., 30., 0.1, 0.2, 0.3};
411 final double baseWeight = 0.5;
412 final double[][] corrCoefRef = new double[6][6];
413 for (int i = 0; i < 6; i++) {
414 for (int j = 0; j < 6; j++) {
415 if (i == j) {
416 corrCoefRef[i][i] = 1.;
417 } else {
418 corrCoefRef[i][j] = i + j + 1;
419 }
420 }
421 }
422
423
424 final double[][] Pref = new double[6][6];
425 for (int i = 0; i < 6; i++) {
426 for (int j = 0; j < 6; j++) {
427 Pref[i][j] = corrCoefRef[i][j]*sigmaPV[i]*sigmaPV[j];
428 }
429 }
430
431
432 final ObservableSatellite[] sats = {
433 new ObservableSatellite(0),
434 new ObservableSatellite(2)
435 };
436
437
438 final PV[] pvs = new PV[2];
439 pvs[0] = new PV(date, position, velocity, Pref, baseWeight, sats[0]);
440 pvs[1] = new PV(date, position, velocity, Pref, baseWeight, sats[1]);
441
442
443 final double eps = 1.8e-15;
444
445
446 for (int k = 0; k < pvs.length; k++) {
447 final PV pv = pvs[k];
448
449
450 Assertions.assertEquals(sats[k].getPropagatorIndex(), pv.getSatellites().get(0).getPropagatorIndex());
451
452
453 for (int i = 0; i < 6; i++) {
454 Assertions.assertEquals(baseWeight, pv.getBaseWeight()[i], eps);
455 }
456
457 for (int i = 0; i < 6; i++) {
458 Assertions.assertEquals(sigmaPV[i], pv.getTheoreticalStandardDeviation()[i] , eps);
459 }
460
461 final double[][] P = pv.getCovarianceMatrix();
462
463 final double normP = MatrixUtils.createRealMatrix(P).subtract(MatrixUtils.createRealMatrix(Pref)).getNorm1();
464 Assertions.assertEquals(0., normP, eps);
465
466
467 final double[][] corrCoef = pv.getCorrelationCoefficientsMatrix();
468
469 final double normCorrCoef = MatrixUtils.createRealMatrix(corrCoef).subtract(MatrixUtils.createRealMatrix(corrCoefRef)).getNorm1();
470 Assertions.assertEquals(0., normCorrCoef, eps);
471 }
472
473 }
474
475
476 @Test
477 public void testExceptions() {
478
479 Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
480
481
482 final Vector3D position = context.initialOrbit.getPosition();
483 final Vector3D velocity = context.initialOrbit.getPVCoordinates().getVelocity();
484 final AbsoluteDate date = context.initialOrbit.getDate();
485 final double weight = 1.;
486
487
488 try {
489 new PV(date, position, velocity, new double[] {0., 0., 0.}, new double[] {1.}, weight, new ObservableSatellite(0));
490 Assertions.fail("An OrekitException should have been thrown");
491 } catch (OrekitException e) {
492
493 }
494
495
496 try {
497 new PV(date, position, velocity, new double[] {0., 0., 0.}, weight, new ObservableSatellite(0));
498 Assertions.fail("An OrekitException should have been thrown");
499 } catch (OrekitException e) {
500
501 }
502
503
504 try {
505 new PV(date, position, velocity, new double[][] {{0., 0.}, {0., 0.}},
506 new double[][] {{0., 0.}, {0., 0.}}, weight, new ObservableSatellite(0));
507 Assertions.fail("An OrekitException should have been thrown");
508 } catch (OrekitException e) {
509
510 }
511
512
513 try {
514 new PV(date, position, velocity, new double[][] {{0., 0.}, {0., 0.}}, weight, new ObservableSatellite(0));
515 Assertions.fail("An OrekitException should have been thrown");
516 } catch (OrekitException e) {
517
518 }
519 }
520 }
521
522