1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.frames;
18
19
20 import java.io.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectOutputStream;
25
26 import org.hipparchus.CalculusFieldElement;
27 import org.hipparchus.geometry.euclidean.threed.Rotation;
28 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
29 import org.hipparchus.geometry.euclidean.threed.Vector3D;
30 import org.junit.Assert;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.orekit.Utils;
34 import org.orekit.data.DataContext;
35 import org.orekit.data.PolynomialNutation;
36 import org.orekit.time.AbsoluteDate;
37 import org.orekit.time.DateComponents;
38 import org.orekit.time.FieldAbsoluteDate;
39 import org.orekit.time.TimeComponents;
40 import org.orekit.time.TimeScalesFactory;
41 import org.orekit.utils.Constants;
42 import org.orekit.utils.IERSConventions;
43 import org.orekit.utils.PVCoordinates;
44
45
46 public class MODProviderTest {
47
48 @Test
49 public void testEuler1976() {
50
51 TransformProvider eulerBasedProvider = new TransformProvider() {
52 private static final long serialVersionUID = 1L;
53 private final PolynomialNutation zetaA =
54 new PolynomialNutation(0.0,
55 2306.2181 * Constants.ARC_SECONDS_TO_RADIANS,
56 0.30188 * Constants.ARC_SECONDS_TO_RADIANS,
57 0.017998 * Constants.ARC_SECONDS_TO_RADIANS);
58 private final PolynomialNutation thetaA =
59 new PolynomialNutation(0.0,
60 2004.3109 * Constants.ARC_SECONDS_TO_RADIANS,
61 -0.42665 * Constants.ARC_SECONDS_TO_RADIANS,
62 -0.041833 * Constants.ARC_SECONDS_TO_RADIANS);
63 private final PolynomialNutation zA =
64 new PolynomialNutation(0.0,
65 2306.2181 * Constants.ARC_SECONDS_TO_RADIANS,
66 1.09468 * Constants.ARC_SECONDS_TO_RADIANS,
67 0.018203 * Constants.ARC_SECONDS_TO_RADIANS);
68
69 public Transform getTransform(AbsoluteDate date) {
70 final double tc = IERSConventions.IERS_1996.evaluateTC(date);
71 final Rotation r1 = new Rotation(Vector3D.PLUS_K, zA.value(tc), RotationConvention.VECTOR_OPERATOR);
72 final Rotation r2 = new Rotation(Vector3D.PLUS_J, -thetaA.value(tc), RotationConvention.VECTOR_OPERATOR);
73 final Rotation r3 = new Rotation(Vector3D.PLUS_K, zetaA.value(tc), RotationConvention.VECTOR_OPERATOR);
74 return new Transform(date, r1.compose(r2.compose(r3,
75 RotationConvention.VECTOR_OPERATOR),
76 RotationConvention.VECTOR_OPERATOR));
77 }
78
79 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
80 throw new UnsupportedOperationException("never called in this test");
81 }
82
83 };
84
85 MODProvider modProvider = new MODProvider(IERSConventions.IERS_1996,
86 DataContext.getDefault().getTimeScales());
87
88 for (double dt = -5 * Constants.JULIAN_YEAR; dt < 5 * Constants.JULIAN_YEAR; dt += 10 * Constants.JULIAN_DAY) {
89 AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
90 Transform t = new Transform(date,
91 modProvider.getTransform(date).getInverse(),
92 eulerBasedProvider.getTransform(date));
93 Assert.assertEquals(0, t.getRotation().getAngle(), 1.01e-11);
94 }
95
96 }
97
98 @Test
99 public void testEuler2000() {
100
101
102
103 TransformProvider eulerBasedProvider = new TransformProvider() {
104 private static final long serialVersionUID = 1L;
105 private final PolynomialNutation zetaA =
106 new PolynomialNutation( 2.5976176 * Constants.ARC_SECONDS_TO_RADIANS,
107 2306.0809506 * Constants.ARC_SECONDS_TO_RADIANS,
108 0.3019015 * Constants.ARC_SECONDS_TO_RADIANS,
109 0.0179663 * Constants.ARC_SECONDS_TO_RADIANS,
110 -0.0000327 * Constants.ARC_SECONDS_TO_RADIANS,
111 -0.0000002 * Constants.ARC_SECONDS_TO_RADIANS);
112 private final PolynomialNutation thetaA =
113 new PolynomialNutation(0.0,
114 2004.1917476 * Constants.ARC_SECONDS_TO_RADIANS,
115 -0.4269353 * Constants.ARC_SECONDS_TO_RADIANS,
116 -0.0418251 * Constants.ARC_SECONDS_TO_RADIANS,
117 -0.0000601 * Constants.ARC_SECONDS_TO_RADIANS,
118 -0.0000001 * Constants.ARC_SECONDS_TO_RADIANS);
119 private final PolynomialNutation zA =
120 new PolynomialNutation( -2.5976176 * Constants.ARC_SECONDS_TO_RADIANS,
121 2306.0803226 * Constants.ARC_SECONDS_TO_RADIANS,
122 1.0947790 * Constants.ARC_SECONDS_TO_RADIANS,
123 0.0182273 * Constants.ARC_SECONDS_TO_RADIANS,
124 0.0000470 * Constants.ARC_SECONDS_TO_RADIANS,
125 -0.0000003 * Constants.ARC_SECONDS_TO_RADIANS);
126
127 public Transform getTransform(AbsoluteDate date) {
128 final double tc = IERSConventions.IERS_2003.evaluateTC(date);
129 final Rotation r1 = new Rotation(Vector3D.PLUS_K, zA.value(tc), RotationConvention.VECTOR_OPERATOR);
130 final Rotation r2 = new Rotation(Vector3D.PLUS_J, -thetaA.value(tc), RotationConvention.VECTOR_OPERATOR);
131 final Rotation r3 = new Rotation(Vector3D.PLUS_K, zetaA.value(tc), RotationConvention.VECTOR_OPERATOR);
132 return new Transform(date, r1.compose(r2.compose(r3,
133 RotationConvention.VECTOR_OPERATOR),
134 RotationConvention.VECTOR_OPERATOR));
135 }
136
137 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
138 throw new UnsupportedOperationException("never called in this test");
139 }
140
141 };
142
143 MODProvider modProvider = new MODProvider(IERSConventions.IERS_2003,
144 DataContext.getDefault().getTimeScales());
145
146 for (double dt = -Constants.JULIAN_CENTURY; dt < Constants.JULIAN_CENTURY; dt += 50 * Constants.JULIAN_DAY) {
147 AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
148 Transform t = new Transform(date,
149 modProvider.getTransform(date).getInverse(),
150 eulerBasedProvider.getTransform(date));
151 Assert.assertEquals(0, t.getRotation().getAngle(), 6.6e-13);
152 }
153
154 }
155
156 @Test
157 public void testAASReferenceLEO() {
158
159
160
161
162
163 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 04, 06),
164 new TimeComponents(07, 51, 28.386009),
165 TimeScalesFactory.getUTC());
166
167 Transform tt = FramesFactory.getGCRF().getTransformTo(FramesFactory.getMOD(IERSConventions.IERS_1996), t0);
168
169 PVCoordinates pvGCRFiau76 =
170 new PVCoordinates(new Vector3D(5102508.9579, 6123011.4007, 6378136.9282),
171 new Vector3D(-4743.220157, 790.536497, 5533.755727));
172 double norm = pvGCRFiau76.getPosition().getNorm();
173
174
175 PVCoordinates pvMODiau76Wcorr =
176 new PVCoordinates(new Vector3D(5094028.3745, 6127870.8164, 6380248.5164),
177 new Vector3D(-4746.263052, 786.014045, 5531.790562));
178
179 checkPV(pvMODiau76Wcorr, tt.transformPVCoordinates(pvGCRFiau76), 9e-12 * norm, 7.3e-7);
180
181 Transform tf = FramesFactory.getEME2000().getTransformTo(FramesFactory.getMOD(false), t0);
182
183 PVCoordinates pvJ2000iau76 =
184 new PVCoordinates(new Vector3D(5102509.6000, 6123011.5200, 6378136.3000),
185 new Vector3D(-4743.219600, 790.536600, 5533.756190));
186
187 PVCoordinates pvMODiau76 =
188 new PVCoordinates(new Vector3D(5094029.0167, 6127870.9363, 6380247.8885),
189 new Vector3D(-4746.262495, 786.014149, 5531.791025));
190 checkPV(pvMODiau76, tf.transformPVCoordinates(pvJ2000iau76), 9e-12 * norm, 3.1e-7);
191
192 }
193
194 @Test
195 public void testAASReferenceGEO() {
196
197
198
199
200
201 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 06, 01),
202 TimeComponents.H00,
203 TimeScalesFactory.getUTC());
204
205 Transform tt = FramesFactory.getGCRF().getTransformTo(FramesFactory.getMOD(IERSConventions.IERS_1996), t0);
206
207 PVCoordinates pvGCRFiau76 =
208 new PVCoordinates(new Vector3D(-40588150.3649, -11462167.0282, 27143.2028),
209 new Vector3D(834.787457, -2958.305691, -1.172994));
210 double norm = pvGCRFiau76.getPosition().getNorm();
211
212
213 PVCoordinates pvMODiau76Wcorr =
214 new PVCoordinates(new Vector3D(-40576822.6395, -11502231.5015, 9733.7842),
215 new Vector3D(837.708020, -2957.480117, -0.814253));
216 checkPV(pvMODiau76Wcorr, tt.transformPVCoordinates(pvGCRFiau76), 9e-12 * norm, 6.9e-7);
217
218 Transform tf = FramesFactory.getEME2000().getTransformTo(FramesFactory.getMOD(false), t0);
219
220 PVCoordinates pvJ2000iau76 =
221 new PVCoordinates(new Vector3D(-40588150.3620, -11462167.0280, 27147.6490),
222 new Vector3D(834.787457, -2958.305691, -1.173016));
223
224 PVCoordinates pvMODiau76 =
225 new PVCoordinates(new Vector3D(-40576822.6385, -11502231.5013, 9738.2304),
226 new Vector3D(837.708020, -2957.480118, -0.814275));
227 checkPV(pvMODiau76, tf.transformPVCoordinates(pvJ2000iau76), 9e-12 * norm, 6.9e-7);
228
229 }
230
231 @Test
232 public void testSofaPmat76() {
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 AbsoluteDate date = new AbsoluteDate(2004, 2, 14, TimeScalesFactory.getUTC());
272 Frame mod = FramesFactory.getFrame(Predefined.MOD_CONVENTIONS_1996);
273 Frame gcrf = FramesFactory.getFrame(Predefined.GCRF);
274 checkRotation(new double[][] {
275 { 0.9999994956729996165, -0.00092111268696996330928, -0.00040025637336518803469 },
276 { 0.00092111268696944094067, 0.99999957577560194544, -1.843419633938077413e-07 },
277 { 0.00040025637336639019806, -1.8433935312187383064e-07, 0.99999991989739756004 }
278
279 }, gcrf.getTransformTo(mod, date), 9e-12);
280
281 }
282
283 @Test
284 public void testSofaBp00() {
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326 AbsoluteDate date = new AbsoluteDate(2004, 2, 14, TimeScalesFactory.getUTC());
327 Frame mod = FramesFactory.getFrame(Predefined.MOD_CONVENTIONS_2003);
328 Frame gcrf = FramesFactory.getFrame(Predefined.GCRF);
329 checkRotation(new double[][] {
330 { 0.99999949570013624278, -0.00092112855376512230675, -0.00040015204695196122638 },
331 { 0.00092112856903123034591, 0.99999957576097886491, -1.4614501776464880046e-07 },
332 { 0.00040015201181019732432, -2.2244653837776004327e-07, 0.99999991993915571253 }
333
334 }, gcrf.getTransformTo(mod, date), 4.0e-16);
335
336 }
337
338 @Test
339 public void testSofaBp06() {
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381 AbsoluteDate date = new AbsoluteDate(2004, 2, 14, TimeScalesFactory.getUTC());
382 Frame mod = FramesFactory.getFrame(Predefined.MOD_CONVENTIONS_2010);
383 Frame gcrf = FramesFactory.getFrame(Predefined.GCRF);
384 checkRotation(new double[][] {
385 { 0.99999949570032919954, -0.00092112833995494939818, -0.00040015205699952106997 },
386 { 0.00092112835526181411488, 0.9999995757611759295, -1.4604312753574433259e-07 },
387 { 0.00040015202176394668336, -2.2254835219115420841e-07, 0.99999991993915182675 }
388
389 }, gcrf.getTransformTo(mod, date), 1.1e-12);
390
391 }
392
393 @Test
394 public void testMOD1976vs2006() {
395
396 final Frame mod1976 = FramesFactory.getMOD(IERSConventions.IERS_1996);
397 final Frame mod2006 = FramesFactory.getMOD(IERSConventions.IERS_2010);
398 for (double dt = 0; dt < 10 * Constants.JULIAN_YEAR; dt += 10 * Constants.JULIAN_DAY) {
399 AbsoluteDate date = new AbsoluteDate(AbsoluteDate.J2000_EPOCH, dt);
400 double delta = mod1976.getTransformTo(mod2006, date).getRotation().getAngle();
401
402 Assert.assertEquals(0.0, delta, 2.0e-7);
403 }
404 }
405
406 @Test
407 public void testMOD2000vs2006() {
408
409 final Frame mod2000 = FramesFactory.getMOD(IERSConventions.IERS_2003);
410 final Frame mod2006 = FramesFactory.getMOD(IERSConventions.IERS_2010);
411 for (double dt = 0; dt < 10 * Constants.JULIAN_YEAR; dt += 10 * Constants.JULIAN_DAY) {
412 AbsoluteDate date = new AbsoluteDate(AbsoluteDate.J2000_EPOCH, dt);
413 double delta = mod2000.getTransformTo(mod2006, date).getRotation().getAngle();
414
415 Assert.assertEquals(0.0, delta, 7.2e-10);
416 }
417 }
418
419 @Test
420 public void testSerialization() throws IOException, ClassNotFoundException {
421 MODProvider provider = new MODProvider(IERSConventions.IERS_2010,
422 DataContext.getDefault().getTimeScales());
423
424 ByteArrayOutputStream bos = new ByteArrayOutputStream();
425 ObjectOutputStream oos = new ObjectOutputStream(bos);
426 oos.writeObject(provider);
427
428 Assert.assertTrue(bos.size() > 150);
429 Assert.assertTrue(bos.size() < 250);
430
431 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
432 ObjectInputStream ois = new ObjectInputStream(bis);
433 MODProvider deserialized = (MODProvider) ois.readObject();
434 for (double dt = 0; dt < Constants.JULIAN_DAY; dt += 3600) {
435 AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
436 Transform expectedIdentity = new Transform(date,
437 provider.getTransform(date).getInverse(),
438 deserialized.getTransform(date));
439 Assert.assertEquals(0.0, expectedIdentity.getTranslation().getNorm(), 1.0e-15);
440 Assert.assertEquals(0.0, expectedIdentity.getRotation().getAngle(), 1.0e-15);
441 }
442
443 }
444
445 @Before
446 public void setUp() {
447 Utils.setDataRoot("compressed-data");
448 }
449
450 private void checkPV(PVCoordinates reference,
451 PVCoordinates result,
452 double positionThreshold,
453 double velocityThreshold) {
454
455 Vector3D dP = result.getPosition().subtract(reference.getPosition());
456 Vector3D dV = result.getVelocity().subtract(reference.getVelocity());
457 Assert.assertEquals(0, dP.getNorm(), positionThreshold);
458 Assert.assertEquals(0, dV.getNorm(), velocityThreshold);
459 }
460
461 private void checkRotation(double[][] reference, Transform t, double epsilon) {
462 double[][] mat = t.getRotation().getMatrix();
463 for (int i = 0; i < 3; ++i) {
464 for (int j = 0; j < 3; ++j) {
465 Assert.assertEquals(reference[i][j], mat[i][j], epsilon);
466 }
467 }
468 }
469
470 }