1   /* Copyright 2002-2025 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 org.hipparchus.geometry.euclidean.threed.Rotation;
20  import org.hipparchus.geometry.euclidean.threed.Vector3D;
21  import org.hipparchus.util.FastMath;
22  import org.junit.jupiter.api.Assertions;
23  import org.junit.jupiter.api.BeforeEach;
24  import org.junit.jupiter.api.Test;
25  import org.orekit.Utils;
26  import org.orekit.errors.FrameAncestorException;
27  import org.orekit.time.AbsoluteDate;
28  
29  import java.util.Random;
30  
31  public class UpdatableFrameTest {
32  
33      @Test
34      public void testUpdateTransform() {
35          Random random     = new Random(0x2f6769c23e53e96el);
36          UpdatableFrame f0 = new UpdatableFrame(FramesFactory.getGCRF(), Transform.IDENTITY, "dummy");
37          AbsoluteDate date = new AbsoluteDate();
38  
39          UpdatableFrame f1 = new UpdatableFrame(f0, randomTransform(random), "f1");
40          UpdatableFrame f2 = new UpdatableFrame(f1, randomTransform(random), "f2");
41          UpdatableFrame f3 = new UpdatableFrame(f2, randomTransform(random), "f3");
42          UpdatableFrame f4 = new UpdatableFrame(f2, randomTransform(random), "f4");
43          UpdatableFrame f5 = new UpdatableFrame(f4, randomTransform(random), "f5");
44          UpdatableFrame f6 = new UpdatableFrame(f0, randomTransform(random), "f6");
45          UpdatableFrame f7 = new UpdatableFrame(f6, randomTransform(random), "f7");
46          UpdatableFrame f8 = new UpdatableFrame(f6, randomTransform(random), "f8");
47          UpdatableFrame f9 = new UpdatableFrame(f7, randomTransform(random), "f9");
48  
49          checkFrameAncestorException(f6, f8, f9, randomTransform(random), date);
50          checkFrameAncestorException(f6, f9, f8, randomTransform(random), date);
51          checkFrameAncestorException(f6, f3, f5, randomTransform(random), date);
52          checkFrameAncestorException(f6, f5, f3, randomTransform(random), date);
53          checkFrameAncestorException(f0, f5, f9, randomTransform(random), date);
54          checkFrameAncestorException(f0, f9, f5, randomTransform(random), date);
55          checkFrameAncestorException(f3, f0, f6, randomTransform(random), date);
56          checkFrameAncestorException(f3, f6, f0, randomTransform(random), date);
57  
58          checkUpdateTransform(f1, f5, f9, date, random);
59          checkUpdateTransform(f7, f6, f9, date, random);
60          checkUpdateTransform(f6, f0, f7, date, random);
61  
62          checkUpdateTransform(f6, f6.getParent(), f6, date, random);
63  
64      }
65  
66      private void checkFrameAncestorException(UpdatableFrame f0, Frame f1, Frame f2,
67                                               Transform transform, AbsoluteDate date) {
68          try {
69              f0.updateTransform(f1, f2, transform, date);
70              Assertions.fail("Should raise a FrameAncestorException");
71          } catch(FrameAncestorException expected){
72              // expected behavior
73          } catch (Exception e) {
74              Assertions.fail("wrong exception caught");
75          }
76      }
77  
78      private void checkUpdateTransform(UpdatableFrame f0, Frame f1, Frame f2,
79                                        AbsoluteDate date, Random random)
80        {
81          Transform f1ToF2 = randomTransform(random);
82  
83          f0.updateTransform(f1, f2, f1ToF2, date);
84          Transform obtained12 = f1.getTransformTo(f2, date);
85          checkNoTransform(new Transform(date, f1ToF2, obtained12.getInverse()), random);
86  
87          f0.updateTransform(f2, f1, f1ToF2.getInverse(), date);
88          Transform obtained21 = f2.getTransformTo(f1, date);
89          checkNoTransform(new Transform(date, f1ToF2.getInverse(), obtained21.getInverse()), random);
90  
91          checkNoTransform(new Transform(date, obtained12, obtained21), random);
92  
93      }
94  
95      private Transform randomTransform(Random random) {
96          Transform transform = Transform.IDENTITY;
97          for (int i = random.nextInt(10); i > 0; --i) {
98              if (random.nextBoolean()) {
99                  Vector3D u = new Vector3D(random.nextDouble() * 1000.0,
100                                           random.nextDouble() * 1000.0,
101                                           random.nextDouble() * 1000.0);
102                 transform = new Transform(transform.getDate(), transform, new Transform(transform.getDate(), u));
103             } else {
104                 double q0 = random.nextDouble() * 2 - 1;
105                 double q1 = random.nextDouble() * 2 - 1;
106                 double q2 = random.nextDouble() * 2 - 1;
107                 double q3 = random.nextDouble() * 2 - 1;
108                 double q  = FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
109                 Rotation r = new Rotation(q0 / q, q1 / q, q2 / q, q3 / q, false);
110                 transform = new Transform(transform.getDate(), transform, new Transform(transform.getDate(), r));
111             }
112         }
113         return transform;
114     }
115 
116     private void checkNoTransform(Transform transform, Random random) {
117         for (int i = 0; i < 100; ++i) {
118             Vector3D a = new Vector3D(random.nextDouble(),
119                                       random.nextDouble(),
120                                       random.nextDouble());
121             Vector3D b = transform.transformVector(a);
122             Assertions.assertEquals(0, a.subtract(b).getNorm(), 1.0e-10);
123             Vector3D c = transform.transformPosition(a);
124             Assertions.assertEquals(0, a.subtract(c).getNorm(), 1.0e-10);
125         }
126     }
127 
128     @BeforeEach
129     public void setUp() {
130         Utils.setDataRoot("compressed-data");
131     }
132 
133 }