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