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