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.files.ccsds.definitions;
18  
19  import org.junit.jupiter.api.Assertions;
20  import org.junit.jupiter.api.DisplayName;
21  import org.junit.jupiter.api.Test;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.frames.LOFType;
24  
25  class OrbitRelativeFrameTest {
26      @Test
27      @DisplayName("Test OrbitRelativeFrame definitions and their LOFType equivalent")
28      void testOrbitRelativeFrameDefinitionsAndLOFTypeEquivalent() {
29          // Given
30          final OrbitRelativeFrame eqwInertial  = OrbitRelativeFrame.EQW_INERTIAL;
31          final OrbitRelativeFrame lvlhRotating = OrbitRelativeFrame.LVLH_ROTATING;
32          final OrbitRelativeFrame lvlhInertial = OrbitRelativeFrame.LVLH_INERTIAL;
33          final OrbitRelativeFrame lvlh         = OrbitRelativeFrame.LVLH;
34          final OrbitRelativeFrame nswRotating  = OrbitRelativeFrame.NSW_ROTATING;
35          final OrbitRelativeFrame nswInertial  = OrbitRelativeFrame.NSW_INERTIAL;
36          final OrbitRelativeFrame ntwRotating  = OrbitRelativeFrame.NTW_ROTATING;
37          final OrbitRelativeFrame ntwInertial  = OrbitRelativeFrame.NTW_INERTIAL;
38          final OrbitRelativeFrame pqwInertial  = OrbitRelativeFrame.PQW_INERTIAL;
39          final OrbitRelativeFrame rswRotating  = OrbitRelativeFrame.RSW_ROTATING;
40          final OrbitRelativeFrame rswInertial  = OrbitRelativeFrame.RSW_INERTIAL;
41          final OrbitRelativeFrame rsw          = OrbitRelativeFrame.RSW;
42          final OrbitRelativeFrame ric          = OrbitRelativeFrame.RIC;
43          final OrbitRelativeFrame rtn          = OrbitRelativeFrame.RTN;
44          final OrbitRelativeFrame qsw          = OrbitRelativeFrame.QSW;
45          final OrbitRelativeFrame tnwRotating  = OrbitRelativeFrame.TNW_ROTATING;
46          final OrbitRelativeFrame tnwInertial  = OrbitRelativeFrame.TNW_INERTIAL;
47          final OrbitRelativeFrame tnw          = OrbitRelativeFrame.TNW;
48          final OrbitRelativeFrame sezRotating  = OrbitRelativeFrame.SEZ_ROTATING;
49          final OrbitRelativeFrame sezInertial  = OrbitRelativeFrame.SEZ_INERTIAL;
50          final OrbitRelativeFrame vncRotating  = OrbitRelativeFrame.VNC_ROTATING;
51          final OrbitRelativeFrame vncInertial  = OrbitRelativeFrame.VNC_INERTIAL;
52  
53          // When
54          final LOFType eqwInertialLOF  = eqwInertial.getLofType();
55          final LOFType lvlhRotatingLOF = lvlhRotating.getLofType();
56          final LOFType lvlhInertialLOF = lvlhInertial.getLofType();
57          final LOFType lvlhLOF         = lvlh.getLofType();
58          final LOFType nswRotatingLOF  = nswRotating.getLofType();
59          final LOFType nswInertialLOF  = nswInertial.getLofType();
60          final LOFType ntwRotatingLOF  = ntwRotating.getLofType();
61          final LOFType ntwInertialLOF  = ntwInertial.getLofType();
62          final LOFType pqwInertialLOF  = pqwInertial.getLofType();
63          final LOFType rswRotatingLOF  = rswRotating.getLofType();
64          final LOFType rswInertialLOF  = rswInertial.getLofType();
65          final LOFType rswLOF          = rsw.getLofType();
66          final LOFType ricLOF          = ric.getLofType();
67          final LOFType rtnLOF          = rtn.getLofType();
68          final LOFType qswLOF          = qsw.getLofType();
69          final LOFType tnwRotatingLOF  = tnwRotating.getLofType();
70          final LOFType tnwInertialLOF  = tnwInertial.getLofType();
71          final LOFType tnwLOF          = tnw.getLofType();
72          final LOFType sezRotatingLOF  = sezRotating.getLofType();
73          final LOFType sezInertialLOF  = sezInertial.getLofType();
74          final LOFType vncRotatingLOF  = vncRotating.getLofType();
75          final LOFType vncInertialLOF  = vncInertial.getLofType();
76  
77          // Then
78          Assertions.assertEquals(eqwInertialLOF.isQuasiInertial(), eqwInertialLOF.isQuasiInertial());
79          Assertions.assertEquals(lvlhInertial.isQuasiInertial(), lvlhInertialLOF.isQuasiInertial());
80          Assertions.assertEquals(lvlhInertial.isQuasiInertial(), LOFType.VVLH_INERTIAL.isQuasiInertial());
81          Assertions.assertEquals(lvlhRotating.isQuasiInertial(), lvlhRotatingLOF.isQuasiInertial());
82          Assertions.assertEquals(lvlhRotating.isQuasiInertial(), LOFType.VVLH.isQuasiInertial());
83          Assertions.assertEquals(lvlhRotating, LOFType.VVLH.toOrbitRelativeFrame());
84          Assertions.assertEquals(lvlh.isQuasiInertial(), lvlhLOF.isQuasiInertial());
85          Assertions.assertNull(nswRotatingLOF);
86          Assertions.assertNull(nswInertialLOF);
87          Assertions.assertEquals(ntwRotating.isQuasiInertial(), ntwRotatingLOF.isQuasiInertial());
88          Assertions.assertEquals(ntwInertialLOF.isQuasiInertial(), ntwInertialLOF.isQuasiInertial());
89          Assertions.assertNull(pqwInertialLOF);
90          Assertions.assertEquals(rswRotating.isQuasiInertial(), rswRotatingLOF.isQuasiInertial());
91          Assertions.assertEquals(rswInertial.isQuasiInertial(), rswInertialLOF.isQuasiInertial());
92          Assertions.assertEquals(rsw.isQuasiInertial(), rswLOF.isQuasiInertial());
93          Assertions.assertEquals(ric.isQuasiInertial(), ricLOF.isQuasiInertial());
94          Assertions.assertEquals(rtn.isQuasiInertial(), rtnLOF.isQuasiInertial());
95          Assertions.assertEquals(qsw.isQuasiInertial(), qswLOF.isQuasiInertial());
96          Assertions.assertEquals(tnwRotating.isQuasiInertial(), tnwRotatingLOF.isQuasiInertial());
97          Assertions.assertEquals(tnwInertial.isQuasiInertial(), tnwInertialLOF.isQuasiInertial());
98          Assertions.assertEquals(tnw.isQuasiInertial(), tnwLOF.isQuasiInertial());
99          Assertions.assertNull(sezRotatingLOF);
100         Assertions.assertNull(sezInertialLOF);
101         Assertions.assertEquals(vncRotating.isQuasiInertial(), vncRotatingLOF.isQuasiInertial());
102         Assertions.assertEquals(vncInertial.isQuasiInertial(), vncInertialLOF.isQuasiInertial());
103     }
104 
105     @Test
106     @DisplayName("test conversion from/to orbit relative frame to/from orekit local orbital frame")
107     void testConversionFromToOrbitRelativeFrameToFromLOFType() {
108         for (OrbitRelativeFrame ccsdsFrame : OrbitRelativeFrame.values()) {
109             final LOFType orekitEquivalentLOF = ccsdsFrame.getLofType();
110 
111             // Bypass cases where there is no Orekit equivalent
112             if (orekitEquivalentLOF != null) {
113                 // Convert back to CCSDS frame
114                 final OrbitRelativeFrame ccsdsFrameFromOrekitLOF = orekitEquivalentLOF.toOrbitRelativeFrame();
115 
116                 // Assert that we come back to the initial CCSDS frame
117                 assertSameOrbitRelativeFrame(ccsdsFrame, ccsdsFrameFromOrekitLOF);
118             }
119         }
120     }
121 
122     /**
123      * Method used to check that initial CCSDS orbital frame is equivalent to converted CCSDS orbital frame converted from
124      * {@link LOFType}.
125      *
126      * @param initialCCSDSFrame initial CCSDS orbital frame
127      * @param ccsdsFrameFromOrekitLOF CCSDS orbital frame converted from {@link LOFType}
128      */
129     private void assertSameOrbitRelativeFrame(final OrbitRelativeFrame initialCCSDSFrame,
130                                               final OrbitRelativeFrame ccsdsFrameFromOrekitLOF) {
131         switch (initialCCSDSFrame) {
132             case RSW:
133             case QSW:
134             case RTN:
135             case RIC:
136                 Assertions.assertEquals(OrbitRelativeFrame.RSW_INERTIAL, ccsdsFrameFromOrekitLOF);
137                 break;
138             case LVLH:
139                 Assertions.assertEquals(OrbitRelativeFrame.LVLH_INERTIAL, ccsdsFrameFromOrekitLOF);
140                 break;
141             case TNW:
142                 Assertions.assertEquals(OrbitRelativeFrame.TNW_INERTIAL, ccsdsFrameFromOrekitLOF);
143                 break;
144             default:
145                 Assertions.assertEquals(initialCCSDSFrame, ccsdsFrameFromOrekitLOF);
146         }
147     }
148 
149     @Test
150     @DisplayName("test error thrown when trying to convert LVLH LOFType to its OrbitRelativeFrame equivalent")
151     void testErrorThrownWhenTryingToConvertLVLHLOFTypeToOrbitRelativeFrame() {
152         // Given
153         final LOFType lvlh         = LOFType.LVLH;
154         final LOFType lvlhInertial = LOFType.LVLH_INERTIAL;
155 
156         // When
157         final Exception firstException  = Assertions.assertThrows(OrekitException.class, lvlh::toOrbitRelativeFrame);
158         final Exception secondException = Assertions.assertThrows(OrekitException.class, lvlhInertial::toOrbitRelativeFrame);
159 
160         // Then
161         final String expectedErrorMessage =
162                 "this LVLH local orbital frame uses a different definition, please use LVLH_CCSDS instead";
163 
164         Assertions.assertEquals(expectedErrorMessage, firstException.getMessage());
165         Assertions.assertEquals(expectedErrorMessage, secondException.getMessage());
166 
167     }
168 }