1   /* Copyright 2002-2021 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.propagation.conversion;
18  
19  import org.orekit.attitudes.AttitudeProvider;
20  import org.orekit.attitudes.InertialProvider;
21  import org.orekit.forces.gravity.potential.GravityFieldFactory;
22  import org.orekit.forces.gravity.potential.TideSystem;
23  import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
24  import org.orekit.orbits.Orbit;
25  import org.orekit.orbits.OrbitType;
26  import org.orekit.orbits.PositionAngle;
27  import org.orekit.propagation.Propagator;
28  import org.orekit.propagation.analytical.EcksteinHechlerPropagator;
29  
30  /** Builder for Eckstein-Hechler propagator.
31   * @author Pascal Parraud
32   * @since 6.0
33   */
34  public class EcksteinHechlerPropagatorBuilder extends AbstractPropagatorBuilder {
35  
36      /** Provider for un-normalized coefficients. */
37      private final UnnormalizedSphericalHarmonicsProvider provider;
38  
39      /** Build a new instance.
40       * <p>
41       * The template orbit is used as a model to {@link
42       * #createInitialOrbit() create initial orbit}. It defines the
43       * inertial frame, the central attraction coefficient, the orbit type, and is also
44       * used together with the {@code positionScale} to convert from the {@link
45       * org.orekit.utils.ParameterDriver#setNormalizedValue(double) normalized} parameters used by the
46       * callers of this builder to the real orbital parameters.
47       * </p>
48       *
49       * @param templateOrbit reference orbit from which real orbits will be built
50       * (note that the mu from this orbit will be overridden with the mu from the
51       * {@code provider})
52       * @param provider for un-normalized zonal coefficients
53       * @param positionAngle position angle type to use
54       * @param positionScale scaling factor used for orbital parameters normalization
55       * (typically set to the expected standard deviation of the position)
56       * @since 8.0
57       * @see #EcksteinHechlerPropagatorBuilder(Orbit,
58       * UnnormalizedSphericalHarmonicsProvider, PositionAngle, double, AttitudeProvider)
59       */
60      public EcksteinHechlerPropagatorBuilder(final Orbit templateOrbit,
61                                              final UnnormalizedSphericalHarmonicsProvider provider,
62                                              final PositionAngle positionAngle,
63                                              final double positionScale) {
64          this(templateOrbit, provider, positionAngle, positionScale,
65                  InertialProvider.of(templateOrbit.getFrame()));
66      }
67  
68      /** Build a new instance.
69       * <p>
70       * The template orbit is used as a model to {@link
71       * #createInitialOrbit() create initial orbit}. It defines the
72       * inertial frame, the central attraction coefficient, the orbit type, and is also
73       * used together with the {@code positionScale} to convert from the {@link
74       * org.orekit.utils.ParameterDriver#setNormalizedValue(double) normalized} parameters used by the
75       * callers of this builder to the real orbital parameters.
76       * </p>
77       * @param templateOrbit reference orbit from which real orbits will be built
78       * (note that the mu from this orbit will be overridden with the mu from the
79       * {@code provider})
80       * @param provider for un-normalized zonal coefficients
81       * @param positionAngle position angle type to use
82       * @param positionScale scaling factor used for orbital parameters normalization
83       * (typically set to the expected standard deviation of the position)
84       * @param attitudeProvider attitude law to use.
85       * @since 10.1
86       */
87      public EcksteinHechlerPropagatorBuilder(final Orbit templateOrbit,
88                                              final UnnormalizedSphericalHarmonicsProvider provider,
89                                              final PositionAngle positionAngle,
90                                              final double positionScale,
91                                              final AttitudeProvider attitudeProvider) {
92          super(overrideMu(templateOrbit, provider, positionAngle), positionAngle,
93                  positionScale, true, attitudeProvider);
94          this.provider = provider;
95      }
96  
97      /** Build a new instance.
98       * <p>
99       * The template orbit is used as a model to {@link
100      * #createInitialOrbit() create initial orbit}. It defines the
101      * inertial frame, the central attraction coefficient, the orbit type, and is also
102      * used together with the {@code positionScale} to convert from the {@link
103      * org.orekit.utils.ParameterDriver#setNormalizedValue(double) normalized} parameters used by the
104      * callers of this builder to the real orbital parameters.
105      * </p>
106      *
107      * @param templateOrbit reference orbit from which real orbits will be built
108      * (note that the mu from this orbit will be overridden with the mu from the
109      * {@code provider})
110      * @param referenceRadius reference radius of the Earth for the potential model (m)
111      * @param mu central attraction coefficient (m³/s²)
112      * @param tideSystem tide system
113      * @param c20 un-normalized zonal coefficient (about -1.08e-3 for Earth)
114      * @param c30 un-normalized zonal coefficient (about +2.53e-6 for Earth)
115      * @param c40 un-normalized zonal coefficient (about +1.62e-6 for Earth)
116      * @param c50 un-normalized zonal coefficient (about +2.28e-7 for Earth)
117      * @param c60 un-normalized zonal coefficient (about -5.41e-7 for Earth)
118      * @param orbitType orbit type to use
119      * @param positionAngle position angle type to use
120      * @param positionScale scaling factor used for orbital parameters normalization
121      * (typically set to the expected standard deviation of the position)
122      * @since 8.0
123      * @see #EcksteinHechlerPropagatorBuilder(Orbit,
124      * UnnormalizedSphericalHarmonicsProvider, PositionAngle, double, AttitudeProvider)
125      */
126     public EcksteinHechlerPropagatorBuilder(final Orbit templateOrbit,
127                                             final double referenceRadius,
128                                             final double mu,
129                                             final TideSystem tideSystem,
130                                             final double c20,
131                                             final double c30,
132                                             final double c40,
133                                             final double c50,
134                                             final double c60,
135                                             final OrbitType orbitType,
136                                             final PositionAngle positionAngle,
137                                             final double positionScale) {
138         this(templateOrbit,
139              GravityFieldFactory.getUnnormalizedProvider(referenceRadius, mu, tideSystem,
140                                                          new double[][] {
141                                                              {
142                                                                  0
143                                                              }, {
144                                                                  0
145                                                              }, {
146                                                                  c20
147                                                              }, {
148                                                                  c30
149                                                              }, {
150                                                                  c40
151                                                              }, {
152                                                                  c50
153                                                              }, {
154                                                                  c60
155                                                              }
156                                                          }, new double[][] {
157                                                              {
158                                                                  0
159                                                              }, {
160                                                                  0
161                                                              }, {
162                                                                  0
163                                                              }, {
164                                                                  0
165                                                              }, {
166                                                                  0
167                                                              }, {
168                                                                  0
169                                                              }, {
170                                                                  0
171                                                              }
172                                                          }),
173              positionAngle, positionScale);
174     }
175 
176     /** Override central attraction coefficient.
177      * @param templateOrbit template orbit
178      * @param provider gravity field provider
179      * @param positionAngle position angle type to use
180      * @return orbit with overridden central attraction coefficient
181      */
182     private static Orbit overrideMu(final Orbit templateOrbit,
183                                     final UnnormalizedSphericalHarmonicsProvider provider,
184                                     final PositionAngle positionAngle) {
185         final double[] parameters    = new double[6];
186         final double[] parametersDot = templateOrbit.hasDerivatives() ? new double[6] : null;
187         templateOrbit.getType().mapOrbitToArray(templateOrbit, positionAngle, parameters, parametersDot);
188         return templateOrbit.getType().mapArrayToOrbit(parameters, parametersDot, positionAngle,
189                                                        templateOrbit.getDate(),
190                                                        provider.getMu(),
191                                                        templateOrbit.getFrame());
192     }
193 
194     /** {@inheritDoc} */
195     public Propagator buildPropagator(final double[] normalizedParameters) {
196         setParameters(normalizedParameters);
197         return new EcksteinHechlerPropagator(createInitialOrbit(), getAttitudeProvider(),
198                 provider);
199     }
200 
201 }