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