1   /* Copyright 2020-2025 Exotrail
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.conversion.averaging.converters;
18  
19  import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
20  import org.orekit.orbits.Orbit;
21  import org.orekit.propagation.SpacecraftState;
22  import org.orekit.propagation.semianalytical.dsst.DSSTPropagator;
23  import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
24  import org.orekit.propagation.conversion.averaging.DSST6X0OrbitalState;
25  import org.orekit.propagation.conversion.averaging.elements.AveragedEquinoctialWithMeanAngle;
26  
27  import java.util.Collection;
28  
29  /**
30   * Class for osculating-to-averaged conversion according to DSST theory, using 6 zonal harmonics as
31   * the only perturbations.
32   *
33   * @author Romain Serra
34   * @see DSSTPropagator
35   * @see DSST6X0OrbitalState
36   * @since 12.1
37   */
38  public class OsculatingToDSST6X0Converter
39          extends FixedPointOsculatingToAveragedConverter<DSST6X0OrbitalState> {
40  
41      /** Spherical harmonics provider. */
42      private final UnnormalizedSphericalHarmonicsProvider harmonicsProvider;
43  
44      /**
45       * Constructor with default parameters for fixed-point algorithm.
46       * @param harmonicsProvider unnormalized provider
47       */
48      public OsculatingToDSST6X0Converter(final UnnormalizedSphericalHarmonicsProvider harmonicsProvider) {
49          this(DEFAULT_EPSILON, DEFAULT_MAX_ITERATIONS, harmonicsProvider);
50      }
51  
52      /**
53       * Constructor.
54       * @param epsilon convergence threshold
55       * @param maxIterations maximum number of iterations
56       * @param harmonicsProvider unnormalized provider
57       */
58      public OsculatingToDSST6X0Converter(final double epsilon, final int maxIterations,
59                                          final UnnormalizedSphericalHarmonicsProvider harmonicsProvider) {
60          super(epsilon, maxIterations);
61          this.harmonicsProvider = harmonicsProvider;
62      }
63  
64      /** {@inheritDoc} */
65      @Override
66      public DSST6X0OrbitalState convertToAveraged(final Orbit osculatingOrbit) {
67          final Orbit averagedOrbit = createAveragedOrbit(osculatingOrbit);
68          final AveragedEquinoctialWithMeanAngle elements = buildElements(averagedOrbit);
69          return new DSST6X0OrbitalState(averagedOrbit.getDate(), elements,
70                  averagedOrbit.getFrame(), harmonicsProvider);
71      }
72  
73      /**
74       * Build averaged orbit.
75       * @param osculatingOrbit osculating orbit
76       * @return averaged orbit in DSST sense.
77       */
78      private Orbit createAveragedOrbit(final Orbit osculatingOrbit) {
79          final Collection<DSSTForceModel> forceModels = DSST6X0OrbitalState
80                  .createForces(harmonicsProvider);
81          final SpacecraftState osculatingState = new SpacecraftState(osculatingOrbit);
82          final SpacecraftState averagedState = DSSTPropagator.computeMeanState(osculatingState,
83                  null, forceModels, getEpsilon(), getMaxIterations());
84          return averagedState.getOrbit();
85      }
86  
87      /**
88       * Build averaged orbital elements from orbit.
89       * @param averagedOrbit averaged orbit
90       * @return orbital elements
91       */
92      private AveragedEquinoctialWithMeanAngle buildElements(final Orbit averagedOrbit) {
93          return new AveragedEquinoctialWithMeanAngle(averagedOrbit.getA(),
94                  averagedOrbit.getEquinoctialEx(), averagedOrbit.getEquinoctialEy(),
95                  averagedOrbit.getHx(), averagedOrbit.getHy(), averagedOrbit.getLM());
96      }
97  
98  }