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