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