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