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.geometry.euclidean.threed.Rotation;
20 import org.hipparchus.ode.ODEIntegrator;
21 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
22 import org.hipparchus.util.FastMath;
23 import org.junit.jupiter.api.*;
24 import org.mockito.Mockito;
25 import org.orekit.Utils;
26 import org.orekit.attitudes.Attitude;
27 import org.orekit.attitudes.AttitudeInterpolator;
28 import org.orekit.attitudes.AttitudeProvider;
29 import org.orekit.attitudes.BodyCenterPointing;
30 import org.orekit.bodies.CelestialBodyFactory;
31 import org.orekit.bodies.OneAxisEllipsoid;
32 import org.orekit.errors.OrekitException;
33 import org.orekit.errors.OrekitIllegalArgumentException;
34 import org.orekit.errors.OrekitInternalError;
35 import org.orekit.errors.OrekitMessages;
36 import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
37 import org.orekit.forces.gravity.SingleBodyAbsoluteAttraction;
38 import org.orekit.forces.gravity.potential.GravityFieldFactory;
39 import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
40 import org.orekit.frames.Frame;
41 import org.orekit.frames.FramesFactory;
42 import org.orekit.orbits.KeplerianOrbit;
43 import org.orekit.orbits.Orbit;
44 import org.orekit.orbits.OrbitHermiteInterpolator;
45 import org.orekit.orbits.PositionAngleType;
46 import org.orekit.propagation.analytical.EcksteinHechlerPropagator;
47 import org.orekit.propagation.numerical.NumericalPropagator;
48 import org.orekit.time.*;
49 import org.orekit.utils.*;
50
51 import java.util.ArrayList;
52 import java.util.Collections;
53 import java.util.List;
54
55 class SpacecraftStateInterpolatorTest {
56
57 private double mass;
58 private Orbit orbit;
59 private AbsolutePVCoordinates absPV;
60 private AttitudeProvider attitudeLaw;
61 private Propagator orbitPropagator;
62 private Propagator absPVPropagator;
63
64 @BeforeEach
65 public void setUp() {
66 try {
67 Utils.setDataRoot("regular-data:potential/icgem-format");
68 double mu = 3.9860047e14;
69 double ae = 6.378137e6;
70 double c20 = -1.08263e-3;
71 double c30 = 2.54e-6;
72 double c40 = 1.62e-6;
73 double c50 = 2.3e-7;
74 double c60 = -5.5e-7;
75
76 mass = 2500;
77 double a = 7187990.1979844316;
78 double e = 0.5e-4;
79 double i = 1.7105407051081795;
80 double omega = 1.9674147913622104;
81 double OMEGA = FastMath.toRadians(261);
82 double lv = 0;
83
84 AbsoluteDate date = new AbsoluteDate(new DateComponents(2004, 1, 1),
85 TimeComponents.H00,
86 TimeScalesFactory.getUTC());
87 final Frame frame = FramesFactory.getEME2000();
88 orbit = new KeplerianOrbit(a, e, i, omega, OMEGA, lv, PositionAngleType.TRUE, frame, date, mu);
89 OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
90 Constants.WGS84_EARTH_FLATTENING,
91 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
92
93 absPV = new AbsolutePVCoordinates(frame, date, orbit.getPVCoordinates());
94
95 attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
96 orbitPropagator =
97 new EcksteinHechlerPropagator(orbit, attitudeLaw, mass,
98 ae, mu, c20, c30, c40, c50, c60);
99
100 absPVPropagator = setUpNumericalPropagator();
101
102 } catch (OrekitException oe) {
103 Assertions.fail(oe.getLocalizedMessage());
104 }
105 }
106
107 @AfterEach
108 public void tearDown() {
109 mass = Double.NaN;
110 orbit = null;
111 attitudeLaw = null;
112 orbitPropagator = null;
113 }
114
115 @Test
116 public void testOrbitInterpolation()
117 throws OrekitException {
118
119
120 final int interpolationPoints1 = 2;
121 final int interpolationPoints2 = 3;
122 final int interpolationPoints3 = 4;
123
124 final Frame intertialFrame = FramesFactory.getEME2000();
125
126
127
128 final SpacecraftStateInterpolator interpolator1 =
129 new SpacecraftStateInterpolator(interpolationPoints1, intertialFrame, intertialFrame);
130
131 final SpacecraftStateInterpolator interpolator2 =
132 new SpacecraftStateInterpolator(interpolationPoints2, SpacecraftStateInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC, intertialFrame, intertialFrame);
133
134 final SpacecraftStateInterpolator interpolator3 =
135 new SpacecraftStateInterpolator(interpolationPoints3, SpacecraftStateInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC, intertialFrame);
136
137
138 checkInterpolationError(interpolationPoints1, 106.46533, 0.40709287, 169847806.33e-9, 0.0, 450 * 450, 450 * 450,
139 interpolator1);
140 checkInterpolationError(interpolationPoints2, 0.00353, 0.00003250, 189886.01e-9, 0.0, 0.0, 0.0, interpolator2);
141 checkInterpolationError(interpolationPoints3, 0.00002, 0.00000023, 232.25e-9, 0.0, 0.0, 0.0, interpolator3);
142 }
143
144 @Test
145 public void testAbsPVAInterpolation()
146 throws OrekitException {
147
148
149 final int interpolationPoints1 = 2;
150 final int interpolationPoints2 = 3;
151 final int interpolationPoints3 = 4;
152
153 final Frame intertialFrame = absPV.getFrame();
154
155
156 final SpacecraftStateInterpolator[] interpolator1 =
157 buildAllTypeOfInterpolator(interpolationPoints1, intertialFrame);
158 final SpacecraftStateInterpolator[] interpolator2 =
159 buildAllTypeOfInterpolator(interpolationPoints2, intertialFrame);
160 final SpacecraftStateInterpolator[] interpolator3 =
161 buildAllTypeOfInterpolator(interpolationPoints3, intertialFrame);
162
163
164 checkAbsPVInterpolationError(interpolationPoints1, 766704.6033758943, 3385.895505018284,
165 9.503905101141868, 0.0, interpolator1[0]);
166 checkAbsPVInterpolationError(interpolationPoints2, 46190.78568215623, 531.3506621730367,
167 0.5601906427491941, 0, interpolator2[0]);
168 checkAbsPVInterpolationError(interpolationPoints3, 2787.7069621834926, 55.5146607205871,
169 0.03372344505743245, 0.0, interpolator3[0]);
170
171
172 checkAbsPVInterpolationError(interpolationPoints1, 14023.999059896296, 48.022197580401084,
173 0.16984517369482555, 0.0, interpolator1[1]);
174 checkAbsPVInterpolationError(interpolationPoints2, 16.186825338590722, 0.13418685366189476,
175 1.898961129289559E-4, 0, interpolator2[1]);
176 checkAbsPVInterpolationError(interpolationPoints3, 0.025110113133073413, 3.5069332429486154E-4,
177 2.3306042475258594E-7, 0.0, interpolator3[1]);
178
179
180 checkAbsPVInterpolationError(interpolationPoints1, 108.13907262943746, 0.4134494277844817,
181 0.001389170843175492, 0.0, interpolator1[2]);
182 checkAbsPVInterpolationError(interpolationPoints2, 0.002974408269435121, 2.6937387601886076E-5,
183 2.051629855188969E-4, 0, interpolator2[2]);
184 checkAbsPVInterpolationError(interpolationPoints3, 0, 0,
185 1.3779131041190534E-4, 0.0, interpolator3[2]);
186 }
187
188
189
190
191
192
193
194
195
196 private Propagator setUpNumericalPropagator() {
197
198 final ODEIntegrator integrator = setUpIntegrator();
199
200 final NumericalPropagator propagator = new NumericalPropagator(integrator);
201
202
203 propagator.setOrbitType(null);
204
205
206 final Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
207 final NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(6, 6);
208 final HolmesFeatherstoneAttractionModel potential = new HolmesFeatherstoneAttractionModel(itrf, provider);
209
210 propagator.addForceModel(potential);
211 propagator.addForceModel(new SingleBodyAbsoluteAttraction(CelestialBodyFactory.getEarth()));
212
213
214 final SpacecraftState initialState = new SpacecraftState(absPV);
215
216 propagator.setInitialState(initialState);
217
218
219 propagator.setAttitudeProvider(attitudeLaw);
220
221 return propagator;
222 }
223
224
225
226
227
228
229 private ODEIntegrator setUpIntegrator() {
230 final double dP = 1;
231 final double minStep = 0.001;
232 final double maxStep = 100;
233 final double[][] tolerances = ToleranceProvider.of(CartesianToleranceProvider.of(dP)).getTolerances(absPV);
234
235 return new DormandPrince853Integrator(minStep, maxStep, tolerances[0], tolerances[1]);
236 }
237
238
239
240
241
242
243
244
245
246 private SpacecraftStateInterpolator[] buildAllTypeOfInterpolator(final int interpolationPoints,
247 final Frame inertialFrame) {
248
249 final CartesianDerivativesFilter[] pvaFilters = CartesianDerivativesFilter.values();
250 final AngularDerivativesFilter[] angularFilters = AngularDerivativesFilter.values();
251
252 final int dim = pvaFilters.length;
253 final SpacecraftStateInterpolator[] interpolators = new SpacecraftStateInterpolator[dim];
254
255 for (int i = 0; i < dim; i++) {
256 interpolators[i] = new SpacecraftStateInterpolator(interpolationPoints,
257 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
258 inertialFrame, inertialFrame,
259 pvaFilters[i], angularFilters[i]);
260 }
261
262 return interpolators;
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278 private void checkInterpolationError(int n, double expectedErrorP, double expectedErrorV,
279 double expectedErrorA, double expectedErrorM,
280 double expectedErrorQ, double expectedErrorD,
281 final TimeInterpolator<SpacecraftState> interpolator) {
282 AbsoluteDate centerDate = orbit.getDate().shiftedBy(100.0);
283 List<SpacecraftState> sample = new ArrayList<>();
284 for (int i = 0; i < n; ++i) {
285 double dt = i * 900.0 / (n - 1);
286 SpacecraftState state = orbitPropagator.propagate(centerDate.shiftedBy(dt));
287 state = state.
288 addAdditionalData("quadratic", dt * dt).
289 addAdditionalStateDerivative("quadratic-dot", dt * dt);
290 sample.add(state);
291 }
292
293 double maxErrorP = 0;
294 double maxErrorV = 0;
295 double maxErrorA = 0;
296 double maxErrorM = 0;
297 double maxErrorQ = 0;
298 double maxErrorD = 0;
299 for (double dt = 0; dt < 900.0; dt += 5) {
300 SpacecraftState interpolated = interpolator.interpolate(centerDate.shiftedBy(dt), sample);
301 SpacecraftState propagated = orbitPropagator.propagate(centerDate.shiftedBy(dt));
302 PVCoordinates dpv = new PVCoordinates(propagated.getPVCoordinates(), interpolated.getPVCoordinates());
303 maxErrorP = FastMath.max(maxErrorP, dpv.getPosition().getNorm());
304 maxErrorV = FastMath.max(maxErrorV, dpv.getVelocity().getNorm());
305 maxErrorA =
306 FastMath.max(maxErrorA, FastMath.toDegrees(Rotation.distance(interpolated.getAttitude().getRotation(),
307 propagated.getAttitude().getRotation())));
308 maxErrorM = FastMath.max(maxErrorM, FastMath.abs(interpolated.getMass() - propagated.getMass()));
309 maxErrorQ = FastMath.max(maxErrorQ, FastMath.abs(interpolated.getAdditionalState("quadratic")[0] - dt * dt));
310 maxErrorD = FastMath.max(maxErrorD,
311 FastMath.abs(interpolated.getAdditionalStateDerivative("quadratic-dot")[0] - dt * dt));
312 }
313 Assertions.assertEquals(expectedErrorP, maxErrorP, 1.0e-3);
314 Assertions.assertEquals(expectedErrorV, maxErrorV, 1.0e-6);
315 Assertions.assertEquals(expectedErrorA, maxErrorA, 4.0e-10);
316 Assertions.assertEquals(expectedErrorM, maxErrorM, 1.0e-15);
317 Assertions.assertEquals(expectedErrorQ, maxErrorQ, 2.0e-10);
318 Assertions.assertEquals(expectedErrorD, maxErrorD, 2.0e-10);
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332
333 private void checkAbsPVInterpolationError(int n, double expectedErrorP, double expectedErrorV,
334 double expectedErrorA, double expectedErrorM,
335 final TimeInterpolator<SpacecraftState> interpolator) {
336 AbsoluteDate centerDate = absPV.getDate().shiftedBy(100.0);
337 List<SpacecraftState> sample = new ArrayList<>();
338 for (int i = 0; i < n; ++i) {
339 double dt = i * 900.0 / (n - 1);
340 SpacecraftState state = absPVPropagator.propagate(centerDate.shiftedBy(dt));
341 state = state.
342 addAdditionalData("quadratic", dt * dt).
343 addAdditionalStateDerivative("quadratic-dot", dt * dt);
344 sample.add(state);
345 }
346
347 double maxErrorP = 0;
348 double maxErrorV = 0;
349 double maxErrorA = 0;
350 double maxErrorM = 0;
351 for (double dt = 0; dt < 900.0; dt += 5) {
352 SpacecraftState interpolated = interpolator.interpolate(centerDate.shiftedBy(dt), sample);
353 SpacecraftState propagated = absPVPropagator.propagate(centerDate.shiftedBy(dt));
354 PVCoordinates dpv = new PVCoordinates(propagated.getPVCoordinates(), interpolated.getPVCoordinates());
355 maxErrorP = FastMath.max(maxErrorP, dpv.getPosition().getNorm());
356 maxErrorV = FastMath.max(maxErrorV, dpv.getVelocity().getNorm());
357 maxErrorA =
358 FastMath.max(maxErrorA, FastMath.toDegrees(Rotation.distance(interpolated.getAttitude().getRotation(),
359 propagated.getAttitude().getRotation())));
360 maxErrorM = FastMath.max(maxErrorM, FastMath.abs(interpolated.getMass() - propagated.getMass()));
361 }
362 Assertions.assertEquals(expectedErrorP, maxErrorP, 1.0e-3);
363 Assertions.assertEquals(expectedErrorV, maxErrorV, 1.0e-6);
364 Assertions.assertEquals(expectedErrorA, maxErrorA, 4.0e-10);
365 Assertions.assertEquals(expectedErrorM, maxErrorM, 1.0e-15);
366 }
367
368 @Test
369 @DisplayName("test error thrown when using different state definition")
370 void testErrorThrownWhenUsingDifferentStateDefinition() {
371
372 final AbsoluteDate interpolationDate = new AbsoluteDate();
373
374 final SpacecraftState orbitDefinedState = Mockito.mock(SpacecraftState.class);
375 final SpacecraftState absPVDefinedState = Mockito.mock(SpacecraftState.class);
376
377 Mockito.when(orbitDefinedState.isOrbitDefined()).thenReturn(true);
378 Mockito.when(absPVDefinedState.isOrbitDefined()).thenReturn(false);
379
380 final List<SpacecraftState> states = new ArrayList<>();
381 states.add(orbitDefinedState);
382 states.add(absPVDefinedState);
383
384
385 final Frame inertialFrameMock = Mockito.mock(Frame.class);
386 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
387
388 final TimeInterpolator<SpacecraftState> stateInterpolator =
389 new SpacecraftStateInterpolator(2, inertialFrameMock, inertialFrameMock);
390
391
392 Exception thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class,
393 () -> stateInterpolator.interpolate(interpolationDate, states));
394
395 Assertions.assertEquals(
396 "one state is defined using an orbit while the other is defined using an absolute position-velocity-acceleration",
397 thrown.getMessage());
398 }
399
400 @Test
401 @DisplayName("test error thrown when using different state definition")
402 void testErrorThrownWhenGivingNoInterpolatorForState() {
403
404 final Frame inertialFrameMock = Mockito.mock(Frame.class);
405 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
406
407
408 Exception thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class,
409 () -> new SpacecraftStateInterpolator(
410 AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
411 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
412 inertialFrameMock, null, null,
413 null, null, null));
414
415 Assertions.assertEquals("creating a spacecraft state interpolator requires at least one orbit interpolator or an "
416 + "absolute position-velocity-acceleration interpolator", thrown.getMessage());
417 }
418
419 @Test
420 @DisplayName("test error thrown when giving wrong sample type for interpolation")
421 void testErrorThrownWhenGivingWrongSampleTypeForInterpolator() {
422
423 final AbsoluteDate interpolationDate = new AbsoluteDate();
424
425 final Frame inertialFrame = FramesFactory.getEME2000();
426
427 final SpacecraftState absPVDefinedState1 = Mockito.mock(SpacecraftState.class);
428 final SpacecraftState absPVDefinedState2 = Mockito.mock(SpacecraftState.class);
429
430 Mockito.when(absPVDefinedState1.isOrbitDefined()).thenReturn(false);
431 Mockito.when(absPVDefinedState2.isOrbitDefined()).thenReturn(false);
432
433 Mockito.when(absPVDefinedState1.getDate()).thenReturn(interpolationDate);
434 Mockito.when(absPVDefinedState2.getDate()).thenReturn(interpolationDate.shiftedBy(1));
435
436 final List<SpacecraftState> states = new ArrayList<>();
437 states.add(absPVDefinedState1);
438 states.add(absPVDefinedState2);
439
440
441 @SuppressWarnings("unchecked") final TimeInterpolator<Orbit> orbitInterpolatorMock = Mockito.mock(TimeInterpolator.class);
442
443 final TimeInterpolator<SpacecraftState> interpolator =
444 new SpacecraftStateInterpolator(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
445 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
446 inertialFrame, orbitInterpolatorMock, null, null, null, null);
447
448
449 Exception thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class, () ->
450 interpolator.interpolate(interpolationDate, states));
451
452 Assertions.assertEquals("wrong interpolator defined for this spacecraft state type (orbit or absolute PV)",
453 thrown.getMessage());
454 }
455
456 @Test
457 void testGetNbInterpolationsWithMultipleSubInterpolators() {
458
459
460 final Frame frame = Mockito.mock(Frame.class);
461
462 final TimeInterpolator<Orbit> orbitInterpolator = Mockito.mock(OrbitHermiteInterpolator.class);
463
464 final TimeInterpolator<AbsolutePVCoordinates> absPVAInterpolator =
465 Mockito.mock(AbsolutePVCoordinatesHermiteInterpolator.class);
466
467 final TimeInterpolator<TimeStampedDouble> massInterpolator =
468 Mockito.mock(TimeStampedDoubleHermiteInterpolator.class);
469
470 final TimeInterpolator<Attitude> attitudeInterpolator = Mockito.mock(AttitudeInterpolator.class);
471
472 final TimeInterpolator<TimeStampedDouble> additionalStateInterpolator =
473 Mockito.mock(TimeStampedDoubleHermiteInterpolator.class);
474
475
476 final int orbitNbInterpolationPoints = 2;
477 final int absPVANbInterpolationPoints = 3;
478 final int massNbInterpolationPoints = 4;
479 final int AttitudeNbInterpolationPoints = 5;
480 final int AdditionalStateNbInterpolationPoints = 6;
481
482 Mockito.when(orbitInterpolator.getNbInterpolationPoints()).thenReturn(orbitNbInterpolationPoints);
483 Mockito.when(absPVAInterpolator.getNbInterpolationPoints()).thenReturn(absPVANbInterpolationPoints);
484 Mockito.when(massInterpolator.getNbInterpolationPoints()).thenReturn(massNbInterpolationPoints);
485 Mockito.when(attitudeInterpolator.getNbInterpolationPoints()).thenReturn(AttitudeNbInterpolationPoints);
486 Mockito.when(additionalStateInterpolator.getNbInterpolationPoints()).thenReturn(AdditionalStateNbInterpolationPoints);
487
488 Mockito.when(orbitInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(orbitInterpolator));
489 Mockito.when(absPVAInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(absPVAInterpolator));
490 Mockito.when(massInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(massInterpolator));
491 Mockito.when(attitudeInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(attitudeInterpolator));
492 Mockito.when(additionalStateInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(additionalStateInterpolator));
493
494 final SpacecraftStateInterpolator stateInterpolator =
495 new SpacecraftStateInterpolator(2, 1.0e-3, frame, orbitInterpolator, absPVAInterpolator, massInterpolator,
496 attitudeInterpolator, additionalStateInterpolator);
497
498
499 final int returnedNbInterpolationPoints = stateInterpolator.getNbInterpolationPoints();
500
501
502 Assertions.assertEquals(AdditionalStateNbInterpolationPoints, returnedNbInterpolationPoints);
503 }
504
505 @SuppressWarnings("deprecation")
506 @Test
507 void testGetNbInterpolationsWithMultipleSubInterpolatorsDeprecated() {
508
509
510 final Frame frame = Mockito.mock(Frame.class);
511
512 final TimeInterpolator<Orbit> orbitInterpolator = Mockito.mock(OrbitHermiteInterpolator.class);
513
514 final TimeInterpolator<AbsolutePVCoordinates> absPVAInterpolator =
515 Mockito.mock(AbsolutePVCoordinatesHermiteInterpolator.class);
516
517 final TimeInterpolator<TimeStampedDouble> massInterpolator =
518 Mockito.mock(TimeStampedDoubleHermiteInterpolator.class);
519
520 final TimeInterpolator<Attitude> attitudeInterpolator = Mockito.mock(AttitudeInterpolator.class);
521
522 final TimeInterpolator<TimeStampedDouble> additionalStateInterpolator =
523 Mockito.mock(TimeStampedDoubleHermiteInterpolator.class);
524
525
526 final int orbitNbInterpolationPoints = 2;
527 final int absPVANbInterpolationPoints = 3;
528 final int massNbInterpolationPoints = 4;
529 final int AttitudeNbInterpolationPoints = 5;
530 final int AdditionalStateNbInterpolationPoints = 6;
531
532 Mockito.when(orbitInterpolator.getNbInterpolationPoints()).thenReturn(orbitNbInterpolationPoints);
533 Mockito.when(absPVAInterpolator.getNbInterpolationPoints()).thenReturn(absPVANbInterpolationPoints);
534 Mockito.when(massInterpolator.getNbInterpolationPoints()).thenReturn(massNbInterpolationPoints);
535 Mockito.when(attitudeInterpolator.getNbInterpolationPoints()).thenReturn(AttitudeNbInterpolationPoints);
536 Mockito.when(additionalStateInterpolator.getNbInterpolationPoints()).thenReturn(AdditionalStateNbInterpolationPoints);
537
538 Mockito.when(orbitInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(orbitInterpolator));
539 Mockito.when(absPVAInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(absPVAInterpolator));
540 Mockito.when(massInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(massInterpolator));
541 Mockito.when(attitudeInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(attitudeInterpolator));
542 Mockito.when(additionalStateInterpolator.getSubInterpolators()).thenReturn(Collections.singletonList(additionalStateInterpolator));
543
544 final SpacecraftStateInterpolator stateInterpolator =
545 new SpacecraftStateInterpolator(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
546 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
547 frame, orbitInterpolator, absPVAInterpolator, massInterpolator,
548 attitudeInterpolator, additionalStateInterpolator);
549
550
551 final int returnedNbInterpolationPoints = stateInterpolator.getNbInterpolationPoints();
552
553
554 Assertions.assertEquals(AdditionalStateNbInterpolationPoints, returnedNbInterpolationPoints);
555 }
556
557 @Test
558 @DisplayName("test error thrown when giving empty sample")
559 void testErrorThrownWhenGivingEmptySample() {
560
561 final AbsoluteDate interpolationDate = new AbsoluteDate();
562
563 final Frame inertialFrame = FramesFactory.getEME2000();
564
565 final List<SpacecraftState> states = new ArrayList<>();
566
567
568 @SuppressWarnings("unchecked") final TimeInterpolator<Orbit> orbitInterpolatorMock = Mockito.mock(TimeInterpolator.class);
569
570 final TimeInterpolator<SpacecraftState> interpolator =
571 new SpacecraftStateInterpolator(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
572 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
573 inertialFrame, orbitInterpolatorMock, null, null, null, null);
574
575
576 OrekitIllegalArgumentException thrown = Assertions.assertThrows(OrekitIllegalArgumentException.class, () ->
577 interpolator.interpolate(interpolationDate, states));
578
579 Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, thrown.getSpecifier());
580 Assertions.assertEquals(0, ((Integer) thrown.getParts()[0]).intValue());
581
582 }
583
584 @Test
585 void testSpacecraftStateInterpolatorCreation() {
586
587 final Frame inertialFrameMock = Mockito.mock(Frame.class);
588 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
589
590 @SuppressWarnings("unchecked") final TimeInterpolator<Orbit> orbitInterpolatorMock =
591 Mockito.mock(TimeInterpolator.class);
592
593 @SuppressWarnings("unchecked") final TimeInterpolator<AbsolutePVCoordinates> absPVInterpolatorMock =
594 Mockito.mock(TimeInterpolator.class);
595
596 @SuppressWarnings("unchecked") final TimeInterpolator<TimeStampedDouble> massInterpolatorMock =
597 Mockito.mock(TimeInterpolator.class);
598
599 @SuppressWarnings("unchecked") final TimeInterpolator<Attitude> attitudeInterpolatorMock =
600 Mockito.mock(TimeInterpolator.class);
601
602 @SuppressWarnings("unchecked") final TimeInterpolator<TimeStampedDouble> additionalInterpolatorMock =
603 Mockito.mock(TimeInterpolator.class);
604
605
606 final SpacecraftStateInterpolator interpolator =
607 new SpacecraftStateInterpolator(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
608 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
609 inertialFrameMock, orbitInterpolatorMock, absPVInterpolatorMock,
610 massInterpolatorMock, attitudeInterpolatorMock, additionalInterpolatorMock);
611
612
613 Assertions.assertEquals(inertialFrameMock, interpolator.getOutputFrame());
614 Assertions.assertEquals(orbitInterpolatorMock, interpolator.getOrbitInterpolator().get());
615 Assertions.assertEquals(absPVInterpolatorMock, interpolator.getAbsPVAInterpolator().get());
616 Assertions.assertEquals(massInterpolatorMock, interpolator.getMassInterpolator().get());
617 Assertions.assertEquals(attitudeInterpolatorMock, interpolator.getAttitudeInterpolator().get());
618 Assertions.assertEquals(additionalInterpolatorMock, interpolator.getAdditionalStateInterpolator().get());
619
620 }
621
622 @Test
623 void testIssue1266() {
624
625 final Frame inertialFrameMock = Mockito.mock(Frame.class);
626 Mockito.when(inertialFrameMock.isPseudoInertial()).thenReturn(true);
627 final int interpolationPoints = 3;
628 final double extrapolationThreshold = 10;
629
630
631 final SpacecraftStateInterpolator interpolator =
632 new SpacecraftStateInterpolator(interpolationPoints, extrapolationThreshold,
633 inertialFrameMock, inertialFrameMock);
634
635
636 Assertions.assertEquals(extrapolationThreshold, interpolator.getExtrapolationThreshold());
637
638 }
639
640 @Test
641 @DisplayName("Test error thrown when sub interpolator is not present")
642 void testErrorThrownWhenSubInterpolatorIsNotPresent() {
643
644 final FakeStateInterpolator fakeStateInterpolator = new FakeStateInterpolator();
645
646
647 Assertions.assertThrows(OrekitInternalError.class, fakeStateInterpolator::getNbInterpolationPoints);
648 }
649
650 private static class FakeStateInterpolator extends AbstractTimeInterpolator<SpacecraftState> {
651
652 public FakeStateInterpolator() {
653 super(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
654 AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC);
655 }
656
657 @Override
658 protected SpacecraftState interpolate(AbstractTimeInterpolator<SpacecraftState>.InterpolationData interpolationData) {
659 return null;
660 }
661
662 @Override
663 public List<TimeInterpolator<? extends TimeStamped>> getSubInterpolators() {
664 return Collections.emptyList();
665 }
666 }
667 }