1   /* Copyright 2022-2025 Romain Serra
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.propagation;
18  
19  import org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import org.hipparchus.util.FastMath;
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.Test;
23  import org.junit.jupiter.params.ParameterizedTest;
24  import org.junit.jupiter.params.provider.EnumSource;
25  import org.mockito.Mockito;
26  import org.orekit.frames.FramesFactory;
27  import org.orekit.orbits.*;
28  import org.orekit.time.AbsoluteDate;
29  import org.orekit.utils.Constants;
30  import org.orekit.utils.TimeStampedPVCoordinates;
31  
32  import java.util.Arrays;
33  
34  class ToleranceProviderTest {
35  
36      @Test
37      void testGetDefaultProvider() {
38          // GIVEN
39          final double dP = 1.;
40          // WHEN
41          final ToleranceProvider toleranceProvider = ToleranceProvider.getDefaultToleranceProvider(dP);
42          final double[][] actualTolerances = toleranceProvider.getTolerances(Vector3D.PLUS_I, Vector3D.MINUS_K);
43          // THEN
44          Assertions.assertEquals(2, actualTolerances.length);
45          for (int i = 0; i < 6; i++) {
46              Assertions.assertEquals(dP, actualTolerances[0][i]);
47          }
48      }
49  
50      @Test
51      void testOfConstantsCartesian() {
52          // GIVEN
53          final double expectedAbsolute = 1.;
54          final double expectedRelative = 2.;
55          // WHEN
56          final ToleranceProvider toleranceProvider = ToleranceProvider.of(expectedAbsolute, expectedRelative);
57          final double[][] actualTolerances = toleranceProvider.getTolerances(Vector3D.ZERO, Vector3D.ZERO);
58          // THEN
59          Assertions.assertEquals(2, actualTolerances.length);
60          Assertions.assertEquals(7, actualTolerances[0].length);
61          Assertions.assertEquals(actualTolerances[1].length, actualTolerances[0].length);
62          for (int i = 0; i < 7; i++) {
63              Assertions.assertEquals(expectedAbsolute, actualTolerances[0][i]);
64              Assertions.assertEquals(expectedRelative, actualTolerances[1][i]);
65          }
66      }
67  
68      @ParameterizedTest
69      @EnumSource(OrbitType.class)
70      void testOfConstantsOrbit(final OrbitType orbitType) {
71          // GIVEN
72          final double expectedAbsolute = 1.;
73          final double expectedRelative = 2.;
74          // WHEN
75          final ToleranceProvider toleranceProvider = ToleranceProvider.of(expectedAbsolute, expectedRelative);
76          final double[][] actualTolerances = toleranceProvider.getTolerances(Mockito.mock(Orbit.class), orbitType,
77                  PositionAngleType.MEAN);
78          // THEN
79          Assertions.assertEquals(2, actualTolerances.length);
80          Assertions.assertEquals(7, actualTolerances[0].length);
81          Assertions.assertEquals(actualTolerances[1].length, actualTolerances[0].length);
82          for (int i = 0; i < 7; i++) {
83              Assertions.assertEquals(expectedAbsolute, actualTolerances[0][i]);
84              Assertions.assertEquals(expectedRelative, actualTolerances[1][i]);
85          }
86      }
87  
88      @ParameterizedTest
89      @EnumSource(PositionAngleType.class)
90      void testOfConstantsOrbit(final PositionAngleType positionAngleType) {
91          // GIVEN
92          final double expectedAbsolute = 1.;
93          final double expectedRelative = 2.;
94          // WHEN
95          final ToleranceProvider toleranceProvider = ToleranceProvider.of(expectedAbsolute, expectedRelative);
96          final double[][] actualTolerances = toleranceProvider.getTolerances(Mockito.mock(Orbit.class), OrbitType.EQUINOCTIAL,
97                  positionAngleType);
98          // THEN
99          Assertions.assertEquals(2, actualTolerances.length);
100         Assertions.assertEquals(7, actualTolerances[0].length);
101         Assertions.assertEquals(actualTolerances[1].length, actualTolerances[0].length);
102         for (int i = 0; i < 7; i++) {
103             Assertions.assertEquals(expectedAbsolute, actualTolerances[0][i]);
104             Assertions.assertEquals(expectedRelative, actualTolerances[1][i]);
105         }
106     }
107 
108     @Test
109     void testOfCartesianProviderVectors() {
110         // GIVEN
111         final double[] absoluteTolerances = new double[7];
112         Arrays.fill(absoluteTolerances, 1.);
113         final double[] relativeTolerances = new double[7];
114         Arrays.fill(relativeTolerances, 2.);
115         final Vector3D vector = Vector3D.ZERO;
116         final CartesianToleranceProvider mockedProvider = Mockito.mock(CartesianToleranceProvider.class);
117         Mockito.when(mockedProvider.getTolerances(vector, vector))
118                 .thenReturn(new double[][] {absoluteTolerances, relativeTolerances});
119         // WHEN
120         final ToleranceProvider toleranceProvider = ToleranceProvider.of(mockedProvider);
121         final double[][] actualTolerances = toleranceProvider.getTolerances(vector, vector);
122         // THEN
123         Assertions.assertArrayEquals(absoluteTolerances, actualTolerances[0]);
124         Assertions.assertArrayEquals(relativeTolerances, actualTolerances[1]);
125     }
126 
127     @Test
128     void testOfCartesianProviderCartesianOrbit() {
129         // GIVEN
130         final double[] absoluteTolerances = new double[7];
131         Arrays.fill(absoluteTolerances, 1.);
132         final double[] relativeTolerances = new double[7];
133         Arrays.fill(relativeTolerances, 2.);
134         final CartesianOrbit mockedOrbit = Mockito.mock(CartesianOrbit.class);
135         final Vector3D vector = Vector3D.ZERO;
136         final CartesianToleranceProvider mockedProvider = Mockito.mock(CartesianToleranceProvider.class);
137         Mockito.when(mockedOrbit.getPosition()).thenReturn(vector);
138         Mockito.when(mockedOrbit.getPVCoordinates()).thenReturn(new TimeStampedPVCoordinates(AbsoluteDate.ARBITRARY_EPOCH, vector, vector));
139         Mockito.when(mockedProvider.getTolerances(vector, vector))
140                 .thenReturn(new double[][] {absoluteTolerances, relativeTolerances});
141         // WHEN
142         final ToleranceProvider toleranceProvider = ToleranceProvider.of(mockedProvider);
143         final double[][] actualTolerances = toleranceProvider.getTolerances(mockedOrbit, OrbitType.CARTESIAN, null);
144         // THEN
145         Assertions.assertArrayEquals(absoluteTolerances, actualTolerances[0]);
146         Assertions.assertArrayEquals(relativeTolerances, actualTolerances[1]);
147     }
148 
149     @ParameterizedTest
150     @EnumSource(value=OrbitType.class, names = {"KEPLERIAN", "EQUINOCTIAL"})
151     void testOfCartesianProviderOrbit(final OrbitType orbitType) {
152         // GIVEN
153         final double[] absoluteTolerances = new double[7];
154         Arrays.fill(absoluteTolerances, 1.);
155         final double[] relativeTolerances = new double[7];
156         Arrays.fill(relativeTolerances, 2.);
157         final Orbit orbit = getOrbit();
158         final CartesianToleranceProvider mockedProvider = Mockito.mock(CartesianToleranceProvider.class);
159         Mockito.when(mockedProvider.getTolerances(Mockito.any(Vector3D.class), Mockito.any(Vector3D.class)))
160                 .thenReturn(new double[][] {absoluteTolerances, relativeTolerances});
161         final PositionAngleType angleType = PositionAngleType.TRUE;
162         // WHEN
163         final ToleranceProvider toleranceProvider = ToleranceProvider.of(mockedProvider);
164         final double[][] actualTolerances = toleranceProvider.getTolerances(orbit, orbitType, angleType);
165         // THEN
166         final double[][] cartesianTolerances = toleranceProvider.getTolerances((CartesianOrbit) OrbitType.CARTESIAN.convertType(orbit));
167         final double[] cartAbsTol = cartesianTolerances[0];
168         final Orbit converted = orbitType.convertType(orbit);
169         final double[][] jacobian = new double[6][6];
170         converted.getJacobianWrtCartesian(angleType, jacobian);
171         for (int i = 0; i < jacobian.length; ++i) {
172             final double[] row = jacobian[i];
173             final double expected = FastMath.abs(row[0]) * cartAbsTol[0] +
174                     FastMath.abs(row[1]) * cartAbsTol[1] +
175                     FastMath.abs(row[2]) * cartAbsTol[2] +
176                     FastMath.abs(row[3]) * cartAbsTol[3] +
177                     FastMath.abs(row[4]) * cartAbsTol[4] +
178                     FastMath.abs(row[5]) * cartAbsTol[5];
179             Assertions.assertEquals(expected, actualTolerances[0][i]);
180         }
181     }
182 
183     private static Orbit getOrbit() {
184         return new KeplerianOrbit(1e7, 0.001, 1, 2, 3, 4, PositionAngleType.ECCENTRIC, FramesFactory.getGCRF(),
185                 AbsoluteDate.ARBITRARY_EPOCH, Constants.EGM96_EARTH_MU);
186     }
187 
188 }