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.analysis.polynomials.PolynomialFunction;
20 import org.hipparchus.exception.LocalizedCoreFormats;
21 import org.hipparchus.exception.MathIllegalStateException;
22 import org.hipparchus.geometry.euclidean.threed.Rotation;
23 import org.hipparchus.geometry.euclidean.threed.Vector3D;
24 import org.hipparchus.ode.ODEIntegrator;
25 import org.hipparchus.ode.events.Action;
26 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
27 import org.hipparchus.util.FastMath;
28 import org.junit.jupiter.api.AfterEach;
29 import org.junit.jupiter.api.Assertions;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Test;
32 import org.mockito.Mockito;
33 import org.orekit.Utils;
34 import org.orekit.attitudes.Attitude;
35 import org.orekit.attitudes.AttitudeProvider;
36 import org.orekit.attitudes.BodyCenterPointing;
37 import org.orekit.bodies.OneAxisEllipsoid;
38 import org.orekit.errors.OrekitException;
39 import org.orekit.errors.OrekitMessages;
40 import org.orekit.frames.FramesFactory;
41 import org.orekit.frames.StaticTransform;
42 import org.orekit.frames.Transform;
43 import org.orekit.orbits.KeplerianOrbit;
44 import org.orekit.orbits.Orbit;
45 import org.orekit.orbits.PositionAngleType;
46 import org.orekit.propagation.analytical.EcksteinHechlerPropagator;
47 import org.orekit.propagation.analytical.KeplerianPropagator;
48 import org.orekit.propagation.events.DateDetector;
49 import org.orekit.propagation.events.EventDetector;
50 import org.orekit.propagation.events.handlers.EventHandler;
51 import org.orekit.propagation.numerical.NumericalPropagator;
52 import org.orekit.time.AbsoluteDate;
53 import org.orekit.time.DateComponents;
54 import org.orekit.time.TimeComponents;
55 import org.orekit.time.TimeScalesFactory;
56 import org.orekit.utils.*;
57
58 import java.text.ParseException;
59
60
61 class SpacecraftStateTest {
62
63 @Test
64 void testWithAttitudeAbsolutePV() {
65
66 final AbsolutePVCoordinates absolutePVCoordinates = new AbsolutePVCoordinates(FramesFactory.getEME2000(),
67 AbsoluteDate.ARBITRARY_EPOCH, new PVCoordinates());
68 final SpacecraftState state = new SpacecraftState(absolutePVCoordinates);
69 final Attitude attitude = Mockito.mock(Attitude.class);
70 Mockito.when(attitude.getDate()).thenReturn(state.getDate());
71 Mockito.when(attitude.getReferenceFrame()).thenReturn(state.getFrame());
72
73 final SpacecraftState stateWithAttitude = state.withAttitude(attitude);
74
75 Assertions.assertEquals(attitude, stateWithAttitude.getAttitude());
76 Assertions.assertEquals(state.getMass(), stateWithAttitude.getMass());
77 Assertions.assertEquals(state.getAbsPVA(), stateWithAttitude.getAbsPVA());
78 }
79
80 @Test
81 void testWithMassAbsolutePV() {
82
83 final AbsolutePVCoordinates absolutePVCoordinates = new AbsolutePVCoordinates(FramesFactory.getEME2000(),
84 AbsoluteDate.ARBITRARY_EPOCH, new PVCoordinates());
85 final SpacecraftState state = new SpacecraftState(absolutePVCoordinates);
86 final double expectedMass = 123;
87
88 final SpacecraftState stateWithMass = state.withMass(expectedMass);
89
90 Assertions.assertEquals(expectedMass, stateWithMass.getMass());
91 Assertions.assertEquals(state.getAttitude(), stateWithMass.getAttitude());
92 Assertions.assertEquals(state.getAbsPVA(), stateWithMass.getAbsPVA());
93 }
94
95 @Test
96 void testWithAdditionalDataAndAbsolutePV() {
97
98 final AbsolutePVCoordinates absolutePVCoordinates = new AbsolutePVCoordinates(FramesFactory.getEME2000(),
99 AbsoluteDate.ARBITRARY_EPOCH, new PVCoordinates());
100 final SpacecraftState state = new SpacecraftState(absolutePVCoordinates);
101 final DataDictionary dictionary = Mockito.mock(DataDictionary.class);
102
103 final SpacecraftState stateWithData = state.withAdditionalData(dictionary);
104
105 Assertions.assertEquals(dictionary.getData(), stateWithData.getAdditionalDataValues().getData());
106 Assertions.assertEquals(state.getMass(), stateWithData.getMass());
107 Assertions.assertEquals(state.getAttitude(), stateWithData.getAttitude());
108 Assertions.assertEquals(state.getAbsPVA(), stateWithData.getAbsPVA());
109 }
110
111 @Test
112 void testWithAdditionalStatesDerivativesAndAbsolutePV() {
113
114 final AbsolutePVCoordinates absolutePVCoordinates = new AbsolutePVCoordinates(FramesFactory.getEME2000(),
115 AbsoluteDate.ARBITRARY_EPOCH, new PVCoordinates());
116 final SpacecraftState state = new SpacecraftState(absolutePVCoordinates);
117 final DoubleArrayDictionary dictionary = Mockito.mock(DoubleArrayDictionary.class);
118
119 final SpacecraftState stateWithDerivatives = state.withAdditionalStatesDerivatives(dictionary);
120
121 Assertions.assertEquals(dictionary.getData(), stateWithDerivatives.getAdditionalStatesDerivatives().getData());
122 Assertions.assertEquals(state.getAbsPVA(), stateWithDerivatives.getAbsPVA());
123 Assertions.assertEquals(state.getAttitude(), stateWithDerivatives.getAttitude());
124 Assertions.assertEquals(state.getMass(), stateWithDerivatives.getMass());
125 }
126
127 @Test
128 void testWithAttitudeAndOrbit() {
129
130 final SpacecraftState state = new SpacecraftState(orbit);
131 final Attitude attitude = Mockito.mock(Attitude.class);
132 Mockito.when(attitude.getDate()).thenReturn(state.getDate());
133 Mockito.when(attitude.getReferenceFrame()).thenReturn(state.getFrame());
134
135 final SpacecraftState stateWithAttitude = state.withAttitude(attitude);
136
137 Assertions.assertEquals(attitude, stateWithAttitude.getAttitude());
138 Assertions.assertEquals(state.getMass(), stateWithAttitude.getMass());
139 Assertions.assertEquals(state.getOrbit(), stateWithAttitude.getOrbit());
140 }
141
142 @Test
143 void testWithMassAndOrbit() {
144
145 final SpacecraftState state = new SpacecraftState(orbit);
146 final double expectedMass = 123;
147
148 final SpacecraftState stateWithMass = state.withMass(expectedMass);
149
150 Assertions.assertEquals(expectedMass, stateWithMass.getMass());
151 Assertions.assertEquals(state.getAttitude(), stateWithMass.getAttitude());
152 Assertions.assertEquals(state.getOrbit(), stateWithMass.getOrbit());
153 }
154
155 @Test
156 void testWithAdditionalDataAndOrbit() {
157
158 final SpacecraftState state = new SpacecraftState(orbit);
159 final DataDictionary dictionary = Mockito.mock(DataDictionary.class);
160
161 final SpacecraftState stateWithData = state.withAdditionalData(dictionary);
162
163 Assertions.assertEquals(dictionary, stateWithData.getAdditionalDataValues());
164 Assertions.assertEquals(state.getMass(), stateWithData.getMass());
165 Assertions.assertEquals(state.getAttitude(), stateWithData.getAttitude());
166 Assertions.assertEquals(state.getOrbit(), stateWithData.getOrbit());
167 }
168
169 @Test
170 void testWithAdditionalStatesDerivativesAndOrbit() {
171
172 final SpacecraftState state = new SpacecraftState(orbit);
173 final DoubleArrayDictionary dictionary = Mockito.mock(DoubleArrayDictionary.class);
174
175 final SpacecraftState stateWithDerivatives = state.withAdditionalStatesDerivatives(dictionary);
176
177 Assertions.assertEquals(dictionary.getData(), stateWithDerivatives.getAdditionalStatesDerivatives().getData());
178 Assertions.assertEquals(state.getOrbit(), stateWithDerivatives.getOrbit());
179 Assertions.assertEquals(state.getAttitude(), stateWithDerivatives.getAttitude());
180 Assertions.assertEquals(state.getMass(), stateWithDerivatives.getMass());
181 }
182
183 @Test
184 void testShiftVsEcksteinHechlerError()
185 throws OrekitException {
186
187
188
189
190
191
192
193
194
195
196
197 PolynomialFunction pModel = new PolynomialFunction(new double[] {
198 1.5664070631933846e-01, 7.5504722733047560e-03, -8.2460562451009510e-05,
199 6.9546332080305580e-06, -1.7045365367533077e-09, -4.2187860791066264e-13
200 });
201 PolynomialFunction vModel = new PolynomialFunction(new double[] {
202 -3.5472364019908720e-04, 1.6568103861124980e-05, 1.9637913327830596e-05,
203 -3.4248792843039766e-09, -5.6565135131014254e-12, 1.4730170946808630e-15
204 });
205 PolynomialFunction aModel = new PolynomialFunction(new double[] {
206 3.0731707577766896e-06, 3.9770746399850350e-05, 1.9779039254538660e-09,
207 8.0263328220724900e-12, -1.5600835252366078e-14, 1.1785257001549687e-18
208 });
209 PolynomialFunction rModel = new PolynomialFunction(new double[] {
210 -2.7689062063188115e-06, 1.7406542538258334e-07, 2.5109795349592287e-09,
211 2.0399322661074575e-11, 9.9126348912426750e-15, -3.5015638905729510e-18
212 });
213
214 AbsoluteDate centerDate = orbit.getDate().shiftedBy(100.0);
215 SpacecraftState centerState = propagator.propagate(centerDate);
216 double maxResidualP = 0;
217 double maxResidualV = 0;
218 double maxResidualA = 0;
219 double maxResidualR = 0;
220 for (double dt = 0; dt < 900.0; dt += 5) {
221 SpacecraftState shifted = centerState.shiftedBy(dt);
222 SpacecraftState propagated = propagator.propagate(centerDate.shiftedBy(dt));
223 PVCoordinates dpv = new PVCoordinates(propagated.getPVCoordinates(), shifted.getPVCoordinates());
224 double residualP = pModel.value(dt) - dpv.getPosition().getNorm();
225 double residualV = vModel.value(dt) - dpv.getVelocity().getNorm();
226 double residualA = aModel.value(dt) - dpv.getAcceleration().getNorm();
227 double residualR = rModel.value(dt) -
228 FastMath.toDegrees(Rotation.distance(shifted.getAttitude().getRotation(),
229 propagated.getAttitude().getRotation()));
230 maxResidualP = FastMath.max(maxResidualP, FastMath.abs(residualP));
231 maxResidualV = FastMath.max(maxResidualV, FastMath.abs(residualV));
232 maxResidualA = FastMath.max(maxResidualA, FastMath.abs(residualA));
233 maxResidualR = FastMath.max(maxResidualR, FastMath.abs(residualR));
234
235 }
236
237 Assertions.assertEquals(0.40, maxResidualP, 0.01);
238 Assertions.assertEquals(4.9e-4, maxResidualV, 1.0e-5);
239 Assertions.assertEquals(7.7e-6, maxResidualA, 1.0e-7);
240 Assertions.assertEquals(2.8e-6, maxResidualR, 1.0e-1);
241
242 }
243
244 @Test
245 void testDatesConsistency() {
246 Assertions.assertThrows(IllegalArgumentException.class, () -> {
247 new SpacecraftState(orbit, attitudeLaw.getAttitude(orbit.shiftedBy(10.0),
248 orbit.getDate().shiftedBy(10.0), orbit.getFrame()));
249 });
250 }
251
252
253
254
255
256 @Test
257 void testDateConsistencyClose() {
258
259 Orbit orbit10Shifts = orbit;
260 for (int i = 0; i < 10; i++) {
261 orbit10Shifts = orbit10Shifts.shiftedBy(0.1);
262 }
263 final Orbit orbit1Shift = orbit.shiftedBy(1);
264 Attitude shiftedAttitude = attitudeLaw.getAttitude(orbit1Shift, orbit1Shift.getDate(), orbit.getFrame());
265
266
267 Assertions.assertEquals(shiftedAttitude.getDate(), orbit10Shifts.getDate());
268
269
270 new SpacecraftState(orbit10Shifts, shiftedAttitude);
271 }
272
273 @Test
274 void testFramesConsistency() {
275 Assertions.assertThrows(IllegalArgumentException.class, () -> {
276 new SpacecraftState(orbit,
277 new Attitude(orbit.getDate(),
278 FramesFactory.getGCRF(),
279 Rotation.IDENTITY, Vector3D.ZERO, Vector3D.ZERO));
280 });
281 }
282
283 @Test
284 void testTransform()
285 throws ParseException, OrekitException {
286
287 double maxDP = 0;
288 double maxDV = 0;
289 double maxDA = 0;
290 for (double t = 0; t < orbit.getKeplerianPeriod(); t += 60) {
291 final SpacecraftState state = propagator.propagate(orbit.getDate().shiftedBy(t));
292 final Transform transform = state.toTransform().getInverse();
293 PVCoordinates pv = transform.transformPVCoordinates(PVCoordinates.ZERO);
294 PVCoordinates dPV = new PVCoordinates(pv, state.getPVCoordinates());
295 Vector3D mZDirection = transform.transformVector(Vector3D.MINUS_K);
296 double alpha = Vector3D.angle(mZDirection, state.getPosition());
297 maxDP = FastMath.max(maxDP, dPV.getPosition().getNorm());
298 maxDV = FastMath.max(maxDV, dPV.getVelocity().getNorm());
299 maxDA = FastMath.max(maxDA, FastMath.toDegrees(alpha));
300 }
301 Assertions.assertEquals(0.0, maxDP, 1.0e-6);
302 Assertions.assertEquals(0.0, maxDV, 1.0e-9);
303 Assertions.assertEquals(0.0, maxDA, 1.0e-12);
304
305 }
306
307 @Test
308 void testGetAdditionalStateBadType() {
309 final SpacecraftState state = new SpacecraftState(orbit).addAdditionalData("string", "hello there");
310 OrekitException exception = Assertions.assertThrows(OrekitException.class, () -> state.getAdditionalState("string"));
311 Assertions.assertEquals(OrekitMessages.ADDITIONAL_STATE_BAD_TYPE, exception.getSpecifier());
312 Assertions.assertEquals("string", exception.getParts()[0]);
313 }
314
315 @Test
316 void testAdditionalStates() {
317 final SpacecraftState state = propagator.propagate(orbit.getDate().shiftedBy(60));
318 final SpacecraftState extended =
319 state.
320 addAdditionalData("test-1", new double[] { 1.0, 2.0 }).
321 addAdditionalData("test-2", 42.0);
322 Assertions.assertEquals(0, state.getAdditionalDataValues().size());
323 Assertions.assertFalse(state.hasAdditionalData("test-1"));
324 try {
325 state.getAdditionalState("test-1");
326 Assertions.fail("an exception should have been thrown");
327 } catch (OrekitException oe) {
328 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
329 Assertions.assertEquals(oe.getParts()[0], "test-1");
330 }
331 try {
332 state.ensureCompatibleAdditionalStates(extended);
333 Assertions.fail("an exception should have been thrown");
334 } catch (OrekitException oe) {
335 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
336 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
337 }
338 try {
339 extended.ensureCompatibleAdditionalStates(state);
340 Assertions.fail("an exception should have been thrown");
341 } catch (OrekitException oe) {
342 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
343 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
344 }
345 try {
346 extended.ensureCompatibleAdditionalStates(extended.addAdditionalData("test-2", new double[7]));
347 Assertions.fail("an exception should have been thrown");
348 } catch (MathIllegalStateException mise) {
349 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
350 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
351 }
352 Assertions.assertEquals(2, extended.getAdditionalDataValues().getData().size());
353 Assertions.assertTrue(extended.hasAdditionalData("test-1"));
354 Assertions.assertTrue(extended.hasAdditionalData("test-2"));
355 Assertions.assertEquals( 1.0, extended.getAdditionalState("test-1")[0], 1.0e-15);
356 Assertions.assertEquals( 2.0, extended.getAdditionalState("test-1")[1], 1.0e-15);
357 Assertions.assertEquals(42.0, extended.getAdditionalState("test-2")[0], 1.0e-15);
358
359
360 DataDictionary dictionary = new DataDictionary();
361 dictionary.put("test-3", new double[] { -6.0 });
362 SpacecraftState sO = new SpacecraftState(state.getOrbit()).withAdditionalData(dictionary);
363 Assertions.assertEquals(-6.0, sO.getAdditionalState("test-3")[0], 1.0e-15);
364
365 }
366
367 @Test
368 void testAdditionalStatesDerivatives() {
369 final SpacecraftState state = propagator.propagate(orbit.getDate().shiftedBy(60));
370 final SpacecraftState extended =
371 state.
372 addAdditionalStateDerivative("test-1", new double[] { 1.0, 2.0 }).
373 addAdditionalStateDerivative("test-2", 42.0);
374 Assertions.assertEquals(0, state.getAdditionalStatesDerivatives().size());
375 Assertions.assertFalse(state.hasAdditionalStateDerivative("test-1"));
376 try {
377 state.getAdditionalStateDerivative("test-1");
378 Assertions.fail("an exception should have been thrown");
379 } catch (OrekitException oe) {
380 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
381 Assertions.assertEquals(oe.getParts()[0], "test-1");
382 }
383 try {
384 state.ensureCompatibleAdditionalStates(extended);
385 Assertions.fail("an exception should have been thrown");
386 } catch (OrekitException oe) {
387 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
388 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
389 }
390 try {
391 extended.ensureCompatibleAdditionalStates(state);
392 Assertions.fail("an exception should have been thrown");
393 } catch (OrekitException oe) {
394 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
395 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
396 }
397 try {
398 extended.ensureCompatibleAdditionalStates(extended.addAdditionalStateDerivative("test-2", new double[7]));
399 Assertions.fail("an exception should have been thrown");
400 } catch (MathIllegalStateException mise) {
401 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
402 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
403 }
404 Assertions.assertEquals(2, extended.getAdditionalStatesDerivatives().size());
405 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-1"));
406 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-2"));
407 Assertions.assertEquals( 1.0, extended.getAdditionalStateDerivative("test-1")[0], 1.0e-15);
408 Assertions.assertEquals( 2.0, extended.getAdditionalStateDerivative("test-1")[1], 1.0e-15);
409 Assertions.assertEquals(42.0, extended.getAdditionalStateDerivative("test-2")[0], 1.0e-15);
410
411
412 DoubleArrayDictionary dictionary = new DoubleArrayDictionary();
413 dictionary.put("test-3", new double[] { -6.0 });
414 SpacecraftState s = new SpacecraftState(state.getOrbit(), state.getAttitude(), state.getMass(), null, dictionary);
415 Assertions.assertFalse(s.hasAdditionalData("test-3"));
416 Assertions.assertEquals(-6.0, s.getAdditionalStateDerivative("test-3")[0], 1.0e-15);
417
418 }
419
420 @Test
421 void testAdditionalTestResetOnEventAnalytical() {
422
423
424 AbsoluteDate date0 = new AbsoluteDate(2000, 1, 1, TimeScalesFactory.getUTC());
425 Orbit orbit = new KeplerianOrbit(7.1E6, 0, 0, 0, 0, 0,
426 PositionAngleType.TRUE, FramesFactory.getGCRF(), date0,
427 Constants.WGS84_EARTH_MU);
428
429
430 KeplerianPropagator propagator = new KeplerianPropagator(orbit);
431
432
433 final String name = "A";
434 SpacecraftState initialState = new SpacecraftState(orbit).
435 addAdditionalData(name, new double[] { -1 });
436
437 propagator.resetInitialState(initialState);
438
439
440 AbsoluteDate changeDate = date0.shiftedBy(3);
441 DateDetector dateDetector = new DateDetector(changeDate).
442 withHandler(new EventHandler() {
443
444 @Override
445 public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
446 return Action.RESET_STATE;
447 }
448
449 @Override
450 public SpacecraftState resetState(EventDetector detector, SpacecraftState oldState) {
451 return oldState.addAdditionalData(name, new double[] { +1 });
452 }
453
454 });
455
456 propagator.addEventDetector(dateDetector);
457 propagator.setStepHandler(0.125, s -> {
458 if (s.getDate().durationFrom(changeDate) < -0.001) {
459 Assertions.assertEquals(-1, s.getAdditionalState(name)[0], 1.0e-15);
460 } else if (s.getDate().durationFrom(changeDate) > +0.001) {
461 Assertions.assertEquals(+1, s.getAdditionalState(name)[0], 1.0e-15);
462 }
463 });
464 SpacecraftState finalState = propagator.propagate(date0, date0.shiftedBy(5));
465 Assertions.assertEquals(+1, finalState.getAdditionalState(name)[0], 1.0e-15);
466
467 }
468
469 @Test
470 void testAdditionalTestResetOnEventNumerical() {
471
472
473 AbsoluteDate date0 = new AbsoluteDate(2000, 1, 1, TimeScalesFactory.getUTC());
474 Orbit orbit = new KeplerianOrbit(7.1E6, 0, 0, 0, 0, 0,
475 PositionAngleType.TRUE, FramesFactory.getGCRF(), date0,
476 Constants.WGS84_EARTH_MU);
477
478
479 ODEIntegrator odeIntegrator = new DormandPrince853Integrator(1E-3, 1E3, 1E-6, 1E-6);
480 NumericalPropagator propagator = new NumericalPropagator(odeIntegrator);
481
482
483 final String name = "A";
484 SpacecraftState initialState = new SpacecraftState(orbit).
485 addAdditionalData(name, new double[] { -1 });
486
487 propagator.setInitialState(initialState);
488
489
490 AbsoluteDate changeDate = date0.shiftedBy(3);
491 DateDetector dateDetector = new DateDetector(changeDate).
492 withHandler(new EventHandler() {
493
494 @Override
495 public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
496 return Action.RESET_STATE;
497 }
498
499 @Override
500 public SpacecraftState resetState(EventDetector detector, SpacecraftState oldState) {
501 return oldState.addAdditionalData(name, new double[] { +1 });
502 }
503
504 });
505
506 propagator.addEventDetector(dateDetector);
507 propagator.setStepHandler(0.125, s -> {
508 if (s.getDate().durationFrom(changeDate) < -0.001) {
509 Assertions.assertEquals(-1, s.getAdditionalState(name)[0], 1.0e-15);
510 } else if (s.getDate().durationFrom(changeDate) > +0.001) {
511 Assertions.assertEquals(+1, s.getAdditionalState(name)[0], 1.0e-15);
512 }
513 });
514 SpacecraftState finalState = propagator.propagate(date0, date0.shiftedBy(5));
515 Assertions.assertEquals(+1, finalState.getAdditionalState(name)[0], 1.0e-15);
516
517 }
518
519 @Test
520 void testAdditionalStatesAbsPV() {
521
522 double x_f = 0.8;
523 double y_f = 0.2;
524 double z_f = 0;
525 double vx_f = 0;
526 double vy_f = 0;
527 double vz_f = 0.1;
528
529 AbsoluteDate date = new AbsoluteDate(new DateComponents(2004, 01, 01),
530 TimeComponents.H00,
531 TimeScalesFactory.getUTC());
532
533 PVCoordinates pva_f = new PVCoordinates(new Vector3D(x_f,y_f,z_f), new Vector3D(vx_f,vy_f,vz_f));
534
535 AbsolutePVCoordinates absPV_f = new AbsolutePVCoordinates(FramesFactory.getEME2000(), date, pva_f);
536
537 NumericalPropagator prop = new NumericalPropagator(new DormandPrince853Integrator(0.1, 500, 0.001, 0.001));
538 prop.setOrbitType(null);
539
540 final SpacecraftState initialState = new SpacecraftState(absPV_f);
541
542 prop.resetInitialState(initialState);
543
544 final SpacecraftState state = prop.propagate(absPV_f.getDate().shiftedBy(60));
545 double[] add = new double[2];
546 add[0] = 1.;
547 add[1] = 2.;
548 final SpacecraftState extended =
549 state.
550 addAdditionalData("test-1", add).
551 addAdditionalData("test-2", 42.0);
552 Assertions.assertEquals(0, state.getAdditionalDataValues().size());
553 Assertions.assertFalse(state.hasAdditionalData("test-1"));
554 try {
555 state.getAdditionalState("test-1");
556 Assertions.fail("an exception should have been thrown");
557 } catch (OrekitException oe) {
558 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
559 Assertions.assertEquals(oe.getParts()[0], "test-1");
560 }
561 try {
562 state.ensureCompatibleAdditionalStates(extended);
563 Assertions.fail("an exception should have been thrown");
564 } catch (OrekitException oe) {
565 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
566 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
567 }
568 try {
569 extended.ensureCompatibleAdditionalStates(state);
570 Assertions.fail("an exception should have been thrown");
571 } catch (OrekitException oe) {
572 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
573 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
574 }
575 try {
576 double[] kk = new double[7];
577 extended.ensureCompatibleAdditionalStates(extended.addAdditionalData("test-2", kk));
578 Assertions.fail("an exception should have been thrown");
579 } catch (MathIllegalStateException mise) {
580 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
581 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
582 }
583 Assertions.assertEquals(2, extended.getAdditionalDataValues().size());
584 Assertions.assertTrue(extended.hasAdditionalData("test-1"));
585 Assertions.assertTrue(extended.hasAdditionalData("test-2"));
586 Assertions.assertEquals( 1.0, extended.getAdditionalState("test-1")[0], 1.0e-15);
587 Assertions.assertEquals( 2.0, extended.getAdditionalState("test-1")[1], 1.0e-15);
588 Assertions.assertEquals(42.0, extended.getAdditionalState("test-2")[0], 1.0e-15);
589
590
591 double[] dd = new double[1];
592 dd[0] = -6.0;
593 DataDictionary additional = new DataDictionary();
594 additional.put("test-3", dd);
595 SpacecraftState sO = state.withAdditionalData(additional);
596 Assertions.assertEquals(-6.0, sO.getAdditionalState("test-3")[0], 1.0e-15);
597
598 }
599
600 @Test
601 void testAdditionalStatesDerivativesAbsPV() {
602
603 double x_f = 0.8;
604 double y_f = 0.2;
605 double z_f = 0;
606 double vx_f = 0;
607 double vy_f = 0;
608 double vz_f = 0.1;
609
610 AbsoluteDate date = new AbsoluteDate(new DateComponents(2004, 01, 01),
611 TimeComponents.H00,
612 TimeScalesFactory.getUTC());
613
614 PVCoordinates pva_f = new PVCoordinates(new Vector3D(x_f,y_f,z_f), new Vector3D(vx_f,vy_f,vz_f));
615
616 AbsolutePVCoordinates absPV_f = new AbsolutePVCoordinates(FramesFactory.getEME2000(), date, pva_f);
617
618 NumericalPropagator prop = new NumericalPropagator(new DormandPrince853Integrator(0.1, 500, 0.001, 0.001));
619 prop.setOrbitType(null);
620
621 final SpacecraftState initialState = new SpacecraftState(absPV_f);
622
623 prop.resetInitialState(initialState);
624
625 final SpacecraftState state = prop.propagate(absPV_f.getDate().shiftedBy(60));
626 double[] add = new double[2];
627 add[0] = 1.;
628 add[1] = 2.;
629 final SpacecraftState extended =
630 state.
631 addAdditionalStateDerivative("test-1", add).
632 addAdditionalStateDerivative("test-2", 42.0);
633 Assertions.assertEquals(0, state.getAdditionalStatesDerivatives().getData().size());
634 Assertions.assertFalse(state.hasAdditionalStateDerivative("test-1"));
635 try {
636 state.getAdditionalStateDerivative("test-1");
637 Assertions.fail("an exception should have been thrown");
638 } catch (OrekitException oe) {
639 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
640 Assertions.assertEquals(oe.getParts()[0], "test-1");
641 }
642 try {
643 state.ensureCompatibleAdditionalStates(extended);
644 Assertions.fail("an exception should have been thrown");
645 } catch (OrekitException oe) {
646 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
647 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
648 }
649 try {
650 extended.ensureCompatibleAdditionalStates(state);
651 Assertions.fail("an exception should have been thrown");
652 } catch (OrekitException oe) {
653 Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.UNKNOWN_ADDITIONAL_DATA);
654 Assertions.assertTrue(oe.getParts()[0].toString().startsWith("test-"));
655 }
656 try {
657 double[] kk = new double[7];
658 extended.ensureCompatibleAdditionalStates(extended.addAdditionalStateDerivative("test-2", kk));
659 Assertions.fail("an exception should have been thrown");
660 } catch (MathIllegalStateException mise) {
661 Assertions.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, mise.getSpecifier());
662 Assertions.assertEquals(7, ((Integer) mise.getParts()[0]).intValue());
663 }
664 Assertions.assertEquals(2, extended.getAdditionalStatesDerivatives().getData().size());
665 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-1"));
666 Assertions.assertTrue(extended.hasAdditionalStateDerivative("test-2"));
667 Assertions.assertEquals( 1.0, extended.getAdditionalStateDerivative("test-1")[0], 1.0e-15);
668 Assertions.assertEquals( 2.0, extended.getAdditionalStateDerivative("test-1")[1], 1.0e-15);
669 Assertions.assertEquals(42.0, extended.getAdditionalStateDerivative("test-2")[0], 1.0e-15);
670
671
672 double[] dd = new double[1];
673 dd[0] = -6.0;
674 DoubleArrayDictionary dict = new DoubleArrayDictionary();
675 dict.put("test-3", dd);
676 SpacecraftState s = new SpacecraftState(state.getAbsPVA(), state.getAttitude(), state.getMass(), null, dict);
677 Assertions.assertEquals(-6.0, s.getAdditionalStateDerivative("test-3")[0], 1.0e-15);
678
679 }
680
681 @Test
682 void testShiftAdditionalDerivatives() {
683
684 final String valueAndDerivative = "value-and-derivative";
685 final String valueOnly = "value-only";
686 final String derivativeOnly = "derivative-only";
687 final SpacecraftState s0 = propagator.getInitialState().
688 addAdditionalData(valueAndDerivative, new double[] { 1.0, 2.0 }).
689 addAdditionalStateDerivative(valueAndDerivative, new double[] { 3.0, 2.0 }).
690 addAdditionalData(valueOnly, new double[] { 5.0, 4.0 }).
691 addAdditionalStateDerivative(derivativeOnly, new double[] { 1.0, -1.0 });
692 Assertions.assertEquals( 1.0, s0.getAdditionalState(valueAndDerivative)[0], 1.0e-15);
693 Assertions.assertEquals( 2.0, s0.getAdditionalState(valueAndDerivative)[1], 1.0e-15);
694 Assertions.assertEquals( 3.0, s0.getAdditionalStateDerivative(valueAndDerivative)[0], 1.0e-15);
695 Assertions.assertEquals( 2.0, s0.getAdditionalStateDerivative(valueAndDerivative)[1], 1.0e-15);
696 Assertions.assertEquals( 5.0, s0.getAdditionalState(valueOnly)[0], 1.0e-15);
697 Assertions.assertEquals( 4.0, s0.getAdditionalState(valueOnly)[1], 1.0e-15);
698 Assertions.assertEquals( 1.0, s0.getAdditionalStateDerivative(derivativeOnly)[0], 1.0e-15);
699 Assertions.assertEquals(-1.0, s0.getAdditionalStateDerivative(derivativeOnly)[1], 1.0e-15);
700 final SpacecraftState s1 = s0.shiftedBy(-2.0);
701 Assertions.assertEquals(-5.0, s1.getAdditionalState(valueAndDerivative)[0], 1.0e-15);
702 Assertions.assertEquals(-2.0, s1.getAdditionalState(valueAndDerivative)[1], 1.0e-15);
703 Assertions.assertEquals( 3.0, s1.getAdditionalStateDerivative(valueAndDerivative)[0], 1.0e-15);
704 Assertions.assertEquals( 2.0, s1.getAdditionalStateDerivative(valueAndDerivative)[1], 1.0e-15);
705 Assertions.assertEquals( 5.0, s1.getAdditionalState(valueOnly)[0], 1.0e-15);
706 Assertions.assertEquals( 4.0, s1.getAdditionalState(valueOnly)[1], 1.0e-15);
707 Assertions.assertEquals( 1.0, s1.getAdditionalStateDerivative(derivativeOnly)[0], 1.0e-15);
708 Assertions.assertEquals(-1.0, s1.getAdditionalStateDerivative(derivativeOnly)[1], 1.0e-15);
709
710 }
711
712 @Test
713 void testToStaticTransform() {
714
715 final SpacecraftState state = new SpacecraftState(orbit,
716 attitudeLaw.getAttitude(orbit, orbit.getDate(), orbit.getFrame()));
717
718 final StaticTransform actualStaticTransform = state.toStaticTransform();
719
720 final StaticTransform expectedStaticTransform = state.toTransform();
721 Assertions.assertEquals(expectedStaticTransform.getDate(), actualStaticTransform.getDate());
722 Assertions.assertEquals(expectedStaticTransform.getTranslation(), actualStaticTransform.getTranslation());
723 Assertions.assertEquals(0., Rotation.distance(expectedStaticTransform.getRotation(),
724 actualStaticTransform.getRotation()));
725 }
726
727 @BeforeEach
728 public void setUp() {
729 try {
730 Utils.setDataRoot("regular-data");
731 double mu = 3.9860047e14;
732 double ae = 6.378137e6;
733 double c20 = -1.08263e-3;
734 double c30 = 2.54e-6;
735 double c40 = 1.62e-6;
736 double c50 = 2.3e-7;
737 double c60 = -5.5e-7;
738
739 mass = 2500;
740 double a = 7187990.1979844316;
741 double e = 0.5e-4;
742 double i = 1.7105407051081795;
743 double omega = 1.9674147913622104;
744 double OMEGA = FastMath.toRadians(261);
745 double lv = 0;
746
747 AbsoluteDate date = new AbsoluteDate(new DateComponents(2004, 01, 01),
748 TimeComponents.H00,
749 TimeScalesFactory.getUTC());
750 orbit = new KeplerianOrbit(a, e, i, omega, OMEGA, lv, PositionAngleType.TRUE,
751 FramesFactory.getEME2000(), date, mu);
752 OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
753 Constants.WGS84_EARTH_FLATTENING,
754 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
755 attitudeLaw = new BodyCenterPointing(orbit.getFrame(), earth);
756 propagator =
757 new EcksteinHechlerPropagator(orbit, attitudeLaw, mass,
758 ae, mu, c20, c30, c40, c50, c60);
759
760 } catch (OrekitException oe) {
761 Assertions.fail(oe.getLocalizedMessage());
762 }
763 }
764
765 @AfterEach
766 public void tearDown() {
767 mass = Double.NaN;
768 orbit = null;
769 attitudeLaw = null;
770 propagator = null;
771 }
772
773 private double mass;
774 private Orbit orbit;
775 private AttitudeProvider attitudeLaw;
776 private Propagator propagator;
777
778 }