1   /* Copyright 2002-2025 Airbus Defence and Space
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    * Airbus Defence and Space 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.propagation.analytical.intelsat;
18  
19  import org.hipparchus.util.Binary64;
20  import org.hipparchus.util.FastMath;
21  import org.hipparchus.util.MathUtils;
22  import org.junit.jupiter.api.Assertions;
23  import org.junit.jupiter.api.BeforeAll;
24  import org.junit.jupiter.api.Test;
25  import org.orekit.errors.OrekitException;
26  import org.orekit.errors.OrekitMessages;
27  import org.orekit.frames.FramesFactory;
28  import org.orekit.orbits.FieldKeplerianOrbit;
29  import org.orekit.orbits.KeplerianOrbit;
30  import org.orekit.orbits.OrbitType;
31  import org.orekit.orbits.PositionAngleType;
32  import org.orekit.time.FieldAbsoluteDate;
33  import org.orekit.time.TimeScalesFactory;
34  import org.orekit.utils.IERSConventions;
35  
36  public class FieldIntelsatElevenElementsPropagatorTest {
37  
38      private static FieldIntelsatElevenElements<Binary64> ELEMENTS;
39  
40      @Test
41      public void testCannotResetIntermediateState() {
42          FieldIntelsatElevenElementsPropagator<Binary64> propagator = new FieldIntelsatElevenElementsPropagator<>(ELEMENTS);
43          try {
44              propagator.resetIntermediateState(null, false);
45          }
46          catch (OrekitException oe) {
47              Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.NON_RESETABLE_STATE);
48          }
49      }
50  
51      @Test
52      public void testCannotResetInitialState() {
53          FieldIntelsatElevenElementsPropagator<Binary64> propagator = new FieldIntelsatElevenElementsPropagator<>(ELEMENTS);
54          try {
55              propagator.resetInitialState(null);
56          }
57          catch (OrekitException oe) {
58              Assertions.assertEquals(oe.getSpecifier(), OrekitMessages.NON_RESETABLE_STATE);
59          }
60      }
61  
62      @Test
63      public void testPropagation() {
64          // Reference: Intelsat calculator for spacecraft 4521 (used 2023/12/07)
65          // https://www.intelsat.com/resources/tools/
66          FieldIntelsatElevenElementsPropagator<Binary64> propagator = new FieldIntelsatElevenElementsPropagator<>(ELEMENTS);
67          double referenceLongitude170Hours = 301.9191;
68          double referenceLatitude170Hours = 0.0257;
69          double tolerance = 0.0001;
70          propagator.propagateInEcef(ELEMENTS.getEpoch().shiftedBy(170 * 3600.0));
71          Assertions.assertNotNull(propagator.getIntelsatElevenElements());
72          Assertions.assertEquals(referenceLongitude170Hours, propagator.getEastLongitudeDegrees().getValue().getReal(), tolerance);
73          Assertions.assertEquals(referenceLatitude170Hours, propagator.getGeocentricLatitudeDegrees().getValue().getReal(), tolerance);
74      }
75  
76      @Test
77      public void testOrbitElementsAtT0() {
78          // Reference use of the Intelsat's 11 elements propagator developed in STK
79          FieldIntelsatElevenElementsPropagator<Binary64> propagator = new FieldIntelsatElevenElementsPropagator<>(ELEMENTS, FramesFactory.getTOD(IERSConventions.IERS_2010, false),
80                                                                                                                   FramesFactory.getITRF(IERSConventions.IERS_2010, false));
81          KeplerianOrbit orbit = ((FieldKeplerianOrbit<Binary64>) OrbitType.KEPLERIAN.convertType(
82                  propagator.propagateOrbit(ELEMENTS.getEpoch(), propagator.getParameters(ELEMENTS.getEpoch().getField())))).toOrbit();
83          Assertions.assertNotNull(propagator.getIntelsatElevenElements());
84          Assertions.assertEquals(302.0355, propagator.getEastLongitudeDegrees().getValue().getReal(), 0.0001);
85          Assertions.assertEquals(0.0378, propagator.getGeocentricLatitudeDegrees().getValue().getReal(), 0.0001);
86          Assertions.assertEquals(-1.529465e-6, propagator.getEastLongitudeDegrees().getFirstDerivative().getReal(), 1.0e-12);
87          Assertions.assertEquals(-1.01044e-7, propagator.getGeocentricLatitudeDegrees().getFirstDerivative().getReal(), 1.0e-12);
88          Assertions.assertEquals(42172456.005, propagator.getOrbitRadius().getValue().getReal(), 1.0e-3);
89          Assertions.assertEquals(0.797, propagator.getOrbitRadius().getFirstDerivative().getReal(), 1.0e-3);
90          Assertions.assertEquals(42166413.453, orbit.getA(), 4.0e-2);
91          Assertions.assertEquals(0.000296, orbit.getE(), 1.0e-6);
92          Assertions.assertEquals(0.037825, FastMath.toDegrees(orbit.getI()), 1.0e-6);
93          Assertions.assertEquals(282.488, FastMath.toDegrees(MathUtils.normalizeAngle(orbit.getRightAscensionOfAscendingNode(), FastMath.PI)), 4.0e-3);
94          Assertions.assertEquals(333.151, FastMath.toDegrees(MathUtils.normalizeAngle(orbit.getPerigeeArgument(), FastMath.PI)), 4.0e-3);
95          Assertions.assertEquals(118.919, FastMath.toDegrees(MathUtils.normalizeAngle(orbit.getAnomaly(PositionAngleType.MEAN), FastMath.PI)), 1.0e-3);
96      }
97  
98      @BeforeAll
99      public static void initialize() {
100         Binary64 zero = new Binary64(0.0);
101         // Reference elements from Intelsat website (spacecraft 4521)
102         ELEMENTS = new FieldIntelsatElevenElements<>(new FieldAbsoluteDate<>(zero.getField(), "2023-12-04T00:00:00.000", TimeScalesFactory.getUTC()), zero.add(302.0058),
103                                                      zero.add(-0.0096), zero.add(-0.000629), zero.add(0.0297), zero.add(-0.0004), zero.add(-0.0194), zero.add(0.0007),
104                                                      zero.add(0.0378), zero.add(-0.0018), zero.add(-0.0011), zero.add(0.0015));
105     }
106 }