1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.definitions;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.linear.MatrixUtils;
21 import org.hipparchus.util.FastMath;
22 import org.junit.jupiter.api.Assertions;
23 import org.junit.jupiter.api.BeforeAll;
24 import org.junit.jupiter.api.BeforeEach;
25 import org.junit.jupiter.api.DisplayName;
26 import org.junit.jupiter.api.Test;
27 import org.mockito.Mockito;
28 import org.orekit.Utils;
29 import org.orekit.data.DataContext;
30 import org.orekit.errors.OrekitException;
31 import org.orekit.frames.Frame;
32 import org.orekit.frames.FramesFactory;
33 import org.orekit.frames.Transform;
34 import org.orekit.orbits.KeplerianOrbit;
35 import org.orekit.orbits.Orbit;
36 import org.orekit.orbits.PositionAngleType;
37 import org.orekit.time.AbsoluteDate;
38 import org.orekit.time.TimeScalesFactory;
39 import org.orekit.utils.Constants;
40 import org.orekit.utils.IERSConventions;
41 import org.orekit.utils.PVCoordinatesProvider;
42
43 import java.util.Arrays;
44
45 public class FrameFacadeTest {
46
47
48
49
50 @BeforeAll
51 public static void configureOrekitDataAccess() {
52 Utils.setDataRoot("regular-data");
53 }
54
55 @Test
56 public void testMapCelestial() {
57 for (CelestialBodyFrame cbf : CelestialBodyFrame.values()) {
58 FrameFacade ff = FrameFacade.parse(cbf.name(),
59 IERSConventions.IERS_2010, true, DataContext.getDefault(),
60 true, true, true);
61 Assertions.assertSame(cbf, ff.asCelestialBodyFrame());
62 Assertions.assertNull(ff.asOrbitRelativeFrame());
63 Assertions.assertNull(ff.asSpacecraftBodyFrame());
64 }
65 }
66
67 @Test
68 public void testMapLOF() {
69 for (OrbitRelativeFrame orf : OrbitRelativeFrame.values()) {
70 FrameFacade ff = FrameFacade.parse(orf.name(),
71 IERSConventions.IERS_2010, true, DataContext.getDefault(),
72 true, true, true);
73 Assertions.assertNull(ff.asCelestialBodyFrame());
74 Assertions.assertSame(orf, ff.asOrbitRelativeFrame());
75 Assertions.assertNull(ff.asSpacecraftBodyFrame());
76 }
77 }
78
79 @Test
80 public void testMapSpacecraft() {
81 for (SpacecraftBodyFrame.BaseEquipment be : SpacecraftBodyFrame.BaseEquipment.values()) {
82 for (String label : Arrays.asList("1", "2", "A", "B")) {
83 SpacecraftBodyFrame sbf = new SpacecraftBodyFrame(be, label);
84 FrameFacade ff = FrameFacade.parse(sbf.toString(),
85 IERSConventions.IERS_2010, true, DataContext.getDefault(),
86 true, true, true);
87 Assertions.assertNull(ff.asCelestialBodyFrame());
88 Assertions.assertNull(ff.asOrbitRelativeFrame());
89 Assertions.assertEquals(be, ff.asSpacecraftBodyFrame().getBaseEquipment());
90 Assertions.assertEquals(label, ff.asSpacecraftBodyFrame().getLabel());
91 }
92 }
93 }
94
95 @Test
96 public void testUnknownFrame() {
97 final String name = "unknown";
98 FrameFacade ff = FrameFacade.parse(name,
99 IERSConventions.IERS_2010, true, DataContext.getDefault(),
100 true, true, true);
101 Assertions.assertNull(ff.asFrame());
102 Assertions.assertNull(ff.asCelestialBodyFrame());
103 Assertions.assertNull(ff.asOrbitRelativeFrame());
104 Assertions.assertNull(ff.asSpacecraftBodyFrame());
105 Assertions.assertEquals(name, ff.getName());
106 }
107
108 @BeforeEach
109 public void setUp() {
110 Utils.setDataRoot("regular-data");
111 }
112
113
114
115
116
117 @Test
118 public void testGetTransformLofToLofAtPeriapsis() {
119
120
121 final Frame pivotFrame = FramesFactory.getGCRF();
122 final Orbit orbit = new KeplerianOrbit(7.E6, 0.001, FastMath.toRadians(45.), 0., 0., 0.,
123 PositionAngleType.TRUE, FramesFactory.getEME2000(),
124 new AbsoluteDate(2000, 1, 1, TimeScalesFactory.getUTC()),
125 Constants.GRIM5C1_EARTH_MU);
126
127 final FrameFacade RTN = new FrameFacade(null, null, OrbitRelativeFrame.QSW, null, "RTN");
128 final FrameFacade TNW = new FrameFacade(null, null, OrbitRelativeFrame.TNW, null, "RTN");
129
130
131 final Transform lofInToLofOut = FrameFacade.getTransform(RTN, TNW, pivotFrame, orbit.getDate(), orbit);
132
133
134 final double[][] expectedRotationMatrix = new double[][] {
135 { 0, 1, 0 },
136 { -1, 0, 0 },
137 { 0, 0, 1 } };
138
139 validateMatrix(lofInToLofOut.getRotation().getMatrix(), expectedRotationMatrix, 1e-15);
140
141 }
142
143 @Test
144 @DisplayName("Test that an exception is thrown if the pivot frame is not pseudo-inertial")
145 void Should_throw_exception_when_given_non_inertial_pivot_frame() {
146
147
148 final FrameFacade frameFacadeInMock = Mockito.mock(FrameFacade.class);
149 final FrameFacade frameFacadeOutMock = Mockito.mock(FrameFacade.class);
150 final Orbit pvCoordinatesProviderMock = Mockito.mock(Orbit.class);
151 final AbsoluteDate dateMock = Mockito.mock(AbsoluteDate.class);
152
153 final Frame nonInertialPivotFrame = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
154
155
156 Assertions.assertThrows(OrekitException.class, () -> {
157 FrameFacade.getTransform(frameFacadeInMock, frameFacadeOutMock, nonInertialPivotFrame, dateMock,
158 pvCoordinatesProviderMock);
159 });
160
161 }
162
163 @Test
164 @DisplayName("Test that an exception is thrown if the frame facade is defined using a SpacecraftBodyFrame or a CelestialBodyFrame")
165 void Should_throw_exception_when_given_unsupported_frame_facade() {
166
167
168 final AbsoluteDate dateMock = Mockito.mock(AbsoluteDate.class);
169 final Frame pivot = FramesFactory.getGCRF();
170 final PVCoordinatesProvider pvProviderMock = Mockito.mock(Orbit.class);
171
172 final FrameFacade inputCelestial =
173 new FrameFacade(null, Mockito.mock(CelestialBodyFrame.class),
174 null, null, "Celestial body frame");
175
176 final FrameFacade inputSpacecraftBody =
177 new FrameFacade(null, null,
178 null, Mockito.mock(SpacecraftBodyFrame.class), "Celestial body frame");
179
180 final FrameFacade output =
181 new FrameFacade(FramesFactory.getEME2000(), null,
182 null, null, "Celestial body frame");
183
184
185 Assertions.assertThrows(OrekitException.class, () -> {
186 FrameFacade.getTransform(inputSpacecraftBody, output, pivot, dateMock, pvProviderMock);
187 });
188
189 Assertions.assertThrows(OrekitException.class, () -> {
190 FrameFacade.getTransform(inputCelestial, output, pivot, dateMock, pvProviderMock);
191 });
192 }
193
194 @Test
195 @DisplayName("Test that an exception is thrown if the frame facade is defined using an orbit relative frame returning a null LOFType")
196 void Should_throw_exception_when_given_null_LOFType() {
197
198
199 final AbsoluteDate dateMock = Mockito.mock(AbsoluteDate.class);
200 final Frame pivot = FramesFactory.getGCRF();
201 final PVCoordinatesProvider pvProviderMock = Mockito.mock(Orbit.class);
202
203 final FrameFacade inputNullLOFType =
204 new FrameFacade(null, null,
205 OrbitRelativeFrame.PQW_INERTIAL, null, "Celestial body frame");
206
207 final FrameFacade output =
208 new FrameFacade(FramesFactory.getEME2000(), null,
209 null, null, "Celestial body frame");
210
211
212 Assertions.assertThrows(OrekitException.class, () -> {
213 FrameFacade.getTransform(inputNullLOFType, output, pivot, dateMock, pvProviderMock);
214 });
215 }
216
217 @Test
218 @DisplayName("Test getTransform method")
219 void Should_return_identity_transform_after_multiple_transforms() {
220
221
222 final AbsoluteDate date = new AbsoluteDate();
223 final Frame pivot = FramesFactory.getGCRF();
224 final Orbit orbit = new KeplerianOrbit(7.E6, 0.001, FastMath.toRadians(45.), 0., 0., 0.,
225 PositionAngleType.MEAN, FramesFactory.getEME2000(),
226 date, Constants.IERS2010_EARTH_MU);
227
228 final FrameFacade initialFrameFacade =
229 new FrameFacade(FramesFactory.getGCRF(),
230 null, null, null,
231 "Initial frame");
232
233 final FrameFacade intermediaryQSWFrameFacade =
234 new FrameFacade(null,
235 null, OrbitRelativeFrame.QSW, null,
236 "QSW");
237
238 final FrameFacade intermediaryTNWFrameFacade =
239 new FrameFacade(null,
240 null, OrbitRelativeFrame.QSW, null,
241 "TNW");
242
243 final FrameFacade intermediaryNonInertialFrameFacade =
244 new FrameFacade(FramesFactory.getITRF(IERSConventions.IERS_2010, true),
245 null, null, null,
246 "Non inertial frame");
247
248
249 final Transform initialToQSW =
250 FrameFacade.getTransform(initialFrameFacade, intermediaryQSWFrameFacade, pivot, date, orbit);
251
252 final Transform QSWToTNW =
253 FrameFacade.getTransform(intermediaryQSWFrameFacade, intermediaryTNWFrameFacade, pivot, date, orbit);
254
255 final Transform TNWToNonInertialFrame =
256 FrameFacade.getTransform(intermediaryTNWFrameFacade, intermediaryNonInertialFrameFacade, pivot, date,
257 orbit);
258
259 final Transform nonInertialFrameToInitial =
260 FrameFacade.getTransform(intermediaryNonInertialFrameFacade, initialFrameFacade, pivot, date, orbit);
261
262 final Transform composedTransform = composeTransform(date,
263 initialToQSW,
264 QSWToTNW,
265 TNWToNonInertialFrame,
266 nonInertialFrameToInitial);
267
268 final Vector3D computedTranslation = composedTransform.getTranslation();
269 final double[][] computedRotationMatrixData = composedTransform.getRotation().getMatrix();
270
271
272 final Vector3D expectedTranslation = new Vector3D(0, 0, 0);
273 final double[][] expectedRotationMatrixData = MatrixUtils.createRealIdentityMatrix(3).getData();
274
275 validateVector3D(expectedTranslation, computedTranslation, 2e-9);
276 validateMatrix(expectedRotationMatrixData, computedRotationMatrixData, 2e-15);
277 }
278
279 private Transform composeTransform(final AbsoluteDate date, final Transform... transforms) {
280 Transform composedTransform = null;
281
282 for (Transform transform : transforms) {
283 if (composedTransform == null) {
284 composedTransform = transform;
285 }
286 else {
287 composedTransform = new Transform(date, composedTransform, transform);
288 }
289 }
290
291 return composedTransform;
292 }
293
294 private void validateVector3D(final Vector3D expected, final Vector3D computed, final double threshold) {
295 Assertions.assertEquals(expected.getX(), computed.getX(), threshold);
296 Assertions.assertEquals(expected.getY(), computed.getY(), threshold);
297 Assertions.assertEquals(expected.getZ(), computed.getZ(), threshold);
298
299 }
300
301
302
303
304
305
306
307
308 private void validateMatrix(double[][] data, double[][] expected, double threshold) {
309 for (int i = 0; i < data.length; i++) {
310 for (int j = 0; j < data[0].length; j++) {
311 Assertions.assertEquals(expected[i][j], data[i][j], threshold);
312 }
313 }
314 }
315
316 }