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.hamcrest.MatcherAssert;
20 import org.hipparchus.complex.Complex;
21 import org.hipparchus.complex.ComplexField;
22 import org.hipparchus.geometry.euclidean.threed.Rotation;
23 import org.hipparchus.geometry.euclidean.threed.Vector3D;
24 import org.hipparchus.util.FastMath;
25 import org.hipparchus.util.Precision;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.api.BeforeEach;
28 import org.junit.jupiter.api.Test;
29 import org.orekit.OrekitMatchers;
30 import org.orekit.Utils;
31 import org.orekit.data.DataContext;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.DateComponents;
34 import org.orekit.time.FieldAbsoluteDate;
35 import org.orekit.time.TimeComponents;
36 import org.orekit.time.TimeScale;
37 import org.orekit.time.TimeScalesFactory;
38 import org.orekit.utils.AngularCoordinates;
39 import org.orekit.utils.IERSConventions;
40 import org.orekit.utils.PVCoordinates;
41
42 import java.util.ArrayList;
43 import java.util.List;
44 import java.util.concurrent.Callable;
45 import java.util.concurrent.ExecutionException;
46 import java.util.concurrent.Executors;
47 import java.util.concurrent.Future;
48
49
50
51
52
53
54 public class TIRFProviderTest {
55
56 @Test
57 public void testAASReferenceLEO() {
58
59
60
61
62
63
64 Utils.setLoaders(IERSConventions.IERS_2010,
65 Utils.buildEOPList(IERSConventions.IERS_2010, ITRFVersion.ITRF_2008, new double[][] {
66 { 53098, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
67 { 53099, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
68 { 53100, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
69 { 53101, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
70 { 53102, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
71 { 53103, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
72 { 53104, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 },
73 { 53105, -0.4399619, 0.0015563, -0.140682, 0.333309, Double.NaN, Double.NaN, -0.000199, -0.000252 }
74 }));
75 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 4, 6),
76 new TimeComponents(7, 51, 28.386009),
77 TimeScalesFactory.getUTC());
78
79
80 Frame itrfA = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
81 PVCoordinates pvITRF =
82 new PVCoordinates(new Vector3D(-1033479.3830, 7901295.2754, 6380356.5958),
83 new Vector3D(-3225.636520, -2872.451450, 5531.924446));
84
85
86 Frame tirf = FramesFactory.getTIRF(IERSConventions.IERS_2010);
87 PVCoordinates pvTIRF =
88 new PVCoordinates(new Vector3D(-1033475.0312, 7901305.5856, 6380344.5328),
89 new Vector3D(-3225.632747, -2872.442511, 5531.931288));
90 checkPV(pvTIRF,
91 itrfA.getTransformTo(tirf, t0).transformPVCoordinates(pvITRF),
92 6.379e-5, 3.78e-7);
93 checkP(pvTIRF.getPosition(),
94 itrfA.getStaticTransformTo(tirf, t0).transformPosition(pvITRF.getPosition()),
95 6.379e-5);
96
97 Frame cirf = FramesFactory.getCIRF(IERSConventions.IERS_2010, true);
98 PVCoordinates pvCIRF =
99 new PVCoordinates(new Vector3D(5100018.4047, 6122786.3648, 6380344.5328),
100 new Vector3D(-4745.380330, 790.341453, 5531.931288));
101 checkPV(pvCIRF,
102 tirf.getTransformTo(cirf, t0).transformPVCoordinates(pvTIRF),
103 8.59e-3, 4.65e-6);
104 checkP(pvCIRF.getPosition(),
105 tirf.getStaticTransformTo(cirf, t0).transformPosition(pvTIRF.getPosition()),
106 8.59e-3);
107
108 }
109
110 @Test
111 public void testAASReferenceGEO() {
112
113
114
115
116
117 Utils.setLoaders(IERSConventions.IERS_2010,
118 Utils.buildEOPList(IERSConventions.IERS_2010, ITRFVersion.ITRF_2008, new double[][] {
119 { 53153, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
120 { 53154, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
121 { 53155, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
122 { 53156, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
123 { 53157, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
124 { 53158, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
125 { 53159, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 },
126 { 53160, -0.4709050, 0.0000000, -0.083853, 0.467217, Double.NaN, Double.NaN, -0.000199, -0.000252 }
127 }));
128
129 AbsoluteDate t0 = new AbsoluteDate(new DateComponents(2004, 6, 1),
130 TimeComponents.H00,
131 TimeScalesFactory.getUTC());
132
133
134 Frame itrfA = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
135 PVCoordinates pvITRF =
136 new PVCoordinates(new Vector3D(24796919.2915, -34115870.9234, 10226.0621),
137 new Vector3D(-0.979178, -1.476538, -0.928776));
138
139 Frame tirf = FramesFactory.getTIRF(IERSConventions.IERS_2010);
140 PVCoordinates pvTIRF =
141 new PVCoordinates(new Vector3D(24796919.2953, -34115870.9004, 10293.2583),
142 new Vector3D(-0.979178, -1.476540, -0.928772));
143 checkPV(pvTIRF,
144 itrfA.getTransformTo(tirf, t0).transformPVCoordinates(pvITRF),
145 5.697e-5, 4.69e-7);
146 checkP(pvTIRF.getPosition(),
147 itrfA.getStaticTransformTo(tirf, t0).transformPosition(pvITRF.getPosition()),
148 5.697e-5);
149
150 Frame cirf = FramesFactory.getCIRF(IERSConventions.IERS_2010, true);
151 PVCoordinates pvCIRF =
152 new PVCoordinates(new Vector3D(-40588158.1236, -11462167.0709, 10293.2583),
153 new Vector3D(834.787843, -2958.305669, -0.928772));
154 checkPV(pvCIRF,
155 tirf.getTransformTo(cirf, t0).transformPVCoordinates(pvTIRF),
156 0.0505, 3.60e-6);
157 checkP(pvCIRF.getPosition(),
158 tirf.getStaticTransformTo(cirf, t0).transformPosition(pvTIRF.getPosition()),
159 0.0505);
160
161 }
162
163
164 @Test
165 public void testContinuousDuringLeap() {
166
167 Utils.setDataRoot("regular-data");
168 Frame tirf = FramesFactory.getTIRF(IERSConventions.IERS_2010, true);
169 Frame cirf = FramesFactory.getCIRF(IERSConventions.IERS_2010, true);
170 TimeScale utc = TimeScalesFactory.getUTC();
171 AbsoluteDate dateA = new AbsoluteDate(2005, 12, 31, 23, 59, 0.0, utc);
172 AbsoluteDate dateB = new AbsoluteDate(2006, 1, 1, 0, 1, 0.0, utc);
173 double dt = 0.5;
174 double expected = dt * 2 * FastMath.PI / (23 * 3600 + 56 * 60 + 4.1);
175 double tol = expected * 1e-6;
176 Rotation previous = cirf.getTransformTo(tirf, dateA.shiftedBy(-dt)).getRotation();
177
178
179 for (AbsoluteDate d = dateA; d.compareTo(dateB) < 0; d = d.shiftedBy(dt)) {
180 Rotation actual = cirf.getTransformTo(tirf, d).getRotation();
181 Assertions.assertEquals(expected,
182 Rotation.distance(previous, actual),
183 tol, "At " + d.toString(utc));
184 Assertions.assertEquals(expected,
185 Rotation.distance(
186 previous,
187 cirf.getStaticTransformTo(tirf, d).getRotation()),
188 tol, "At " + d.toString(utc));
189 previous = actual;
190 }
191 }
192
193
194
195
196 @Test
197 public void testConcurrentGetTransform()
198 throws InterruptedException, ExecutionException {
199
200
201 final EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, false);
202 final TimeScale ut1 = DataContext.getDefault().getTimeScales().getUT1(eopHistory);
203 final TIRFProvider tirf = new TIRFProvider(eopHistory, ut1);
204
205 final AbsoluteDate start = new AbsoluteDate("2009-09-19T23:59:45.000", TimeScalesFactory.getUTC());
206
207 final double timeStep = 300;
208
209 final int nJobs = 24;
210
211 final int nPerJob = 1000;
212
213 final double absTol = Precision.EPSILON;
214
215 final List<Transform> expecteds = new ArrayList<>();
216 for (int j = 0; j < nPerJob; j++) {
217 final AbsoluteDate date = start.shiftedBy(timeStep * j);
218
219 final Transform expected = tirf.getTransform(date);
220
221 expecteds.add(expected);
222 }
223
224
225 final List<Callable<Boolean>> jobs = new ArrayList<>();
226 for (int i = 0; i < nJobs; i++) {
227 jobs.add(() -> {
228 for (int j = 0; j < nPerJob; j++) {
229 final AbsoluteDate date = start.shiftedBy(timeStep * j);
230
231 final Transform actual = tirf.getTransform(date);
232
233 assertTransformEquals(expecteds.get(j), actual, absTol);
234 }
235 return true;
236 });
237 }
238
239
240 runConcurrentlyAndCheck(jobs, nJobs);
241 }
242
243
244
245
246
247
248
249
250
251 private static void runConcurrentlyAndCheck(List<Callable<Boolean>> jobs, int threads)
252 throws InterruptedException, ExecutionException {
253
254
255 final List<Future<Boolean>> futures = Executors.newFixedThreadPool(threads).invokeAll(jobs);
256
257
258 for (Future<Boolean> future : futures) {
259 Assertions.assertEquals(true, future.get());
260 }
261
262 }
263
264
265
266
267 private static void assertTransformEquals(Transform expected, Transform actual, double absTol) {
268 final AngularCoordinates expectedAngular = expected.getAngular();
269 final AngularCoordinates actualAngular = actual.getAngular();
270 final Rotation expectedRotation = expectedAngular.getRotation();
271 final Rotation actualRotation = actualAngular.getRotation();
272 final PVCoordinates expectedPV = expected.getCartesian();
273 final PVCoordinates actualPV = actual.getCartesian();
274
275
276 Assertions.assertEquals(Rotation.distance(actualRotation, expectedRotation), 0, absTol);
277 Assertions.assertEquals(expectedAngular.getRotationRate(), actualAngular.getRotationRate());
278 Assertions.assertEquals(expectedPV.getPosition(), actualPV.getPosition());
279 Assertions.assertEquals(expectedPV.getVelocity(), actualPV.getVelocity());
280 }
281
282 @Test
283 void testGetKinematicTransform() {
284
285 final EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, false);
286 final TimeScale ut1 = DataContext.getDefault().getTimeScales().getUT1(eopHistory);
287 final TIRFProvider provider = new TIRFProvider(eopHistory, ut1);
288 final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
289
290 final KinematicTransform kinematicTransform = provider.getKinematicTransform(date);
291
292 final Transform transform = provider.getTransform(date);
293 Assertions.assertEquals(date, kinematicTransform.getDate());
294 Assertions.assertEquals(transform.getCartesian().getPosition(), kinematicTransform.getTranslation());
295 Assertions.assertEquals(transform.getCartesian().getVelocity(), kinematicTransform.getVelocity());
296 Assertions.assertEquals(0., Rotation.distance(transform.getRotation(), kinematicTransform.getRotation()));
297 Assertions.assertEquals(transform.getRotationRate(), kinematicTransform.getRotationRate());
298 }
299
300 @Test
301 void testFieldGetKinematicTransform() {
302
303 final EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, false);
304 final TimeScale ut1 = DataContext.getDefault().getTimeScales().getUT1(eopHistory);
305 final TIRFProvider provider = new TIRFProvider(eopHistory, ut1);
306 final ComplexField field = ComplexField.getInstance();
307 final FieldAbsoluteDate<Complex> date = FieldAbsoluteDate.getArbitraryEpoch(field);
308
309 final FieldKinematicTransform<Complex> fieldKinematicTransform = provider.getKinematicTransform(date);
310
311 final KinematicTransform kinematicTransform = provider.getKinematicTransform(date.toAbsoluteDate());
312 Assertions.assertEquals(kinematicTransform.getDate(), fieldKinematicTransform.getDate());
313 Assertions.assertEquals(kinematicTransform.getTranslation(), fieldKinematicTransform.getTranslation().toVector3D());
314 Assertions.assertEquals(kinematicTransform.getVelocity(), fieldKinematicTransform.getVelocity().toVector3D());
315 Assertions.assertEquals(0., Rotation.distance(kinematicTransform.getRotation(),
316 fieldKinematicTransform.getRotation().toRotation()), 1e-15);
317 Assertions.assertEquals(kinematicTransform.getRotationRate(), fieldKinematicTransform.getRotationRate().toVector3D());
318 }
319
320 @Test
321 void testFieldGetStaticTransform() {
322
323 final EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, false);
324 final TimeScale ut1 = DataContext.getDefault().getTimeScales().getUT1(eopHistory);
325 final TIRFProvider provider = new TIRFProvider(eopHistory, ut1);
326 final ComplexField field = ComplexField.getInstance();
327 final FieldAbsoluteDate<Complex> date = FieldAbsoluteDate.getArbitraryEpoch(field);
328
329 final FieldStaticTransform<Complex> fieldStaticTransform = provider.getStaticTransform(date);
330
331 final StaticTransform staticTransform = provider.getStaticTransform(date.toAbsoluteDate());
332 Assertions.assertEquals(staticTransform.getDate(), fieldStaticTransform.getDate());
333 Assertions.assertEquals(staticTransform.getTranslation(), fieldStaticTransform.getTranslation().toVector3D());
334 Assertions.assertEquals(0., Rotation.distance(staticTransform.getRotation(),
335 fieldStaticTransform.getRotation().toRotation()), 1e-15);
336
337 }
338
339 @BeforeEach
340 public void setUp() {
341 Utils.setDataRoot("compressed-data");
342 }
343
344 private void checkPV(PVCoordinates reference, PVCoordinates result,
345 double expectedPositionError, double expectedVelocityError) {
346
347 Vector3D dP = result.getPosition().subtract(reference.getPosition());
348 Vector3D dV = result.getVelocity().subtract(reference.getVelocity());
349 Assertions.assertEquals(expectedPositionError, dP.getNorm(), 0.01 * expectedPositionError);
350 Assertions.assertEquals(expectedVelocityError, dV.getNorm(), 0.01 * expectedVelocityError);
351 }
352
353 private void checkP(Vector3D position,
354 Vector3D transformPosition,
355 double tol) {
356 MatcherAssert.assertThat(
357 transformPosition,
358 OrekitMatchers.vectorCloseTo(position, tol));
359 }
360
361 }