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.RotationConvention;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.util.FastMath;
23 import org.hipparchus.util.MathUtils;
24 import org.junit.jupiter.api.Assertions;
25 import org.junit.jupiter.api.BeforeEach;
26 import org.junit.jupiter.api.Test;
27 import org.orekit.Utils;
28 import org.orekit.time.AbsoluteDate;
29 import org.orekit.time.DateComponents;
30 import org.orekit.time.TTScale;
31 import org.orekit.time.TimeComponents;
32 import org.orekit.time.TimeScale;
33 import org.orekit.time.TimeScalesFactory;
34 import org.orekit.time.UT1Scale;
35 import org.orekit.utils.Constants;
36 import org.orekit.utils.IERSConventions;
37 import org.orekit.utils.PVCoordinates;
38
39 import java.util.ArrayList;
40
41
42 public class ITRFEquinoxProviderTest {
43
44 @Test
45 public void testEquinoxVersusCIO() {
46 Frame itrfEquinox = FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true);
47 Frame itrfCIO = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
48 AbsoluteDate start = new AbsoluteDate(2011, 4, 10, TimeScalesFactory.getUTC());
49 AbsoluteDate end = new AbsoluteDate(2011, 7, 4, TimeScalesFactory.getUTC());
50 for (AbsoluteDate date = start; date.compareTo(end) < 0; date = date.shiftedBy(10000)) {
51 double angularOffset =
52 itrfEquinox.getTransformTo(itrfCIO, date).getRotation().getAngle();
53 Assertions.assertEquals(0, angularOffset / Constants.ARC_SECONDS_TO_RADIANS, 0.07);
54 }
55 }
56
57 @Test
58 public void testAASReferenceLEO() {
59
60
61
62
63
64 Utils.setLoaders(IERSConventions.IERS_1996,
65 Utils.buildEOPList(IERSConventions.IERS_1996, ITRFVersion.ITRF_2008, new double[][] {
66 { 53098, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
67 { 53099, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
68 { 53100, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
69 { 53101, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
70 { 53102, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
71 { 53103, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
72 { 53104, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN },
73 { 53105, -0.4399619, 0.0015563, -0.140682, 0.333309, -0.052195, -0.003875, Double.NaN, Double.NaN }
74 }));
75 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 04, 06),
76 new TimeComponents(07, 51, 28.386009),
77 TimeScalesFactory.getUTC());
78
79
80 PVCoordinates pvITRF =
81 new PVCoordinates(new Vector3D(-1033479.3830, 7901295.2754, 6380356.5958),
82 new Vector3D(-3225.636520, -2872.451450, 5531.924446));
83
84
85 PVCoordinates pvGTOD =
86 new PVCoordinates(new Vector3D(-1033475.0313, 7901305.5856, 6380344.5328),
87 new Vector3D(-3225.632747, -2872.442511, 5531.931288));
88
89 Transform t = FramesFactory.getGTOD(IERSConventions.IERS_1996, true).
90 getTransformTo(FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true), t0);
91 checkPV(pvITRF, t.transformPVCoordinates(pvGTOD), 8.08e-5, 3.78e-7);
92
93 }
94
95 @Test
96 public void testAASReferenceGEO() {
97
98
99
100
101
102 Utils.setLoaders(IERSConventions.IERS_1996,
103 Utils.buildEOPList(IERSConventions.IERS_1996, ITRFVersion.ITRF_2008, new double[][] {
104 { 53153, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
105 { 53154, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
106 { 53155, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
107 { 53156, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
108 { 53157, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
109 { 53158, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
110 { 53159, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN },
111 { 53160, -0.4709050, 0.0000000, -0.083853, 0.467217, -0.053614, -0.004494, Double.NaN, Double.NaN }
112 }));
113 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 06, 01),
114 TimeComponents.H00,
115 TimeScalesFactory.getUTC());
116
117 Transform t = FramesFactory.getGTOD(IERSConventions.IERS_1996, true).
118 getTransformTo(FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true), t0);
119
120
121 PVCoordinates pvGTOD =
122 new PVCoordinates(new Vector3D(24796919.2956, -34115870.9001, 10293.2583),
123 new Vector3D(-0.979178, -1.476540, -0.928772));
124
125
126 PVCoordinates pvITRF =
127 new PVCoordinates(new Vector3D(24796919.2915, -34115870.9234, 10226.0621),
128 new Vector3D(-0.979178, -1.476538, -0.928776));
129
130 checkPV(pvITRF, t.transformPVCoordinates(pvGTOD), 3.954e-4, 4.69e-7);
131
132 }
133
134 @Test
135 public void testSofaCookbook() {
136
137
138
139
140
141
142
143
144
145
146
147
148
149 Utils.setLoaders(IERSConventions.IERS_1996,
150 Utils.buildEOPList(IERSConventions.IERS_1996, ITRFVersion.ITRF_2008, new double[][] {
151 { 54192, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN },
152 { 54193, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN },
153 { 54194, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN },
154 { 54195, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN },
155 { 54196, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN },
156 { 54197, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN },
157 { 54198, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN },
158 { 54199, -0.072073685, 1.4020, 0.0349282, 0.4833163, -0.0550666, -0.0063580, Double.NaN, Double.NaN }
159 }));
160
161 EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_1996, true);
162
163 TimeScale utc = TimeScalesFactory.getUTC();
164 TTScale tt = TimeScalesFactory.getTT();
165 UT1Scale ut1 = TimeScalesFactory.getUT1(eopHistory);
166 Frame gcrf = FramesFactory.getGCRF();
167 Frame itrf = FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true);
168 Frame gtod = itrf.getParent();
169 Frame tod = gtod.getParent();
170
171
172 AbsoluteDate date = new AbsoluteDate(new DateComponents(2007, 4, 5), TimeComponents.H12, utc);
173 Assertions.assertEquals(0.50075444444444,
174 date.getComponents(tt).getTime().getSecondsInUTCDay() / Constants.JULIAN_DAY,
175 5.0e-15);
176 Assertions.assertEquals(0.499999165813831,
177 date.getComponents(ut1).getTime().getSecondsInUTCDay() / Constants.JULIAN_DAY,
178 1.0e-15);
179
180
181 double gast = IERSConventions.IERS_1996.getGASTFunction(ut1, eopHistory).value(date);
182 Assertions.assertEquals(13.412402380740 * 3600 * 1.0e6,
183 radToMicroAS(MathUtils.normalizeAngle(gast, 0)),
184 25);
185
186
187 Rotation refNPB = new Rotation(new double[][] {
188 { +0.999998403176203, -0.001639032970562, -0.000712190961847 },
189 { +0.001639000942243, +0.999998655799521, -0.000045552846624 },
190 { +0.000712264667137, +0.000044385492226, +0.999999745354454 }
191 }, 1.0e-13);
192 Rotation npb = gcrf.getTransformTo(tod, date).getRotation();
193 Assertions.assertEquals(0.0, radToMicroAS(Rotation.distance(refNPB, npb)), 27.0);
194
195
196 Rotation refWithoutPolarMotion = new Rotation(new double[][] {
197 { +0.973104317592265, +0.230363826166883, -0.000703332813776 },
198 { -0.230363798723533, +0.973104570754697, +0.000120888299841 },
199 { +0.000712264667137, +0.000044385492226, +0.999999745354454 }
200 }, 1.0e-13);
201 Rotation withoutPM = gcrf.getTransformTo(gtod, date).getRotation();
202 Assertions.assertEquals(0.0, radToMicroAS(Rotation.distance(refWithoutPolarMotion, withoutPM)), 9);
203
204
205 Rotation refWithPolarMotion = new Rotation(new double[][] {
206 { +0.973104317712772, +0.230363826174782, -0.000703163477127 },
207 { -0.230363800391868, +0.973104570648022, +0.000118545116892 },
208 { +0.000711560100206, +0.000046626645796, +0.999999745754058 }
209 }, 1.0e-13);
210 Rotation withPM = gcrf.getTransformTo(itrf, date).getRotation();
211 Assertions.assertEquals(0.0, radToMicroAS(Rotation.distance(refWithPolarMotion, withPM)), 10);
212
213 }
214
215 @Test
216 public void testNROvsEquinoxRealEOP() {
217 Utils.setDataRoot("regular-data");
218 checkFrames(FramesFactory.getITRF(IERSConventions.IERS_2010, true),
219 FramesFactory.getITRFEquinox(IERSConventions.IERS_2010, true),
220 1.7);
221 }
222
223 @Test
224 public void testNROvsEquinoxNoEOP2010() {
225 Utils.setLoaders(IERSConventions.IERS_2010, new ArrayList<EOPEntry>());
226 checkFrames(FramesFactory.getITRF(IERSConventions.IERS_2010, true),
227 FramesFactory.getITRFEquinox(IERSConventions.IERS_2010, true),
228 1.7);
229 }
230
231 @Test
232 public void testNROvsEquinoxNoEOP2003() {
233 Utils.setLoaders(IERSConventions.IERS_2003, new ArrayList<EOPEntry>());
234 checkFrames(FramesFactory.getITRF(IERSConventions.IERS_2003, true),
235 FramesFactory.getITRFEquinox(IERSConventions.IERS_2003, true),
236 1.9);
237 }
238
239 @Test
240 public void testNROvsEquinoxNoEOP1996() {
241 Utils.setLoaders(IERSConventions.IERS_1996, new ArrayList<EOPEntry>());
242 checkFrames(FramesFactory.getITRF(IERSConventions.IERS_1996, true),
243 FramesFactory.getITRFEquinox(IERSConventions.IERS_1996, true),
244 100);
245 }
246
247 private void checkFrames(Frame frame1, Frame frame2, double toleranceMicroAS)
248 {
249 AbsoluteDate t0 = new AbsoluteDate(2005, 5, 30, TimeScalesFactory.getUTC());
250 for (double dt = 0; dt < Constants.JULIAN_YEAR; dt += Constants.JULIAN_DAY / 4) {
251 AbsoluteDate date = t0.shiftedBy(dt);
252 Transform t = FramesFactory.getNonInterpolatingTransform(frame1, frame2, date);
253 Vector3D a = t.getRotation().getAxis(RotationConvention.VECTOR_OPERATOR);
254 double delta = FastMath.copySign(radToMicroAS(t.getRotation().getAngle()), a.getZ());
255 Assertions.assertEquals(0.0, delta, toleranceMicroAS);
256 }
257 }
258
259 @BeforeEach
260 public void setUp() {
261 Utils.setDataRoot("rapid-data-columns");
262 }
263
264 private void checkPV(PVCoordinates reference, PVCoordinates result,
265 double expectedPositionError, double expectedVelocityError) {
266
267 Vector3D dP = result.getPosition().subtract(reference.getPosition());
268 Vector3D dV = result.getVelocity().subtract(reference.getVelocity());
269 Assertions.assertEquals(expectedPositionError, dP.getNorm(), 0.01 * expectedPositionError);
270 Assertions.assertEquals(expectedVelocityError, dV.getNorm(), 0.01 * expectedVelocityError);
271 }
272
273 double radToMicroAS(double deltaRad) {
274 return deltaRad * 1.0e6 / Constants.ARC_SECONDS_TO_RADIANS;
275 }
276
277 }