1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical.tle.generation;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.analysis.differentiation.Gradient;
21 import org.hipparchus.analysis.differentiation.GradientField;
22 import org.hipparchus.linear.MatrixUtils;
23 import org.hipparchus.linear.RealMatrix;
24 import org.hipparchus.util.FastMath;
25 import org.hipparchus.util.MathUtils;
26 import org.orekit.frames.Frame;
27 import org.orekit.orbits.AbstractOrbitalParameterFactory;
28 import org.orekit.orbits.FieldKeplerianOrbit;
29 import org.orekit.orbits.KeplerianOrbit;
30 import org.orekit.orbits.Orbit;
31 import org.orekit.orbits.OrbitType;
32 import org.orekit.orbits.PositionAngleType;
33 import org.orekit.propagation.FieldSpacecraftState;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.propagation.analytical.tle.FieldTLE;
36 import org.orekit.propagation.analytical.tle.FieldTLEPropagator;
37 import org.orekit.propagation.analytical.tle.TLE;
38 import org.orekit.propagation.analytical.tle.TLEConstants;
39 import org.orekit.propagation.conversion.osc2mean.OsculatingToMeanConverter;
40 import org.orekit.time.FieldAbsoluteDate;
41 import org.orekit.utils.ParameterDriver;
42 import org.orekit.utils.ParameterDriversList;
43 import org.orekit.utils.ParameterDriversList.DelegatingDriver;
44 import org.orekit.utils.TimeStampedFieldPVCoordinates;
45
46 import java.util.List;
47
48
49
50
51
52
53 public abstract class TleGenerationAlgorithm extends AbstractOrbitalParameterFactory<TLE> {
54
55
56 public static final String MEAN_MOTION = "TleMeanMotion";
57
58
59 public static final String ECCENTRICITY = "TleEccentricity";
60
61
62 public static final String INCLINATION = "TleInclination";
63
64
65 public static final String PERIAPSIS_ARGUMENT = "TlePeriapsisArgument";
66
67
68 public static final String RAAN = "TleRighAscensionAscendingNode";
69
70
71 public static final String MEAN_ANOM = "TleMeanAnomaly";
72
73
74 public static final String B_STAR = "BSTAR";
75
76
77
78
79
80
81
82 public static final double B_STAR_SCALE = FastMath.scalb(1.0, -20);
83
84
85 private static final int DEFAULT_STATE_DIMENSION = 6;
86
87
88 private final TLE templateTLE;
89
90
91 private ParameterDriversList nonKeplerianDrivers;
92
93
94 private final OsculatingToMeanConverter converter;
95
96
97
98
99
100
101 protected TleGenerationAlgorithm(final TLE templateTLE, final Frame teme,
102 final OsculatingToMeanConverter converter) {
103 super(null, createOrbitalParametersDrivers(templateTLE), teme, PositionAngleType.MEAN,
104 templateTLE.getDate(), TLEConstants.MU);
105 this.templateTLE = templateTLE;
106
107
108 nonKeplerianDrivers = new ParameterDriversList();
109 nonKeplerianDrivers.add(new ParameterDriver(B_STAR, templateTLE.getBStar(), B_STAR_SCALE,
110 Double.NEGATIVE_INFINITY,
111 Double.POSITIVE_INFINITY));
112
113
114 this.converter = converter;
115
116 }
117
118
119
120
121 public TLE getTemplateTLE() {
122 return templateTLE;
123 }
124
125
126
127
128
129 public OsculatingToMeanConverter getConverter() {
130 return converter;
131 }
132
133
134 @Override
135 public ParameterDriversList getNonKeplerianParametersDrivers() {
136 return nonKeplerianDrivers;
137 }
138
139
140
141
142
143 private static ParameterDriversList createOrbitalParametersDrivers(final TLE tle) {
144 final ParameterDriversList drivers = new ParameterDriversList();
145 drivers.add(new ParameterDriver(MEAN_MOTION, tle.getMeanMotion(),
146 FastMath.scalb(1.0, -32),
147 0, Double.POSITIVE_INFINITY));
148 drivers.add(new ParameterDriver(ECCENTRICITY, tle.getE(),
149 FastMath.scalb(1.0, -22),
150 0.0, 1.0));
151 drivers.add(new ParameterDriver(INCLINATION, tle.getI(),
152 FastMath.scalb(1.0, -22),
153 0, FastMath.PI));
154 drivers.add(new ParameterDriver(PERIAPSIS_ARGUMENT, tle.getPeriapsisArgument(),
155 FastMath.scalb(1.0, -22),
156 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
157 drivers.add(new ParameterDriver(RAAN, tle.getRaan(),
158 FastMath.scalb(1.0, -22),
159 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
160 drivers.add(new ParameterDriver(MEAN_ANOM, tle.getMeanAnomaly(),
161 FastMath.scalb(1.0, -22),
162 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
163 return drivers;
164 }
165
166
167 @Override
168 protected double[] toArray(final Orbit orbit) {
169
170
171 final Orbit mean = converter.convertToMean(orbit);
172 final Orbit partiallyConverted = orbit.getFrame() == getFrame() ? mean : mean.inFrame(getFrame());
173 final Orbit fullyConverted = OrbitType.KEPLERIAN.convertType(partiallyConverted);
174
175
176 final double[] stateVector = new double[6];
177 OrbitType.KEPLERIAN.mapOrbitToArray(fullyConverted, PositionAngleType.MEAN, stateVector, null);
178
179
180 stateVector[0] = fullyConverted.getKeplerianMeanMotion();
181
182 return stateVector;
183
184 }
185
186
187 @Override
188 public TLE createFromDrivers() {
189
190 final List<DelegatingDriver> drivers = getOrbitalParametersDrivers().getDrivers();
191
192
193
194 final double latArg0 =
195 MathUtils.normalizeAngle(drivers.get(3).getValue() + drivers.get(5).getValue(),
196 FastMath.PI);
197 final double deltaT = getDate().durationFrom(templateTLE.getDate());
198 final double latArg1 = latArg0 + deltaT * drivers.get(0).getValue();
199 final int deltaRev = (int) FastMath.floor(latArg1 / MathUtils.TWO_PI);
200
201 return new TLE(templateTLE.getSatelliteNumber(), templateTLE.getClassification(),
202 templateTLE.getLaunchYear(), templateTLE.getLaunchNumber(), templateTLE.getLaunchPiece(),
203 templateTLE.getEphemerisType(),
204 templateTLE.getElementNumber() + 1,
205 getDate(),
206 drivers.get(0).getValue(),
207 templateTLE.getMeanMotionFirstDerivative(), templateTLE.getMeanMotionSecondDerivative(),
208 drivers.get(1).getValue(),
209 drivers.get(2).getValue(),
210 drivers.get(3).getValue(),
211 drivers.get(4).getValue(),
212 drivers.get(5).getValue(),
213 templateTLE.getRevolutionNumberAtEpoch() + deltaRev,
214 getBStar(),
215 templateTLE.getUtc());
216 }
217
218
219
220
221
222
223
224
225
226
227 @Override
228 public RealMatrix getJacobianWrtParameters() {
229 return getJacobianWrtParameters(createFromDrivers());
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243 public RealMatrix getJacobianWrtParameters(final TLE tle) {
244
245
246 final TimeStampedFieldPVCoordinates<Gradient> pv =
247 FieldTLEPropagator.selectExtrapolator(toGradient(tle), getFrame()).
248 getBaseInitialState().
249 getPVCoordinates();
250
251
252 final RealMatrix jacobian = MatrixUtils.createRealMatrix(DEFAULT_STATE_DIMENSION, DEFAULT_STATE_DIMENSION);
253 jacobian.setRow(0, pv.getPosition().getX().getGradient());
254 jacobian.setRow(1, pv.getPosition().getY().getGradient());
255 jacobian.setRow(2, pv.getPosition().getZ().getGradient());
256 jacobian.setRow(3, pv.getVelocity().getX().getGradient());
257 jacobian.setRow(4, pv.getVelocity().getY().getGradient());
258 jacobian.setRow(5, pv.getVelocity().getZ().getGradient());
259
260 return jacobian;
261
262 }
263
264
265
266
267
268
269 private static FieldTLE<Gradient> toGradient(final TLE tle) {
270 final GradientField field = GradientField.getField(DEFAULT_STATE_DIMENSION);
271 return new FieldTLE<>(tle.getSatelliteNumber(), tle.getClassification(),
272 tle.getLaunchYear(), tle.getLaunchNumber(), tle.getLaunchPiece(),
273 tle.getEphemerisType(), tle.getElementNumber(),
274 new FieldAbsoluteDate<>(field, tle.getDate()),
275 Gradient.variable(DEFAULT_STATE_DIMENSION, 0, tle.getMeanMotion()),
276 Gradient.constant(DEFAULT_STATE_DIMENSION, tle.getMeanMotionFirstDerivative()),
277 Gradient.constant(DEFAULT_STATE_DIMENSION, tle.getMeanMotionSecondDerivative()),
278 Gradient.variable(DEFAULT_STATE_DIMENSION, 1, tle.getE()),
279 Gradient.variable(DEFAULT_STATE_DIMENSION, 2, tle.getI()),
280 Gradient.variable(DEFAULT_STATE_DIMENSION, 3, tle.getPeriapsisArgument()),
281 Gradient.variable(DEFAULT_STATE_DIMENSION, 4, tle.getRaan()),
282 Gradient.variable(DEFAULT_STATE_DIMENSION, 5, tle.getMeanAnomaly()),
283 tle.getRevolutionNumberAtEpoch(),
284 Gradient.constant(DEFAULT_STATE_DIMENSION, tle.getBStar()),
285 tle.getUtc());
286 }
287
288
289
290
291 protected double getBStar() {
292 return nonKeplerianDrivers.getDrivers().getFirst().getValue();
293 }
294
295
296
297
298
299
300
301
302
303
304
305
306
307 public TLE generate(final SpacecraftState state, final TLE newTemplateTLE) {
308 final KeplerianOrbit mean =
309 (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(converter.convertToMean(state.getOrbit()));
310 return TleGenerationUtil.newTLE(mean, newTemplateTLE);
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326 public <T extends CalculusFieldElement<T>> FieldTLE<T> generate(final FieldSpacecraftState<T> state,
327 final FieldTLE<T> newTemplateTLE) {
328 final FieldKeplerianOrbit<T> mean =
329 (FieldKeplerianOrbit<T>) OrbitType.KEPLERIAN.convertType(converter.convertToMean(state.getOrbit()));
330 return TleGenerationUtil.newTLE(mean, newTemplateTLE);
331 }
332
333
334 @Override
335 public TleGenerationAlgorithm clone() {
336
337 final TleGenerationAlgorithm clone = (TleGenerationAlgorithm) super.clone();
338
339
340 final ParameterDriversList newDrivers = new ParameterDriversList();
341 final ParameterDriver driver = nonKeplerianDrivers.getDrivers().getFirst();
342 newDrivers.add(new ParameterDriver(driver.getName(), driver.getValue(), driver.getScale(),
343 driver.getMinValue(), driver.getMaxValue()));
344 clone.nonKeplerianDrivers = newDrivers;
345
346 return clone;
347
348 }
349
350 }