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.util.FastMath;
20 import org.junit.jupiter.api.Assertions;
21 import org.junit.jupiter.api.BeforeEach;
22 import org.junit.jupiter.api.Test;
23 import org.orekit.Utils;
24 import org.orekit.time.AbsoluteDate;
25 import org.orekit.time.TimeScalesFactory;
26 import org.orekit.utils.AngularDerivativesFilter;
27 import org.orekit.utils.CartesianDerivativesFilter;
28 import org.orekit.utils.Constants;
29 import org.orekit.utils.IERSConventions;
30 import org.orekit.utils.OrekitConfiguration;
31
32 import java.util.ArrayList;
33
34 public class CIRFProviderTest {
35
36 @Test
37 public void testRotationRate() {
38 EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
39 TransformProvider provider =
40 new InterpolatingTransformProvider(new CIRFProvider(eopHistory),
41 CartesianDerivativesFilter.USE_PVA,
42 AngularDerivativesFilter.USE_R,
43 3, 1.0, 5, Constants.JULIAN_DAY, 100.0);
44 AbsoluteDate tMin = new AbsoluteDate(2009, 4, 7, 2, 56, 33.816, TimeScalesFactory.getUTC());
45 double minRate = provider.getTransform(tMin).getRotationRate().getNorm();
46 Assertions.assertEquals(1.1e-15, minRate, 1.0e-16);
47 AbsoluteDate tMax = new AbsoluteDate(2043, 12, 16, 10, 47, 20, TimeScalesFactory.getUTC());
48 double maxRate = provider.getTransform(tMax).getRotationRate().getNorm();
49 Assertions.assertEquals(8.6e-12, maxRate, 1.0e-13);
50 }
51
52 @Test
53 public void testShiftingAccuracyWithEOP() {
54
55 // max shift error observed on a 2 months period with 60 seconds step
56 // the shifting step after the interpolation step induces that mainly the
57 // step size has an influence on the error. The number of points used in
58 // the lower level interpolation does affect the results but less than
59 // step size. Plotting the error curves show almost superposition of all
60 // curves with the same time step. The error curves exhibit smooth periodic
61 // pattern with a main period corresponding to the Moon period plus peaks
62 // corresponding to Runge phenomenon when EOP data changes at midnight.
63 //
64 // number of sample points time between sample points max error
65 // 6 86400s / 12 = 2h00 9.56e-12 rad
66 // 6 86400s / 18 = 1h20 6.20e-12 rad
67 // 6 86400s / 24 = 1h00 4.60e-12 rad
68 // 6 86400s / 48 = 0h30 2.25e-12 rad
69 // 8 86400s / 12 = 2h00 8.21e-12 rad
70 // 8 86400s / 18 = 1h20 5.32e-12 rad
71 // 8 86400s / 24 = 1h00 3.94e-12 rad
72 // 8 86400s / 48 = 0h30 1.93e-12 rad
73 // 12 86400s / 12 = 2h00 7.09e-12 rad
74 // 12 86400s / 18 = 1h20 4.61e-12 rad
75 // 12 86400s / 24 = 1h00 3.42e-12 rad
76 // 12 86400s / 48 = 0h30 1.68e-12 rad
77 EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, false);
78 TransformProvider nonShitfing = new CIRFProvider(eopHistory);
79 final TransformProvider shifting =
80 new ShiftingTransformProvider(nonShitfing,
81 CartesianDerivativesFilter.USE_PVA,
82 AngularDerivativesFilter.USE_R,
83 6, Constants.JULIAN_DAY / 24,
84 OrekitConfiguration.getCacheSlotsNumber(),
85 Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY);
86
87 // the following time range is located around the maximal observed error
88 AbsoluteDate start = new AbsoluteDate(2002, 9, 12, TimeScalesFactory.getTAI());
89 AbsoluteDate end = new AbsoluteDate(2002, 9, 14, TimeScalesFactory.getTAI());
90 double maxError = 0.0;
91 for (AbsoluteDate date = start; date.compareTo(end) < 0; date = date.shiftedBy(60)) {
92 final Transform transform =
93 new Transform(date,
94 shifting.getTransform(date),
95 nonShitfing.getTransform(date).getInverse());
96 final double error = transform.getRotation().getAngle();
97 maxError = FastMath.max(maxError, error);
98 }
99 Assertions.assertTrue(maxError < 4.6e-12);
100
101 }
102
103 @Test
104 public void testShiftingAccuracyWithoutEOP() {
105
106 // max shift error observed on a 2 months period with 60 seconds step
107 // the shifting step after the interpolation step induces that only the
108 // step size has an influence on the error. The number of points used in
109 // the lower level interpolation does not affect the results. Plotting
110 // the error curves show exact superposition of all curves with the same
111 // time step. The error curves exhibit smooth periodic pattern with a
112 // main period corresponding to the Moon period
113 //
114 // number of sample points time between sample points max error
115 // 6 86400s / 12 = 2h00 9.99e-13 rad
116 // 6 86400s / 18 = 1h20 2.96e-13 rad
117 // 6 86400s / 24 = 1h00 1.25e-13 rad
118 // 6 86400s / 48 = 0h30 1.56e-14 rad
119 // 8 86400s / 12 = 2h00 9.99e-13 rad
120 // 8 86400s / 18 = 1h20 2.96e-13 rad
121 // 8 86400s / 24 = 1h00 1.25e-13 rad
122 // 8 86400s / 48 = 0h30 1.56e-14 rad
123 // 12 86400s / 12 = 2h00 9.99e-13 rad
124 // 12 86400s / 18 = 1h20 2.96e-13 rad
125 // 12 86400s / 24 = 1h00 1.25e-13 rad
126 // 12 86400s / 48 = 0h30 1.56e-14 rad
127 EOPHistory eopHistory = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
128 new ArrayList<EOPEntry>(), true);
129 TransformProvider nonShifting = new CIRFProvider(eopHistory);
130 final TransformProvider shifting =
131 new ShiftingTransformProvider(nonShifting,
132 CartesianDerivativesFilter.USE_PVA,
133 AngularDerivativesFilter.USE_R,
134 6, Constants.JULIAN_DAY / 24,
135 OrekitConfiguration.getCacheSlotsNumber(),
136 Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY);
137
138 // the following time range is located around the maximal observed error
139 AbsoluteDate start = new AbsoluteDate(2002, 9, 7, TimeScalesFactory.getTAI());
140 AbsoluteDate end = new AbsoluteDate(2002, 9, 8, TimeScalesFactory.getTAI());
141 double maxError = 0.0;
142 for (AbsoluteDate date = start; date.compareTo(end) < 0; date = date.shiftedBy(60)) {
143 final Transform transform =
144 new Transform(date,
145 shifting.getTransform(date),
146 nonShifting.getTransform(date).getInverse());
147 final double error = transform.getRotation().getAngle();
148 maxError = FastMath.max(maxError, error);
149 }
150 Assertions.assertTrue(maxError < 1.3e-13);
151
152 }
153
154 @BeforeEach
155 public void setUp() {
156 Utils.setDataRoot("compressed-data");
157 }
158
159 }