1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical.intelsat;
18
19 import java.util.Collections;
20 import java.util.List;
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.Field;
23 import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
24 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
25 import org.hipparchus.util.FastMath;
26 import org.hipparchus.util.FieldSinCos;
27 import org.orekit.annotation.DefaultDataContext;
28 import org.orekit.attitudes.AttitudeProvider;
29 import org.orekit.attitudes.FieldAttitude;
30 import org.orekit.attitudes.FrameAlignedProvider;
31 import org.orekit.data.DataContext;
32 import org.orekit.errors.OrekitException;
33 import org.orekit.errors.OrekitMessages;
34 import org.orekit.frames.Frame;
35 import org.orekit.frames.FramesFactory;
36 import org.orekit.orbits.FieldCartesianOrbit;
37 import org.orekit.orbits.FieldOrbit;
38 import org.orekit.propagation.FieldSpacecraftState;
39 import org.orekit.propagation.Propagator;
40 import org.orekit.propagation.analytical.FieldAbstractAnalyticalPropagator;
41 import org.orekit.time.FieldAbsoluteDate;
42 import org.orekit.utils.Constants;
43 import org.orekit.utils.FieldPVCoordinates;
44 import org.orekit.utils.IERSConventions;
45 import org.orekit.utils.ParameterDriver;
46 import org.orekit.utils.units.Unit;
47
48
49
50
51
52
53
54
55
56
57 public class FieldIntelsatElevenElementsPropagator<T extends CalculusFieldElement<T>> extends FieldAbstractAnalyticalPropagator<T> {
58
59
60
61
62 private final FieldIntelsatElevenElements<T> elements;
63
64
65
66
67 private final Frame inertialFrame;
68
69
70
71
72 private final Frame ecefFrame;
73
74
75
76
77 private final T mass;
78
79
80
81
82 private FieldUnivariateDerivative2<T> eastLongitudeDegrees;
83
84
85
86
87 private FieldUnivariateDerivative2<T> geocentricLatitudeDegrees;
88
89
90
91
92 private FieldUnivariateDerivative2<T> orbitRadius;
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 @DefaultDataContext
113 public FieldIntelsatElevenElementsPropagator(final FieldIntelsatElevenElements<T> elements) {
114 this(elements, FramesFactory.getTOD(IERSConventions.IERS_2010, true), FramesFactory.getITRF(IERSConventions.IERS_2010, true));
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public FieldIntelsatElevenElementsPropagator(final FieldIntelsatElevenElements<T> elements, final Frame inertialFrame, final Frame ecefFrame) {
130 this(elements, inertialFrame, ecefFrame, FrameAlignedProvider.of(inertialFrame), elements.getEpoch().getField().getZero().add(Propagator.DEFAULT_MASS));
131 }
132
133
134
135
136
137
138
139
140
141
142 public FieldIntelsatElevenElementsPropagator(final FieldIntelsatElevenElements<T> elements, final Frame inertialFrame, final Frame ecefFrame,
143 final AttitudeProvider attitudeProvider, final T mass) {
144 super(elements.getEpoch().getField(), attitudeProvider);
145 this.elements = elements;
146 this.inertialFrame = inertialFrame;
147 this.ecefFrame = ecefFrame;
148 this.mass = mass;
149 setStartDate(elements.getEpoch());
150 final FieldOrbit<T> orbitAtElementsDate = propagateOrbit(elements.getEpoch(), getParameters(elements.getEpoch().getField()));
151 final FieldAttitude<T> attitude = attitudeProvider.getAttitude(orbitAtElementsDate, elements.getEpoch(), inertialFrame);
152 super.resetInitialState(new FieldSpacecraftState<>(orbitAtElementsDate, attitude).withMass(mass));
153 }
154
155
156
157
158
159
160
161 public FieldPVCoordinates<T> propagateInEcef(final FieldAbsoluteDate<T> date) {
162 final Field<T> field = date.getField();
163 final FieldUnivariateDerivative2<T> tDays = new FieldUnivariateDerivative2<>(date.durationFrom(elements.getEpoch()), field.getOne(), field.getZero()).divide(
164 Constants.JULIAN_DAY);
165 final T wDegreesPerDay = elements.getLm1().add(IntelsatElevenElements.DRIFT_RATE_SHIFT_DEG_PER_DAY);
166 final FieldUnivariateDerivative2<T> wt = FastMath.toRadians(tDays.multiply(wDegreesPerDay));
167 final FieldSinCos<FieldUnivariateDerivative2<T>> scWt = FastMath.sinCos(wt);
168 final FieldSinCos<FieldUnivariateDerivative2<T>> sc2Wt = FastMath.sinCos(wt.multiply(2.0));
169 final FieldUnivariateDerivative2<T> satelliteEastLongitudeDegrees = computeSatelliteEastLongitudeDegrees(tDays, scWt, sc2Wt);
170 final FieldUnivariateDerivative2<T> satelliteGeocentricLatitudeDegrees = computeSatelliteGeocentricLatitudeDegrees(tDays, scWt);
171 final FieldUnivariateDerivative2<T> satelliteRadius = computeSatelliteRadiusKilometers(wDegreesPerDay, scWt).multiply(Unit.KILOMETRE.getScale());
172 this.eastLongitudeDegrees = satelliteEastLongitudeDegrees;
173 this.geocentricLatitudeDegrees = satelliteGeocentricLatitudeDegrees;
174 this.orbitRadius = satelliteRadius;
175 final FieldSinCos<FieldUnivariateDerivative2<T>> scLongitude = FastMath.sinCos(FastMath.toRadians(satelliteEastLongitudeDegrees));
176 final FieldSinCos<FieldUnivariateDerivative2<T>> scLatitude = FastMath.sinCos(FastMath.toRadians(satelliteGeocentricLatitudeDegrees));
177 final FieldVector3D<FieldUnivariateDerivative2<T>> positionWithDerivatives = new FieldVector3D<>(satelliteRadius.multiply(scLatitude.cos()).multiply(scLongitude.cos()),
178 satelliteRadius.multiply(scLatitude.cos()).multiply(scLongitude.sin()),
179 satelliteRadius.multiply(scLatitude.sin()));
180 return new FieldPVCoordinates<>(new FieldVector3D<>(positionWithDerivatives.getX().getValue(),
181 positionWithDerivatives.getY().getValue(),
182 positionWithDerivatives.getZ().getValue()),
183 new FieldVector3D<>(positionWithDerivatives.getX().getFirstDerivative(),
184 positionWithDerivatives.getY().getFirstDerivative(),
185 positionWithDerivatives.getZ().getFirstDerivative()),
186 new FieldVector3D<>(positionWithDerivatives.getX().getSecondDerivative(),
187 positionWithDerivatives.getY().getSecondDerivative(),
188 positionWithDerivatives.getZ().getSecondDerivative()));
189 }
190
191
192
193
194 @Override
195 public void resetInitialState(final FieldSpacecraftState<T> state) {
196 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
197 }
198
199
200
201
202 @Override
203 protected T getMass(final FieldAbsoluteDate<T> date) {
204 return mass;
205 }
206
207
208
209
210 @Override
211 protected void resetIntermediateState(final FieldSpacecraftState<T> state, final boolean forward) {
212 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
213 }
214
215
216
217
218 @Override
219 public FieldOrbit<T> propagateOrbit(final FieldAbsoluteDate<T> date,
220 final T[] parameters) {
221 return new FieldCartesianOrbit<>(ecefFrame.getTransformTo(inertialFrame, date).transformPVCoordinates(propagateInEcef(date)), inertialFrame, date,
222 date.getField().getZero().add(Constants.WGS84_EARTH_MU));
223 }
224
225
226
227
228
229
230
231
232
233 private FieldUnivariateDerivative2<T> computeSatelliteEastLongitudeDegrees(final FieldUnivariateDerivative2<T> tDays, final FieldSinCos<FieldUnivariateDerivative2<T>> scW,
234 final FieldSinCos<FieldUnivariateDerivative2<T>> sc2W) {
235 final FieldUnivariateDerivative2<T> longitude = tDays.multiply(tDays).multiply(elements.getLm2())
236 .add(tDays.multiply(elements.getLm1()))
237 .add(elements.getLm0());
238 final FieldUnivariateDerivative2<T> cosineLongitudeTerm = scW.cos().multiply(tDays.multiply(elements.getLonC1()).add(elements.getLonC()));
239 final FieldUnivariateDerivative2<T> sineLongitudeTerm = scW.sin().multiply(tDays.multiply(elements.getLonS1()).add(elements.getLonS()));
240 final FieldUnivariateDerivative2<T> latitudeTerm = sc2W.sin()
241 .multiply(elements.getLatC()
242 .multiply(elements.getLatC())
243 .subtract(elements.getLatS().multiply(elements.getLatS()))
244 .multiply(0.5))
245 .subtract(sc2W.cos().multiply(elements.getLatC().multiply(elements.getLatS())))
246 .multiply(IntelsatElevenElements.K);
247 return longitude.add(cosineLongitudeTerm).add(sineLongitudeTerm).add(latitudeTerm);
248 }
249
250
251
252
253
254
255
256
257 private FieldUnivariateDerivative2<T> computeSatelliteGeocentricLatitudeDegrees(final FieldUnivariateDerivative2<T> tDays,
258 final FieldSinCos<FieldUnivariateDerivative2<T>> scW) {
259 final FieldUnivariateDerivative2<T> cosineTerm = scW.cos().multiply(tDays.multiply(elements.getLatC1()).add(elements.getLatC()));
260 final FieldUnivariateDerivative2<T> sineTerm = scW.sin().multiply(tDays.multiply(elements.getLatS1()).add(elements.getLatS()));
261 return cosineTerm.add(sineTerm);
262 }
263
264
265
266
267
268
269
270
271 private FieldUnivariateDerivative2<T> computeSatelliteRadiusKilometers(final T wDegreesPerDay, final FieldSinCos<FieldUnivariateDerivative2<T>> scW) {
272 final T coefficient = elements.getLm1()
273 .multiply(2.0)
274 .divide(wDegreesPerDay.subtract(elements.getLm1()).multiply(3.0))
275 .negate()
276 .add(1.0)
277 .multiply(IntelsatElevenElements.SYNCHRONOUS_RADIUS_KM);
278 return scW.sin()
279 .multiply(elements.getLonC().multiply(IntelsatElevenElements.K))
280 .add(1.0)
281 .subtract(scW.cos().multiply(elements.getLonS().multiply(IntelsatElevenElements.K)))
282 .multiply(coefficient);
283 }
284
285
286
287
288
289
290 public FieldUnivariateDerivative2<T> getEastLongitudeDegrees() {
291 return eastLongitudeDegrees;
292 }
293
294
295
296
297
298
299 public FieldUnivariateDerivative2<T> getGeocentricLatitudeDegrees() {
300 return geocentricLatitudeDegrees;
301 }
302
303
304
305
306
307
308 public FieldUnivariateDerivative2<T> getOrbitRadius() {
309 return orbitRadius;
310 }
311
312
313
314
315 @Override
316 public Frame getFrame() {
317 return inertialFrame;
318 }
319
320
321
322
323 @Override
324 public List<ParameterDriver> getParametersDrivers() {
325 return Collections.emptyList();
326 }
327
328
329
330
331
332
333 public FieldIntelsatElevenElements<T> getIntelsatElevenElements() {
334 return elements;
335 }
336 }