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.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26
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.hipparchus.util.FastMath;
31 import org.junit.Assert;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.orekit.Utils;
35 import org.orekit.data.DataContext;
36 import org.orekit.time.AbsoluteDate;
37 import org.orekit.time.DateComponents;
38 import org.orekit.time.TimeComponents;
39 import org.orekit.time.TimeScalesFactory;
40 import org.orekit.utils.AngularDerivativesFilter;
41 import org.orekit.utils.CartesianDerivativesFilter;
42 import org.orekit.utils.Constants;
43 import org.orekit.utils.IERSConventions;
44 import org.orekit.utils.OrekitConfiguration;
45 import org.orekit.utils.PVCoordinates;
46
47
48 public class TODProviderTest {
49
50 @Test
51 public void testRotationRate() {
52 TransformProvider provider =
53 new InterpolatingTransformProvider(new TODProvider(IERSConventions.IERS_1996, null, DataContext.getDefault().getTimeScales()),
54 CartesianDerivativesFilter.USE_PVA,
55 AngularDerivativesFilter.USE_R,
56 3, 1.0, 5, Constants.JULIAN_DAY, 100.0);
57 AbsoluteDate tMin = new AbsoluteDate(2035, 3, 2, 15, 58, 59, TimeScalesFactory.getUTC());
58 double minRate = provider.getTransform(tMin).getRotationRate().getNorm();
59 Assert.assertEquals(6.4e-14, minRate, 1.0e-15);
60 AbsoluteDate tMax = new AbsoluteDate(2043, 12, 16, 14, 18, 9, TimeScalesFactory.getUTC());
61 double maxRate = provider.getTransform(tMax).getRotationRate().getNorm();
62 Assert.assertEquals(1.4e-11, maxRate, 1.0e-12);
63 }
64
65 @Test
66 public void testAASReferenceLEO() {
67
68
69
70
71
72 Utils.setLoaders(IERSConventions.IERS_1996,
73 Utils.buildEOPList(IERSConventions.IERS_1996, ITRFVersion.ITRF_2008, new double[][] {
74 { 53098, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
75 { 53099, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
76 { 53100, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
77 { 53101, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
78 { 53102, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
79 { 53103, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
80 { 53104, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
81 { 53105, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN }
82 }));
83 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 04, 06),
84 new TimeComponents(07, 51, 28.386009),
85 TimeScalesFactory.getUTC());
86
87 Transform tt = FramesFactory.getMOD(IERSConventions.IERS_1996).
88 getTransformTo(FramesFactory.getTOD(IERSConventions.IERS_1996, true), t0);
89 Transform ff = FramesFactory.getMOD(false).getTransformTo(FramesFactory.getTOD(false), t0);
90
91
92 PVCoordinates pvTODiau76 =
93 new PVCoordinates(new Vector3D(5094514.7804, 6127366.4612, 6380344.5328),
94 new Vector3D(-4746.088567, 786.077222, 5531.931288));
95
96 PVCoordinates pvMODiau76WithoutNutCorr =
97 new PVCoordinates(new Vector3D(5094029.0167, 6127870.9363, 6380247.8885),
98 new Vector3D(-4746.262495, 786.014149, 5531.791025));
99
100 PVCoordinates pvMODiau76 =
101 new PVCoordinates(new Vector3D(5094028.3745, 6127870.8164, 6380248.5164),
102 new Vector3D(-4746.263052, 786.014045, 5531.790562));
103
104
105
106 final double dDeltaPsi =
107 FramesFactory.getEOPHistory(IERSConventions.IERS_1996, true).getEquinoxNutationCorrection(t0)[0];
108 final double epsilonA = IERSConventions.IERS_1996.getMeanObliquityFunction().value(t0);
109 final Transform fix =
110 new Transform(t0, new Rotation(Vector3D.PLUS_K,
111 dDeltaPsi * FastMath.cos(epsilonA),
112 RotationConvention.FRAME_TRANSFORM));
113
114 checkPV(pvTODiau76, fix.transformPVCoordinates(tt.transformPVCoordinates(pvMODiau76)), 1.13e-3, 5.3e-5);
115 checkPV(pvTODiau76, ff.transformPVCoordinates(pvMODiau76WithoutNutCorr), 1.07e-3, 5.3e-5);
116
117 }
118
119 @Test
120 public void testAASReferenceGEO() {
121
122
123
124
125
126 Utils.setLoaders(IERSConventions.IERS_1996,
127 Utils.buildEOPList(IERSConventions.IERS_1996, ITRFVersion.ITRF_2008, new double[][] {
128 { 53153, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
129 { 53154, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
130 { 53155, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
131 { 53156, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
132 { 53157, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
133 { 53158, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
134 { 53159, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
135 { 53160, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN }
136 }));
137 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 06, 01),
138 TimeComponents.H00,
139 TimeScalesFactory.getUTC());
140
141 Transform tt = FramesFactory.getMOD(IERSConventions.IERS_1996).
142 getTransformTo(FramesFactory.getTOD(IERSConventions.IERS_1996, true), t0);
143 Transform ff = FramesFactory.getMOD(false).getTransformTo(FramesFactory.getTOD(false), t0);
144
145
146 PVCoordinates pvTODiau76 =
147 new PVCoordinates(new Vector3D(-40577427.7501, -11500096.1306, 10293.2583),
148 new Vector3D(837.552338, -2957.524176, -0.928772));
149
150 PVCoordinates pvMODiau76WithoutNutCorr =
151 new PVCoordinates(new Vector3D(-40576822.6385, -11502231.5013, 9738.2304),
152 new Vector3D(837.708020, -2957.480118, -0.814275));
153
154
155 PVCoordinates pvMODiau76 =
156 new PVCoordinates(new Vector3D(-40576822.6395, -11502231.5015, 9733.7842),
157 new Vector3D(837.708020, -2957.480117, -0.814253));
158
159
160
161
162 final double dDeltaPsi =
163 FramesFactory.getEOPHistory(IERSConventions.IERS_1996, true).getEquinoxNutationCorrection(t0)[0];
164 final double epsilonA = IERSConventions.IERS_1996.getMeanObliquityFunction().value(t0);
165 final Transform fix =
166 new Transform(t0, new Rotation(Vector3D.PLUS_K,
167 dDeltaPsi * FastMath.cos(epsilonA),
168 RotationConvention.FRAME_TRANSFORM));
169
170 checkPV(pvTODiau76, fix.transformPVCoordinates(tt.transformPVCoordinates(pvMODiau76)), 4.86e-4, 6.2e-5);
171 checkPV(pvTODiau76, ff.transformPVCoordinates(pvMODiau76WithoutNutCorr), 4.87e-4, 6.31e-5);
172
173 }
174
175 @Test
176 public void testInterpolationAccuracyWithEOP() throws FileNotFoundException {
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_1996, false);
213 TransformProvider nonInterpolating = new TODProvider(IERSConventions.IERS_1996, eopHistory, DataContext.getDefault().getTimeScales());
214 final TransformProvider interpolating =
215 new InterpolatingTransformProvider(nonInterpolating,
216 CartesianDerivativesFilter.USE_PVA,
217 AngularDerivativesFilter.USE_R,
218 6, Constants.JULIAN_DAY / 24,
219 OrekitConfiguration.getCacheSlotsNumber(),
220 Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY);
221
222
223 AbsoluteDate start = new AbsoluteDate(2002, 11, 11, 0, 0, 0.0, TimeScalesFactory.getTAI());
224 AbsoluteDate end = new AbsoluteDate(2002, 11, 15, 6, 0, 0.0, TimeScalesFactory.getTAI());
225 double maxError = 0.0;
226 for (AbsoluteDate date = start; date.compareTo(end) < 0; date = date.shiftedBy(60)) {
227 final Transform transform =
228 new Transform(date,
229 interpolating.getTransform(date),
230 nonInterpolating.getTransform(date).getInverse());
231 final double error = transform.getRotation().getAngle();
232 maxError = FastMath.max(maxError, error);
233 }
234
235 Assert.assertTrue(maxError < 7e-12);
236
237 }
238
239 @Test
240 public void testInterpolationAccuracyWithoutEOP() throws FileNotFoundException {
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 TransformProvider nonInterpolating = new TODProvider(IERSConventions.IERS_1996, null, DataContext.getDefault().getTimeScales());
268 final TransformProvider interpolating =
269 new InterpolatingTransformProvider(nonInterpolating,
270 CartesianDerivativesFilter.USE_PVA,
271 AngularDerivativesFilter.USE_R,
272 6, Constants.JULIAN_DAY / 8,
273 OrekitConfiguration.getCacheSlotsNumber(),
274 Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY);
275
276
277 AbsoluteDate start = new AbsoluteDate(2002, 11, 11, 0, 0, 0.0, TimeScalesFactory.getTAI());
278 AbsoluteDate end = new AbsoluteDate(2002, 11, 15, 6, 0, 0.0, TimeScalesFactory.getTAI());
279 double maxError = 0.0;
280 for (AbsoluteDate date = start; date.compareTo(end) < 0; date = date.shiftedBy(60)) {
281 final Transform transform =
282 new Transform(date,
283 interpolating.getTransform(date),
284 nonInterpolating.getTransform(date).getInverse());
285 final double error = transform.getRotation().getAngle();
286 maxError = FastMath.max(maxError, error);
287 }
288
289 Assert.assertTrue(maxError < 4.0e-15);
290
291 }
292
293 @Test
294 public void testSofaPnm80() {
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
327
328
329
330
331 AbsoluteDate date = new AbsoluteDate(2004, 2, 14, TimeScalesFactory.getUTC());
332 Frame tod = FramesFactory.getFrame(Predefined.TOD_WITHOUT_EOP_CORRECTIONS);
333 checkRotation(new double[][] {
334 { 0.99999999859236310407, 4.8681019508684473249e-05, 2.1105264333587349032e-05 },
335 { -4.8680343021901595118e-05, 0.99999999830143670998, -3.205231683600651138e-05 },
336 { -2.1106824637199909505e-05, 3.2051289379386727063e-05, 0.99999999926360838565 }
337
338 }, tod.getParent().getTransformTo(tod, date), 5.0e-11);
339 checkRotation(new double[][] {
340 { 0.99999954755358466674, -0.00087243169070689370777, -0.00037915111913272635073 },
341 { 0.0008724195377896877112, 0.99999961892302935418, -3.2217171614061089913e-05 },
342 { 0.00037917908192846747854, 3.1886378193416632805e-05, 0.99999992760323874741 }
343
344 }, tod.getParent().getParent().getTransformTo(tod, date), 5.0e-11);
345
346 }
347
348 @Test
349 public void testTOD1976vs2006() {
350
351 final Frame tod1976 = FramesFactory.getTOD(IERSConventions.IERS_1996, true);
352 final Frame tod2006 = FramesFactory.getTOD(IERSConventions.IERS_2010, true);
353 for (double dt = 0; dt < 2 * Constants.JULIAN_YEAR; dt += 100 * Constants.JULIAN_DAY) {
354 AbsoluteDate date = new AbsoluteDate(AbsoluteDate.J2000_EPOCH, dt);
355 double delta = tod1976.getTransformTo(tod2006, date).getRotation().getAngle();
356
357
358 Assert.assertEquals(0.0, delta, 3.2e-7);
359 }
360
361 }
362
363 @Test
364 public void testTOD2000vs2006() {
365
366 final Frame tod2000 = FramesFactory.getTOD(IERSConventions.IERS_2003, true);
367 final Frame tod2006 = FramesFactory.getTOD(IERSConventions.IERS_2010, true);
368 for (double dt = 0; dt < 2 * Constants.JULIAN_YEAR; dt += 100 * Constants.JULIAN_DAY) {
369 AbsoluteDate date = new AbsoluteDate(AbsoluteDate.J2000_EPOCH, dt);
370 double delta = tod2000.getTransformTo(tod2006, date).getRotation().getAngle();
371
372
373 Assert.assertEquals(0.0, delta, 1.5e-10);
374 }
375
376 }
377
378 @Test
379 public void testSerialization() throws IOException, ClassNotFoundException {
380 TODProvider provider = new TODProvider(IERSConventions.IERS_2010,
381 FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true),
382 DataContext.getDefault().getTimeScales());
383
384 ByteArrayOutputStream bos = new ByteArrayOutputStream();
385 ObjectOutputStream oos = new ObjectOutputStream(bos);
386 oos.writeObject(provider);
387
388 Assert.assertTrue(bos.size() > 295000);
389 Assert.assertTrue(bos.size() < 300000);
390
391 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
392 ObjectInputStream ois = new ObjectInputStream(bis);
393 TODProvider deserialized = (TODProvider) ois.readObject();
394 for (int i = 0; i < FastMath.min(100, provider.getEOPHistory().getEntries().size()); ++i) {
395 AbsoluteDate date = provider.getEOPHistory().getEntries().get(i).getDate();
396 Transform expectedIdentity = new Transform(date,
397 provider.getTransform(date).getInverse(),
398 deserialized.getTransform(date));
399 Assert.assertEquals(0.0, expectedIdentity.getTranslation().getNorm(), 1.0e-15);
400 Assert.assertEquals(0.0, expectedIdentity.getRotation().getAngle(), 1.0e-15);
401 }
402
403 }
404
405 @Before
406 public void setUp() {
407 Utils.setDataRoot("compressed-data");
408 }
409
410 private void checkPV(PVCoordinates reference, PVCoordinates result,
411 double expectedPositionError, double expectedVelocityError) {
412
413 Vector3D dP = result.getPosition().subtract(reference.getPosition());
414 Vector3D dV = result.getVelocity().subtract(reference.getVelocity());
415 Assert.assertEquals(expectedPositionError, dP.getNorm(), 0.01 * expectedPositionError);
416 Assert.assertEquals(expectedVelocityError, dV.getNorm(), 0.01 * expectedVelocityError);
417 }
418
419 private void checkRotation(double[][] reference, Transform t, double epsilon) {
420 double[][] mat = t.getRotation().getMatrix();
421 for (int i = 0; i < 3; ++i) {
422 for (int j = 0; j < 3; ++j) {
423 Assert.assertEquals(reference[i][j], mat[i][j], epsilon);
424 }
425 }
426 }
427
428 }