1   /* Copyright 2002-2025 Bryan Cazabonne
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    * Bryan Cazabonne 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.tle.generation;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.optim.nonlinear.vector.leastsquares.GaussNewtonOptimizer;
22  import org.hipparchus.util.Binary64Field;
23  import org.junit.jupiter.api.Assertions;
24  import org.junit.jupiter.api.BeforeEach;
25  import org.junit.jupiter.api.Test;
26  import org.orekit.Utils;
27  import org.orekit.data.DataContext;
28  import org.orekit.propagation.FieldSpacecraftState;
29  import org.orekit.propagation.Propagator;
30  import org.orekit.propagation.SpacecraftState;
31  import org.orekit.propagation.analytical.tle.FieldTLE;
32  import org.orekit.propagation.analytical.tle.FieldTLEPropagator;
33  import org.orekit.propagation.analytical.tle.TLE;
34  import org.orekit.propagation.analytical.tle.TLEPropagator;
35  import org.orekit.propagation.conversion.osc2mean.LeastSquaresConverter;
36  
37  
38  public class LeastSquaresTleGenerationAlgorithmTest {
39  
40      private TLE geoTLE;
41      private TLE leoTLE;
42  
43      @BeforeEach
44      public void setUp() {
45          Utils.setDataRoot("regular-data");
46          geoTLE = new TLE("1 27508U 02040A   12021.25695307 -.00000113  00000-0  10000-3 0  7326",
47                           "2 27508   0.0571 356.7800 0005033 344.4621 218.7816  1.00271798 34501");
48          leoTLE = new TLE("1 31135U 07013A   11003.00000000  .00000816  00000+0  47577-4 0    11",
49                           "2 31135   2.4656 183.9084 0021119 236.4164  60.4567 15.10546832    15");
50      }
51  
52      @Test
53      public void testConversionLeo() {
54          checkConversion(leoTLE, 1.0e-12, 3.755238453429068E-9);
55      }
56  
57      @Test
58      public void testConversionGeo() {
59          checkConversion(geoTLE, 1.0e-12, 3.135996497102161E-9);
60      }
61  
62      /** Check the State to TLE conversion. */
63      private void checkConversion(final TLE tle, final double threshold, final double rms) {
64  
65          Propagator p = TLEPropagator.selectExtrapolator(tle);
66          LeastSquaresTleGenerationAlgorithm converter = new LeastSquaresTleGenerationAlgorithm();
67          final TLE converted = converter.generate(p.getInitialState(), tle);
68  
69          Assertions.assertEquals(tle.getSatelliteNumber(),         converted.getSatelliteNumber());
70          Assertions.assertEquals(tle.getClassification(),          converted.getClassification());
71          Assertions.assertEquals(tle.getLaunchYear(),              converted.getLaunchYear());
72          Assertions.assertEquals(tle.getLaunchNumber(),            converted.getLaunchNumber());
73          Assertions.assertEquals(tle.getLaunchPiece(),             converted.getLaunchPiece());
74          Assertions.assertEquals(tle.getElementNumber(),           converted.getElementNumber());
75          Assertions.assertEquals(tle.getRevolutionNumberAtEpoch(), converted.getRevolutionNumberAtEpoch());
76  
77          Assertions.assertEquals(tle.getMeanMotion(), converted.getMeanMotion(), threshold * tle.getMeanMotion());
78          Assertions.assertEquals(tle.getE(), converted.getE(), threshold * tle.getE());
79          Assertions.assertEquals(tle.getI(), converted.getI(), threshold * tle.getI());
80          Assertions.assertEquals(tle.getPerigeeArgument(), converted.getPerigeeArgument(), threshold * tle.getPerigeeArgument());
81          Assertions.assertEquals(tle.getRaan(), converted.getRaan(), threshold * tle.getRaan());
82          Assertions.assertEquals(tle.getMeanAnomaly(), converted.getMeanAnomaly(), threshold * tle.getMeanAnomaly());
83  
84          Assertions.assertEquals(converter.getRms(), rms, threshold);
85  
86      }
87  
88      @Test
89      public void testIssue864() {
90  
91          // Initialize TLE
92          final TLE tleISS = new TLE("1 25544U 98067A   21035.14486477  .00001026  00000-0  26816-4 0  9998",
93                                     "2 25544  51.6455 280.7636 0002243 335.6496 186.1723 15.48938788267977");
94  
95          // TLE propagator
96          final TLEPropagator propagator = TLEPropagator.selectExtrapolator(tleISS);
97  
98          // State at TLE epoch
99          final SpacecraftState state = propagator.propagate(tleISS.getDate());
100 
101         // Set the BStar driver to selected
102         tleISS.getParametersDrivers().forEach(driver -> driver.setSelected(true));
103 
104         // Convert to TLE
105         final TLE rebuilt = new LeastSquaresTleGenerationAlgorithm().generate(state, tleISS);
106 
107         // Verify if driver is still selected
108         rebuilt.getParametersDrivers().forEach(driver -> Assertions.assertTrue(driver.isSelected()));
109 
110     }
111 
112     @Test
113     public void testUnsupportedField() {
114         doTestUnsupportedField(Binary64Field.getInstance());
115     }
116 
117     private <T extends CalculusFieldElement<T>> void doTestUnsupportedField(final Field<T> field) {
118         // Initialize TLE
119         final FieldTLE<T> tleISS = new FieldTLE<>(field, "1 25544U 98067A   21035.14486477  .00001026  00000-0  26816-4 0  9998",
120                                                          "2 25544  51.6455 280.7636 0002243 335.6496 186.1723 15.48938788267977");
121         // TLE propagator
122         final FieldTLEPropagator<T> propagator = FieldTLEPropagator.selectExtrapolator(tleISS, tleISS.getParameters(field));
123         // State at TLE epoch
124         final FieldSpacecraftState<T> state = propagator.propagate(tleISS.getDate());
125         // LeastSquaresConverter
126         final LeastSquaresConverter converter = new LeastSquaresConverter(null, new GaussNewtonOptimizer());
127         // LeastSquaresTleGenerationAlgorithm
128         final LeastSquaresTleGenerationAlgorithm ls = new LeastSquaresTleGenerationAlgorithm(DataContext.getDefault().getTimeScales().getUTC(),
129                                                                                              DataContext.getDefault().getFrames().getTEME(),
130                                                                                              converter);
131         // Should throw an exception
132         Assertions.assertThrows(UnsupportedOperationException.class, () -> {
133             ls.generate(state, tleISS);
134         });
135     }
136 
137 }