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.CalculusFieldElement;
20 import org.hipparchus.complex.Complex;
21 import org.hipparchus.complex.ComplexField;
22 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23 import org.hipparchus.geometry.euclidean.threed.Rotation;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.hipparchus.random.RandomGenerator;
26 import org.hipparchus.random.Well19937a;
27 import org.hipparchus.util.Binary64;
28 import org.hipparchus.util.Binary64Field;
29 import org.hipparchus.util.FastMath;
30 import org.junit.jupiter.api.Assertions;
31 import org.junit.jupiter.api.Test;
32 import org.mockito.Mockito;
33 import org.orekit.time.AbsoluteDate;
34 import org.orekit.time.FieldAbsoluteDate;
35 import org.orekit.utils.FieldPVCoordinates;
36 import org.orekit.utils.PVCoordinates;
37
38 public class TransformProviderUtilTest {
39
40 @Test
41 void testGetCombinedProviderGetKinematicTransform() {
42
43 final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
44 final TransformProvider mockedProvider1 = Mockito.mock(TransformProvider.class);
45 final TransformProvider mockedProvider2 = Mockito.mock(TransformProvider.class);
46 final KinematicTransform kinematicTransform = KinematicTransform.of(date, new PVCoordinates(Vector3D.MINUS_I,
47 Vector3D.PLUS_J));
48 Mockito.when(mockedProvider1.getKinematicTransform(date)).thenReturn(kinematicTransform);
49 Mockito.when(mockedProvider2.getKinematicTransform(date)).thenReturn(kinematicTransform.getInverse());
50 final TransformProvider combinedProvider = TransformProviderUtils.getCombinedProvider(mockedProvider1,
51 mockedProvider2);
52
53 final KinematicTransform actualTransform = combinedProvider.getKinematicTransform(date);
54
55 final KinematicTransform expectedTransform = KinematicTransform.getIdentity();
56 Assertions.assertEquals(expectedTransform.getDate(), actualTransform.getDate());
57 Assertions.assertEquals(expectedTransform.getTranslation(), actualTransform.getTranslation());
58 Assertions.assertEquals(expectedTransform.getVelocity(), actualTransform.getVelocity());
59 }
60
61 @Test
62 void testGetCombinedProviderFieldGetKinematicTransform() {
63
64 final ComplexField field = ComplexField.getInstance();
65 final FieldAbsoluteDate<Complex> date = new FieldAbsoluteDate<>(field, AbsoluteDate.ARBITRARY_EPOCH);
66 final TransformProvider mockedProvider1 = Mockito.mock(TransformProvider.class);
67 final TransformProvider mockedProvider2 = Mockito.mock(TransformProvider.class);
68 final FieldKinematicTransform<Complex> kinematicTransform = FieldKinematicTransform.of(date,
69 new FieldPVCoordinates<>(field, new PVCoordinates(Vector3D.MINUS_I, Vector3D.PLUS_J)));
70 Mockito.when(mockedProvider1.getKinematicTransform(date)).thenReturn(kinematicTransform);
71 Mockito.when(mockedProvider2.getKinematicTransform(date)).thenReturn(kinematicTransform.getInverse());
72 final TransformProvider combinedProvider = TransformProviderUtils.getCombinedProvider(mockedProvider1,
73 mockedProvider2);
74
75 final FieldKinematicTransform<Complex> actualTransform = combinedProvider.getKinematicTransform(date);
76
77 final FieldKinematicTransform<Complex> expectedTransform = FieldKinematicTransform.getIdentity(field);
78 Assertions.assertEquals(expectedTransform.getDate(), actualTransform.getDate());
79 Assertions.assertEquals(expectedTransform.getTranslation().toVector3D(),
80 actualTransform.getTranslation().toVector3D());
81 Assertions.assertEquals(expectedTransform.getVelocity().toVector3D(),
82 actualTransform.getVelocity().toVector3D());
83 }
84
85 @Test
86 void testGetCombinedProviderFieldGetStaticTransform() {
87
88 final ComplexField field = ComplexField.getInstance();
89 final FieldAbsoluteDate<Complex> date = new FieldAbsoluteDate<>(field, AbsoluteDate.ARBITRARY_EPOCH);
90 final TransformProvider mockedProvider1 = Mockito.mock(TransformProvider.class);
91 final TransformProvider mockedProvider2 = Mockito.mock(TransformProvider.class);
92 final FieldStaticTransform<Complex> staticTransform = FieldStaticTransform.of(date,
93 new FieldVector3D<>(field, Vector3D.PLUS_J));
94 Mockito.when(mockedProvider1.getStaticTransform(date)).thenReturn(staticTransform);
95 Mockito.when(mockedProvider2.getStaticTransform(date)).thenReturn(staticTransform.getInverse());
96 final TransformProvider combinedProvider = TransformProviderUtils.getCombinedProvider(mockedProvider1,
97 mockedProvider2);
98
99 final FieldStaticTransform<Complex> actualTransform = combinedProvider.getStaticTransform(date);
100
101 final FieldStaticTransform<Complex> expectedTransform = FieldStaticTransform.getIdentity(field);
102 Assertions.assertEquals(expectedTransform.getDate(), actualTransform.getDate());
103 Assertions.assertEquals(expectedTransform.getTranslation().toVector3D(),
104 actualTransform.getTranslation().toVector3D());
105 }
106
107 @Test
108 void testGetReversedProviderGetKinematicTransform() {
109
110 final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
111 final TransformProvider mockedProvider = Mockito.mock(TransformProvider.class);
112 final TransformProvider reversedProvider = TransformProviderUtils.getReversedProvider(mockedProvider);
113 final KinematicTransform expectedTransform = Mockito.mock(KinematicTransform.class);
114 final KinematicTransform mockedTransform = Mockito.mock(KinematicTransform.class);
115 Mockito.when(mockedTransform.getInverse()).thenReturn(expectedTransform);
116 Mockito.when(mockedProvider.getKinematicTransform(date)).thenReturn(mockedTransform);
117
118 final KinematicTransform actualTransform = reversedProvider.getKinematicTransform(date);
119
120 Assertions.assertEquals(expectedTransform, actualTransform);
121 }
122
123 @Test
124 @SuppressWarnings("unchecked")
125 void testGetReversedProviderFieldGetKinematicTransform() {
126
127 final FieldAbsoluteDate<Complex> date = new FieldAbsoluteDate<>(ComplexField.getInstance(),
128 AbsoluteDate.ARBITRARY_EPOCH);
129 final TransformProvider mockedProvider = Mockito.mock(TransformProvider.class);
130 final TransformProvider reversedProvider = TransformProviderUtils.getReversedProvider(mockedProvider);
131 final FieldKinematicTransform<Complex> expectedTransform = Mockito.mock(FieldKinematicTransform.class);
132 final FieldKinematicTransform<Complex> mockedTransform = Mockito.mock(FieldKinematicTransform.class);
133 Mockito.when(mockedTransform.getInverse()).thenReturn(expectedTransform);
134 Mockito.when(mockedProvider.getKinematicTransform(date)).thenReturn(mockedTransform);
135
136 final FieldKinematicTransform<Complex> actualTransform = reversedProvider.getKinematicTransform(date);
137
138 Assertions.assertEquals(expectedTransform, actualTransform);
139 }
140
141 @Test
142 @SuppressWarnings("unchecked")
143 void testGetReversedProviderFieldGetStaticTransform() {
144
145 final FieldAbsoluteDate<Complex> date = new FieldAbsoluteDate<>(ComplexField.getInstance(),
146 AbsoluteDate.ARBITRARY_EPOCH);
147 final TransformProvider mockedProvider = Mockito.mock(TransformProvider.class);
148 final TransformProvider reversedProvider = TransformProviderUtils.getReversedProvider(mockedProvider);
149 final FieldStaticTransform<Complex> expectedTransform = Mockito.mock(FieldStaticTransform.class);
150 final FieldStaticTransform<Complex> mockedTransform = Mockito.mock(FieldStaticTransform.class);
151 Mockito.when(mockedTransform.getInverse()).thenReturn(expectedTransform);
152 Mockito.when(mockedProvider.getStaticTransform(date)).thenReturn(mockedTransform);
153
154 final FieldStaticTransform<Complex> actualTransform = reversedProvider.getStaticTransform(date);
155
156 Assertions.assertEquals(expectedTransform, actualTransform);
157 }
158
159 @Test
160 void testStaticIdentity() {
161
162
163
164 final StaticTransform staticTransform = TransformProviderUtils.IDENTITY_PROVIDER.getStaticTransform(Mockito.mock(AbsoluteDate.class));
165
166 Assertions.assertEquals(Rotation.IDENTITY, staticTransform.getRotation());
167 Assertions.assertEquals(Vector3D.ZERO, staticTransform.getTranslation());
168 }
169
170 @Test
171 void testFieldStaticIdentity() {
172
173 final FieldAbsoluteDate<Complex> fieldDate = new FieldAbsoluteDate<>(ComplexField.getInstance(), AbsoluteDate.BEIDOU_EPOCH);
174
175 final FieldStaticTransform<Complex> staticTransform = TransformProviderUtils.IDENTITY_PROVIDER.getStaticTransform(fieldDate);
176
177 Assertions.assertEquals(0., Rotation.distance(Rotation.IDENTITY, staticTransform.getRotation().toRotation()));
178 Assertions.assertEquals(Vector3D.ZERO, staticTransform.getTranslation().toVector3D());
179 }
180
181 @Test
182 public void testIdentity() {
183 RandomGenerator random = new Well19937a(0x87c3a5c51fb0235el);
184 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
185 checkNoTransform(TransformProviderUtils.IDENTITY_PROVIDER.getTransform(date), random);
186 }
187
188 @Test
189 public void testIdentityField() {
190 RandomGenerator random = new Well19937a(0x7086a8e4ad1265b0l);
191 final FieldAbsoluteDate<Binary64> date = new FieldAbsoluteDate<>(Binary64Field.getInstance(),
192 AbsoluteDate.J2000_EPOCH);
193 checkNoTransform(TransformProviderUtils.IDENTITY_PROVIDER.getTransform(date), random);
194 }
195
196 @Test
197 public void testReverse() {
198 RandomGenerator random = new Well19937a(0xba49d4909717ec6cl);
199 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
200 for (int i = 0; i < 20; ++i) {
201 TransformProvider tp = constantProvider(random);
202 TransformProvider reversed = TransformProviderUtils.getReversedProvider(tp);
203 checkNoTransform(new Transform(date, tp.getTransform(date), reversed.getTransform(date)), random);
204 checkNoTransform(new Transform(date, reversed.getTransform(date), tp.getTransform(date)), random);
205 }
206 }
207
208 @Test
209 public void testReverseField() {
210 RandomGenerator random = new Well19937a(0xd74443b3079403e7l);
211 final FieldAbsoluteDate<Binary64> date = new FieldAbsoluteDate<>(Binary64Field.getInstance(),
212 AbsoluteDate.J2000_EPOCH);
213 for (int i = 0; i < 20; ++i) {
214 TransformProvider tp = constantProvider(random);
215 TransformProvider reversed = TransformProviderUtils.getReversedProvider(tp);
216 checkNoTransform(new FieldTransform<>(date, tp.getTransform(date), reversed.getTransform(date)), random);
217 checkNoTransform(new FieldTransform<>(date, reversed.getTransform(date), tp.getTransform(date)), random);
218 }
219 }
220
221 @Test
222 public void testCombine() {
223 RandomGenerator random = new Well19937a(0x6e3b2c793680e7e3l);
224 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
225 for (int i = 0; i < 20; ++i) {
226 TransformProvider first = constantProvider(random);
227 TransformProvider second = constantProvider(random);
228 TransformProvider combined = TransformProviderUtils.getCombinedProvider(first, second);
229 checkNoTransform(new Transform(date,
230 new Transform(date, first.getTransform(date), second.getTransform(date)).getInverse(),
231 combined.getTransform(date)),
232 random);
233 }
234 }
235
236 @Test
237 public void testCombineField() {
238 RandomGenerator random = new Well19937a(0x1f8bf20bfa4b54eal);
239 final FieldAbsoluteDate<Binary64> date = new FieldAbsoluteDate<>(Binary64Field.getInstance(),
240 AbsoluteDate.J2000_EPOCH);
241 for (int i = 0; i < 20; ++i) {
242 TransformProvider first = constantProvider(random);
243 TransformProvider second = constantProvider(random);
244 TransformProvider combined = TransformProviderUtils.getCombinedProvider(first, second);
245 checkNoTransform(new FieldTransform<>(date,
246 new FieldTransform<>(date, first.getTransform(date), second.getTransform(date)).getInverse(),
247 combined.getTransform(date)),
248 random);
249 }
250 }
251
252 private TransformProvider constantProvider(RandomGenerator random) {
253 final Transform combined = randomTransform(random);
254 return new TransformProvider() {
255 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(FieldAbsoluteDate<T> date)
256 {
257 return new FieldTransform<>(date.getField(), combined);
258 }
259 public Transform getTransform(AbsoluteDate date)
260 {
261 return combined;
262 }
263 };
264 }
265
266 private Transform randomTransform(RandomGenerator random) {
267
268 Transform combined = Transform.IDENTITY;
269 for (int k = 0; k < 20; ++k) {
270 Transform t = random.nextBoolean() ?
271 new Transform(AbsoluteDate.J2000_EPOCH, randomVector(1.0e3, random), randomVector(1.0, random), randomVector(1.0e-3, random)) :
272 new Transform(AbsoluteDate.J2000_EPOCH, randomRotation(random), randomVector(0.01, random), randomVector(1.0e-4, random));
273 combined = new Transform(AbsoluteDate.J2000_EPOCH, combined, t);
274 }
275 return combined;
276 }
277
278 private Vector3D randomVector(double scale, RandomGenerator random) {
279 return new Vector3D(random.nextDouble() * scale,
280 random.nextDouble() * scale,
281 random.nextDouble() * scale);
282 }
283
284 private Rotation randomRotation(RandomGenerator random) {
285 double q0 = random.nextDouble() * 2 - 1;
286 double q1 = random.nextDouble() * 2 - 1;
287 double q2 = random.nextDouble() * 2 - 1;
288 double q3 = random.nextDouble() * 2 - 1;
289 double q = FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
290 return new Rotation(q0 / q, q1 / q, q2 / q, q3 / q, false);
291 }
292
293 private void checkNoTransform(FieldTransform<Binary64> transform, RandomGenerator random) {
294 for (int i = 0; i < 100; ++i) {
295 Vector3D a = randomVector(1.0e3, random);
296 Vector3D tA = transform.transformVector(a).toVector3D();
297 Assertions.assertEquals(0, a.subtract(tA).getNorm(), 1.0e-10 * a.getNorm());
298 Vector3D b = randomVector(1.0e3, random);
299 Vector3D tB = transform.transformPosition(b).toVector3D();
300 Assertions.assertEquals(0, b.subtract(tB).getNorm(), 1.0e-10 * b.getNorm());
301 PVCoordinates pv = new PVCoordinates(randomVector(1.0e3, random), randomVector(1.0, random), randomVector(1.0e-3, random));
302 PVCoordinates tPv = transform.transformPVCoordinates(pv).toPVCoordinates();
303 checkVector(pv.getPosition(), tPv.getPosition(), 1.0e-10);
304 checkVector(pv.getVelocity(), tPv.getVelocity(), 3.0e-9);
305 checkVector(pv.getAcceleration(), tPv.getAcceleration(), 3.0e-9);
306 }
307 }
308
309 private void checkNoTransform(Transform transform, RandomGenerator random) {
310 for (int i = 0; i < 100; ++i) {
311 Vector3D a = randomVector(1.0e3, random);
312 Vector3D tA = transform.transformVector(a);
313 Assertions.assertEquals(0, a.subtract(tA).getNorm(), 1.0e-10 * a.getNorm());
314 Vector3D b = randomVector(1.0e3, random);
315 Vector3D tB = transform.transformPosition(b);
316 Assertions.assertEquals(0, b.subtract(tB).getNorm(), 1.0e-10 * b.getNorm());
317 PVCoordinates pv = new PVCoordinates(randomVector(1.0e3, random), randomVector(1.0, random), randomVector(1.0e-3, random));
318 PVCoordinates tPv = transform.transformPVCoordinates(pv);
319 checkVector(pv.getPosition(), tPv.getPosition(), 1.0e-10);
320 checkVector(pv.getVelocity(), tPv.getVelocity(), 3.0e-9);
321 checkVector(pv.getAcceleration(), tPv.getAcceleration(), 3.0e-9);
322 }
323 }
324
325 private void checkVector(Vector3D reference, Vector3D result, double relativeTolerance) {
326 double refNorm = reference.getNorm();
327 double resNorm = result.getNorm();
328 double tolerance = relativeTolerance * (1 + FastMath.max(refNorm, resNorm));
329 Assertions.assertEquals(0, Vector3D.distance(reference, result), tolerance,"ref = " + reference + ", res = " + result + " -> " +
330 (Vector3D.distance(reference, result) / (1 + FastMath.max(refNorm, resNorm))));
331 }
332
333 }