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.CalculusFieldElement;
20  import org.hipparchus.geometry.euclidean.threed.Rotation;
21  import org.hipparchus.geometry.euclidean.threed.RotationConvention;
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.hipparchus.util.FastMath;
24  import org.junit.jupiter.api.Assertions;
25  import org.junit.jupiter.api.Test;
26  import org.orekit.errors.OrekitException;
27  import org.orekit.errors.OrekitMessages;
28  import org.orekit.time.AbsoluteDate;
29  import org.orekit.time.FieldAbsoluteDate;
30  import org.orekit.utils.AngularDerivativesFilter;
31  import org.orekit.utils.CartesianDerivativesFilter;
32  
33  
34  public class InterpolatingTransformProviderTest {
35  
36      @Test
37      public void testCacheHitWithDerivatives() {
38  
39          AbsoluteDate t0 = AbsoluteDate.GALILEO_EPOCH;
40          CirclingProvider referenceProvider = new CirclingProvider(t0, 0.2);
41          CirclingProvider rawProvider = new CirclingProvider(t0, 0.2);
42          InterpolatingTransformProvider interpolatingProvider =
43                  new InterpolatingTransformProvider(rawProvider,
44                                                     CartesianDerivativesFilter.USE_PVA,
45                                                     AngularDerivativesFilter.USE_RR,
46                                                     5, 0.8, 10, 60.0, 60.0);
47  
48          for (double dt = 0.1; dt <= 3.1; dt += 0.001) {
49              Transform reference = referenceProvider.getTransform(t0.shiftedBy(dt));
50              Transform interpolated = interpolatingProvider.getTransform(t0.shiftedBy(dt));
51              Transform error = new Transform(reference.getDate(), reference, interpolated.getInverse());
52              Assertions.assertEquals(0.0, error.getCartesian().getPosition().getNorm(),           7.0e-15);
53              Assertions.assertEquals(0.0, error.getCartesian().getVelocity().getNorm(),           3.0e-14);
54              Assertions.assertEquals(0.0, error.getAngular().getRotation().getAngle(),            1.3e-15);
55              Assertions.assertEquals(0.0, error.getAngular().getRotationRate().getNorm(),         2.2e-15);
56              Assertions.assertEquals(0.0, error.getAngular().getRotationAcceleration().getNorm(), 1.2e-14);
57  
58          }
59          Assertions.assertEquals(10,   rawProvider.getCount());
60          Assertions.assertEquals(3001, referenceProvider.getCount());
61  
62      }
63  
64      @Test
65      public void testCacheHitWithoutDerivatives() {
66  
67          AbsoluteDate t0 = AbsoluteDate.GALILEO_EPOCH;
68          CirclingProvider referenceProvider = new CirclingProvider(t0, 0.2);
69          CirclingProvider rawProvider = new CirclingProvider(t0, 0.2);
70          InterpolatingTransformProvider interpolatingProvider =
71                  new InterpolatingTransformProvider(rawProvider,
72                                                     CartesianDerivativesFilter.USE_P,
73                                                     AngularDerivativesFilter.USE_R,
74                                                     5, 0.8, 10, 60.0, 60.0);
75  
76          for (double dt = 0.1; dt <= 3.1; dt += 0.001) {
77              Transform reference = referenceProvider.getTransform(t0.shiftedBy(dt));
78              Transform interpolated = interpolatingProvider.getTransform(t0.shiftedBy(dt));
79              Transform error = new Transform(reference.getDate(), reference, interpolated.getInverse());
80              Assertions.assertEquals(0.0, error.getCartesian().getPosition().getNorm(),   1.3e-6);
81              Assertions.assertEquals(0.0, error.getCartesian().getVelocity().getNorm(),   7.0e-6);
82              Assertions.assertEquals(0.0, error.getAngular().getRotation().getAngle(),    2.0e-15);
83              Assertions.assertEquals(0.0, error.getAngular().getRotationRate().getNorm(), 2.0e-15);
84  
85          }
86          Assertions.assertEquals(10,   rawProvider.getCount());
87          Assertions.assertEquals(3001, referenceProvider.getCount());
88  
89      }
90  
91      @Test
92      public void testForwardException() {
93          Assertions.assertThrows(OrekitException.class, () -> {
94              InterpolatingTransformProvider interpolatingProvider =
95                      new InterpolatingTransformProvider(new TransformProvider() {
96                          public Transform getTransform(AbsoluteDate date) {
97                              throw new OrekitException(OrekitMessages.INTERNAL_ERROR);
98                          }
99                          public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
100                             throw new UnsupportedOperationException("never called in this test");
101                         }
102                     },
103                             CartesianDerivativesFilter.USE_PVA,
104                             AngularDerivativesFilter.USE_RRA,
105                             5, 0.8, 10, 60.0, 60.0);
106             interpolatingProvider.getTransform(AbsoluteDate.J2000_EPOCH);
107         });
108     }
109 
110     private static class CirclingProvider implements TransformProvider {
111 
112         private int count;
113         private final AbsoluteDate t0;
114         private final double omega;
115 
116         public CirclingProvider(final AbsoluteDate t0, final double omega) {
117             this.count = 0;
118             this.t0    = t0;
119             this.omega = omega;
120         }
121 
122         public Transform getTransform(final AbsoluteDate date) {
123             // the following transform corresponds to a frame moving along the circle r = 1
124             // with its x axis always pointing to the reference frame center
125             ++count;
126             final double dt = date.durationFrom(t0);
127             final double cos = FastMath.cos(omega * dt);
128             final double sin = FastMath.sin(omega * dt);
129             return new Transform(date,
130                                  new Transform(date,
131                                                new Vector3D(-cos, -sin, 0),
132                                                new Vector3D(omega * sin, -omega * cos, 0),
133                                                new Vector3D(omega * omega * cos, omega * omega * sin, 0)),
134                                  new Transform(date,
135                                                new Rotation(Vector3D.PLUS_K,
136                                                             FastMath.PI - omega * dt,
137                                                             RotationConvention.VECTOR_OPERATOR),
138                                                new Vector3D(omega, Vector3D.PLUS_K)));
139         }
140 
141         public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
142             throw new UnsupportedOperationException("never called in this test");
143         }
144 
145         public int getCount() {
146             return count;
147         }
148 
149         private Object readResolve() {
150             count = 0;
151             return this;
152         }
153     }
154 
155 }