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.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.analysis.polynomials.PolynomialFunction;
22 import org.hipparchus.complex.Complex;
23 import org.hipparchus.complex.ComplexField;
24 import org.hipparchus.exception.LocalizedCoreFormats;
25 import org.hipparchus.exception.MathIllegalStateException;
26 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
27 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
28 import org.hipparchus.geometry.euclidean.threed.Rotation;
29 import org.hipparchus.geometry.euclidean.threed.Vector3D;
30 import org.hipparchus.ode.FieldODEIntegrator;
31 import org.hipparchus.ode.events.Action;
32 import org.hipparchus.ode.nonstiff.DormandPrince853FieldIntegrator;
33 import org.hipparchus.util.Binary64;
34 import org.hipparchus.util.Binary64Field;
35 import org.hipparchus.util.FastMath;
36 import org.hipparchus.util.MathArrays;
37 import org.junit.jupiter.api.Assertions;
38 import org.junit.jupiter.api.BeforeEach;
39 import org.junit.jupiter.api.Test;
40 import org.orekit.TestUtils;
41 import org.orekit.Utils;
42 import org.orekit.attitudes.BodyCenterPointing;
43 import org.orekit.attitudes.FieldAttitude;
44 import org.orekit.bodies.OneAxisEllipsoid;
45 import org.orekit.errors.OrekitException;
46 import org.orekit.errors.OrekitIllegalArgumentException;
47 import org.orekit.errors.OrekitMessages;
48 import org.orekit.frames.FieldStaticTransform;
49 import org.orekit.frames.FieldTransform;
50 import org.orekit.frames.FramesFactory;
51 import org.orekit.frames.Transform;
52 import org.orekit.orbits.FieldCartesianOrbit;
53 import org.orekit.orbits.FieldKeplerianOrbit;
54 import org.orekit.orbits.FieldOrbit;
55 import org.orekit.orbits.KeplerianOrbit;
56 import org.orekit.orbits.Orbit;
57 import org.orekit.orbits.PositionAngleType;
58 import org.orekit.propagation.analytical.FieldEcksteinHechlerPropagator;
59 import org.orekit.propagation.analytical.FieldKeplerianPropagator;
60 import org.orekit.propagation.events.FieldDateDetector;
61 import org.orekit.propagation.events.FieldEventDetector;
62 import org.orekit.propagation.events.handlers.FieldEventHandler;
63 import org.orekit.propagation.numerical.FieldNumericalPropagator;
64 import org.orekit.time.AbsoluteDate;
65 import org.orekit.time.DateComponents;
66 import org.orekit.time.FieldAbsoluteDate;
67 import org.orekit.time.TimeComponents;
68 import org.orekit.time.TimeScalesFactory;
69 import org.orekit.utils.*;
70
71
72 class FieldSpacecraftStateTest {
73
74 @Test
75 public void testToFieldSpacecraftStateWithStringAdditionalData() {
76 final Binary64Field field = Binary64Field.getInstance();
77 final SpacecraftState state = new SpacecraftState(TestUtils.getDefaultOrbit(AbsoluteDate.ARBITRARY_EPOCH)).addAdditionalData("test-string", "hello");
78 final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
79 Assertions.assertTrue(fieldState.hasAdditionalData("test-string"));
80 Assertions.assertEquals("hello", fieldState.getAdditionalData("test-string"));
81 }
82
83 @Test
84 void testWithAttitudeAndOrbit() {
85
86 final SpacecraftState state = new SpacecraftState(TestUtils.getDefaultOrbit(AbsoluteDate.ARBITRARY_EPOCH));
87 final Binary64Field field = Binary64Field.getInstance();
88 final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
89 final FieldAttitude<Binary64> attitude = new FieldAttitude<>(fieldState.getDate(), state.getFrame(),
90 new FieldAngularCoordinates<>(FieldRotation.getIdentity(field), FieldVector3D.getMinusI(field)));
91
92 final FieldSpacecraftState<Binary64> fieldStateWithAttitude = fieldState.withAttitude(attitude);
93
94 Assertions.assertEquals(attitude, fieldStateWithAttitude.getAttitude());
95 Assertions.assertEquals(fieldState.getMass(), fieldStateWithAttitude.getMass());
96 Assertions.assertEquals(fieldState.getOrbit(), fieldStateWithAttitude.getOrbit());
97 }
98
99 @Test
100 void testWithMassAndOrbit() {
101
102 final SpacecraftState state = new SpacecraftState(TestUtils.getDefaultOrbit(AbsoluteDate.ARBITRARY_EPOCH));
103 final Binary64Field field = Binary64Field.getInstance();
104 final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
105 final Binary64 expectedMass = new Binary64(123);
106
107 final FieldSpacecraftState<Binary64> fieldStateWithMass = fieldState.withMass(expectedMass);
108
109 Assertions.assertEquals(expectedMass, fieldStateWithMass.getMass());
110 Assertions.assertEquals(fieldState.getAttitude(), fieldStateWithMass.getAttitude());
111 Assertions.assertEquals(fieldState.getOrbit(), fieldStateWithMass.getOrbit());
112 }
113
114 @Test
115 void testWithAttitudeAndAbsolutePV() {
116
117 final AbsolutePVCoordinates absolutePVCoordinates = new AbsolutePVCoordinates(FramesFactory.getEME2000(),
118 AbsoluteDate.ARBITRARY_EPOCH, new PVCoordinates());
119 final SpacecraftState state = new SpacecraftState(absolutePVCoordinates);
120 final Binary64Field field = Binary64Field.getInstance();
121 final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
122 final FieldAttitude<Binary64> attitude = new FieldAttitude<>(fieldState.getDate(), state.getFrame(),
123 new FieldAngularCoordinates<>(FieldRotation.getIdentity(field), FieldVector3D.getMinusI(field)));
124
125 final FieldSpacecraftState<Binary64> fieldStateWithAttitude = fieldState.withAttitude(attitude);
126
127 Assertions.assertEquals(attitude, fieldStateWithAttitude.getAttitude());
128 Assertions.assertEquals(fieldState.getMass(), fieldStateWithAttitude.getMass());
129 Assertions.assertEquals(fieldState.getAbsPVA(), fieldStateWithAttitude.getAbsPVA());
130 }
131
132 @Test
133 void testWithMassAndAbsolutePV() {
134
135 final AbsolutePVCoordinates absolutePVCoordinates = new AbsolutePVCoordinates(FramesFactory.getEME2000(),
136 AbsoluteDate.ARBITRARY_EPOCH, new PVCoordinates());
137 final SpacecraftState state = new SpacecraftState(absolutePVCoordinates);
138 final Binary64Field field = Binary64Field.getInstance();
139 final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
140 final Binary64 expectedMass = new Binary64(123);
141
142 final FieldSpacecraftState<Binary64> fieldStateWithMass = fieldState.withMass(expectedMass);
143
144 Assertions.assertEquals(expectedMass, fieldStateWithMass.getMass());
145 Assertions.assertEquals(fieldState.getAttitude(), fieldStateWithMass.getAttitude());
146 Assertions.assertEquals(fieldState.getAbsPVA(), fieldStateWithMass.getAbsPVA());
147 }
148
149 @Test
150 void testFieldVSReal() {
151 doTestFieldVsReal(Binary64Field.getInstance());
152 }
153
154 @Test
155 void testShiftVsEcksteinHechlerError() {
156 doTestShiftVsEcksteinHechlerError(Binary64Field.getInstance());
157 }
158
159 @Test
160 void testDatesConsistency() {
161 Assertions.assertThrows(IllegalArgumentException.class, () -> doTestDatesConsistency(Binary64Field.getInstance()));
162 }
163
164 @Test
165 void testDateConsistencyClose() {
166 doTestDateConsistencyClose(Binary64Field.getInstance());
167 }
168
169 @Test
170 void testFramesConsistency() {
171 Assertions.assertThrows(IllegalArgumentException.class, () -> doTestFramesConsistency(Binary64Field.getInstance()));
172 }
173
174 @Test
175 void testGetAdditionalStateBadType() {
176 doTestGetAdditionalStateBadType(Binary64Field.getInstance());
177 }
178
179 @Test
180 void testTransform() {
181 doTestTransform(Binary64Field.getInstance());
182 }
183
184 @Test
185 void testAdditionalStates() {
186 doTestAdditionalStates(Binary64Field.getInstance());
187 }
188
189 @Test
190 void testAdditionalStatesDerivatives() {
191 doTestAdditionalStatesDerivatives(Binary64Field.getInstance());
192 }
193
194 @Test
195 void testFieldVSRealAbsPV() {
196 doTestFieldVsRealAbsPV(Binary64Field.getInstance());
197 }
198
199 @Test
200 void testDateConsistencyCloseAbsPV() {
201 doTestDateConsistencyCloseAbsPV(Binary64Field.getInstance());
202 }
203
204 @Test
205 void testFramesConsistencyAbsPV() {
206 Assertions.assertThrows(IllegalArgumentException.class,
207 () -> doTestFramesConsistencyAbsPV(Binary64Field.getInstance()));
208 }
209
210 @Test
211 void testAdditionalStatesAbsPV() {
212 doTestAdditionalStatesAbsPV(Binary64Field.getInstance());
213 }
214
215 @Test
216 void testAdditionalStatesDerivativesAbsPV() {
217 doTestAdditionalStatesDerivativesAbsPV(Binary64Field.getInstance());
218 }
219
220 @Test
221 void testResetOnEventAnalytical() {
222 doTestAdditionalTestResetOnEventAnalytical(Binary64Field.getInstance());
223 }
224
225 @Test
226 void testResetOnEventNumerical() {
227 doTestAdditionalTestResetOnEventNumerical(Binary64Field.getInstance());
228 }
229
230 @Test
231 void testShiftAdditionalDerivativesDouble() {
232 doTestShiftAdditionalDerivativesDouble(Binary64Field.getInstance());
233 }
234
235 @Test
236 void testShiftAdditionalDerivativesField() {
237 doTestShiftAdditionalDerivativesField(Binary64Field.getInstance());
238 }
239
240 @Test
241 void testToTransform() {
242
243 final ComplexField field = ComplexField.getInstance();
244 final FieldOrbit<Complex> orbit = new FieldCartesianOrbit<>(field, rOrbit);
245 final TimeStampedAngularCoordinates angularCoordinates = new TimeStampedAngularCoordinates(
246 orbit.getDate().toAbsoluteDate(), Rotation.IDENTITY, Vector3D.ZERO, Vector3D.ZERO);
247 final FieldAttitude<Complex> attitude = new FieldAttitude<>(orbit.getFrame(),
248 new TimeStampedFieldAngularCoordinates<>(field, angularCoordinates));
249 final FieldSpacecraftState<Complex> state = new FieldSpacecraftState<>(orbit, attitude);
250
251 final FieldTransform<Complex> fieldTransform = state.toTransform();
252
253 final Transform expectedTransform = state.toSpacecraftState().toTransform();
254 Assertions.assertEquals(expectedTransform.getDate(), fieldTransform.getDate());
255 final double tolerance = 1e-10;
256 Assertions.assertEquals(expectedTransform.getTranslation().getX(),
257 fieldTransform.getTranslation().getX().getReal(), tolerance);
258 Assertions.assertEquals(expectedTransform.getTranslation().getY(),
259 fieldTransform.getTranslation().getY().getReal(), tolerance);
260 Assertions.assertEquals(expectedTransform.getTranslation().getZ(),
261 fieldTransform.getTranslation().getZ().getReal(), tolerance);
262 Assertions.assertEquals(0., Rotation.distance(expectedTransform.getRotation(),
263 fieldTransform.getRotation().toRotation()));
264 }
265
266 @Test
267 void testToStaticTransform() {
268
269 final ComplexField field = ComplexField.getInstance();
270 final FieldOrbit<Complex> orbit = new FieldCartesianOrbit<>(field, rOrbit);
271 final TimeStampedAngularCoordinates angularCoordinates = new TimeStampedAngularCoordinates(
272 orbit.getDate().toAbsoluteDate(), Rotation.IDENTITY, Vector3D.ZERO, Vector3D.ZERO);
273 final FieldAttitude<Complex> attitude = new FieldAttitude<>(orbit.getFrame(),
274 new TimeStampedFieldAngularCoordinates<>(field, angularCoordinates));
275 final FieldSpacecraftState<Complex> state = new FieldSpacecraftState<>(orbit, attitude);
276
277 final FieldStaticTransform<Complex> actualStaticTransform = state.toStaticTransform();
278
279 final FieldStaticTransform<Complex> expectedStaticTransform = state.toTransform();
280 Assertions.assertEquals(expectedStaticTransform.getDate(), actualStaticTransform.getDate());
281 final double tolerance = 1e-10;
282 Assertions.assertEquals(expectedStaticTransform.getTranslation().getX().getReal(),
283 actualStaticTransform.getTranslation().getX().getReal(), tolerance);
284 Assertions.assertEquals(expectedStaticTransform.getTranslation().getY().getReal(),
285 actualStaticTransform.getTranslation().getY().getReal(), tolerance);
286 Assertions.assertEquals(expectedStaticTransform.getTranslation().getZ().getReal(),
287 actualStaticTransform.getTranslation().getZ().getReal(), tolerance);
288 Assertions.assertEquals(0., Rotation.distance(expectedStaticTransform.getRotation().toRotation(),
289 actualStaticTransform.getRotation().toRotation()));
290 }
291
292 private <T extends CalculusFieldElement<T>> void doTestFieldVsReal(final Field<T> field) {
293 T zero = field.getZero();
294
295 double mu = 3.9860047e14;
296
297 T a_f = zero.add(150000);
298 T e_f = zero.add( 0);
299 T i_f = zero.add( 0);
300 T pa_f = zero.add( 0);
301 T raan_f = zero.add( 0);
302 T m_f = zero.add( 0);
303
304 FieldAbsoluteDate<T> t_f = new FieldAbsoluteDate<>(field);
305
306 double a_r = a_f.getReal();
307 double e_r = e_f.getReal();
308 double i_r = i_f.getReal();
309 double pa_r = pa_f.getReal();
310 double raan_r = raan_f.getReal();
311 double m_r = m_f.getReal();
312
313 AbsoluteDate t_r = t_f.toAbsoluteDate();
314
315
316 KeplerianOrbit kep_r = new KeplerianOrbit(a_r, e_r, i_r, pa_r, raan_r, m_r, PositionAngleType.ECCENTRIC, FramesFactory.getEME2000(), t_r, mu);
317 FieldKeplerianOrbit<T> kep_f = new FieldKeplerianOrbit<>(a_f, e_f, i_f, pa_f, raan_f, m_f, PositionAngleType.ECCENTRIC, FramesFactory.getEME2000(), t_f, zero.add(mu));
318
319 SpacecraftState ScS_r = new SpacecraftState(kep_r);
320 FieldSpacecraftState<T> ScS_f = new FieldSpacecraftState<>(kep_f);
321
322 for (double dt = 0; dt < 500; dt+=100){
323 SpacecraftState control_r = ScS_r.shiftedBy(dt);
324 FieldSpacecraftState<T> control_f = ScS_f.shiftedBy(zero.add(dt));
325
326
327 Assertions.assertEquals(control_r.getOrbit().getA(), control_f.getOrbit().getA().getReal(), 1e-10);
328 Assertions.assertEquals(control_r.getOrbit().getE(), control_f.getOrbit().getE().getReal(), 1e-10);
329 Assertions.assertEquals(control_r.getOrbit().getEquinoctialEx(), control_f.getOrbit().getEquinoctialEx().getReal(), 1e-10);
330 Assertions.assertEquals(control_r.getOrbit().getEquinoctialEy(), control_f.getOrbit().getEquinoctialEy().getReal(), 1e-10);
331 Assertions.assertEquals(control_r.getPosition().getX(), control_f.getPVCoordinates().toPVCoordinates().getPosition().getX(), 1e-10);
332 Assertions.assertEquals(control_r.getPosition().getY(), control_f.getPVCoordinates().toPVCoordinates().getPosition().getY(), 1e-10);
333 Assertions.assertEquals(control_r.getPosition().getZ(), control_f.getPVCoordinates().toPVCoordinates().getPosition().getZ(), 1e-10);
334 Assertions.assertEquals(control_r.getPVCoordinates().getVelocity().getX(), control_f.getPVCoordinates().toPVCoordinates().getVelocity().getX(), 1e-10);
335 Assertions.assertEquals(control_r.getPVCoordinates().getVelocity().getY(), control_f.getPVCoordinates().toPVCoordinates().getVelocity().getY(), 1e-10);
336 Assertions.assertEquals(control_r.getPVCoordinates().getVelocity().getZ(), control_f.getPVCoordinates().toPVCoordinates().getVelocity().getZ(), 1e-10);
337 Assertions.assertEquals(control_r.getPVCoordinates().getAcceleration().getX(), control_f.getPVCoordinates().toPVCoordinates().getAcceleration().getX(), 1e-10);
338 Assertions.assertEquals(control_r.getPVCoordinates().getAcceleration().getY(), control_f.getPVCoordinates().toPVCoordinates().getAcceleration().getY(), 1e-10);
339 Assertions.assertEquals(control_r.getPVCoordinates().getAcceleration().getZ(), control_f.getPVCoordinates().toPVCoordinates().getAcceleration().getZ(), 1e-10);
340 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ0(), control_f.getAttitude().getOrientation().getRotation().getQ0().getReal(), 1e-10);
341 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ1(), control_f.getAttitude().getOrientation().getRotation().getQ1().getReal(), 1e-10);
342 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ2(), control_f.getAttitude().getOrientation().getRotation().getQ2().getReal(), 1e-10);
343 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ3(), control_f.getAttitude().getOrientation().getRotation().getQ3().getReal(), 1e-10);
344
345 Assertions.assertEquals(control_r.getAttitude().getSpin().getAlpha(), control_f.getAttitude().getSpin().getAlpha().getReal(), 1e-10);
346 Assertions.assertEquals(control_r.getAttitude().getSpin().getDelta(), control_f.getAttitude().getSpin().getDelta().getReal(), 1e-10);
347 Assertions.assertEquals(control_r.getAttitude().getSpin().getNorm(), control_f.getAttitude().getSpin().getNorm().getReal(), 1e-10);
348
349 Assertions.assertEquals(control_r.getAttitude().getReferenceFrame().isPseudoInertial(), control_f.getAttitude().getReferenceFrame().isPseudoInertial());
350 Assertions.assertEquals(control_r.getAttitude().getDate().durationFrom(AbsoluteDate.J2000_EPOCH), control_f.getAttitude().getDate().durationFrom(AbsoluteDate.J2000_EPOCH).getReal(), 1e-10);
351
352
353 }
354
355 }
356
357 private <T extends CalculusFieldElement<T>> void doTestShiftVsEcksteinHechlerError(final Field<T> field)
358 {
359
360 T zero = field.getZero();
361 T mass = zero.add(2500.);
362 T a = zero.add(rOrbit.getA());
363 T e = zero.add(rOrbit.getE());
364 T i = zero.add(rOrbit.getI());
365 T pa = zero.add(1.9674147913622104);
366 T raan = zero.add(FastMath.toRadians(261));
367 T lv = zero.add(0);
368 final double ae = 6.378137e6;
369 final double c20 = -1.08263e-3;
370 final double c30 = 2.54e-6;
371 final double c40 = 1.62e-6;
372 final double c50 = 2.3e-7;
373 final double c60 = -5.5e-7;
374
375
376
377
378
379
380
381
382
383
384
385 PolynomialFunction pModel = new PolynomialFunction(new double[] {
386 1.5664070631933846e-01, 7.5504722733047560e-03, -8.2460562451009510e-05,
387 6.9546332080305580e-06, -1.7045365367533077e-09, -4.2187860791066264e-13
388 });
389 PolynomialFunction vModel = new PolynomialFunction(new double[] {
390 -3.5472364019908720e-04, 1.6568103861124980e-05, 1.9637913327830596e-05,
391 -3.4248792843039766e-09, -5.6565135131014254e-12, 1.4730170946808630e-15
392 });
393 PolynomialFunction aModel = new PolynomialFunction(new double[] {
394 3.0731707577766896e-06, 3.9770746399850350e-05, 1.9779039254538660e-09,
395 8.0263328220724900e-12, -1.5600835252366078e-14, 1.1785257001549687e-18
396 });
397 PolynomialFunction rModel = new PolynomialFunction(new double[] {
398 -2.7689062063188115e-06, 1.7406542538258334e-07, 2.5109795349592287e-09,
399 2.0399322661074575e-11, 9.9126348912426750e-15, -3.5015638905729510e-18
400 });
401
402 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
403 TimeComponents.H00,
404 TimeScalesFactory.getUTC());
405
406 FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(a, e, i, pa, raan, lv, PositionAngleType.TRUE,
407 FramesFactory.getEME2000(), date, zero.add(mu));
408
409 BodyCenterPointing attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
410
411 FieldPropagator<T> propagator =
412 new FieldEcksteinHechlerPropagator<>(orbit, attitudeLaw, mass,
413 ae, zero.add(mu), c20, c30, c40, c50, c60);
414
415 FieldAbsoluteDate<T> centerDate = orbit.getDate().shiftedBy(100.0);
416
417 FieldSpacecraftState<T> centerState = propagator.propagate(centerDate);
418
419 double maxResidualP = 0;
420 double maxResidualV = 0;
421 double maxResidualA = 0;
422 double maxResidualR = 0;
423 for (T dt = field.getZero(); dt.getReal() < 900.0; dt = dt.add(5)) {
424
425 FieldSpacecraftState<T> shifted = centerState.shiftedBy(dt);
426 FieldSpacecraftState<T> propagated = propagator.propagate(centerDate.shiftedBy(dt));
427 FieldPVCoordinates<T> dpv = new FieldPVCoordinates<>(propagated.getPVCoordinates(), shifted.getPVCoordinates());
428
429
430 double residualP = pModel.value(dt.getReal()) - dpv.getPosition().getNorm().getReal();
431 double residualV = vModel.value(dt.getReal()) - dpv.getVelocity().getNorm().getReal();
432 double residualA = aModel.value(dt.getReal()) - dpv.getAcceleration().getNorm().getReal();
433 double residualR = rModel.value(dt.getReal()) -
434 FastMath.toDegrees(FieldRotation.distance(shifted.getAttitude().getRotation(),
435 propagated.getAttitude().getRotation()).getReal());
436 maxResidualP = FastMath.max(maxResidualP, FastMath.abs(residualP));
437 maxResidualV = FastMath.max(maxResidualV, FastMath.abs(residualV));
438 maxResidualA = FastMath.max(maxResidualA, FastMath.abs(residualA));
439 maxResidualR = FastMath.max(maxResidualR, FastMath.abs(residualR));
440
441 }
442
443 Assertions.assertEquals(0.40, maxResidualP, 0.01);
444 Assertions.assertEquals(4.9e-4, maxResidualV, 1.0e-5);
445 Assertions.assertEquals(2.8e-6, maxResidualR, 1.0e-1);
446
447 }
448
449 private <T extends CalculusFieldElement<T>> void doTestDatesConsistency(final Field<T> field) {
450
451 T zero = field.getZero();
452 T a = zero.add(rOrbit.getA());
453 T e = zero.add(rOrbit.getE());
454 T i = zero.add(rOrbit.getI());
455 T pa = zero.add(1.9674147913622104);
456 T raan = zero.add(FastMath.toRadians(261));
457 T lv = zero.add(0);
458
459
460 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
461 TimeComponents.H00,
462 TimeScalesFactory.getUTC());
463
464 FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(a, e, i, pa, raan, lv, PositionAngleType.TRUE,
465 FramesFactory.getEME2000(), date, zero.add(mu));
466 BodyCenterPointing attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
467
468 new FieldSpacecraftState<>(orbit, attitudeLaw.getAttitude(orbit.shiftedBy(zero.add(10.0)),
469 orbit.getDate().shiftedBy(10.0),
470 orbit.getFrame()));
471 }
472
473
474
475
476
477 private <T extends CalculusFieldElement<T>> void doTestDateConsistencyClose(final Field<T> field) {
478
479
480
481 T zero = field.getZero();
482 T one = field.getOne();
483 T a = zero.add(rOrbit.getA());
484 T e = zero.add(rOrbit.getE());
485 T i = zero.add(rOrbit.getI());
486 T pa = zero.add(1.9674147913622104);
487 T raan = zero.add(FastMath.toRadians(261));
488 T lv = zero.add(0);
489
490 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
491 TimeComponents.H00,
492 TimeScalesFactory.getUTC());
493 FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(a, e, i, pa, raan, lv, PositionAngleType.TRUE,
494 FramesFactory.getEME2000(), date, zero.add(mu));
495
496 FieldKeplerianOrbit<T> orbit10Shifts = orbit;
497 for (int ii = 0; ii < 10; ii++) {
498 orbit10Shifts = orbit10Shifts.shiftedBy(zero.add(0.1));
499 }
500 final FieldOrbit<T> orbit1Shift = orbit.shiftedBy(one);
501
502 BodyCenterPointing attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
503
504 FieldAttitude<T> shiftedAttitude = attitudeLaw
505 .getAttitude(orbit1Shift, orbit1Shift.getDate(), orbit.getFrame());
506
507
508 Assertions.assertEquals(shiftedAttitude.getDate(), orbit10Shifts.getDate());
509
510
511 new FieldSpacecraftState<>(orbit10Shifts, shiftedAttitude);
512 }
513
514
515 private <T extends CalculusFieldElement<T>> void doTestFramesConsistency(final Field<T> field) {
516
517 T zero = field.getZero();
518 T a = zero.add(rOrbit.getA());
519 T e = zero.add(rOrbit.getE());
520 T i = zero.add(rOrbit.getI());
521 T pa = zero.add(1.9674147913622104);
522 T raan = zero.add(FastMath.toRadians(261));
523 T lv = zero.add(0);
524
525 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
526 TimeComponents.H00,
527 TimeScalesFactory.getUTC());
528 FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(a, e, i, pa, raan, lv, PositionAngleType.TRUE,
529 FramesFactory.getEME2000(), date, zero.add(mu));
530
531 new FieldSpacecraftState<>(orbit,
532 new FieldAttitude<>(orbit.getDate(),
533 FramesFactory.getGCRF(),
534 Rotation.IDENTITY,
535 Vector3D.ZERO,
536 Vector3D.ZERO,
537 field));
538 }
539
540 private <T extends CalculusFieldElement<T>> void doTestTransform(final Field<T> field) {
541
542 T zero = field.getZero();
543 T a = zero.add(rOrbit.getA());
544 T e = zero.add(rOrbit.getE());
545 T i = zero.add(rOrbit.getI());
546 T pa = zero.add(1.9674147913622104);
547 T raan = zero.add(FastMath.toRadians(261));
548 T lv = zero.add(0);
549 T mass = zero.add(2500);
550
551 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
552 TimeComponents.H00,
553 TimeScalesFactory.getUTC());
554
555 FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(a, e, i, pa, raan, lv, PositionAngleType.TRUE,
556 FramesFactory.getEME2000(), date, zero.add(mu));
557
558 BodyCenterPointing attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
559
560 FieldKeplerianPropagator<T> propagator =
561 new FieldKeplerianPropagator<>(orbit, attitudeLaw, zero.add(mu), mass);
562
563 double maxDP = 0;
564 double maxDV = 0;
565 double maxDA = 0;
566 for (double t = 0; t < orbit.getKeplerianPeriod().getReal(); t += 60) {
567 final FieldSpacecraftState<T> state = propagator.propagate(orbit.getDate().shiftedBy(zero.add(t)));
568 final Transform transform = state.toSpacecraftState().toTransform().getInverse();
569 PVCoordinates pv = transform.transformPVCoordinates(PVCoordinates.ZERO);
570 PVCoordinates dPV = new PVCoordinates(pv, state.getPVCoordinates().toPVCoordinates());
571 Vector3D mZDirection = transform.transformVector(Vector3D.MINUS_K);
572 double alpha = Vector3D.angle(mZDirection, state.getPosition().toVector3D());
573 maxDP = FastMath.max(maxDP, dPV.getPosition().getNorm());
574 maxDV = FastMath.max(maxDV, dPV.getVelocity().getNorm());
575 maxDA = FastMath.max(maxDA, FastMath.toDegrees(alpha));
576 }
577 Assertions.assertEquals(0.0, maxDP, 1.0e-6);
578 Assertions.assertEquals(0.0, maxDV, 1.0e-9);
579 Assertions.assertEquals(0.0, maxDA, 8.1e-10);
580
581 }
582
583 private <T extends CalculusFieldElement<T>> void doTestAdditionalStates(final Field<T> field) {
584
585 T zero = field.getZero();
586 T a = zero.add(rOrbit.getA());
587 T e = zero.add(rOrbit.getE());
588 T i = zero.add(rOrbit.getI());
589 T pa = zero.add(1.9674147913622104);
590 T raan = zero.add(FastMath.toRadians(261));
591 T lv = zero.add(0);
592 T mass = zero.add(2500);
593
594 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
595 TimeComponents.H00,
596 TimeScalesFactory.getUTC());
597
598 FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(a, e, i, pa, raan, lv, PositionAngleType.TRUE,
599 FramesFactory.getEME2000(), date, zero.add(mu));
600
601 BodyCenterPointing attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
602
603 FieldKeplerianPropagator<T> propagator =
604 new FieldKeplerianPropagator<>(orbit, attitudeLaw, zero.add(mu), mass);
605
606
607
608
609 final FieldSpacecraftState<T> state = propagator.propagate(orbit.getDate().shiftedBy(60));
610 T[] add = MathArrays.buildArray(field, 2);
611 add[0] = zero.add(1.);
612 add[1] = zero.add(2.);
613 final FieldSpacecraftState<T> extended =
614 state.
615 addAdditionalData("test-1", add).
616 addAdditionalData("test-2", zero.add(42.0)).
617 addAdditionalData("test-string", "hello");
618 Assertions.assertEquals(0, state.getAdditionalDataValues().size());
619 Assertions.assertFalse(state.hasAdditionalData("test-1"));
620 try {
621 state.getAdditionalData("test-1");
622 Assertions.fail("an exception should have been thrown");
623 } catch (OrekitException oe) {
624 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
625 Assertions.assertEquals(oe.getParts()[0], "test-1");
626 }
627 try {
628 state.ensureCompatibleAdditionalStates(extended);
629 Assertions.fail("an exception should have been thrown");
630 } catch (OrekitException oe) {
631 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
632 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
633 }
634 try {
635 extended.ensureCompatibleAdditionalStates(state);
636 Assertions.fail("an exception should have been thrown");
637 } catch (OrekitException oe) {
638 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
639 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
640 }
641 try {
642 T[] kk = MathArrays.buildArray(field, 7);
643 extended.ensureCompatibleAdditionalStates(extended.addAdditionalData("test-2", kk));
644 Assertions.fail("an exception should have been thrown");
645 } catch (MathIllegalStateException mise) {
646 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
647 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
648 }
649 extended.ensureCompatibleAdditionalStates(extended.addAdditionalData("test-string", "hello"));
650 Assertions.assertEquals(3, extended.getAdditionalDataValues().size());
651 Assertions.assertTrue(extended.hasAdditionalData("test-1"));
652 Assertions.assertTrue(extended.hasAdditionalData("test-2"));
653 Assertions.assertEquals( 1.0, extended.getAdditionalState("test-1")[0].getReal(), 1.0e-15);
654 Assertions.assertEquals( 2.0, extended.getAdditionalState("test-1")[1].getReal(), 1.0e-15);
655 Assertions.assertEquals(42.0, extended.getAdditionalState("test-2")[0].getReal(), 1.0e-15);
656 Assertions.assertEquals("hello", extended.getAdditionalData("test-string"));
657
658
659 T[] dd = MathArrays.buildArray(field, 1);
660 dd[0] = zero.add(-6.0);
661 FieldDataDictionary<T> dictionary = new FieldDataDictionary<>(field);
662 dictionary.put("test-3", dd);
663 FieldSpacecraftState<T> sO = state.withAdditionalData(dictionary);
664 FieldSpacecraftState<T> sFromDouble = new FieldSpacecraftState<>(field, sO.toSpacecraftState());
665 Assertions.assertEquals(-6.0, sFromDouble.getAdditionalState("test-3")[0].getReal(), 1.0e-15);
666
667 }
668
669 private <T extends CalculusFieldElement<T>> void doTestAdditionalStatesDerivatives(final Field<T> field) {
670
671 T zero = field.getZero();
672 T a = zero.add(rOrbit.getA());
673 T e = zero.add(rOrbit.getE());
674 T i = zero.add(rOrbit.getI());
675 T pa = zero.add(1.9674147913622104);
676 T raan = zero.add(FastMath.toRadians(261));
677 T lv = zero.add(0);
678 T mass = zero.add(2500);
679
680 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
681 TimeComponents.H00,
682 TimeScalesFactory.getUTC());
683
684 FieldKeplerianOrbit<T> orbit = new FieldKeplerianOrbit<>(a, e, i, pa, raan, lv, PositionAngleType.TRUE,
685 FramesFactory.getEME2000(), date, zero.add(mu));
686
687 BodyCenterPointing attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
688
689 FieldKeplerianPropagator<T> propagator =
690 new FieldKeplerianPropagator<>(orbit, attitudeLaw, zero.add(mu), mass);
691
692
693
694
695 final FieldSpacecraftState<T> state = propagator.propagate(orbit.getDate().shiftedBy(60));
696 T[] add = MathArrays.buildArray(field, 2);
697 add[0] = zero.add(1.);
698 add[1] = zero.add(2.);
699 final FieldSpacecraftState<T> extended =
700 state.
701 addAdditionalStateDerivative("test-1", add).
702 addAdditionalStateDerivative("test-2", zero.add(42.0));
703 Assertions.assertEquals(0, state.getAdditionalStatesDerivatives().size());
704 Assertions.assertFalse(state.hasAdditionalStateDerivative("test-1"));
705 try {
706 state.getAdditionalStateDerivative("test-1");
707 Assertions.fail("an exception should have been thrown");
708 } catch (OrekitException oe) {
709 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
710 Assertions.assertEquals(oe.getParts()[0], "test-1");
711 }
712 try {
713 state.ensureCompatibleAdditionalStates(extended);
714 Assertions.fail("an exception should have been thrown");
715 } catch (OrekitException oe) {
716 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
717 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
718 }
719 try {
720 extended.ensureCompatibleAdditionalStates(state);
721 Assertions.fail("an exception should have been thrown");
722 } catch (OrekitException oe) {
723 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
724 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
725 }
726 try {
727 T[] kk = MathArrays.buildArray(field, 7);
728 extended.ensureCompatibleAdditionalStates(extended.addAdditionalStateDerivative("test-2", kk));
729 Assertions.fail("an exception should have been thrown");
730 } catch (MathIllegalStateException mise) {
731 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
732 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
733 }
734 Assertions.assertEquals(2, extended.getAdditionalStatesDerivatives().size());
735 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-1"));
736 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-2"));
737 Assertions.assertEquals( 1.0, extended.getAdditionalStateDerivative("test-1")[0].getReal(), 1.0e-15);
738 Assertions.assertEquals( 2.0, extended.getAdditionalStateDerivative("test-1")[1].getReal(), 1.0e-15);
739 Assertions.assertEquals(42.0, extended.getAdditionalStateDerivative("test-2")[0].getReal(), 1.0e-15);
740
741
742 T[] dd = MathArrays.buildArray(field, 1);
743 dd[0] = zero.add(-6.0);
744 FieldArrayDictionary<T> dict = new FieldArrayDictionary<>(field);
745 dict.put("test-3", dd);
746 FieldSpacecraftState<T> s = new FieldSpacecraftState<>(state.getOrbit(), state.getAttitude(), state.getMass(), null, dict);
747 Assertions.assertFalse(s.hasAdditionalData("test-3"));
748 Assertions.assertEquals(-6.0, s.getAdditionalStateDerivative("test-3")[0].getReal(), 1.0e-15);
749
750
751 FieldSpacecraftState<T> rebuilt = new FieldSpacecraftState<>(field, s.toSpacecraftState());
752 rebuilt.ensureCompatibleAdditionalStates(s);
753
754 }
755
756 private <T extends CalculusFieldElement<T>> void doTestFieldVsRealAbsPV(final Field<T> field) {
757 T zero = field.getZero();
758
759 T x_f = zero.add(0.8);
760 T y_f = zero.add(0.2);
761 T z_f = zero;
762 T vx_f = zero;
763 T vy_f = zero;
764 T vz_f = zero.add(0.1);
765
766 FieldAbsoluteDate<T> t_f = new FieldAbsoluteDate<>(field);
767
768 FieldPVCoordinates<T> pva_f = new FieldPVCoordinates<>(new FieldVector3D<>(x_f,y_f,z_f), new FieldVector3D<>(vx_f,vy_f,vz_f));
769
770 FieldAbsolutePVCoordinates<T> absPV_f = new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(), t_f, pva_f);
771
772 FieldSpacecraftState<T> ScS_f = new FieldSpacecraftState<>(absPV_f);
773 FieldSpacecraftState<T> withM = new FieldSpacecraftState<>(absPV_f).withMass(zero.newInstance(1234.5));
774 Assertions.assertEquals(1234.5, withM.getMass().getReal(), 1.0e-10);
775 SpacecraftState ScS_r = ScS_f.toSpacecraftState();
776
777 for (double dt = 0; dt < 500; dt+=100){
778 SpacecraftState control_r = ScS_r.shiftedBy(dt);
779 FieldSpacecraftState<T> control_f = ScS_f.shiftedBy(zero.add(dt));
780
781 Assertions.assertEquals(control_r.getPosition().getX(), control_f.getPVCoordinates().toPVCoordinates().getPosition().getX(), 1e-10);
782 Assertions.assertEquals(control_r.getPosition().getY(), control_f.getPVCoordinates().toPVCoordinates().getPosition().getY(), 1e-10);
783 Assertions.assertEquals(control_r.getPosition().getZ(), control_f.getPVCoordinates().toPVCoordinates().getPosition().getZ(), 1e-10);
784 Assertions.assertEquals(control_r.getPVCoordinates().getVelocity().getX(), control_f.getPVCoordinates().toPVCoordinates().getVelocity().getX(), 1e-10);
785 Assertions.assertEquals(control_r.getPVCoordinates().getVelocity().getY(), control_f.getPVCoordinates().toPVCoordinates().getVelocity().getY(), 1e-10);
786 Assertions.assertEquals(control_r.getPVCoordinates().getVelocity().getZ(), control_f.getPVCoordinates().toPVCoordinates().getVelocity().getZ(), 1e-10);
787 Assertions.assertEquals(control_r.getPVCoordinates().getAcceleration().getX(), control_f.getPVCoordinates().toPVCoordinates().getAcceleration().getX(), 1e-10);
788 Assertions.assertEquals(control_r.getPVCoordinates().getAcceleration().getY(), control_f.getPVCoordinates().toPVCoordinates().getAcceleration().getY(), 1e-10);
789 Assertions.assertEquals(control_r.getPVCoordinates().getAcceleration().getZ(), control_f.getPVCoordinates().toPVCoordinates().getAcceleration().getZ(), 1e-10);
790 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ0(), control_f.getAttitude().getOrientation().getRotation().getQ0().getReal(), 1e-10);
791 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ1(), control_f.getAttitude().getOrientation().getRotation().getQ1().getReal(), 1e-10);
792 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ2(), control_f.getAttitude().getOrientation().getRotation().getQ2().getReal(), 1e-10);
793 Assertions.assertEquals(control_r.getAttitude().getOrientation().getRotation().getQ3(), control_f.getAttitude().getOrientation().getRotation().getQ3().getReal(), 1e-10);
794
795 Assertions.assertEquals(control_r.getAttitude().getSpin().getAlpha(), control_f.getAttitude().getSpin().getAlpha().getReal(), 1e-10);
796 Assertions.assertEquals(control_r.getAttitude().getSpin().getDelta(), control_f.getAttitude().getSpin().getDelta().getReal(), 1e-10);
797 Assertions.assertEquals(control_r.getAttitude().getSpin().getNorm(), control_f.getAttitude().getSpin().getNorm().getReal(), 1e-10);
798
799 Assertions.assertEquals(control_r.getAttitude().getReferenceFrame().isPseudoInertial(), control_f.getAttitude().getReferenceFrame().isPseudoInertial());
800 Assertions.assertEquals(control_r.getAttitude().getDate().durationFrom(AbsoluteDate.J2000_EPOCH), control_f.getAttitude().getDate().durationFrom(AbsoluteDate.J2000_EPOCH).getReal(), 1e-10);
801
802
803 }
804 }
805
806
807
808
809
810
811 private <T extends CalculusFieldElement<T>> void doTestDateConsistencyCloseAbsPV(final Field<T> field) {
812
813
814
815 T zero = field.getZero();
816 T one = field.getOne();
817 T x_f = zero.add(0.8);
818 T y_f = zero.add(0.2);
819 T z_f = zero;
820 T vx_f = zero;
821 T vy_f = zero;
822 T vz_f = zero.add(0.1);
823 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
824 TimeComponents.H00,
825 TimeScalesFactory.getUTC());
826 FieldPVCoordinates<T> pva_f = new FieldPVCoordinates<>(new FieldVector3D<>(x_f,y_f,z_f), new FieldVector3D<>(vx_f,vy_f,vz_f));
827
828 FieldAbsolutePVCoordinates<T> absPV_f = new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(), date, pva_f);
829
830 FieldAbsolutePVCoordinates<T> AbsolutePVCoordinates10Shifts = absPV_f;
831 for (int ii = 0; ii < 10; ii++) {
832 AbsolutePVCoordinates10Shifts = AbsolutePVCoordinates10Shifts.shiftedBy(zero.add(0.1));
833 }
834 final FieldAbsolutePVCoordinates<T> AbsolutePVCoordinates1Shift = absPV_f.shiftedBy(one);
835
836 BodyCenterPointing attitudeLaw = new BodyCenterPointing(absPV_f.getFrame(), earth);
837
838 FieldAttitude<T> shiftedAttitude = attitudeLaw.getAttitude(AbsolutePVCoordinates1Shift,
839 AbsolutePVCoordinates1Shift.getDate(),
840 absPV_f.getFrame());
841
842 Assertions.assertEquals(shiftedAttitude.getDate(), AbsolutePVCoordinates10Shifts.getDate());
843
844
845 FieldSpacecraftState<T> s1 = new FieldSpacecraftState<>(AbsolutePVCoordinates10Shifts, shiftedAttitude);
846 FieldSpacecraftState<T> s2 = s1.shiftedBy(0.001);
847
848 try {
849
850 new FieldSpacecraftState<>(AbsolutePVCoordinates10Shifts, s2.getAttitude());
851 Assertions.fail("an exception should have been thrown");
852 } catch (OrekitIllegalArgumentException oiae) {
853 Assertions.assertEquals(OrekitMessages.ORBIT_AND_ATTITUDE_DATES_MISMATCH,
854 oiae.getSpecifier());
855 }
856 }
857
858 private <T extends CalculusFieldElement<T>> void doTestGetAdditionalStateBadType(final Field<T> field) {
859 final SpacecraftState state = new SpacecraftState(rOrbit);
860 final FieldSpacecraftState<T> fieldState = new FieldSpacecraftState<>(field, state).addAdditionalData("string", "hello there");
861 OrekitException exception = Assertions.assertThrows(OrekitException.class, () -> fieldState.getAdditionalState("string"));
862 Assertions.assertEquals(OrekitMessages.ADDITIONAL_STATE_BAD_TYPE, exception.getSpecifier());
863 Assertions.assertEquals("string", exception.getParts()[0]);
864 }
865
866 private <T extends CalculusFieldElement<T>> void doTestFramesConsistencyAbsPV(final Field<T> field) {
867
868 T zero = field.getZero();
869
870 T x_f = zero.add(0.8);
871 T y_f = zero.add(0.2);
872 T z_f = zero;
873 T vx_f = zero;
874 T vy_f = zero;
875 T vz_f = zero.add(0.1);
876
877
878 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
879 TimeComponents.H00,
880 TimeScalesFactory.getUTC());
881
882 FieldPVCoordinates<T> pva_f = new FieldPVCoordinates<>(new FieldVector3D<>(x_f,y_f,z_f), new FieldVector3D<>(vx_f,vy_f,vz_f));
883
884 FieldAbsolutePVCoordinates<T> absPV_f = new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(), date, pva_f);
885
886 new FieldSpacecraftState<>(absPV_f,
887 new FieldAttitude<>(absPV_f.getDate(),
888 FramesFactory.getGCRF(),
889 FieldRotation.getIdentity(field),
890 FieldVector3D.getZero(field),
891 FieldVector3D.getZero(field)));
892 }
893
894 private <T extends CalculusFieldElement<T>> void doTestAdditionalStatesAbsPV(final Field<T> field) {
895
896 T zero = field.getZero();
897 T x_f = zero.add(0.8);
898 T y_f = zero.add(0.2);
899 T z_f = zero;
900 T vx_f = zero;
901 T vy_f = zero;
902 T vz_f = zero.add(0.1);
903
904 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
905 TimeComponents.H00,
906 TimeScalesFactory.getUTC());
907
908 FieldPVCoordinates<T> pva_f = new FieldPVCoordinates<>(new FieldVector3D<>(x_f,y_f,z_f), new FieldVector3D<>(vx_f,vy_f,vz_f));
909
910 FieldAbsolutePVCoordinates<T> absPV_f = new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(), date, pva_f);
911
912 FieldNumericalPropagator<T> prop = new FieldNumericalPropagator<>(field,
913 new DormandPrince853FieldIntegrator<>(field, 0.1, 500, 0.001, 0.001));
914 prop.setOrbitType(null);
915
916 final FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(absPV_f);
917
918 prop.resetInitialState(initialState);
919
920 final FieldSpacecraftState<T> state = prop.propagate(absPV_f.getDate().shiftedBy(60));
921 T[] add = MathArrays.buildArray(field, 2);
922 add[0] = zero.add(1.);
923 add[1] = zero.add(2.);
924 final FieldSpacecraftState<T> extended =
925 state.
926 addAdditionalData("test-1", add).
927 addAdditionalData("test-2", zero.add(42.0));
928 Assertions.assertEquals(0, state.getAdditionalDataValues().size());
929 Assertions.assertFalse(state.hasAdditionalData("test-1"));
930 try {
931 state.getAdditionalData("test-1");
932 Assertions.fail("an exception should have been thrown");
933 } catch (OrekitException oe) {
934 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
935 Assertions.assertEquals(oe.getParts()[0], "test-1");
936 }
937 try {
938 state.ensureCompatibleAdditionalStates(extended);
939 Assertions.fail("an exception should have been thrown");
940 } catch (OrekitException oe) {
941 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
942 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
943 }
944 try {
945 extended.ensureCompatibleAdditionalStates(state);
946 Assertions.fail("an exception should have been thrown");
947 } catch (OrekitException oe) {
948 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
949 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
950 }
951 try {
952 T[] kk = MathArrays.buildArray(field, 7);
953 extended.ensureCompatibleAdditionalStates(extended.addAdditionalData("test-2", kk));
954 Assertions.fail("an exception should have been thrown");
955 } catch (MathIllegalStateException mise) {
956 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
957 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
958 }
959 Assertions.assertEquals(2, extended.getAdditionalDataValues().size());
960 Assertions.assertTrue(extended.hasAdditionalData("test-1"));
961 Assertions.assertTrue(extended.hasAdditionalData("test-2"));
962 Assertions.assertEquals( 1.0, extended.getAdditionalState("test-1")[0].getReal(), 1.0e-15);
963 Assertions.assertEquals( 2.0, extended.getAdditionalState("test-1")[1].getReal(), 1.0e-15);
964 Assertions.assertEquals(42.0, extended.getAdditionalState("test-2")[0].getReal(), 1.0e-15);
965
966
967 T[] dd = MathArrays.buildArray(field, 1);
968 dd[0] = zero.add(-6.0);
969 FieldDataDictionary<T> map = new FieldDataDictionary<>(field);
970 map.put("test-3", dd);
971 FieldSpacecraftState<T> sO = new FieldSpacecraftState<>(state.getAbsPVA()).withAdditionalData(map);
972 Assertions.assertEquals(-6.0, sO.getAdditionalState("test-3")[0].getReal(), 1.0e-15);
973 FieldSpacecraftState<T> sFromDouble = new FieldSpacecraftState<>(field, sO.toSpacecraftState());
974 Assertions.assertEquals(-6.0, sFromDouble.getAdditionalState("test-3")[0].getReal(), 1.0e-15);
975
976 }
977
978 private <T extends CalculusFieldElement<T>> void doTestAdditionalStatesDerivativesAbsPV(final Field<T> field) {
979
980 T zero = field.getZero();
981 T x_f = zero.add(0.8);
982 T y_f = zero.add(0.2);
983 T z_f = zero;
984 T vx_f = zero;
985 T vy_f = zero;
986 T vz_f = zero.add(0.1);
987
988 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2004, 01, 01),
989 TimeComponents.H00,
990 TimeScalesFactory.getUTC());
991
992 FieldPVCoordinates<T> pva_f = new FieldPVCoordinates<>(new FieldVector3D<>(x_f,y_f,z_f), new FieldVector3D<>(vx_f,vy_f,vz_f));
993
994 FieldAbsolutePVCoordinates<T> absPV_f = new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(), date, pva_f);
995
996 FieldNumericalPropagator<T> prop = new FieldNumericalPropagator<>(field,
997 new DormandPrince853FieldIntegrator<>(field, 0.1, 500, 0.001, 0.001));
998 prop.setOrbitType(null);
999
1000 final FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(absPV_f);
1001
1002 prop.resetInitialState(initialState);
1003
1004 final FieldSpacecraftState<T> state = prop.propagate(absPV_f.getDate().shiftedBy(60));
1005 T[] add = MathArrays.buildArray(field, 2);
1006 add[0] = zero.add(1.);
1007 add[1] = zero.add(2.);
1008 final FieldSpacecraftState<T> extended =
1009 state.
1010 addAdditionalStateDerivative("test-1", add).
1011 addAdditionalStateDerivative("test-2", zero.add(42.0));
1012 Assertions.assertEquals(0, state.getAdditionalStatesDerivatives().size());
1013 Assertions.assertFalse(state.hasAdditionalStateDerivative("test-1"));
1014 try {
1015 state.getAdditionalStateDerivative("test-1");
1016 Assertions.fail("an exception should have been thrown");
1017 } catch (OrekitException oe) {
1018 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
1019 Assertions.assertEquals(oe.getParts()[0], "test-1");
1020 }
1021 try {
1022 state.ensureCompatibleAdditionalStates(extended);
1023 Assertions.fail("an exception should have been thrown");
1024 } catch (OrekitException oe) {
1025 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
1026 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
1027 }
1028 try {
1029 extended.ensureCompatibleAdditionalStates(state);
1030 Assertions.fail("an exception should have been thrown");
1031 } catch (OrekitException oe) {
1032 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
1033 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
1034 }
1035 try {
1036 T[] kk = MathArrays.buildArray(field, 7);
1037 extended.ensureCompatibleAdditionalStates(extended.addAdditionalStateDerivative("test-2", kk));
1038 Assertions.fail("an exception should have been thrown");
1039 } catch (MathIllegalStateException mise) {
1040 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
1041 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
1042 }
1043 Assertions.assertEquals(2, extended.getAdditionalStatesDerivatives().size());
1044 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-1"));
1045 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-2"));
1046 Assertions.assertEquals( 1.0, extended.getAdditionalStateDerivative("test-1")[0].getReal(), 1.0e-15);
1047 Assertions.assertEquals( 2.0, extended.getAdditionalStateDerivative("test-1")[1].getReal(), 1.0e-15);
1048 Assertions.assertEquals(42.0, extended.getAdditionalStateDerivative("test-2")[0].getReal(), 1.0e-15);
1049
1050
1051 T[] dd = MathArrays.buildArray(field, 1);
1052 dd[0] = zero.add(-6.0);
1053 FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<T>(field);
1054 dictionary.put("test-3", dd);
1055 FieldSpacecraftState<T> s = new FieldSpacecraftState<>(state.getAbsPVA(), state.getAttitude(), state.getMass(), null, dictionary);
1056 Assertions.assertFalse(s.hasAdditionalData("test-3"));
1057 Assertions.assertEquals(-6.0, s.getAdditionalStateDerivative("test-3")[0].getReal(), 1.0e-15);
1058
1059 }
1060
1061 private <T extends CalculusFieldElement<T>> void doTestAdditionalTestResetOnEventAnalytical(final Field<T> field) {
1062
1063 T zero = field.getZero();
1064
1065
1066 FieldAbsoluteDate<T> date0 = new FieldAbsoluteDate<>(field, 2000, 1, 1, TimeScalesFactory.getUTC());
1067 FieldOrbit<T> orbit = new FieldKeplerianOrbit<>(zero.add(7.1E6), zero, zero, zero, zero, zero,
1068 PositionAngleType.TRUE, FramesFactory.getGCRF(), date0,
1069 zero.add(Constants.WGS84_EARTH_MU));
1070
1071
1072 FieldKeplerianPropagator<T> propagator = new FieldKeplerianPropagator<>(orbit);
1073
1074
1075 final String name = "A";
1076 FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(orbit).
1077 addAdditionalData(name, zero.add(-1));
1078
1079 propagator.resetInitialState(initialState);
1080
1081
1082 FieldAbsoluteDate<T> changeDate = date0.shiftedBy(3);
1083 FieldDateDetector<T> dateDetector = new FieldDateDetector<>(field, changeDate).
1084 withHandler(new FieldEventHandler<T>() {
1085
1086 @Override
1087 public Action eventOccurred(FieldSpacecraftState<T> s, FieldEventDetector<T> detector, boolean increasing) {
1088 return Action.RESET_STATE;
1089 }
1090
1091 @Override
1092 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector, FieldSpacecraftState<T> oldState) {
1093 return oldState.addAdditionalData(name, zero.add(+1));
1094 }
1095
1096 });
1097
1098 propagator.addEventDetector(dateDetector);
1099 propagator.setStepHandler(zero.add(0.125), s -> {
1100 if (s.getDate().durationFrom(changeDate).getReal() < -0.001) {
1101 Assertions.assertEquals(-1, s.getAdditionalState(name)[0].getReal(), 1.0e-15);
1102 } else if (s.getDate().durationFrom(changeDate).getReal() > +0.001) {
1103 Assertions.assertEquals(+1, s.getAdditionalState(name)[0].getReal(), 1.0e-15);
1104 }
1105 });
1106 FieldSpacecraftState<T> finalState = propagator.propagate(date0, date0.shiftedBy(5));
1107 Assertions.assertEquals(+1, finalState.getAdditionalState(name)[0].getReal(), 1.0e-15);
1108
1109 }
1110
1111 private <T extends CalculusFieldElement<T>> void doTestAdditionalTestResetOnEventNumerical(final Field<T> field) {
1112
1113 T zero = field.getZero();
1114
1115
1116 FieldAbsoluteDate<T> date0 = new FieldAbsoluteDate<>(field, 2000, 1, 1, TimeScalesFactory.getUTC());
1117 FieldOrbit<T> orbit = new FieldKeplerianOrbit<>(zero.add(7.1E6), zero, zero, zero, zero, zero,
1118 PositionAngleType.TRUE, FramesFactory.getGCRF(), date0,
1119 zero.add(Constants.WGS84_EARTH_MU));
1120
1121
1122 FieldODEIntegrator<T> odeIntegrator = new DormandPrince853FieldIntegrator<>(field, 1E-3, 1E3, 1E-6, 1E-6);
1123 FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, odeIntegrator);
1124
1125
1126 final String name = "A";
1127 FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(orbit).
1128 addAdditionalData(name, zero.add(-1));
1129
1130 propagator.resetInitialState(initialState);
1131
1132
1133 FieldAbsoluteDate<T> changeDate = date0.shiftedBy(3);
1134 FieldDateDetector<T> dateDetector = new FieldDateDetector<>(field, changeDate).
1135 withHandler(new FieldEventHandler<T>() {
1136
1137 @Override
1138 public Action eventOccurred(FieldSpacecraftState<T> s, FieldEventDetector<T> detector, boolean increasing) {
1139 return Action.RESET_STATE;
1140 }
1141
1142 @Override
1143 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector, FieldSpacecraftState<T> oldState) {
1144 return oldState.addAdditionalData(name, zero.add(+1));
1145 }
1146
1147 });
1148
1149 propagator.addEventDetector(dateDetector);
1150 propagator.setStepHandler(zero.add(0.125), s -> {
1151 if (s.getDate().durationFrom(changeDate).getReal() < -0.001) {
1152 Assertions.assertEquals(-1, s.getAdditionalState(name)[0].getReal(), 1.0e-15);
1153 } else if (s.getDate().durationFrom(changeDate).getReal() > +0.001) {
1154 Assertions.assertEquals(+1, s.getAdditionalState(name)[0].getReal(), 1.0e-15);
1155 }
1156 });
1157 FieldSpacecraftState<T> finalState = propagator.propagate(date0, date0.shiftedBy(5));
1158 Assertions.assertEquals(+1, finalState.getAdditionalState(name)[0].getReal(), 1.0e-15);
1159
1160 }
1161
1162 private <T extends CalculusFieldElement<T>> void doTestShiftAdditionalDerivativesDouble(final Field<T> field) {
1163
1164 T zero = field.getZero();
1165
1166
1167 FieldAbsoluteDate<T> date0 = new FieldAbsoluteDate<>(field, 2000, 1, 1, TimeScalesFactory.getUTC());
1168 FieldOrbit<T> orbit = new FieldKeplerianOrbit<>(zero.add(7.1E6), zero, zero, zero, zero, zero,
1169 PositionAngleType.TRUE, FramesFactory.getGCRF(), date0,
1170 zero.add(Constants.WGS84_EARTH_MU));
1171
1172
1173 FieldKeplerianPropagator<T> propagator = new FieldKeplerianPropagator<>(orbit);
1174
1175 final String valueAndDerivative = "value-and-derivative";
1176 final String valueOnly = "value-only";
1177 final String derivativeOnly = "derivative-only";
1178 final FieldSpacecraftState<T> s0 = propagator.getInitialState().
1179 addAdditionalData(valueAndDerivative, convert(field, new double[] { 1.0, 2.0 })).
1180 addAdditionalStateDerivative(valueAndDerivative, convert(field, new double[] { 3.0, 2.0 })).
1181 addAdditionalData(valueOnly, convert(field, new double[] { 5.0, 4.0 })).
1182 addAdditionalStateDerivative(derivativeOnly, convert(field, new double[] { 1.0, -1.0 }));
1183 Assertions.assertEquals( 1.0, s0.getAdditionalState(valueAndDerivative)[0].getReal(), 1.0e-15);
1184 Assertions.assertEquals( 2.0, s0.getAdditionalState(valueAndDerivative)[1].getReal(), 1.0e-15);
1185 Assertions.assertEquals( 3.0, s0.getAdditionalStateDerivative(valueAndDerivative)[0].getReal(), 1.0e-15);
1186 Assertions.assertEquals( 2.0, s0.getAdditionalStateDerivative(valueAndDerivative)[1].getReal(), 1.0e-15);
1187 Assertions.assertEquals( 5.0, s0.getAdditionalState(valueOnly)[0].getReal(), 1.0e-15);
1188 Assertions.assertEquals( 4.0, s0.getAdditionalState(valueOnly)[1].getReal(), 1.0e-15);
1189 Assertions.assertEquals( 1.0, s0.getAdditionalStateDerivative(derivativeOnly)[0].getReal(), 1.0e-15);
1190 Assertions.assertEquals(-1.0, s0.getAdditionalStateDerivative(derivativeOnly)[1].getReal(), 1.0e-15);
1191 final FieldSpacecraftState<T> s1 = s0.shiftedBy(-2.0);
1192 Assertions.assertEquals(-5.0, s1.getAdditionalState(valueAndDerivative)[0].getReal(), 1.0e-15);
1193 Assertions.assertEquals(-2.0, s1.getAdditionalState(valueAndDerivative)[1].getReal(), 1.0e-15);
1194 Assertions.assertEquals( 3.0, s1.getAdditionalStateDerivative(valueAndDerivative)[0].getReal(), 1.0e-15);
1195 Assertions.assertEquals( 2.0, s1.getAdditionalStateDerivative(valueAndDerivative)[1].getReal(), 1.0e-15);
1196 Assertions.assertEquals( 5.0, s1.getAdditionalState(valueOnly)[0].getReal(), 1.0e-15);
1197 Assertions.assertEquals( 4.0, s1.getAdditionalState(valueOnly)[1].getReal(), 1.0e-15);
1198 Assertions.assertEquals( 1.0, s1.getAdditionalStateDerivative(derivativeOnly)[0].getReal(), 1.0e-15);
1199 Assertions.assertEquals(-1.0, s1.getAdditionalStateDerivative(derivativeOnly)[1].getReal(), 1.0e-15);
1200
1201 }
1202
1203 private <T extends CalculusFieldElement<T>> void doTestShiftAdditionalDerivativesField(final Field<T> field) {
1204
1205 T zero = field.getZero();
1206
1207
1208 FieldAbsoluteDate<T> date0 = new FieldAbsoluteDate<>(field, 2000, 1, 1, TimeScalesFactory.getUTC());
1209 FieldOrbit<T> orbit = new FieldKeplerianOrbit<>(zero.add(7.1E6), zero, zero, zero, zero, zero,
1210 PositionAngleType.TRUE, FramesFactory.getGCRF(), date0,
1211 zero.add(Constants.WGS84_EARTH_MU));
1212
1213
1214 FieldKeplerianPropagator<T> propagator = new FieldKeplerianPropagator<>(orbit);
1215
1216 final String valueAndDerivative = "value-and-derivative";
1217 final String valueOnly = "value-only";
1218 final String derivativeOnly = "derivative-only";
1219 final FieldSpacecraftState<T> s0 = propagator.getInitialState().
1220 addAdditionalData(valueAndDerivative, convert(field, new double[] { 1.0, 2.0 })).
1221 addAdditionalStateDerivative(valueAndDerivative, convert(field, new double[] { 3.0, 2.0 })).
1222 addAdditionalData(valueOnly, convert(field, new double[] { 5.0, 4.0 })).
1223 addAdditionalStateDerivative(derivativeOnly, convert(field, new double[] { 1.0, -1.0 }));
1224 Assertions.assertEquals( 1.0, s0.getAdditionalState(valueAndDerivative)[0].getReal(), 1.0e-15);
1225 Assertions.assertEquals( 2.0, s0.getAdditionalState(valueAndDerivative)[1].getReal(), 1.0e-15);
1226 Assertions.assertEquals( 3.0, s0.getAdditionalStateDerivative(valueAndDerivative)[0].getReal(), 1.0e-15);
1227 Assertions.assertEquals( 2.0, s0.getAdditionalStateDerivative(valueAndDerivative)[1].getReal(), 1.0e-15);
1228 Assertions.assertEquals( 5.0, s0.getAdditionalState(valueOnly)[0].getReal(), 1.0e-15);
1229 Assertions.assertEquals( 4.0, s0.getAdditionalState(valueOnly)[1].getReal(), 1.0e-15);
1230 Assertions.assertEquals( 1.0, s0.getAdditionalStateDerivative(derivativeOnly)[0].getReal(), 1.0e-15);
1231 Assertions.assertEquals(-1.0, s0.getAdditionalStateDerivative(derivativeOnly)[1].getReal(), 1.0e-15);
1232 final FieldSpacecraftState<T> s1 = s0.shiftedBy(field.getZero().newInstance(-2.0));
1233 Assertions.assertEquals(-5.0, s1.getAdditionalState(valueAndDerivative)[0].getReal(), 1.0e-15);
1234 Assertions.assertEquals(-2.0, s1.getAdditionalState(valueAndDerivative)[1].getReal(), 1.0e-15);
1235 Assertions.assertEquals( 3.0, s1.getAdditionalStateDerivative(valueAndDerivative)[0].getReal(), 1.0e-15);
1236 Assertions.assertEquals( 2.0, s1.getAdditionalStateDerivative(valueAndDerivative)[1].getReal(), 1.0e-15);
1237 Assertions.assertEquals( 5.0, s1.getAdditionalState(valueOnly)[0].getReal(), 1.0e-15);
1238 Assertions.assertEquals( 4.0, s1.getAdditionalState(valueOnly)[1].getReal(), 1.0e-15);
1239 Assertions.assertEquals( 1.0, s1.getAdditionalStateDerivative(derivativeOnly)[0].getReal(), 1.0e-15);
1240 Assertions.assertEquals(-1.0, s1.getAdditionalStateDerivative(derivativeOnly)[1].getReal(), 1.0e-15);
1241
1242 }
1243
1244 @BeforeEach
1245 public void setUp(){
1246 try {
1247
1248 Utils.setDataRoot("regular-data");
1249 mu = 3.9860047e14;
1250
1251 double a = 7187990.1979844316;
1252 double e = 0.5e-4;
1253 double i = 1.7105407051081795;
1254 double omega = 1.9674147913622104;
1255 double OMEGA = FastMath.toRadians(261);
1256 double lv = 0;
1257
1258 rDate = new AbsoluteDate(new DateComponents(2004, 1, 1),
1259 TimeComponents.H00,
1260 TimeScalesFactory.getUTC());
1261 rOrbit = new KeplerianOrbit(a, e, i, omega, OMEGA, lv, PositionAngleType.TRUE,
1262 FramesFactory.getEME2000(), rDate, mu);
1263 earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
1264 Constants.WGS84_EARTH_FLATTENING,
1265 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
1266 } catch (OrekitException oe) {
1267
1268 Assertions.fail(oe.getLocalizedMessage());
1269 }
1270 }
1271
1272 private <T extends CalculusFieldElement<T>> T[] convert(final Field<T> field, final double[] a) {
1273 final T[] converted = MathArrays.buildArray(field, a.length);
1274 for (int i = 0; i < a.length; ++i) {
1275 converted[i] = field.getZero().newInstance(a[i]);
1276 }
1277 return converted;
1278 }
1279
1280 private AbsoluteDate rDate;
1281 private double mu;
1282 private Orbit rOrbit;
1283 private OneAxisEllipsoid earth;
1284
1285 }
1286