1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.frames;
18
19 import org.hipparchus.geometry.euclidean.threed.Rotation;
20 import org.hipparchus.geometry.euclidean.threed.Vector3D;
21 import org.hipparchus.util.FastMath;
22 import org.hipparchus.util.MathUtils;
23 import org.junit.jupiter.api.Assertions;
24 import org.junit.jupiter.api.BeforeEach;
25 import org.junit.jupiter.api.Test;
26 import org.orekit.Utils;
27 import org.orekit.time.AbsoluteDate;
28 import org.orekit.time.DateComponents;
29 import org.orekit.time.TTScale;
30 import org.orekit.time.TimeComponents;
31 import org.orekit.time.TimeScale;
32 import org.orekit.time.TimeScalesFactory;
33 import org.orekit.time.UT1Scale;
34 import org.orekit.utils.Constants;
35 import org.orekit.utils.IERSConventions;
36 import org.orekit.utils.PVCoordinates;
37
38 public class ITRFProviderTest {
39
40 @Test
41 public void testTidalEffects() {
42
43 final Frame itrfWith = FramesFactory.getITRF(IERSConventions.IERS_2010, false);
44 final Frame itrfWithout = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
45 final AbsoluteDate date0 = new AbsoluteDate(2007, 10, 20, TimeScalesFactory.getUTC());
46
47 double minCorrection = Double.POSITIVE_INFINITY;
48 double maxCorrection = Double.NEGATIVE_INFINITY;
49 for (double dt = 0; dt < 3 * Constants.JULIAN_DAY; dt += 60) {
50 final AbsoluteDate date = date0.shiftedBy(dt);
51 final Transform t = itrfWith.getTransformTo(itrfWithout, date);
52 Assertions.assertEquals(0, t.getTranslation().getNorm(), 1.0e-15);
53 final double milliarcSeconds = FastMath.toDegrees(t.getRotation().getAngle()) * 3600000.0;
54 minCorrection = FastMath.min(minCorrection, milliarcSeconds);
55 maxCorrection = FastMath.max(maxCorrection, milliarcSeconds);
56 }
57
58 Assertions.assertEquals(0.064, minCorrection, 0.001);
59 Assertions.assertEquals(0.613, maxCorrection, 0.001);
60
61 }
62
63 @Test
64 public void testAASReferenceLEO() {
65
66
67
68
69
70
71 Utils.setLoaders(IERSConventions.IERS_2010,
72 Utils.buildEOPList(IERSConventions.IERS_2010, ITRFVersion.ITRF_2008, new double[][] {
73 { 53098, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
74 { 53099, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
75 { 53100, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
76 { 53101, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
77 { 53102, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
78 { 53103, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
79 { 53104, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
80 { 53105, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 }
81 }));
82 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 04, 06),
83 new TimeComponents(07, 51, 28.386009),
84 TimeScalesFactory.getUTC());
85
86
87 Frame itrfA = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
88 PVCoordinates pvITRF =
89 new PVCoordinates(new Vector3D(-1033479.3830, 7901295.2754, 6380356.5958),
90 new Vector3D(-3225.636520, -2872.451450, 5531.924446));
91
92
93 PVCoordinates pvGcrfIau2000A =
94 new PVCoordinates(new Vector3D(5102508.9579, 6123011.4038, 6378136.9252),
95 new Vector3D(-4743.220156, 790.536497, 5533.755728));
96 checkPV(pvGcrfIau2000A,
97 itrfA.getTransformTo(FramesFactory.getGCRF(), t0).transformPVCoordinates(pvITRF),
98 0.0192, 2.15e-5);
99
100 PVCoordinates pvEME2000EqA =
101 new PVCoordinates(new Vector3D(5102509.0383, 6123011.9758, 6378136.3118),
102 new Vector3D(-4743.219766, 790.536344, 5533.756084));
103 checkPV(pvEME2000EqA,
104 itrfA.getTransformTo(FramesFactory.getEME2000(), t0).transformPVCoordinates(pvITRF),
105 0.0191, 2.13e-5);
106
107 }
108
109 @Test
110 public void testAASReferenceGEO() {
111
112
113
114
115
116 Utils.setLoaders(IERSConventions.IERS_2010,
117 Utils.buildEOPList(IERSConventions.IERS_2010, ITRFVersion.ITRF_2008, new double[][] {
118 { 53153, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
119 { 53154, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
120 { 53155, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
121 { 53156, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
122 { 53157, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
123 { 53158, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
124 { 53159, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
125 { 53160, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 }
126 }));
127
128 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 06, 01),
129 TimeComponents.H00,
130 TimeScalesFactory.getUTC());
131
132
133 Frame itrfA = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
134 PVCoordinates pvITRF =
135 new PVCoordinates(new Vector3D(24796919.2915, -34115870.9234, 10226.0621),
136 new Vector3D(-0.979178, -1.476538, -0.928776));
137
138 PVCoordinates pvGCRFiau2000A =
139 new PVCoordinates(new Vector3D(-40588150.3617, -11462167.0397, 27143.1974),
140 new Vector3D(834.787458, -2958.305691, -1.172993));
141 checkPV(pvGCRFiau2000A,
142 itrfA.getTransformTo(FramesFactory.getGCRF(), t0).transformPVCoordinates(pvITRF),
143 0.0806, 1.03e-4);
144
145 PVCoordinates pvEME2000EqA =
146 new PVCoordinates(new Vector3D(-40588149.5482, -11462169.9118, 27146.8462),
147 new Vector3D(834.787667, -2958.305632, -1.172963));
148 checkPV(pvEME2000EqA,
149 itrfA.getTransformTo(FramesFactory.getEME2000(), t0).transformPVCoordinates(pvITRF),
150 0.0806, 1.04e-4);
151
152 }
153
154 @Test
155 public void testAASReferenceGEODX0DY0() {
156
157
158
159
160
161 Utils.setLoaders(IERSConventions.IERS_2010,
162 Utils.buildEOPList(IERSConventions.IERS_2010, ITRFVersion.ITRF_2008, new double[][] {
163 { 53153, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 },
164 { 53154, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 },
165 { 53155, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 },
166 { 53156, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 },
167 { 53157, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 },
168 { 53158, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 },
169 { 53159, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 },
170 { 53160, -0.4709050, 0.0000000, -0.083853, 0.467217, 0.0, 0.0, 0.0, 0.0 }
171 }));
172
173 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 06, 01),
174 TimeComponents.H00,
175 TimeScalesFactory.getUTC());
176
177
178 Frame itrfA = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
179 PVCoordinates pvITRF =
180 new PVCoordinates(new Vector3D(24796919.2915, -34115870.9234, 10226.0621),
181 new Vector3D(-0.979178, -1.476538, -0.928776));
182
183 PVCoordinates pvGCRFdx0dy0 =
184 new PVCoordinates(new Vector3D(-40588150.3643, -11462167.0302, 27143.1979),
185 new Vector3D(834.787457, -2958.305691, -1.172993));
186 checkPV(pvGCRFdx0dy0,
187 itrfA.getTransformTo(FramesFactory.getGCRF(), t0).transformPVCoordinates(pvITRF),
188 0.0505, 1.06e-4);
189
190 PVCoordinates pvEME2000EqA =
191 new PVCoordinates(new Vector3D(-40588149.5482, -11462169.9118, 27146.8462),
192 new Vector3D(834.787667, -2958.305632, -1.172963));
193 checkPV(pvEME2000EqA,
194 itrfA.getTransformTo(FramesFactory.getEME2000(), t0).transformPVCoordinates(pvITRF),
195 0.0603, 1.07e-4);
196
197 }
198
199 @Test
200 public void testSofaCookbook() {
201
202
203
204
205
206
207
208
209
210
211
212
213
214 Utils.setLoaders(IERSConventions.IERS_2010,
215 Utils.buildEOPList(IERSConventions.IERS_2010, ITRFVersion.ITRF_2008, new double[][] {
216 { 54192, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 },
217 { 54193, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 },
218 { 54194, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 },
219 { 54195, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 },
220 { 54196, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 },
221 { 54197, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 },
222 { 54198, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 },
223 { 54199, -0.072073685, 1.4020, 0.0349282, 0.4833163, -Double.NaN, Double.NaN, 0.0001750, -0.0002259 }
224 }));
225
226 EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
227
228 TimeScale utc = TimeScalesFactory.getUTC();
229 TTScale tt = TimeScalesFactory.getTT();
230 UT1Scale ut1 = TimeScalesFactory.getUT1(eopHistory);
231 Frame gcrf = FramesFactory.getGCRF();
232 Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
233 Frame gtod = itrf.getParent();
234 Frame tod = gtod.getParent();
235
236
237 AbsoluteDate date = new AbsoluteDate(new DateComponents(2007, 4, 5), TimeComponents.H12, utc);
238 Assertions.assertEquals(0.50075444444444,
239 date.getComponents(tt).getTime().getSecondsInUTCDay() / Constants.JULIAN_DAY,
240 5.0e-15);
241 Assertions.assertEquals(0.499999165813831,
242 date.getComponents(ut1).getTime().getSecondsInUTCDay() / Constants.JULIAN_DAY,
243 1.0e-15);
244
245
246 double era = IERSConventions.IERS_2010.getEarthOrientationAngleFunction(ut1).value(date);
247 Assertions.assertEquals(13.318492966097 * 3600 * 1.0e6,
248 radToMicroAS(MathUtils.normalizeAngle(era, 0)),
249 0.0022);
250
251
252 Rotation refNPB = new Rotation(new double[][] {
253 { +0.999999746339445, -0.000000005138721, -0.000712264730182 },
254 { -0.000000026475329, +0.999999999014975, -0.000044385242666 },
255 { +0.000712264729708, +0.000044385250265, +0.999999745354420 }
256 }, 1.0e-13);
257 Rotation npb = gcrf.getTransformTo(tod, date).getRotation();
258 Assertions.assertEquals(0.0, radToMicroAS(Rotation.distance(refNPB, npb)), 0.31);
259
260
261 Rotation refWithoutPolarMotion = new Rotation(new double[][] {
262 { +0.973104317573104, +0.230363826247808, -0.000703332818915 },
263 { -0.230363798804281, +0.973104570735550, +0.000120888549767 },
264 { +0.000712264729708, +0.000044385250265, +0.999999745354420 }
265 }, 1.0e-13);
266 Rotation withoutPM = gcrf.getTransformTo(gtod, date).getRotation();
267 Assertions.assertEquals(0.0, radToMicroAS(Rotation.distance(refWithoutPolarMotion, withoutPM)), 0.31);
268
269
270 Rotation refWithPolarMotion = new Rotation(new double[][] {
271 { +0.973104317697512, +0.230363826239227, -0.000703163482268 },
272 { -0.230363800456136, +0.973104570632777, +0.000118545366806 },
273 { +0.000711560162777, +0.000046626403835, +0.999999745754024 }
274 }, 1.0e-13);
275 Rotation withPM = gcrf.getTransformTo(itrf, date).getRotation();
276 Assertions.assertEquals(0.0, radToMicroAS(Rotation.distance(refWithPolarMotion, withPM)), 0.31);
277
278 }
279
280 @BeforeEach
281 public void setUp() {
282 Utils.setDataRoot("compressed-data");
283 }
284
285 private void checkPV(PVCoordinates reference, PVCoordinates result,
286 double expectedPositionError, double expectedVelocityError) {
287
288 Vector3D dP = result.getPosition().subtract(reference.getPosition());
289 Vector3D dV = result.getVelocity().subtract(reference.getVelocity());
290 Assertions.assertEquals(expectedPositionError, dP.getNorm(), 0.01 * expectedPositionError);
291 Assertions.assertEquals(expectedVelocityError, dV.getNorm(), 0.01 * expectedVelocityError);
292 }
293
294 double radToMicroAS(double deltaRad) {
295 return deltaRad * 1.0e6 / Constants.ARC_SECONDS_TO_RADIANS;
296 }
297
298 }