1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.semianalytical.dsst.forces;
18
19 import java.io.IOException;
20 import java.text.ParseException;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
24
25 import org.hipparchus.exception.LocalizedCoreFormats;
26 import org.hipparchus.ode.nonstiff.ClassicalRungeKuttaIntegrator;
27 import org.hipparchus.stat.descriptive.StreamingStatistics;
28 import org.hipparchus.util.FastMath;
29 import org.junit.jupiter.api.Assertions;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Test;
32 import org.orekit.Utils;
33 import org.orekit.attitudes.AttitudeProvider;
34 import org.orekit.attitudes.FrameAlignedProvider;
35 import org.orekit.errors.OrekitException;
36 import org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel;
37 import org.orekit.forces.gravity.potential.GRGSFormatReader;
38 import org.orekit.forces.gravity.potential.GravityFieldFactory;
39 import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
40 import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
41 import org.orekit.frames.Frame;
42 import org.orekit.frames.FramesFactory;
43 import org.orekit.orbits.CircularOrbit;
44 import org.orekit.orbits.EquinoctialOrbit;
45 import org.orekit.orbits.Orbit;
46 import org.orekit.orbits.PositionAngleType;
47 import org.orekit.propagation.BoundedPropagator;
48 import org.orekit.propagation.EphemerisGenerator;
49 import org.orekit.propagation.PropagationType;
50 import org.orekit.propagation.SpacecraftState;
51 import org.orekit.propagation.numerical.NumericalPropagator;
52 import org.orekit.propagation.semianalytical.dsst.DSSTPropagator;
53 import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
54 import org.orekit.time.AbsoluteDate;
55 import org.orekit.time.DateComponents;
56 import org.orekit.time.TimeComponents;
57 import org.orekit.time.TimeScalesFactory;
58 import org.orekit.utils.IERSConventions;
59
60 class DSSTZonalTest {
61
62
63
64
65
66
67 @Test
68 void testGetMeanElementRate() {
69 doTestGetMeanElementRate(false);
70 doTestGetMeanElementRate(true);
71 }
72
73 private void doTestGetMeanElementRate(final boolean testIssue1104) {
74
75
76 final UnnormalizedSphericalHarmonicsProvider provider =
77 GravityFieldFactory.getUnnormalizedProvider(4, 4);
78
79 final Frame earthFrame = FramesFactory.getEME2000();
80 final AbsoluteDate initDate = new AbsoluteDate(2007, 04, 16, 0, 46, 42.400, TimeScalesFactory.getUTC());
81
82
83
84
85
86
87
88 final Orbit orbit = new EquinoctialOrbit(2.655989E7,
89 2.719455286199036E-4,
90 0.0041543085910249414,
91 -0.3412974060023717,
92 0.3960084733107685,
93 8.566537840341699,
94 PositionAngleType.TRUE,
95 earthFrame,
96 initDate,
97 3.986004415E14);
98
99 final SpacecraftState state = new SpacecraftState(orbit, 1000.0);
100
101 final DSSTForceModel zonal;
102 if (testIssue1104) {
103
104 zonal = new DSSTZonal(state.getFrame(), provider, 4, 3, 9);
105 } else {
106
107 zonal = new DSSTZonal(provider, 4, 3, 9);
108 }
109
110
111 final double[] parameters = zonal.getParameters(orbit.getDate());
112
113 final AuxiliaryElements auxiliaryElements = new AuxiliaryElements(state.getOrbit(), 1);
114
115
116 zonal.initializeShortPeriodTerms(auxiliaryElements, PropagationType.MEAN, parameters);
117
118 final double[] elements = new double[7];
119 Arrays.fill(elements, 0.0);
120
121 final double[] daidt = zonal.getMeanElementRate(state, auxiliaryElements, parameters);
122 for (int i = 0; i < daidt.length; i++) {
123 elements[i] = daidt[i];
124 }
125
126 Assertions.assertEquals(0.0, elements[0], 1.e-25);
127 Assertions.assertEquals(1.3909396722346468E-11, elements[1], 3.e-26);
128 Assertions.assertEquals(-2.0275977261372793E-13, elements[2], 3.e-27);
129 Assertions.assertEquals(3.087141512018238E-9, elements[3], 1.e-24);
130 Assertions.assertEquals(2.6606317310148797E-9, elements[4], 4.e-24);
131 Assertions.assertEquals(-3.659904725206694E-9, elements[5], 1.e-24);
132
133 }
134
135 @Test
136 void testShortPeriodTerms() {
137 final SpacecraftState meanState = getGEOState();
138
139 final UnnormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getUnnormalizedProvider(2, 0);
140 final DSSTForceModel zonal = new DSSTZonal(provider, 2, 1, 5);
141
142
143 final AuxiliaryElements aux = new AuxiliaryElements(meanState.getOrbit(), 1);
144
145
146 final List<ShortPeriodTerms> shortPeriodTerms = new ArrayList<ShortPeriodTerms>();
147
148 zonal.registerAttitudeProvider(null);
149 shortPeriodTerms.addAll(zonal.initializeShortPeriodTerms(aux, PropagationType.OSCULATING, zonal.getParameters(meanState.getDate())));
150 zonal.updateShortPeriodTerms(zonal.getParametersAllValues(), meanState);
151
152 double[] y = new double[6];
153 for (final ShortPeriodTerms spt : shortPeriodTerms) {
154 final double[] shortPeriodic = spt.value(meanState.getOrbit());
155 for (int i = 0; i < shortPeriodic.length; i++) {
156 y[i] += shortPeriodic[i];
157 }
158 }
159
160 Assertions.assertEquals(35.005618980090276, y[0], 1.e-15);
161 Assertions.assertEquals(3.75891551882889E-5, y[1], 1.e-20);
162 Assertions.assertEquals(3.929119925563796E-6, y[2], 1.e-21);
163 Assertions.assertEquals(-1.1781951949124315E-8, y[3], 1.e-24);
164 Assertions.assertEquals(-3.2134924513679615E-8, y[4], 1.e-24);
165 Assertions.assertEquals(-1.1607392915997098E-6, y[5], 1.e-21);
166 }
167
168 private SpacecraftState getGEOState() {
169
170 final AbsoluteDate initDate = new AbsoluteDate(new DateComponents(2003, 05, 21), new TimeComponents(1, 0, 0.),
171 TimeScalesFactory.getUTC());
172 final Orbit orbit = new EquinoctialOrbit(42164000,
173 10e-3,
174 10e-3,
175 FastMath.tan(0.001745329) * FastMath.cos(2 * FastMath.PI / 3),
176 FastMath.tan(0.001745329) * FastMath.sin(2 * FastMath.PI / 3), 0.1,
177 PositionAngleType.TRUE,
178 FramesFactory.getEME2000(),
179 initDate,
180 3.986004415E14);
181 return new SpacecraftState(orbit);
182 }
183
184 @Test
185 void testIssue625() {
186
187 Utils.setDataRoot("regular-data:potential/grgs-format");
188 GravityFieldFactory.addPotentialCoefficientsReader(new GRGSFormatReader("grim4s4_gr", true));
189
190 final Frame earthFrame = FramesFactory.getEME2000();
191 final AbsoluteDate initDate = new AbsoluteDate(2007, 04, 16, 0, 46, 42.400, TimeScalesFactory.getUTC());
192
193
194
195
196
197
198
199 final Orbit orbit = new EquinoctialOrbit(2.655989E6,
200 2.719455286199036E-4,
201 0.0041543085910249414,
202 -0.3412974060023717,
203 0.3960084733107685,
204 8.566537840341699,
205 PositionAngleType.TRUE,
206 earthFrame,
207 initDate,
208 3.986004415E14);
209
210 final SpacecraftState state = new SpacecraftState(orbit, 1000.0);
211
212 final AuxiliaryElements auxiliaryElements = new AuxiliaryElements(state.getOrbit(), 1);
213
214
215 final UnnormalizedSphericalHarmonicsProvider provider =
216 GravityFieldFactory.getUnnormalizedProvider(32, 32);
217
218
219 final DSSTZonal zonal = new DSSTZonal(provider, 32, 4, 65);
220 zonal.initializeShortPeriodTerms(auxiliaryElements, PropagationType.MEAN, zonal.getParameters(orbit.getDate()));
221
222
223 final DSSTZonal zonalDefault = new DSSTZonal(provider);
224 zonalDefault.initializeShortPeriodTerms(auxiliaryElements, PropagationType.MEAN, zonalDefault.getParameters(orbit.getDate()));
225
226
227 final double[] elements = zonal.getMeanElementRate(state, auxiliaryElements, zonal.getParameters(orbit.getDate()));
228
229
230 final double[] elementsDefault = zonalDefault.getMeanElementRate(state, auxiliaryElements, zonalDefault.getParameters(orbit.getDate()));
231
232
233 for (int i = 0; i < 6; i++) {
234 Assertions.assertEquals(elements[i], elementsDefault[i], Double.MIN_VALUE);
235 }
236
237 }
238
239 @Test
240 void testOutOfRangeException() {
241 try {
242 @SuppressWarnings("unused")
243 final DSSTZonal zonal = new DSSTZonal(GravityFieldFactory.getUnnormalizedProvider(1, 0));
244 Assertions.fail("An exception should have been thrown");
245 } catch (OrekitException oe) {
246 Assertions.assertEquals(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE, oe.getSpecifier());
247 }
248 }
249
250
251
252
253
254 @Test
255 void testIssue1104() {
256
257 final boolean printResults = false;
258
259
260 final Frame gcrf = FramesFactory.getGCRF();
261 final Frame tod = FramesFactory.getTOD(IERSConventions.IERS_2010, true);
262 final Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
263
264
265
266
267
268 double diMax = 9.615e-5;
269 double dOmMax = 3.374e-3;
270 double dLmMax = 1.128e-2;
271 doTestIssue1104(gcrf, gcrf, printResults, diMax, dOmMax, dLmMax);
272
273
274
275
276
277
278
279 diMax = 1.059e-5;
280 dOmMax = 2.789e-3;
281 dLmMax = 1.040e-2;
282 doTestIssue1104(tod, tod, printResults, diMax, dOmMax, dLmMax);
283
284
285
286
287
288
289 diMax = 1.067e-5;
290 dOmMax = 2.789e-3;
291 dLmMax = 1.040e-2;
292 doTestIssue1104(gcrf, itrf, printResults, diMax, dOmMax, dLmMax);
293
294
295
296
297
298
299 diMax = 1.059e-5;
300 dOmMax = 2.789e-3;
301 dLmMax = 1.040e-2;
302 doTestIssue1104(tod, itrf, printResults, diMax, dOmMax, dLmMax);
303
304
305
306 }
307
308
309 private void doTestIssue1104(final Frame inertialFrame,
310 final Frame bodyFixedFrame,
311 final boolean printResults,
312 final double diMax,
313 final double dOmMax,
314 final double dLmMax) {
315
316
317
318
319
320 final double step = 60.;
321 final double nOrb = 50.;
322
323 final AbsoluteDate t0 = new AbsoluteDate();
324
325
326 final Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
327
328
329 final int degree = 2;
330 final int order = 0;
331 final UnnormalizedSphericalHarmonicsProvider unnormalized =
332 GravityFieldFactory.getConstantUnnormalizedProvider(degree, order, t0);
333 final NormalizedSphericalHarmonicsProvider normalized =
334 GravityFieldFactory.getConstantNormalizedProvider(degree, order, t0);
335
336
337 final double mass = 150.;
338 final double a = 6906780.35;
339 final double ex = 5.09E-4;
340 final double ey = 1.24e-3;
341 final double i = FastMath.toRadians(97.49);
342 final double raan = FastMath.toRadians(-94.607);
343 final double alphaM = FastMath.toRadians(0.);
344 final CircularOrbit oscCircOrbit0 = new CircularOrbit(a, ex, ey, i, raan, alphaM, PositionAngleType.MEAN,
345 inertialFrame, t0, unnormalized.getMu());
346
347 final Orbit oscOrbit0 = new EquinoctialOrbit(oscCircOrbit0);
348 final SpacecraftState oscState0 = new SpacecraftState(oscOrbit0, mass);
349 final AttitudeProvider attProvider = new FrameAlignedProvider(inertialFrame);
350
351
352 final double duration = nOrb * oscOrbit0.getKeplerianPeriod();
353 final AbsoluteDate tf = t0.shiftedBy(duration);
354
355
356 final ClassicalRungeKuttaIntegrator integrator = new ClassicalRungeKuttaIntegrator(step);
357
358 final NumericalPropagator numProp = new NumericalPropagator(integrator);
359 numProp.setOrbitType(oscOrbit0.getType());
360 numProp.setInitialState(oscState0);
361 numProp.setAttitudeProvider(attProvider);
362 numProp.addForceModel(new HolmesFeatherstoneAttractionModel(itrf, normalized));
363 final EphemerisGenerator numEphemGen = numProp.getEphemerisGenerator();
364
365
366 final ClassicalRungeKuttaIntegrator integratorDsst = new ClassicalRungeKuttaIntegrator(step);
367 final DSSTPropagator dsstProp = new DSSTPropagator(integratorDsst, PropagationType.OSCULATING);
368 dsstProp.setInitialState(oscState0, PropagationType.OSCULATING);
369 dsstProp.setAttitudeProvider(attProvider);
370 final DSSTForceModel zonal = new DSSTZonal(bodyFixedFrame, unnormalized);
371 dsstProp.addForceModel(zonal);
372 final EphemerisGenerator dsstEphemGen = dsstProp.getEphemerisGenerator();
373
374
375
376
377
378
379 final StreamingStatistics dI = new StreamingStatistics();
380 final StreamingStatistics dOm = new StreamingStatistics();
381 final StreamingStatistics dLM = new StreamingStatistics();
382
383
384 numProp.propagate(t0, tf);
385 dsstProp.propagate(t0, tf);
386
387 final BoundedPropagator numEphem = numEphemGen.getGeneratedEphemeris();
388 final BoundedPropagator dsstEphem = dsstEphemGen.getGeneratedEphemeris();
389
390
391 for (double dt = 0; dt < duration; dt += step) {
392
393
394 final AbsoluteDate t = t0.shiftedBy(dt);
395
396
397 final CircularOrbit num = new CircularOrbit(numEphem.propagate(t).getOrbit());
398 final CircularOrbit dsst = new CircularOrbit(dsstEphem.propagate(t).getOrbit());
399 dI.addValue(FastMath.toDegrees(dsst.getI() - num.getI()));
400 dOm.addValue(FastMath.toDegrees(dsst.getRightAscensionOfAscendingNode() - num.getRightAscensionOfAscendingNode()));
401 dLM.addValue(FastMath.toDegrees(dsst.getLM() - num.getLM()));
402 }
403
404
405
406
407
408 if (printResults) {
409 System.out.println("Inertial frame : " + inertialFrame.toString());
410 System.out.println("Body-Fixed frame: " + bodyFixedFrame.toString());
411 System.out.println("\ndi\n" + dI.toString());
412 System.out.println("\ndΩ\n" + dOm.toString());
413 System.out.println("\ndLM\n" + dLM.toString());
414 }
415
416
417 Assertions.assertEquals(diMax, FastMath.max(FastMath.abs(dI.getMax()), FastMath.abs(dI.getMin())), 1.e-8);
418 Assertions.assertEquals(dOmMax, FastMath.max(FastMath.abs(dOm.getMax()), FastMath.abs(dOm.getMin())), 1.e-6);
419 Assertions.assertEquals(dLmMax, FastMath.max(FastMath.abs(dLM.getMax()), FastMath.abs(dLM.getMin())), 1.e-5);
420 }
421
422 @BeforeEach
423 public void setUp() throws IOException, ParseException {
424 Utils.setDataRoot("regular-data:potential/shm-format");
425 }
426
427 }