1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.geometry.euclidean.threed.Rotation;
22 import org.hipparchus.ode.FieldODEIntegrator;
23 import org.hipparchus.ode.nonstiff.DormandPrince853FieldIntegrator;
24 import org.hipparchus.util.Binary64;
25 import org.hipparchus.util.Binary64Field;
26 import org.hipparchus.util.FastMath;
27 import org.junit.jupiter.api.AfterEach;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.api.BeforeEach;
30 import org.junit.jupiter.api.DisplayName;
31 import org.junit.jupiter.api.Test;
32 import org.mockito.Mockito;
33 import org.orekit.Utils;
34 import org.orekit.attitudes.AttitudeProvider;
35 import org.orekit.attitudes.BodyCenterPointing;
36 import org.orekit.attitudes.FieldAttitude;
37 import org.orekit.attitudes.FieldAttitudeInterpolator;
38 import org.orekit.bodies.CelestialBodyFactory;
39 import org.orekit.bodies.OneAxisEllipsoid;
40 import org.orekit.errors.OrekitException;
41 import org.orekit.errors.OrekitIllegalArgumentException;
42 import org.orekit.errors.OrekitInternalError;
43 import org.orekit.errors.OrekitMessages;
44 import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
45 import org.orekit.forces.gravity.SingleBodyAbsoluteAttraction;
46 import org.orekit.forces.gravity.potential.GravityFieldFactory;
47 import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
48 import org.orekit.frames.Frame;
49 import org.orekit.frames.FramesFactory;
50 import org.orekit.orbits.FieldKeplerianOrbit;
51 import org.orekit.orbits.FieldOrbit;
52 import org.orekit.orbits.FieldOrbitHermiteInterpolator;
53 import org.orekit.orbits.OrbitType;
54 import org.orekit.orbits.PositionAngleType;
55 import org.orekit.propagation.analytical.FieldEcksteinHechlerPropagator;
56 import org.orekit.propagation.numerical.FieldNumericalPropagator;
57 import org.orekit.time.AbsoluteDate;
58 import org.orekit.time.AbstractFieldTimeInterpolator;
59 import org.orekit.time.AbstractTimeInterpolator;
60 import org.orekit.time.DateComponents;
61 import org.orekit.time.FieldAbsoluteDate;
62 import org.orekit.time.FieldTimeInterpolator;
63 import org.orekit.time.FieldTimeStamped;
64 import org.orekit.time.TimeComponents;
65 import org.orekit.time.TimeScalesFactory;
66 import org.orekit.time.TimeStampedField;
67 import org.orekit.time.TimeStampedFieldHermiteInterpolator;
68 import org.orekit.utils.AngularDerivativesFilter;
69 import org.orekit.utils.CartesianDerivativesFilter;
70 import org.orekit.utils.Constants;
71 import org.orekit.utils.FieldAbsolutePVCoordinates;
72 import org.orekit.utils.FieldAbsolutePVCoordinatesHermiteInterpolator;
73 import org.orekit.utils.FieldPVCoordinates;
74 import org.orekit.utils.IERSConventions;
75
76 import java.util.ArrayList;
77 import java.util.Collections;
78 import java.util.List;
79
80 class FieldSpacecraftStateInterpolatorTest {
81
82 final private Field<Binary64> field = Binary64Field.getInstance();
83 private Binary64 mass;
84 private FieldOrbit<Binary64> orbit;
85 private FieldAbsolutePVCoordinates<Binary64> absPV;
86 private AttitudeProvider attitudeLaw;
87 private FieldPropagator<Binary64> analyticalPropagator;
88 private FieldPropagator<Binary64> absPVPropagator;
89
90 @BeforeEach
91 public void setUp() {
92 try {
93 Utils.setDataRoot("regular-data:potential/icgem-format");
94 Binary64 mu = new Binary64(3.9860047e14);
95 double ae = 6.378137e6;
96 double c20 = -1.08263e-3;
97 double c30 = 2.54e-6;
98 double c40 = 1.62e-6;
99 double c50 = 2.3e-7;
100 double c60 = -5.5e-7;
101
102 mass = new Binary64(2500);
103 Binary64 a = new Binary64(7187990.1979844316);
104 Binary64 e = new Binary64(0.5e-4);
105 Binary64 i = new Binary64(1.7105407051081795);
106 Binary64 omega = new Binary64(1.9674147913622104);
107 Binary64 OMEGA = new Binary64(FastMath.toRadians(261));
108 Binary64 lv = new Binary64(0);
109
110 FieldAbsoluteDate<Binary64> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 1, 1),
111 TimeComponents.H00,
112 TimeScalesFactory.getUTC());
113 final Frame frame = FramesFactory.getEME2000();
114
115 orbit = new FieldKeplerianOrbit<>(a, e, i, omega, OMEGA, lv, PositionAngleType.TRUE,
116 frame, date, mu);
117 OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
118 Constants.WGS84_EARTH_FLATTENING,
119 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
120
121 absPV = new FieldAbsolutePVCoordinates<>(frame, date, orbit.getPVCoordinates());
122
123 attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
124
125 analyticalPropagator =
126 new FieldEcksteinHechlerPropagator<>(orbit, attitudeLaw, mass,
127 ae, mu, c20, c30, c40, c50, c60);
128
129 absPVPropagator = setUpNumericalPropagator();
130
131 }
132 catch (OrekitException oe) {
133 Assertions.fail(oe.getLocalizedMessage());
134 }
135 }
136
137 @AfterEach
138 public void tearDown() {
139 mass = org.hipparchus.util.Binary64.NAN;
140 orbit = null;
141 attitudeLaw = null;
142 analyticalPropagator = null;
143 }
144
145 @Test
146 public void testOrbitInterpolation()
147 throws OrekitException {
148
149
150 final Frame inertialFrame = orbit.getFrame();
151
152 final FieldSpacecraftStateInterpolator<Binary64> interpolator1 =
153 new FieldSpacecraftStateInterpolator<>(2, inertialFrame);
154
155 final FieldSpacecraftStateInterpolator<Binary64> interpolator2 =
156 new FieldSpacecraftStateInterpolator<>(3, SpacecraftStateInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC, inertialFrame);
157
158 final FieldSpacecraftStateInterpolator<Binary64> interpolator3 =
159 new FieldSpacecraftStateInterpolator<>(4, SpacecraftStateInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC, inertialFrame, inertialFrame);
160
161
162 checkStandardInterpolationError(2, 106.46533, 0.40709287, 169847806.33e-9, 0.0, 450 * 450, 450 * 450, interpolator1);
163 checkStandardInterpolationError(3, 0.00353, 0.00003250, 189886.01e-9, 0.0, 0.0, 0.0, interpolator2);
164 checkStandardInterpolationError(4, 0.00002, 0.00000023, 232.25e-9, 0.0, 0.0, 0.0, interpolator3);
165
166 }
167
168 @Test
169 public void testErrorThrownWhenOneInterpolatorIsNotConsistentWithSampleSize() {
170
171 final Frame outputFrame = Mockito.mock(Frame.class);
172
173 @SuppressWarnings("unchecked")
174 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolator =
175 Mockito.mock(FieldTimeInterpolator.class);
176 Mockito.when(orbitInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(orbitInterpolator));
177 Mockito.when(orbitInterpolator.getNbInterpolationPoints()).thenReturn(2);
178
179 @SuppressWarnings("unchecked")
180 final FieldTimeInterpolator<FieldAbsolutePVCoordinates<Binary64>, Binary64> absPVInterpolator =
181 Mockito.mock(FieldTimeInterpolator.class);
182 Mockito.when(absPVInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(absPVInterpolator));
183 Mockito.when(absPVInterpolator.getNbInterpolationPoints()).thenReturn(4);
184
185 @SuppressWarnings("unchecked")
186 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> massInterpolator =
187 Mockito.mock(FieldTimeInterpolator.class);
188 Mockito.when(massInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(massInterpolator));
189 Mockito.when(massInterpolator.getNbInterpolationPoints()).thenReturn(2);
190
191 final FieldSpacecraftStateInterpolator<Binary64> stateInterpolator =
192 new FieldSpacecraftStateInterpolator<>(2, 1.0e-3, outputFrame, orbitInterpolator, absPVInterpolator, massInterpolator,
193 null, null);
194
195
196 OrekitIllegalArgumentException thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class, () ->
197 AbstractFieldTimeInterpolator.checkInterpolatorCompatibilityWithSampleSize(stateInterpolator, 2));
198
199 Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, thrown.getSpecifier());
200 Assertions.assertEquals(2, ((Integer) thrown.getParts()[0]).intValue());
201
202 }
203
204 @Test
205 public void testErrorThrownWhenOneInterpolatorIsNotConsistentWithSampleSizeDeprecated() {
206
207 final Frame outputFrame = Mockito.mock(Frame.class);
208
209 @SuppressWarnings("unchecked")
210 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolator =
211 Mockito.mock(FieldTimeInterpolator.class);
212 Mockito.when(orbitInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(orbitInterpolator));
213 Mockito.when(orbitInterpolator.getNbInterpolationPoints()).thenReturn(2);
214
215 @SuppressWarnings("unchecked")
216 final FieldTimeInterpolator<FieldAbsolutePVCoordinates<Binary64>, Binary64> absPVInterpolator =
217 Mockito.mock(FieldTimeInterpolator.class);
218 Mockito.when(absPVInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(absPVInterpolator));
219 Mockito.when(absPVInterpolator.getNbInterpolationPoints()).thenReturn(4);
220
221 @SuppressWarnings("unchecked")
222 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> massInterpolator =
223 Mockito.mock(FieldTimeInterpolator.class);
224 Mockito.when(massInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(massInterpolator));
225 Mockito.when(massInterpolator.getNbInterpolationPoints()).thenReturn(2);
226
227 final FieldSpacecraftStateInterpolator<Binary64> stateInterpolator =
228 new FieldSpacecraftStateInterpolator<>(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
229 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
230 outputFrame, orbitInterpolator, absPVInterpolator, massInterpolator,
231 null, null);
232
233
234 OrekitIllegalArgumentException thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class, () ->
235 AbstractFieldTimeInterpolator.checkInterpolatorCompatibilityWithSampleSize(stateInterpolator, 2));
236
237 Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, thrown.getSpecifier());
238 Assertions.assertEquals(2, ((Integer) thrown.getParts()[0]).intValue());
239
240 }
241
242 @Test
243 public void testAbsPVAInterpolation()
244 throws OrekitException {
245
246
247 final int interpolationPoints1 = 2;
248 final int interpolationPoints2 = 3;
249 final int interpolationPoints3 = 4;
250
251 final Frame intertialFrame = absPV.getFrame();
252
253
254 final FieldSpacecraftStateInterpolator<Binary64>[] interpolator1 =
255 buildAllTypeOfInterpolator(interpolationPoints1, intertialFrame);
256 final FieldSpacecraftStateInterpolator<Binary64>[] interpolator2 =
257 buildAllTypeOfInterpolator(interpolationPoints2, intertialFrame);
258 final FieldSpacecraftStateInterpolator<Binary64>[] interpolator3 =
259 buildAllTypeOfInterpolator(interpolationPoints3, intertialFrame);
260
261
262 checkAbsPVInterpolationError(interpolationPoints1, 766704.6033758943, 3385.895505018284,
263 9.503905101141868, 0.0, interpolator1[0]);
264 checkAbsPVInterpolationError(interpolationPoints2, 46190.78568215623, 531.3506621730367,
265 0.5601906427491941, 0, interpolator2[0]);
266 checkAbsPVInterpolationError(interpolationPoints3, 2787.7069621834926, 55.5146607205871,
267 0.03372344505743245, 0.0, interpolator3[0]);
268
269
270 checkAbsPVInterpolationError(interpolationPoints1, 14023.999059896296, 48.022197580401084,
271 0.16984517369482555, 0.0, interpolator1[1]);
272 checkAbsPVInterpolationError(interpolationPoints2, 16.186825338590722, 0.13418685366189476,
273 1.898961129289559E-4, 0, interpolator2[1]);
274 checkAbsPVInterpolationError(interpolationPoints3, 0.025110113133073413, 3.5069332429486154E-4,
275 2.3306042475258594E-7, 0.0, interpolator3[1]);
276
277
278 checkAbsPVInterpolationError(interpolationPoints1, 108.13907262943746, 0.4134494277844817,
279 0.001389170843175492, 0.0, interpolator1[2]);
280 checkAbsPVInterpolationError(interpolationPoints2, 0.002974408269435121, 2.6937387601886076E-5,
281 2.051629855188969E-4, 0, interpolator2[2]);
282 checkAbsPVInterpolationError(interpolationPoints3, 0, 0, 1.3779131041190534E-4,
283 0.0, interpolator3[2]);
284 }
285
286 @Test
287 public void testIssue775() {
288 final Field<Binary64> field = Binary64Field.getInstance();
289 final Binary64 zero = field.getZero();
290
291
292 FieldAbsoluteDate<Binary64> initDate = new FieldAbsoluteDate<>(field, new AbsoluteDate(
293 new DateComponents(2004, 1, 1), TimeComponents.H00, TimeScalesFactory.getUTC()));
294 FieldAbsoluteDate<Binary64> finalDate = new FieldAbsoluteDate<>(field, new AbsoluteDate(
295 new DateComponents(2004, 1, 2), TimeComponents.H00, TimeScalesFactory.getUTC()));
296 Frame inertialFrame = FramesFactory.getEME2000();
297
298
299 final FieldVector3D<Binary64> position = new FieldVector3D<>(zero.add(-29536113.0),
300 zero.add(30329259.0),
301 zero.add(-100125.0));
302 final FieldVector3D<Binary64> velocity = new FieldVector3D<>(zero.add(-2194.0),
303 zero.add(-2141.0),
304 zero.add(-8.0));
305
306 final FieldPVCoordinates<Binary64> pv = new FieldPVCoordinates<>(position, velocity);
307 final FieldAbsolutePVCoordinates<Binary64> initAbsPV = new FieldAbsolutePVCoordinates<>(inertialFrame, initDate, pv);
308
309
310 int numberOfIntervals = 15;
311 Binary64 deltaT = finalDate.durationFrom(initDate).divide(numberOfIntervals);
312
313
314 List<FieldSpacecraftState<Binary64>> states = new ArrayList<>(numberOfIntervals + 1);
315 for (int j = 0; j <= numberOfIntervals; j++) {
316 states.add(new FieldSpacecraftState<>(initAbsPV).shiftedBy(deltaT.multiply(j)));
317 }
318
319
320 FieldSpacecraftState<Binary64> withoutOrbit;
321
322
323 final FieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64> interpolator =
324 new FieldSpacecraftStateInterpolator<>(states.size(), inertialFrame);
325
326
327 withoutOrbit = interpolator.interpolate(states.get(10).getDate(), states);
328 Assertions.assertEquals(0.0, FieldVector3D.distance(withoutOrbit.getAbsPVA().getPosition(),
329 states.get(10).getAbsPVA().getPosition()).getReal(), 1.0e-10);
330 }
331
332
333
334
335
336
337
338
339
340 private FieldPropagator<Binary64> setUpNumericalPropagator() {
341
342
343 final FieldODEIntegrator<Binary64> integrator = setUpDefaultIntegrator();
344
345 final FieldNumericalPropagator<Binary64> propagator = new FieldNumericalPropagator<>(integrator);
346
347
348 propagator.setOrbitType(null);
349
350
351 final Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
352 final NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(6, 6);
353 final HolmesFeatherstoneAttractionModel potential = new HolmesFeatherstoneAttractionModel(itrf, provider);
354
355 propagator.addForceModel(potential);
356 propagator.addForceModel(new SingleBodyAbsoluteAttraction(CelestialBodyFactory.getEarth()));
357
358
359 final FieldSpacecraftState<Binary64> initialState = new FieldSpacecraftState<>(absPV);
360
361 propagator.setInitialState(initialState);
362
363
364 propagator.setAttitudeProvider(attitudeLaw);
365
366 return propagator;
367 }
368
369
370
371
372
373
374 private FieldODEIntegrator<Binary64> setUpDefaultIntegrator() {
375 final Binary64 dP = new Binary64(1);
376 final double minStep = 0.001;
377 final double maxStep = 100;
378 final double[][] tolerances = ToleranceProvider.getDefaultToleranceProvider(dP.getReal()).getTolerances(orbit, OrbitType.CARTESIAN);
379
380 return new DormandPrince853FieldIntegrator<>(field, minStep, maxStep, tolerances[0], tolerances[1]);
381 }
382
383
384
385
386
387
388
389
390
391
392 private FieldSpacecraftStateInterpolator<Binary64>[] buildAllTypeOfInterpolator(final int interpolationPoints,
393 final Frame inertialFrame) {
394
395 final CartesianDerivativesFilter[] pvaFilters = CartesianDerivativesFilter.values();
396 final AngularDerivativesFilter[] angularFilters = AngularDerivativesFilter.values();
397
398 final int dim = pvaFilters.length;
399 @SuppressWarnings("unchecked")
400 final FieldSpacecraftStateInterpolator<Binary64>[] interpolators =
401 new FieldSpacecraftStateInterpolator[dim];
402
403 for (int i = 0; i < dim; i++) {
404 interpolators[i] =
405 new FieldSpacecraftStateInterpolator<>(interpolationPoints,
406 AbstractFieldTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
407 inertialFrame, inertialFrame,
408 pvaFilters[i], angularFilters[i]);
409 }
410
411 return interpolators;
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 private void checkStandardInterpolationError(int n, double expectedErrorP, double expectedErrorV,
428 double expectedErrorA, double expectedErrorM,
429 double expectedErrorQ, double expectedErrorD,
430 final FieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64> interpolator) {
431 FieldAbsoluteDate<Binary64> centerDate = orbit.getDate().shiftedBy(100.0);
432 List<FieldSpacecraftState<Binary64>> sample = new ArrayList<>();
433 for (int i = 0; i < n; ++i) {
434 Binary64 dt = new Binary64(i * 900.0 / (n - 1));
435 FieldSpacecraftState<Binary64> state = analyticalPropagator.propagate(centerDate.shiftedBy(dt));
436 state = state.
437 addAdditionalData("quadratic", dt.multiply(dt)).
438 addAdditionalStateDerivative("quadratic-dot", dt.multiply(dt));
439 sample.add(state);
440 }
441
442 double maxErrorP = 0;
443 double maxErrorV = 0;
444 double maxErrorA = 0;
445 double maxErrorM = 0;
446 double maxErrorQ = 0;
447 double maxErrorD = 0;
448 for (double dt = 0; dt < 900.0; dt += 5) {
449 FieldSpacecraftState<Binary64> interpolated = interpolator.interpolate(centerDate.shiftedBy(dt), sample);
450 FieldSpacecraftState<Binary64> propagated = analyticalPropagator.propagate(centerDate.shiftedBy(dt));
451 FieldPVCoordinates<Binary64> dpv =
452 new FieldPVCoordinates<>(propagated.getPVCoordinates(), interpolated.getPVCoordinates());
453 maxErrorP = FastMath.max(maxErrorP, dpv.getPosition().getNorm().getReal());
454 maxErrorV = FastMath.max(maxErrorV, dpv.getVelocity().getNorm().getReal());
455 maxErrorA =
456 FastMath.max(maxErrorA,
457 FastMath.toDegrees(Rotation.distance(interpolated.getAttitude().getRotation().toRotation(),
458 propagated.getAttitude().getRotation().toRotation())));
459 maxErrorM =
460 FastMath.max(maxErrorM, FastMath.abs(interpolated.getMass().getReal() - propagated.getMass().getReal()));
461 maxErrorQ = FastMath.max(maxErrorQ,
462 FastMath.abs(interpolated.getAdditionalState("quadratic")[0].getReal() - dt * dt));
463 maxErrorD =
464 FastMath.max(maxErrorD,
465 FastMath.abs(interpolated.getAdditionalStateDerivative("quadratic-dot")[0].getReal()
466 - dt * dt));
467 }
468 Assertions.assertEquals(expectedErrorP, maxErrorP, 1.0e-3);
469 Assertions.assertEquals(expectedErrorV, maxErrorV, 1.0e-6);
470 Assertions.assertEquals(expectedErrorA, maxErrorA, 4.0e-10);
471 Assertions.assertEquals(expectedErrorM, maxErrorM, 1.0e-15);
472 Assertions.assertEquals(expectedErrorQ, maxErrorQ, 2.0e-10);
473 Assertions.assertEquals(expectedErrorD, maxErrorD, 2.0e-10);
474 }
475
476
477
478
479
480
481
482
483
484
485
486
487
488 private void checkAbsPVInterpolationError(int n, double expectedErrorP, double expectedErrorV,
489 double expectedErrorA, double expectedErrorM,
490 final FieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64> interpolator) {
491 FieldAbsoluteDate<Binary64> centerDate = absPV.getDate().shiftedBy(100.0);
492 List<FieldSpacecraftState<Binary64>> sample = new ArrayList<>();
493 for (int i = 0; i < n; ++i) {
494 Binary64 dt = new Binary64(i * 900.0 / (n - 1));
495 FieldSpacecraftState<Binary64> state = absPVPropagator.propagate(centerDate.shiftedBy(dt));
496 sample.add(state);
497 }
498
499 double maxErrorP = 0;
500 double maxErrorV = 0;
501 double maxErrorA = 0;
502 double maxErrorM = 0;
503 for (double dt = 0; dt < 900.0; dt += 5) {
504 FieldSpacecraftState<Binary64> interpolated = interpolator.interpolate(centerDate.shiftedBy(dt), sample);
505 FieldSpacecraftState<Binary64> propagated = absPVPropagator.propagate(centerDate.shiftedBy(dt));
506 FieldPVCoordinates<Binary64> dpv =
507 new FieldPVCoordinates<>(propagated.getPVCoordinates(), interpolated.getPVCoordinates());
508 maxErrorP = FastMath.max(maxErrorP, dpv.getPosition().getNorm().getReal());
509 maxErrorV = FastMath.max(maxErrorV, dpv.getVelocity().getNorm().getReal());
510 maxErrorA =
511 FastMath.max(maxErrorA,
512 FastMath.toDegrees(Rotation.distance(interpolated.getAttitude().getRotation().toRotation(),
513 propagated.getAttitude().getRotation().toRotation())));
514 maxErrorM =
515 FastMath.max(maxErrorM, FastMath.abs(interpolated.getMass().getReal() - propagated.getMass().getReal()));
516 }
517 Assertions.assertEquals(expectedErrorP, maxErrorP, 1.0e-3);
518 Assertions.assertEquals(expectedErrorV, maxErrorV, 1.0e-6);
519 Assertions.assertEquals(expectedErrorA, maxErrorA, 4.0e-10);
520 Assertions.assertEquals(expectedErrorM, maxErrorM, 1.0e-15);
521 }
522
523 @Test
524 void testErrorThrownWhenInterpolatingWithNonFieldDateAndEmptySample() {
525
526 final FieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64> interpolator =
527 new FieldSpacecraftStateInterpolator<>(FramesFactory.getEME2000());
528
529 final List<FieldSpacecraftState<Binary64>> states = new ArrayList<>();
530
531
532 OrekitIllegalArgumentException thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class,
533 () -> interpolator.interpolate(new AbsoluteDate(), states.stream()));
534
535 Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, thrown.getSpecifier());
536 Assertions.assertEquals(0, ((Integer) thrown.getParts()[0]).intValue());
537
538 }
539
540 @Test
541 void testGetNbInterpolationsWithMultipleSubInterpolators() {
542
543
544 final Frame frame = Mockito.mock(Frame.class);
545
546 @SuppressWarnings("unchecked")
547 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolator =
548 Mockito.mock(FieldOrbitHermiteInterpolator.class);
549 @SuppressWarnings("unchecked")
550 final FieldTimeInterpolator<FieldAbsolutePVCoordinates<Binary64>, Binary64> absPVAInterpolator =
551 Mockito.mock(FieldAbsolutePVCoordinatesHermiteInterpolator.class);
552 @SuppressWarnings("unchecked")
553 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> massInterpolator =
554 Mockito.mock(TimeStampedFieldHermiteInterpolator.class);
555 @SuppressWarnings("unchecked")
556 final FieldTimeInterpolator<FieldAttitude<Binary64>, Binary64> attitudeInterpolator =
557 Mockito.mock(FieldAttitudeInterpolator.class);
558 @SuppressWarnings("unchecked")
559 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> additionalStateInterpolator =
560 Mockito.mock(TimeStampedFieldHermiteInterpolator.class);
561
562
563 final int orbitNbInterpolationPoints = 2;
564 final int absPVANbInterpolationPoints = 3;
565 final int massNbInterpolationPoints = 4;
566 final int AttitudeNbInterpolationPoints = 5;
567 final int AdditionalStateNbInterpolationPoints = 6;
568
569 Mockito.when(orbitInterpolator.getNbInterpolationPoints()).thenReturn(orbitNbInterpolationPoints);
570 Mockito.when(absPVAInterpolator.getNbInterpolationPoints()).thenReturn(absPVANbInterpolationPoints);
571 Mockito.when(massInterpolator.getNbInterpolationPoints()).thenReturn(massNbInterpolationPoints);
572 Mockito.when(attitudeInterpolator.getNbInterpolationPoints()).thenReturn(AttitudeNbInterpolationPoints);
573 Mockito.when(additionalStateInterpolator.getNbInterpolationPoints()).thenReturn(AdditionalStateNbInterpolationPoints);
574
575 Mockito.when(orbitInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(orbitInterpolator));
576 Mockito.when(absPVAInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(absPVAInterpolator));
577 Mockito.when(massInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(massInterpolator));
578 Mockito.when(attitudeInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(attitudeInterpolator));
579 Mockito.when(additionalStateInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(additionalStateInterpolator));
580
581 final FieldSpacecraftStateInterpolator<Binary64> stateInterpolator =
582 new FieldSpacecraftStateInterpolator<>(2, 1.0e-3, frame, orbitInterpolator, absPVAInterpolator, massInterpolator,
583 attitudeInterpolator, additionalStateInterpolator);
584
585
586 final int returnedNbInterpolationPoints = stateInterpolator.getNbInterpolationPoints();
587
588
589 Assertions.assertEquals(AdditionalStateNbInterpolationPoints, returnedNbInterpolationPoints);
590 Assertions.assertEquals(2, stateInterpolator.getInternalNbInterpolationPoints());
591 }
592
593 @Test
594 void testGetNbInterpolationsWithMultipleSubInterpolatorsDeprecated() {
595
596
597 final Frame frame = Mockito.mock(Frame.class);
598
599 @SuppressWarnings("unchecked")
600 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolator =
601 Mockito.mock(FieldOrbitHermiteInterpolator.class);
602 @SuppressWarnings("unchecked")
603 final FieldTimeInterpolator<FieldAbsolutePVCoordinates<Binary64>, Binary64> absPVAInterpolator =
604 Mockito.mock(FieldAbsolutePVCoordinatesHermiteInterpolator.class);
605 @SuppressWarnings("unchecked")
606 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> massInterpolator =
607 Mockito.mock(TimeStampedFieldHermiteInterpolator.class);
608 @SuppressWarnings("unchecked")
609 final FieldTimeInterpolator<FieldAttitude<Binary64>, Binary64> attitudeInterpolator =
610 Mockito.mock(FieldAttitudeInterpolator.class);
611 @SuppressWarnings("unchecked")
612 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> additionalStateInterpolator =
613 Mockito.mock(TimeStampedFieldHermiteInterpolator.class);
614
615
616 final int orbitNbInterpolationPoints = 2;
617 final int absPVANbInterpolationPoints = 3;
618 final int massNbInterpolationPoints = 4;
619 final int AttitudeNbInterpolationPoints = 5;
620 final int AdditionalStateNbInterpolationPoints = 6;
621
622 Mockito.when(orbitInterpolator.getNbInterpolationPoints()).thenReturn(orbitNbInterpolationPoints);
623 Mockito.when(absPVAInterpolator.getNbInterpolationPoints()).thenReturn(absPVANbInterpolationPoints);
624 Mockito.when(massInterpolator.getNbInterpolationPoints()).thenReturn(massNbInterpolationPoints);
625 Mockito.when(attitudeInterpolator.getNbInterpolationPoints()).thenReturn(AttitudeNbInterpolationPoints);
626 Mockito.when(additionalStateInterpolator.getNbInterpolationPoints()).thenReturn(AdditionalStateNbInterpolationPoints);
627
628 Mockito.when(orbitInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(orbitInterpolator));
629 Mockito.when(absPVAInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(absPVAInterpolator));
630 Mockito.when(massInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(massInterpolator));
631 Mockito.when(attitudeInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(attitudeInterpolator));
632 Mockito.when(additionalStateInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(additionalStateInterpolator));
633
634 final FieldSpacecraftStateInterpolator<Binary64> stateInterpolator =
635 new FieldSpacecraftStateInterpolator<>(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
636 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
637 frame, orbitInterpolator, absPVAInterpolator, massInterpolator,
638 attitudeInterpolator, additionalStateInterpolator);
639
640
641 final int returnedNbInterpolationPoints = stateInterpolator.getNbInterpolationPoints();
642
643
644 Assertions.assertEquals(AdditionalStateNbInterpolationPoints, returnedNbInterpolationPoints);
645 }
646
647 @Test
648 @DisplayName("test error thrown when using different state definition")
649 void testErrorThrownWhenUsingDifferentStateDefinition() {
650
651 final Field<Binary64> field = Binary64Field.getInstance();
652 final FieldAbsoluteDate<Binary64> interpolationDate = new FieldAbsoluteDate<>(field);
653
654 @SuppressWarnings("unchecked")
655 final FieldSpacecraftState<Binary64> orbitDefinedFieldState = Mockito.mock(FieldSpacecraftState.class);
656 final SpacecraftState orbitDefinedState = Mockito.mock(SpacecraftState.class);
657
658 Mockito.when(orbitDefinedState.isOrbitDefined()).thenReturn(true);
659 Mockito.when(orbitDefinedFieldState.toSpacecraftState()).thenReturn(orbitDefinedState);
660
661 @SuppressWarnings("unchecked")
662 final FieldSpacecraftState<Binary64> absPVDefinedFieldState = Mockito.mock(FieldSpacecraftState.class);
663 final SpacecraftState absPVDefinedState = Mockito.mock(SpacecraftState.class);
664
665 Mockito.when(absPVDefinedState.isOrbitDefined()).thenReturn(false);
666 Mockito.when(absPVDefinedFieldState.toSpacecraftState()).thenReturn(absPVDefinedState);
667
668 final List<FieldSpacecraftState<Binary64>> states = new ArrayList<>();
669 states.add(orbitDefinedFieldState);
670 states.add(absPVDefinedFieldState);
671
672
673 final Frame inertialFrameMock = Mockito.mock(Frame.class);
674 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
675
676 final FieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64> stateInterpolator =
677 new FieldSpacecraftStateInterpolator<>(inertialFrameMock);
678
679
680 Exception thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class,
681 () -> stateInterpolator.interpolate(interpolationDate, states));
682
683 Assertions.assertEquals(
684 "one state is defined using an orbit while the other is defined using an absolute position-velocity-acceleration",
685 thrown.getMessage());
686 }
687
688 @Test
689 @DisplayName("test error thrown when using no interpolator for state")
690 void testErrorThrownWhenGivingNoInterpolatorForState() {
691
692 final Frame inertialFrameMock = Mockito.mock(Frame.class);
693 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
694
695
696 Exception thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class,
697 () -> new FieldSpacecraftStateInterpolator<>(2, 1.0e-3, inertialFrameMock,
698 null, null, null, null,
699 null));
700
701 Assertions.assertEquals("creating a spacecraft state interpolator requires at least one orbit interpolator or an "
702 + "absolute position-velocity-acceleration interpolator", thrown.getMessage());
703 }
704
705 @Test
706 @DisplayName("test error thrown when using no interpolator for state")
707 void testErrorThrownWhenGivingNoInterpolatorForStateDeprecated() {
708
709 final Frame inertialFrameMock = Mockito.mock(Frame.class);
710 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
711
712
713 Exception thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class,
714 () -> new FieldSpacecraftStateInterpolator<>(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
715 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
716 inertialFrameMock,
717 null, null, null, null,
718 null));
719
720 Assertions.assertEquals("creating a spacecraft state interpolator requires at least one orbit interpolator or an "
721 + "absolute position-velocity-acceleration interpolator", thrown.getMessage());
722 }
723
724 @Test
725 @DisplayName("test error thrown when giving empty sample")
726 void testErrorThrownWhenGivingEmptySample() {
727
728
729 @SuppressWarnings("unchecked")
730 final FieldAbsoluteDate<Binary64> interpolationDate = Mockito.mock(FieldAbsoluteDate.class);
731
732 final Frame inertialFrame = FramesFactory.getEME2000();
733
734 final List<FieldSpacecraftState<Binary64>> states = new ArrayList<>();
735
736
737 @SuppressWarnings("unchecked")
738 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolatorMock =
739 Mockito.mock(FieldTimeInterpolator.class);
740
741 final FieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64> interpolator =
742 new FieldSpacecraftStateInterpolator<>(2, 1.0e-3, inertialFrame, orbitInterpolatorMock, null, null, null, null);
743
744
745 OrekitIllegalArgumentException thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class, () ->
746 interpolator.interpolate(interpolationDate, states));
747
748 Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, thrown.getSpecifier());
749 Assertions.assertEquals(0, ((Integer) thrown.getParts()[0]).intValue());
750
751 }
752
753 @Test
754 @DisplayName("test error thrown when giving empty sample")
755 void testErrorThrownWhenGivingEmptySampleDeprecated() {
756
757
758 @SuppressWarnings("unchecked")
759 final FieldAbsoluteDate<Binary64> interpolationDate = Mockito.mock(FieldAbsoluteDate.class);
760
761 final Frame inertialFrame = FramesFactory.getEME2000();
762
763 final List<FieldSpacecraftState<Binary64>> states = new ArrayList<>();
764
765
766 @SuppressWarnings("unchecked")
767 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolatorMock =
768 Mockito.mock(FieldTimeInterpolator.class);
769
770 final FieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64> interpolator =
771 new FieldSpacecraftStateInterpolator<>(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
772 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
773 inertialFrame, orbitInterpolatorMock,
774 null, null, null, null);
775
776
777 OrekitIllegalArgumentException thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class, () ->
778 interpolator.interpolate(interpolationDate, states));
779
780 Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, thrown.getSpecifier());
781 Assertions.assertEquals(0, ((Integer) thrown.getParts()[0]).intValue());
782
783 }
784
785 @Test
786 void testFieldSpacecraftStateInterpolatorCreation() {
787
788 final Frame inertialFrameMock = Mockito.mock(Frame.class);
789 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
790
791 @SuppressWarnings("unchecked")
792 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolatorMock =
793 Mockito.mock(FieldTimeInterpolator.class);
794
795 @SuppressWarnings("unchecked")
796 final FieldTimeInterpolator<FieldAbsolutePVCoordinates<Binary64>, Binary64> absPVInterpolatorMock =
797 Mockito.mock(FieldTimeInterpolator.class);
798
799 @SuppressWarnings("unchecked")
800 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> massInterpolatorMock =
801 Mockito.mock(FieldTimeInterpolator.class);
802
803 @SuppressWarnings("unchecked")
804 final FieldTimeInterpolator<FieldAttitude<Binary64>, Binary64> attitudeInterpolatorMock =
805 Mockito.mock(FieldTimeInterpolator.class);
806
807 @SuppressWarnings("unchecked")
808 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> additionalInterpolatorMock =
809 Mockito.mock(FieldTimeInterpolator.class);
810
811
812 final FieldSpacecraftStateInterpolator<Binary64> interpolator =
813 new FieldSpacecraftStateInterpolator<>(2, 1.0e-3, inertialFrameMock, orbitInterpolatorMock, absPVInterpolatorMock,
814 massInterpolatorMock, attitudeInterpolatorMock,
815 additionalInterpolatorMock);
816
817
818 Assertions.assertEquals(inertialFrameMock, interpolator.getOutputFrame());
819 Assertions.assertEquals(orbitInterpolatorMock, interpolator.getOrbitInterpolator().get());
820 Assertions.assertEquals(absPVInterpolatorMock, interpolator.getAbsPVAInterpolator().get());
821 Assertions.assertEquals(massInterpolatorMock, interpolator.getMassInterpolator().get());
822 Assertions.assertEquals(attitudeInterpolatorMock, interpolator.getAttitudeInterpolator().get());
823 Assertions.assertEquals(additionalInterpolatorMock, interpolator.getAdditionalStateInterpolator().get());
824
825 }
826
827 @Test
828 void testFieldSpacecraftStateInterpolatorCreationDeprecated() {
829
830 final Frame inertialFrameMock = Mockito.mock(Frame.class);
831 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
832
833 @SuppressWarnings("unchecked")
834 final FieldTimeInterpolator<FieldOrbit<Binary64>, Binary64> orbitInterpolatorMock =
835 Mockito.mock(FieldTimeInterpolator.class);
836
837 @SuppressWarnings("unchecked")
838 final FieldTimeInterpolator<FieldAbsolutePVCoordinates<Binary64>, Binary64> absPVInterpolatorMock =
839 Mockito.mock(FieldTimeInterpolator.class);
840
841 @SuppressWarnings("unchecked")
842 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> massInterpolatorMock =
843 Mockito.mock(FieldTimeInterpolator.class);
844
845 @SuppressWarnings("unchecked")
846 final FieldTimeInterpolator<FieldAttitude<Binary64>, Binary64> attitudeInterpolatorMock =
847 Mockito.mock(FieldTimeInterpolator.class);
848
849 @SuppressWarnings("unchecked")
850 final FieldTimeInterpolator<TimeStampedField<Binary64>, Binary64> additionalInterpolatorMock =
851 Mockito.mock(FieldTimeInterpolator.class);
852
853
854 final FieldSpacecraftStateInterpolator<Binary64> interpolator =
855 new FieldSpacecraftStateInterpolator<>(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
856 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
857 inertialFrameMock, orbitInterpolatorMock, absPVInterpolatorMock,
858 massInterpolatorMock, attitudeInterpolatorMock,
859 additionalInterpolatorMock);
860
861
862 Assertions.assertEquals(inertialFrameMock, interpolator.getOutputFrame());
863 Assertions.assertEquals(orbitInterpolatorMock, interpolator.getOrbitInterpolator().get());
864 Assertions.assertEquals(absPVInterpolatorMock, interpolator.getAbsPVAInterpolator().get());
865 Assertions.assertEquals(massInterpolatorMock, interpolator.getMassInterpolator().get());
866 Assertions.assertEquals(attitudeInterpolatorMock, interpolator.getAttitudeInterpolator().get());
867 Assertions.assertEquals(additionalInterpolatorMock, interpolator.getAdditionalStateInterpolator().get());
868
869 }
870
871 @Test
872 @DisplayName("Test error thrown when sub interpolator is not present")
873 void testErrorThrownWhenSubInterpolatorIsNotPresent() {
874
875 final FakeFieldStateInterpolator fakeStateInterpolator = new FakeFieldStateInterpolator();
876
877
878 Assertions.assertThrows(OrekitInternalError.class, fakeStateInterpolator::getNbInterpolationPoints);
879 }
880
881 @Test
882 @DisplayName("Test does not throw error when checking interpolator compatibility")
883 void testDoesNotThrowWhenCheckingInterpolatorCompatibility() {
884
885 final FakeFieldStateInterpolator fakeStateInterpolator = new FakeFieldStateInterpolator();
886
887
888 Assertions.assertThrows(OrekitInternalError.class, fakeStateInterpolator::getNbInterpolationPoints);
889 }
890
891 private static class FakeFieldStateInterpolator extends AbstractFieldTimeInterpolator<FieldSpacecraftState<Binary64>,Binary64> {
892
893 public FakeFieldStateInterpolator() {
894 super(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
895 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC);
896 }
897
898 @Override
899 public List<FieldTimeInterpolator<? extends FieldTimeStamped<Binary64>, Binary64>> getSubInterpolators() {
900 return Collections.emptyList();
901 }
902
903 @Override
904 protected FieldSpacecraftState<Binary64> interpolate(AbstractFieldTimeInterpolator<FieldSpacecraftState<Binary64>, Binary64>.InterpolationData interpolationData) {
905 return null;
906 }
907 }
908 }