1   /* Copyright 2002-2022 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.frames;
18  
19  import java.util.Random;
20  
21  import org.hipparchus.geometry.euclidean.threed.Rotation;
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.hipparchus.util.FastMath;
24  import org.junit.Assert;
25  import org.junit.Before;
26  import org.junit.Test;
27  import org.orekit.Utils;
28  import org.orekit.bodies.GeodeticPoint;
29  import org.orekit.bodies.OneAxisEllipsoid;
30  import org.orekit.time.AbsoluteDate;
31  import org.orekit.time.TimeScalesFactory;
32  import org.orekit.utils.Constants;
33  import org.orekit.utils.IERSConventions;
34  import org.orekit.utils.PVCoordinates;
35  
36  public class FrameTest {
37  
38      @Test
39      public void testSameFrameRoot() {
40          Random random = new Random(0x29448c7d58b95565l);
41          Frame  frame  = FramesFactory.getEME2000();
42          checkNoTransform(frame.getTransformTo(frame, new AbsoluteDate()), random);
43          Assert.assertTrue(frame.getDepth() > 0);
44          Assert.assertEquals(frame.getParent().getDepth() + 1, frame.getDepth());
45      }
46  
47      @Test
48      public void testSameFrameNoRoot() {
49          Random random = new Random(0xc6e88d0f53e29116l);
50          Transform t   = randomTransform(random);
51          Frame frame   = new Frame(FramesFactory.getEME2000(), t, null, true);
52          checkNoTransform(frame.getTransformTo(frame, new AbsoluteDate()), random);
53      }
54  
55      @Test
56      public void testSimilarFrames() {
57          Random random = new Random(0x1b868f67a83666e5l);
58          Transform t   = randomTransform(random);
59          Frame frame1  = new Frame(FramesFactory.getEME2000(), t, null, true);
60          Frame frame2  = new Frame(FramesFactory.getEME2000(), t, null, false);
61          checkNoTransform(frame1.getTransformTo(frame2, new AbsoluteDate()), random);
62      }
63  
64      @Test
65      public void testFromParent() {
66          Random random = new Random(0xb92fba1183fe11b8l);
67          Transform fromEME2000  = randomTransform(random);
68          Frame frame = new Frame(FramesFactory.getEME2000(), fromEME2000, null);
69          Transform toEME2000 = frame.getTransformTo(FramesFactory.getEME2000(), new AbsoluteDate());
70          checkNoTransform(new Transform(fromEME2000.getDate(), fromEME2000, toEME2000), random);
71      }
72  
73      @Test
74      public void testDecomposedTransform() {
75          Random random = new Random(0xb7d1a155e726da57l);
76          Transform t1  = randomTransform(random);
77          Transform t2  = randomTransform(random);
78          Transform t3  = randomTransform(random);
79          Frame frame1 =
80              new Frame(FramesFactory.getEME2000(),
81                        new Transform(t1.getDate(), new Transform(t1.getDate(), t1, t2), t3),
82                        null);
83          Frame frame2 =
84              new Frame(new Frame(new Frame(FramesFactory.getEME2000(), t1, null), t2, null), t3, null);
85          checkNoTransform(frame1.getTransformTo(frame2, new AbsoluteDate()), random);
86      }
87  
88      @Test
89      public void testFindCommon() {
90  
91          Random random = new Random(0xb7d1a155e726da57l);
92          Transform t1  = randomTransform(random);
93          Transform t2  = randomTransform(random);
94          Transform t3  = randomTransform(random);
95  
96          Frame R1 = new Frame(FramesFactory.getEME2000(), t1, "R1");
97          Frame R2 = new Frame(R1, t2, "R2");
98          Frame R3 = new Frame(R2, t3, "R3");
99          Assert.assertTrue(R1.getDepth() > 0);
100         Assert.assertEquals(R1.getDepth() + 1, R2.getDepth());
101         Assert.assertEquals(R2.getDepth() + 1, R3.getDepth());
102 
103         Transform T = R1.getTransformTo(R3, new AbsoluteDate());
104 
105         Transform S = new Transform(t2.getDate(), t2, t3);
106 
107         checkNoTransform(new Transform(T.getDate(), T, S.getInverse()) , random);
108 
109     }
110 
111     @Test
112     public void testDepthAndAncestor() {
113         Random random = new Random(0x01f8d3b944123044l);
114         Frame root = Frame.getRoot();
115 
116         Frame f1 = new Frame(root, randomTransform(random), "f1");
117         Frame f2 = new Frame(f1,   randomTransform(random), "f2");
118         Frame f3 = new Frame(f1,   randomTransform(random), "f3");
119         Frame f4 = new Frame(f2,   randomTransform(random), "f4");
120         Frame f5 = new Frame(f3,   randomTransform(random), "f5");
121         Frame f6 = new Frame(f5,   randomTransform(random), "f6");
122 
123         Assert.assertEquals(0, root.getDepth());
124         Assert.assertEquals(1, f1.getDepth());
125         Assert.assertEquals(2, f2.getDepth());
126         Assert.assertEquals(2, f3.getDepth());
127         Assert.assertEquals(3, f4.getDepth());
128         Assert.assertEquals(3, f5.getDepth());
129         Assert.assertEquals(4, f6.getDepth());
130 
131         Assert.assertTrue(root == f1.getAncestor(1));
132         Assert.assertTrue(root == f6.getAncestor(4));
133         Assert.assertTrue(f1   == f6.getAncestor(3));
134         Assert.assertTrue(f3   == f6.getAncestor(2));
135         Assert.assertTrue(f5   == f6.getAncestor(1));
136         Assert.assertTrue(f6   == f6.getAncestor(0));
137 
138         try {
139             f6.getAncestor(5);
140             Assert.fail("an exception should have been triggered");
141         } catch (IllegalArgumentException iae) {
142             // expected behavior
143         } catch (Exception e) {
144             Assert.fail("wrong exception caught: " + e.getClass().getName());
145         }
146 
147     }
148 
149     @Test
150     public void testIsChildOf() {
151         Random random = new Random(0xb7d1a155e726da78l);
152         Frame eme2000 = FramesFactory.getEME2000();
153 
154         Frame f1 = new Frame(eme2000, randomTransform(random), "f1");
155         Frame f2 = new Frame(f1     , randomTransform(random), "f2");
156         Frame f4 = new Frame(f2     , randomTransform(random), "f4");
157         Frame f5 = new Frame(f4     , randomTransform(random), "f5");
158         Frame f6 = new Frame(eme2000, randomTransform(random), "f6");
159         Frame f7 = new Frame(f6     , randomTransform(random), "f7");
160         Frame f8 = new Frame(f6     , randomTransform(random), "f8");
161         Frame f9 = new Frame(f7     , randomTransform(random), "f9");
162 
163         // check if the root frame can be an ancestor of another frame
164         Assert.assertEquals(false, eme2000.isChildOf(f5));
165 
166         // check if a frame which belongs to the same branch than the 2nd frame is a branch of it
167         Assert.assertEquals(true, f5.isChildOf(f1));
168 
169         // check if a random frame is the child of the root frame
170         Assert.assertEquals(true, f9.isChildOf(eme2000));
171 
172         // check that a frame is not its own child
173         Assert.assertEquals(false, f4.isChildOf(f4));
174 
175         // check if a frame which belongs to a different branch than the 2nd frame can be a child for it
176         Assert.assertEquals(false, f9.isChildOf(f5));
177 
178         // check if the root frame is not a child of itself
179         Assert.assertEquals(false, eme2000.isChildOf(eme2000));
180 
181         Assert.assertEquals(false, f9.isChildOf(f8));
182 
183     }
184 
185     @Test
186     public void testH0m9() {
187         AbsoluteDate h0         = new AbsoluteDate("2010-07-01T10:42:09", TimeScalesFactory.getUTC());
188         Frame itrf              = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
189         Frame rotatingPadFrame  = new TopocentricFrame(new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
190                                                                             Constants.WGS84_EARTH_FLATTENING,
191                                                                             itrf),
192                                                        new GeodeticPoint(FastMath.toRadians(5.0),
193                                                                                               FastMath.toRadians(-100.0),
194                                                                                               0.0),
195                                                        "launch pad");
196 
197         // create a new inertially oriented frame that is aligned with ITRF at h0 - 9 seconds
198         AbsoluteDate h0M9       = h0.shiftedBy(-9.0);
199         Frame eme2000           = FramesFactory.getEME2000();
200         Frame frozenLaunchFrame = rotatingPadFrame.getFrozenFrame(eme2000, h0M9, "launch frame");
201 
202         // check velocity module is unchanged
203         Vector3D pEme2000 = new Vector3D(-29536113.0, 30329259.0, -100125.0);
204         Vector3D vEme2000 = new Vector3D(-2194.0, -2141.0, -8.0);
205         PVCoordinates pvEme2000 = new PVCoordinates(pEme2000, vEme2000);
206         PVCoordinates pvH0m9 = eme2000.getTransformTo(frozenLaunchFrame, h0M9).transformPVCoordinates(pvEme2000);
207         Assert.assertEquals(vEme2000.getNorm(), pvH0m9.getVelocity().getNorm(), 1.0e-6);
208 
209         // this frame is fixed with respect to EME2000 but rotates with respect to the non-frozen one
210         // the following loop should have a fixed angle a1 and an evolving angle a2
211         double minA1 = Double.POSITIVE_INFINITY;
212         double maxA1 = Double.NEGATIVE_INFINITY;
213         double minA2 = Double.POSITIVE_INFINITY;
214         double maxA2 = Double.NEGATIVE_INFINITY;
215         double dt;
216         for (dt = 0; dt < 86164; dt += 300.0) {
217             AbsoluteDate date = h0M9.shiftedBy(dt);
218             double a1 = frozenLaunchFrame.getTransformTo(eme2000,          date).getRotation().getAngle();
219             double a2 = frozenLaunchFrame.getTransformTo(rotatingPadFrame, date).getRotation().getAngle();
220             minA1 = FastMath.min(minA1, a1);
221             maxA1 = FastMath.max(maxA1, a1);
222             minA2 = FastMath.min(minA2, a2);
223             maxA2 = FastMath.max(maxA2, a2);
224         }
225         Assert.assertEquals(0, maxA1 - minA1, 1.0e-12);
226         Assert.assertEquals(FastMath.PI, maxA2 - minA2, 0.01);
227 
228     }
229 
230     private Transform randomTransform(Random random) {
231         Transform transform = Transform.IDENTITY;
232         for (int i = random.nextInt(10); i > 0; --i) {
233             if (random.nextBoolean()) {
234                 Vector3D u = new Vector3D(random.nextDouble() * 1000.0,
235                                           random.nextDouble() * 1000.0,
236                                           random.nextDouble() * 1000.0);
237                 transform = new Transform(transform.getDate(), transform, new Transform(transform.getDate(), u));
238             } else {
239                 double q0 = random.nextDouble() * 2 - 1;
240                 double q1 = random.nextDouble() * 2 - 1;
241                 double q2 = random.nextDouble() * 2 - 1;
242                 double q3 = random.nextDouble() * 2 - 1;
243                 double q  = FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
244                 Rotation r = new Rotation(q0 / q, q1 / q, q2 / q, q3 / q, false);
245                 transform = new Transform(transform.getDate(), transform, new Transform(transform.getDate(), r));
246             }
247         }
248         return transform;
249     }
250 
251     private void checkNoTransform(Transform transform, Random random) {
252         for (int i = 0; i < 100; ++i) {
253             Vector3D a = new Vector3D(random.nextDouble(),
254                                       random.nextDouble(),
255                                       random.nextDouble());
256             Vector3D b = transform.transformVector(a);
257             Assert.assertEquals(0, a.subtract(b).getNorm(), 1.0e-10);
258             Vector3D c = transform.transformPosition(a);
259             Assert.assertEquals(0, a.subtract(c).getNorm(), 1.0e-10);
260         }
261     }
262 
263     @Before
264     public void setUp() {
265         Utils.setDataRoot("compressed-data");
266     }
267 
268 }