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 org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.geometry.euclidean.threed.Rotation;
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.hipparchus.random.RandomGenerator;
24 import org.hipparchus.random.Well19937a;
25 import org.hipparchus.util.Decimal64;
26 import org.hipparchus.util.Decimal64Field;
27 import org.hipparchus.util.FastMath;
28 import org.junit.Assert;
29 import org.junit.Test;
30 import org.orekit.time.AbsoluteDate;
31 import org.orekit.time.FieldAbsoluteDate;
32 import org.orekit.utils.PVCoordinates;
33
34 public class TransformProviderUtilTest {
35
36 @Test
37 public void testIdentity() {
38 RandomGenerator random = new Well19937a(0x87c3a5c51fb0235el);
39 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
40 checkNoTransform(TransformProviderUtils.IDENTITY_PROVIDER.getTransform(date), random);
41 }
42
43 @Test
44 public void testIdentityField() {
45 RandomGenerator random = new Well19937a(0x7086a8e4ad1265b0l);
46 final FieldAbsoluteDate<Decimal64> date = new FieldAbsoluteDate<>(Decimal64Field.getInstance(),
47 AbsoluteDate.J2000_EPOCH);
48 checkNoTransform(TransformProviderUtils.IDENTITY_PROVIDER.getTransform(date), random);
49 }
50
51 @Test
52 public void testReverse() {
53 RandomGenerator random = new Well19937a(0xba49d4909717ec6cl);
54 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
55 for (int i = 0; i < 20; ++i) {
56 TransformProvider tp = constantProvider(random);
57 TransformProvider reversed = TransformProviderUtils.getReversedProvider(tp);
58 checkNoTransform(new Transform(date, tp.getTransform(date), reversed.getTransform(date)), random);
59 checkNoTransform(new Transform(date, reversed.getTransform(date), tp.getTransform(date)), random);
60 }
61 }
62
63 @Test
64 public void testReverseField() {
65 RandomGenerator random = new Well19937a(0xd74443b3079403e7l);
66 final FieldAbsoluteDate<Decimal64> date = new FieldAbsoluteDate<>(Decimal64Field.getInstance(),
67 AbsoluteDate.J2000_EPOCH);
68 for (int i = 0; i < 20; ++i) {
69 TransformProvider tp = constantProvider(random);
70 TransformProvider reversed = TransformProviderUtils.getReversedProvider(tp);
71 checkNoTransform(new FieldTransform<>(date, tp.getTransform(date), reversed.getTransform(date)), random);
72 checkNoTransform(new FieldTransform<>(date, reversed.getTransform(date), tp.getTransform(date)), random);
73 }
74 }
75
76 @Test
77 public void testCombine() {
78 RandomGenerator random = new Well19937a(0x6e3b2c793680e7e3l);
79 final AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
80 for (int i = 0; i < 20; ++i) {
81 TransformProvider first = constantProvider(random);
82 TransformProvider second = constantProvider(random);
83 TransformProvider combined = TransformProviderUtils.getCombinedProvider(first, second);
84 checkNoTransform(new Transform(date,
85 new Transform(date, first.getTransform(date), second.getTransform(date)).getInverse(),
86 combined.getTransform(date)),
87 random);
88 }
89 }
90
91 @Test
92 public void testCombineField() {
93 RandomGenerator random = new Well19937a(0x1f8bf20bfa4b54eal);
94 final FieldAbsoluteDate<Decimal64> date = new FieldAbsoluteDate<>(Decimal64Field.getInstance(),
95 AbsoluteDate.J2000_EPOCH);
96 for (int i = 0; i < 20; ++i) {
97 TransformProvider first = constantProvider(random);
98 TransformProvider second = constantProvider(random);
99 TransformProvider combined = TransformProviderUtils.getCombinedProvider(first, second);
100 checkNoTransform(new FieldTransform<>(date,
101 new FieldTransform<>(date, first.getTransform(date), second.getTransform(date)).getInverse(),
102 combined.getTransform(date)),
103 random);
104 }
105 }
106
107 private TransformProvider constantProvider(RandomGenerator random) {
108 final Transform combined = randomTransform(random);
109 return new TransformProvider() {
110 private static final long serialVersionUID = 20180330L;
111 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(FieldAbsoluteDate<T> date)
112 {
113 return new FieldTransform<>(date.getField(), combined);
114 }
115 public Transform getTransform(AbsoluteDate date)
116 {
117 return combined;
118 }
119 };
120 }
121
122 private Transform randomTransform(RandomGenerator random) {
123
124 Transform combined = Transform.IDENTITY;
125 for (int k = 0; k < 20; ++k) {
126 Transform t = random.nextBoolean() ?
127 new Transform(AbsoluteDate.J2000_EPOCH, randomVector(1.0e3, random), randomVector(1.0, random), randomVector(1.0e-3, random)) :
128 new Transform(AbsoluteDate.J2000_EPOCH, randomRotation(random), randomVector(0.01, random), randomVector(1.0e-4, random));
129 combined = new Transform(AbsoluteDate.J2000_EPOCH, combined, t);
130 }
131 return combined;
132 }
133
134 private Vector3D randomVector(double scale, RandomGenerator random) {
135 return new Vector3D(random.nextDouble() * scale,
136 random.nextDouble() * scale,
137 random.nextDouble() * scale);
138 }
139
140 private Rotation randomRotation(RandomGenerator random) {
141 double q0 = random.nextDouble() * 2 - 1;
142 double q1 = random.nextDouble() * 2 - 1;
143 double q2 = random.nextDouble() * 2 - 1;
144 double q3 = random.nextDouble() * 2 - 1;
145 double q = FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
146 return new Rotation(q0 / q, q1 / q, q2 / q, q3 / q, false);
147 }
148
149 private void checkNoTransform(FieldTransform<Decimal64> transform, RandomGenerator random) {
150 for (int i = 0; i < 100; ++i) {
151 Vector3D a = randomVector(1.0e3, random);
152 Vector3D tA = transform.transformVector(a).toVector3D();
153 Assert.assertEquals(0, a.subtract(tA).getNorm(), 1.0e-10 * a.getNorm());
154 Vector3D b = randomVector(1.0e3, random);
155 Vector3D tB = transform.transformPosition(b).toVector3D();
156 Assert.assertEquals(0, b.subtract(tB).getNorm(), 1.0e-10 * b.getNorm());
157 PVCoordinates pv = new PVCoordinates(randomVector(1.0e3, random), randomVector(1.0, random), randomVector(1.0e-3, random));
158 PVCoordinates tPv = transform.transformPVCoordinates(pv).toPVCoordinates();
159 checkVector(pv.getPosition(), tPv.getPosition(), 1.0e-10);
160 checkVector(pv.getVelocity(), tPv.getVelocity(), 3.0e-9);
161 checkVector(pv.getAcceleration(), tPv.getAcceleration(), 3.0e-9);
162 }
163 }
164
165 private void checkNoTransform(Transform transform, RandomGenerator random) {
166 for (int i = 0; i < 100; ++i) {
167 Vector3D a = randomVector(1.0e3, random);
168 Vector3D tA = transform.transformVector(a);
169 Assert.assertEquals(0, a.subtract(tA).getNorm(), 1.0e-10 * a.getNorm());
170 Vector3D b = randomVector(1.0e3, random);
171 Vector3D tB = transform.transformPosition(b);
172 Assert.assertEquals(0, b.subtract(tB).getNorm(), 1.0e-10 * b.getNorm());
173 PVCoordinates pv = new PVCoordinates(randomVector(1.0e3, random), randomVector(1.0, random), randomVector(1.0e-3, random));
174 PVCoordinates tPv = transform.transformPVCoordinates(pv);
175 checkVector(pv.getPosition(), tPv.getPosition(), 1.0e-10);
176 checkVector(pv.getVelocity(), tPv.getVelocity(), 3.0e-9);
177 checkVector(pv.getAcceleration(), tPv.getAcceleration(), 3.0e-9);
178 }
179 }
180
181 private void checkVector(Vector3D reference, Vector3D result, double relativeTolerance) {
182 double refNorm = reference.getNorm();
183 double resNorm = result.getNorm();
184 double tolerance = relativeTolerance * (1 + FastMath.max(refNorm, resNorm));
185 Assert.assertEquals("ref = " + reference + ", res = " + result + " -> " +
186 (Vector3D.distance(reference, result) / (1 + FastMath.max(refNorm, resNorm))),
187 0, Vector3D.distance(reference, result), tolerance);
188 }
189
190 }