1   /* Copyright 2022-2025 Romain Serra
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.propagation;
18  
19  import org.hipparchus.linear.MatrixUtils;
20  import org.hipparchus.linear.RealMatrix;
21  import org.hipparchus.ode.nonstiff.DormandPrince54Integrator;
22  import org.junit.jupiter.params.ParameterizedTest;
23  import org.junit.jupiter.params.provider.EnumSource;
24  import org.orekit.frames.FramesFactory;
25  import org.orekit.frames.LOFType;
26  import org.orekit.orbits.EquinoctialOrbit;
27  import org.orekit.orbits.Orbit;
28  import org.orekit.orbits.OrbitType;
29  import org.orekit.orbits.PositionAngleType;
30  import org.orekit.propagation.conversion.DormandPrince54IntegratorBuilder;
31  import org.orekit.propagation.numerical.NumericalPropagator;
32  import org.orekit.time.AbsoluteDate;
33  import org.orekit.utils.Constants;
34  
35  import java.util.List;
36  
37  import static org.junit.jupiter.api.Assertions.assertEquals;
38  
39  class LinearKeplerianCovarianceHandlerTest {
40  
41      @ParameterizedTest
42      @EnumSource(OrbitType.class)
43      void testPropagationLof(final OrbitType orbitType) {
44          testPropagationTemplate(LOFType.QSW, orbitType);
45      }
46  
47      @ParameterizedTest
48      @EnumSource(value = LOFType.class, names = {"QSW", "TNW", "NTW", "LVLH"})
49      void testPropagationLof(final LOFType lofType) {
50          testPropagationTemplate(lofType, OrbitType.CARTESIAN);
51      }
52  
53      private void testPropagationTemplate(final LOFType lofType, final OrbitType orbitType) {
54          // GIVEN
55          final Orbit initialOrbit = new EquinoctialOrbit(7e6, 0.0001, 0., 1., 2., 3., PositionAngleType.MEAN,
56                  FramesFactory.getGCRF(), AbsoluteDate.ARBITRARY_EPOCH, Constants.EGM96_EARTH_MU);
57          final NumericalPropagator propagator = buildPropagator(initialOrbit, orbitType);
58          final AbsoluteDate targetDate = initialOrbit.getDate().shiftedBy(1e4);
59          final RealMatrix initialMatrix = MatrixUtils.createRealIdentityMatrix(6);
60          initialMatrix.setSubMatrix(MatrixUtils.createRealIdentityMatrix(3).scalarMultiply(1e-2).getData(), 3, 3);
61          final StateCovariance initialCovariance = new StateCovariance(initialMatrix, initialOrbit.getDate(), lofType);
62          final LinearKeplerianCovarianceHandler covarianceHandler = new LinearKeplerianCovarianceHandler(initialCovariance);
63          propagator.setStepHandler(covarianceHandler.toOrekitStepHandler());
64          // WHEN
65          propagator.propagate(targetDate);
66          final List<StateCovariance> covariances = covarianceHandler.getStatesCovariances();
67          final StateCovariance actualTerminalCovariance = covariances.get(covariances.size() - 1);
68          // THEN
69          final NumericalPropagator otherPropagator = buildPropagator(initialOrbit, orbitType);
70          final String stmName = "stm";
71          final MatricesHarvester harvester = otherPropagator.setupMatricesComputation(stmName, null, null);
72          final StateCovarianceMatrixProvider covarianceMatrixProvider = new StateCovarianceMatrixProvider("cov",
73                  stmName, harvester, initialCovariance.changeCovarianceFrame(initialOrbit, otherPropagator.getFrame()));
74          otherPropagator.addAdditionalDataProvider(covarianceMatrixProvider);
75          final SpacecraftState terminalState = otherPropagator.propagate(targetDate);
76          final StateCovariance terminalCovariance = covarianceMatrixProvider.getStateCovariance(terminalState);
77          final StateCovariance expectedCovariance = terminalCovariance.changeCovarianceFrame(terminalState.getOrbit(), lofType);
78          final RealMatrix difference = expectedCovariance.getMatrix().subtract(actualTerminalCovariance.getMatrix());
79          assertEquals(0., difference.getNorm1(),expectedCovariance.getMatrix().getNorm1() * 1e-6);
80      }
81  
82      private static NumericalPropagator buildPropagator(final Orbit initialOrbit, final OrbitType orbitType) {
83          final ToleranceProvider toleranceProvider = ToleranceProvider.getDefaultToleranceProvider(1e-3);
84          final DormandPrince54IntegratorBuilder integratorBuilder = new DormandPrince54IntegratorBuilder(1e-3, 1e2, toleranceProvider);
85          final DormandPrince54Integrator integrator = integratorBuilder.buildIntegrator(initialOrbit, orbitType);
86          final NumericalPropagator propagator = new NumericalPropagator(integrator);
87          propagator.setInitialState(new SpacecraftState(initialOrbit));
88          propagator.setOrbitType(orbitType);
89          propagator.setPositionAngleType(PositionAngleType.MEAN);
90          return propagator;
91      }
92  }