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