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.files.ccsds.definitions;
18  
19  import org.hamcrest.CoreMatchers;
20  import org.hamcrest.MatcherAssert;
21  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.hipparchus.util.Decimal64;
24  import org.hipparchus.util.Decimal64Field;
25  import org.junit.Assert;
26  import org.junit.Before;
27  import org.junit.Test;
28  import org.orekit.Utils;
29  import org.orekit.bodies.CelestialBodyFactory;
30  import org.orekit.bodies.GeodeticPoint;
31  import org.orekit.bodies.OneAxisEllipsoid;
32  import org.orekit.data.DataContext;
33  import org.orekit.errors.OrekitException;
34  import org.orekit.errors.OrekitMessages;
35  import org.orekit.frames.Frame;
36  import org.orekit.frames.FramesFactory;
37  import org.orekit.frames.ITRFVersion;
38  import org.orekit.frames.TopocentricFrame;
39  import org.orekit.frames.Transform;
40  import org.orekit.time.AbsoluteDate;
41  import org.orekit.time.FieldAbsoluteDate;
42  import org.orekit.utils.Constants;
43  import org.orekit.utils.IERSConventions;
44  
45  
46  public class CelestialBodyFrameTest {
47  
48      /**
49       * Check mapping frames to CCSDS frames.
50       */
51      @Test
52      public void testMap() {
53          // action + verify
54          // check all non-LOF frames created by OEMParser
55          for (CelestialBodyFrame ccsdsFrame : CelestialBodyFrame.values()) {
56              Frame frame = ccsdsFrame.getFrame(IERSConventions.IERS_2010, true, DataContext.getDefault());
57              CelestialBodyFrame actual = CelestialBodyFrame.map(frame);
58              if (ccsdsFrame == CelestialBodyFrame.J2000) {
59                  // CCSDS allows both J2000 and EME2000 names
60                  // Orekit chose to use EME2000 when guessing name from frame instance
61                  MatcherAssert.assertThat(actual, CoreMatchers.is(CelestialBodyFrame.EME2000));
62              } else  if (ccsdsFrame == CelestialBodyFrame.TDR) {
63                  // CCSDS allows both GTOD (in ADM section A3) and
64                  // TDR (in ODM table 5-3 and section A2) names
65                  // Orekit chose to use GTOD when guessing name from frame instance
66                  MatcherAssert.assertThat(actual, CoreMatchers.is(CelestialBodyFrame.GTOD));
67              } else {
68                  MatcherAssert.assertThat(actual, CoreMatchers.is(ccsdsFrame));
69              }
70          }
71  
72          // check common Orekit frames from FramesFactory
73          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getGCRF()),
74                                   CoreMatchers.is(CelestialBodyFrame.GCRF));
75          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getEME2000()),
76                                   CoreMatchers.is(CelestialBodyFrame.EME2000));
77          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getITRFEquinox(IERSConventions.IERS_2010, true)),
78                                   CoreMatchers.is(CelestialBodyFrame.GRC));
79          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getICRF()),
80                                   CoreMatchers.is(CelestialBodyFrame.ICRF));
81          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getITRF(IERSConventions.IERS_2010, true)),
82                                   CoreMatchers.is(CelestialBodyFrame.ITRF2014));
83          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getGTOD(true)),
84                                   CoreMatchers.is(CelestialBodyFrame.GTOD));
85          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getTEME()),
86                                   CoreMatchers.is(CelestialBodyFrame.TEME));
87          MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getTOD(true)),
88                                   CoreMatchers.is(CelestialBodyFrame.TOD));
89  
90          // check that guessed name loses the IERS conventions and simpleEOP flag
91          for (ITRFVersion version : ITRFVersion.values()) {
92              final String name = version.getName().replaceAll("-", "");
93              for (final IERSConventions conventions : IERSConventions.values()) {
94                  MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getITRF(version, conventions, true)).name(),
95                                           CoreMatchers.is(name));
96                  MatcherAssert.assertThat(CelestialBodyFrame.map(FramesFactory.getITRF(version, conventions, false)).name(),
97                                           CoreMatchers.is(name));
98              }
99          }
100 
101         // check other names in Annex A
102         MatcherAssert.assertThat(
103                 CelestialBodyFrame.map(CelestialBodyFactory.getMars().getInertiallyOrientedFrame()),
104                 CoreMatchers.is(CelestialBodyFrame.MCI));
105         MatcherAssert.assertThat(CelestialBodyFrame.map(CelestialBodyFactory.getSolarSystemBarycenter().
106                                  getInertiallyOrientedFrame()),
107                                  CoreMatchers.is(CelestialBodyFrame.ICRF));
108         // check some special CCSDS frames
109         ModifiedFrame frame = new ModifiedFrame(FramesFactory.getEME2000(),
110                                                           CelestialBodyFrame.EME2000,
111                                                           CelestialBodyFactory.getMars(), "MARS");
112         MatcherAssert.assertThat(CelestialBodyFrame.map(frame), CoreMatchers.is(CelestialBodyFrame.EME2000));
113         Vector3D v = frame.getTransformProvider().getTransform(AbsoluteDate.J2000_EPOCH).getTranslation();
114         FieldVector3D<Decimal64> v64 = frame.getTransformProvider().getTransform(FieldAbsoluteDate.getJ2000Epoch(Decimal64Field.getInstance())).getTranslation();
115         Assert.assertEquals(0.0, FieldVector3D.distance(v64, v).getReal(), 1.0e-10);
116 
117         // check unknown frame
118         try {
119             Frame topo = new TopocentricFrame(new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
120                                                                    Constants.WGS84_EARTH_FLATTENING,
121                                                                    FramesFactory.getITRF(IERSConventions.IERS_2010, true)),
122                                               new GeodeticPoint(1.2, 2.3, 45.6),
123                             "dummy");
124             CelestialBodyFrame.map(topo);
125             Assert.fail("an exception should have been thrown");
126         } catch (OrekitException oe) {
127             Assert.assertEquals(OrekitMessages.CCSDS_INVALID_FRAME, oe.getSpecifier());
128             Assert.assertEquals("dummy", oe.getParts()[0]);
129         }
130 
131         // check a fake ICRF
132         Frame fakeICRF = new Frame(FramesFactory.getGCRF(), Transform.IDENTITY,
133                                    CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER + "/inertial");
134         MatcherAssert.assertThat(CelestialBodyFrame.map(fakeICRF), CoreMatchers.is(CelestialBodyFrame.ICRF));
135     }
136 
137     @Test
138     public void testNoConventions() {
139         for (final CelestialBodyFrame cbf : CelestialBodyFrame.values()) {
140             if (cbf == CelestialBodyFrame.EME2000 || cbf == CelestialBodyFrame.J2000 ||
141                 cbf == CelestialBodyFrame.GCRF    || cbf == CelestialBodyFrame.ICRF ||
142                 cbf == CelestialBodyFrame.MCI     || cbf == CelestialBodyFrame.TEME) {
143                 Assert.assertNotNull(cbf.getFrame(null, false, DataContext.getDefault()));
144             } else {
145                 try {
146                     cbf.getFrame(null, false, DataContext.getDefault());
147                     Assert.fail("an exception should have been thrown");
148                 } catch (OrekitException oe) {
149                     Assert.assertEquals(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS, oe.getSpecifier());
150                 }
151             }
152         }
153     }
154 
155     @Test
156     public void testParse() {
157         Assert.assertEquals(CelestialBodyFrame.EME2000, CelestialBodyFrame.parse("EME2000"));
158         Assert.assertEquals(CelestialBodyFrame.ITRF2014, CelestialBodyFrame.parse("ITRF2014"));
159         Assert.assertEquals(CelestialBodyFrame.ITRF1997, CelestialBodyFrame.parse("ITRF97"));
160         try {
161             Assert.assertEquals(CelestialBodyFrame.EME2000, CelestialBodyFrame.parse("ITRF00"));
162             Assert.fail("an exception should have been thrown");
163         } catch (IllegalArgumentException iae) {
164             Assert.assertTrue(iae.getMessage().contains("ITRF00"));
165         }
166         try {
167             CelestialBodyFrame.parse("ITRF");
168             Assert.fail("an exception should have been thrown");
169         } catch (IllegalArgumentException iae) {
170             Assert.assertTrue(iae.getMessage().contains("ITRF"));
171         }
172     }
173 
174     /**
175      * Check guessing names.
176      */
177     @Test
178     public void testGuessFrame() {
179 
180         Frame itrf89 = FramesFactory.getITRF(ITRFVersion.ITRF_1989, IERSConventions.IERS_1996, true);
181         Assert.assertEquals("ITRF1989", CelestialBodyFrame.guessFrame(itrf89));
182 
183         Frame topo = new TopocentricFrame(new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
184                                                                Constants.WGS84_EARTH_FLATTENING,
185                                                                FramesFactory.getITRF(IERSConventions.IERS_2010, true)),
186                                           new GeodeticPoint(1.2, 2.3, 45.6),
187                         "dummy");
188         Assert.assertEquals("dummy", CelestialBodyFrame.guessFrame(topo));
189     }
190 
191     @Before
192     public void setUp() {
193         Utils.setDataRoot("regular-data");
194     }
195 
196 }