1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical.gnss;
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.hipparchus.util.MathArrays;
25 import org.hipparchus.util.MathUtils;
26 import org.hipparchus.util.Precision;
27 import org.orekit.attitudes.Attitude;
28 import org.orekit.attitudes.AttitudeProvider;
29 import org.orekit.data.DataContext;
30 import org.orekit.errors.OrekitException;
31 import org.orekit.errors.OrekitMessages;
32 import org.orekit.frames.Frame;
33 import org.orekit.orbits.CartesianOrbit;
34 import org.orekit.orbits.Orbit;
35 import org.orekit.propagation.SpacecraftState;
36 import org.orekit.propagation.analytical.AbstractAnalyticalPropagator;
37 import org.orekit.propagation.analytical.gnss.data.GLONASSAlmanac;
38 import org.orekit.propagation.analytical.gnss.data.GLONASSNavigationMessage;
39 import org.orekit.propagation.analytical.gnss.data.GLONASSOrbitalElements;
40 import org.orekit.propagation.analytical.gnss.data.GNSSConstants;
41 import org.orekit.time.AbsoluteDate;
42 import org.orekit.time.GLONASSDate;
43 import org.orekit.time.TimeScale;
44 import org.orekit.utils.PVCoordinates;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class GLONASSAnalyticalPropagator extends AbstractAnalyticalPropagator {
61
62
63
64 private static final double SEVEN_THIRD = 7.0 / 3.0;
65
66
67 private static final double SEVEN_SIXTH = 7.0 / 6.0;
68
69
70 private static final double SEVEN_24TH = 7.0 / 24.0;
71
72
73 private static final double FN_72TH = 49.0 / 72.0;
74
75
76 private static final double GLONASS_AV = 7.2921150e-5;
77
78
79 private static final double GLONASS_MEAN_INCLINATION = 64.8;
80
81
82 private static final double GLONASS_MEAN_DRACONIAN_PERIOD = 40544;
83
84
85 private static final double GLONASS_J20 = 1.08262575e-3;
86
87
88 private static final double GLONASS_EARTH_EQUATORIAL_RADIUS = 6378136;
89
90
91
92 private static final double A;
93
94
95 private static final double B;
96
97 static {
98 final double k1 = 3 * FastMath.PI + 2;
99 final double k2 = FastMath.PI - 1;
100 final double k3 = 6 * FastMath.PI - 1;
101 A = 3 * k2 * k2 / k1;
102 B = k3 * k3 / (6 * k1);
103 }
104
105
106 private final GLONASSOrbitalElements glonassOrbit;
107
108
109 private final double mass;
110
111
112 private final Frame eci;
113
114
115 private final Frame ecef;
116
117
118 private final DataContext dataContext;
119
120
121
122
123
124
125
126
127
128
129 GLONASSAnalyticalPropagator(final GLONASSOrbitalElements glonassOrbit, final Frame eci,
130 final Frame ecef, final AttitudeProvider provider,
131 final double mass, final DataContext context) {
132 super(provider);
133 this.dataContext = context;
134
135 this.glonassOrbit = glonassOrbit;
136
137 setStartDate(glonassOrbit.getDate());
138
139 this.mass = mass;
140
141 this.eci = eci;
142
143 this.ecef = ecef;
144
145 final Orbit orbit = propagateOrbit(getStartDate());
146 final Attitude attitude = provider.getAttitude(orbit, orbit.getDate(), orbit.getFrame());
147 super.resetInitialState(new SpacecraftState(orbit, attitude).withMass(mass));
148 }
149
150
151
152
153
154
155
156
157
158
159
160 public PVCoordinates propagateInEcef(final AbsoluteDate date) {
161
162
163 final UnivariateDerivative2 dTpr = getdTpr(date);
164
165
166 final UnivariateDerivative2 zero = dTpr.getField().getZero();
167
168
169 final UnivariateDerivative2 w = FastMath.floor(dTpr.divide(GLONASS_MEAN_DRACONIAN_PERIOD + glonassOrbit.getDeltaT()));
170
171
172 final UnivariateDerivative2 i = zero.newInstance(GLONASS_MEAN_INCLINATION / 180 * GNSSConstants.GLONASS_PI + glonassOrbit.getDeltaI());
173
174
175 final UnivariateDerivative2 e = zero.newInstance(glonassOrbit.getE());
176
177
178 final UnivariateDerivative2 tDR = w.multiply(2.0).add(1.0).multiply(glonassOrbit.getDeltaTDot()).
179 add(glonassOrbit.getDeltaT()).
180 add(GLONASS_MEAN_DRACONIAN_PERIOD);
181 final UnivariateDerivative2 n = tDR.divide(2.0 * GNSSConstants.GLONASS_PI).reciprocal();
182
183
184 final UnivariateDerivative2 sma = computeSma(tDR, i, e);
185
186
187 final UnivariateDerivative2 p = sma.multiply(e.multiply(e).negate().add(1.0));
188 final UnivariateDerivative2 aeop = p.divide(GLONASS_EARTH_EQUATORIAL_RADIUS).reciprocal();
189 final UnivariateDerivative2 aeop2 = aeop.multiply(aeop);
190
191
192 final UnivariateDerivative2 lambda = computeLambda(dTpr, n, aeop2, i);
193
194
195 final UnivariateDerivative2 pa = computePA(dTpr, n, aeop2, i);
196
197
198 final UnivariateDerivative2 tanPAo2 = FastMath.tan(pa.divide(2.0));
199 final UnivariateDerivative2 coef = tanPAo2.multiply(FastMath.sqrt(e.negate().add(1.0).divide(e.add(1.0))));
200 final UnivariateDerivative2 e0 = FastMath.atan(coef).multiply(2.0).negate();
201 final UnivariateDerivative2 m1 = pa.add(e0).subtract(FastMath.sin(e0).multiply(e));
202
203
204 final UnivariateDerivative2 correction = dTpr.
205 subtract(w.multiply(GLONASS_MEAN_DRACONIAN_PERIOD + glonassOrbit.getDeltaT())).
206 subtract(w.square().multiply(glonassOrbit.getDeltaTDot()));
207 final UnivariateDerivative2 m = m1.add(n.multiply(correction));
208
209
210 final FieldSinCos<UnivariateDerivative2> scPa = FastMath.sinCos(pa);
211 final UnivariateDerivative2 h = e.multiply(scPa.sin());
212 final UnivariateDerivative2 l = e.multiply(scPa.cos());
213
214 final UnivariateDerivative2[] d1 = getParameterDifferentials(sma, i, h, l, m1);
215
216 final UnivariateDerivative2[] d2 = getParameterDifferentials(sma, i, h, l, m);
217
218 final UnivariateDerivative2 smaCorr = sma.add(d2[0]).subtract(d1[0]);
219 final UnivariateDerivative2 hCorr = h.add(d2[1]).subtract(d1[1]);
220 final UnivariateDerivative2 lCorr = l.add(d2[2]).subtract(d1[2]);
221 final UnivariateDerivative2 lambdaCorr = lambda.add(d2[3]).subtract(d1[3]);
222 final UnivariateDerivative2 iCorr = i.add(d2[4]).subtract(d1[4]);
223 final UnivariateDerivative2 mCorr = m.add(d2[5]).subtract(d1[5]);
224 final UnivariateDerivative2 eCorr = FastMath.sqrt(hCorr.multiply(hCorr).add(lCorr.multiply(lCorr)));
225 final UnivariateDerivative2 paCorr;
226 if (eCorr.getValue() == 0.) {
227 paCorr = zero;
228 } else {
229 if (lCorr.getValue() == eCorr.getValue()) {
230 paCorr = zero.newInstance(0.5 * GNSSConstants.GLONASS_PI);
231 } else if (lCorr.getValue() == -eCorr.getValue()) {
232 paCorr = zero.newInstance(-0.5 * GNSSConstants.GLONASS_PI);
233 } else {
234 paCorr = FastMath.atan2(hCorr, lCorr);
235 }
236 }
237
238
239 final UnivariateDerivative2 mk = mCorr.subtract(paCorr);
240 final UnivariateDerivative2 ek = getEccentricAnomaly(mk, eCorr);
241
242
243 final UnivariateDerivative2 vk = getTrueAnomaly(ek, eCorr);
244
245
246 final UnivariateDerivative2 phik = vk.add(paCorr);
247
248
249 final UnivariateDerivative2 pCorr = smaCorr.multiply(eCorr.multiply(eCorr).negate().add(1.0));
250 final UnivariateDerivative2 rk = pCorr.divide(eCorr.multiply(FastMath.cos(vk)).add(1.0));
251
252
253 final FieldSinCos<UnivariateDerivative2> scPhik = FastMath.sinCos(phik);
254 final UnivariateDerivative2 xk = scPhik.cos().multiply(rk);
255 final UnivariateDerivative2 yk = scPhik.sin().multiply(rk);
256
257
258 final FieldSinCos<UnivariateDerivative2> scL = FastMath.sinCos(lambdaCorr);
259 final FieldSinCos<UnivariateDerivative2> scI = FastMath.sinCos(iCorr);
260 final FieldVector3D<UnivariateDerivative2> positionwithDerivatives =
261 new FieldVector3D<>(xk.multiply(scL.cos()).subtract(yk.multiply(scL.sin()).multiply(scI.cos())),
262 xk.multiply(scL.sin()).add(yk.multiply(scL.cos()).multiply(scI.cos())),
263 yk.multiply(scI.sin()));
264
265 return new PVCoordinates(new Vector3D(positionwithDerivatives.getX().getValue(),
266 positionwithDerivatives.getY().getValue(),
267 positionwithDerivatives.getZ().getValue()),
268 new Vector3D(positionwithDerivatives.getX().getFirstDerivative(),
269 positionwithDerivatives.getY().getFirstDerivative(),
270 positionwithDerivatives.getZ().getFirstDerivative()),
271 new Vector3D(positionwithDerivatives.getX().getSecondDerivative(),
272 positionwithDerivatives.getY().getSecondDerivative(),
273 positionwithDerivatives.getZ().getSecondDerivative()));
274 }
275
276
277
278
279
280
281
282
283
284
285
286
287 private UnivariateDerivative2 getEccentricAnomaly(final UnivariateDerivative2 mk, final UnivariateDerivative2 e) {
288
289
290 final UnivariateDerivative2 reducedM = new UnivariateDerivative2(MathUtils.normalizeAngle(mk.getValue(), 0.0),
291 mk.getFirstDerivative(),
292 mk.getSecondDerivative());
293
294
295 UnivariateDerivative2 ek;
296 if (FastMath.abs(reducedM.getValue()) < 1.0 / 6.0) {
297 if (FastMath.abs(reducedM.getValue()) < Precision.SAFE_MIN) {
298
299
300
301 ek = reducedM;
302 } else {
303
304 ek = reducedM.add(reducedM.multiply(6).cbrt().subtract(reducedM).multiply(e));
305 }
306 } else {
307 if (reducedM.getValue() < 0) {
308 final UnivariateDerivative2 w = reducedM.add(FastMath.PI);
309 ek = reducedM.add(w.multiply(-A).divide(w.subtract(B)).subtract(FastMath.PI).subtract(reducedM).multiply(e));
310 } else {
311 final UnivariateDerivative2 minusW = reducedM.subtract(FastMath.PI);
312 ek = reducedM.add(minusW.multiply(A).divide(minusW.add(B)).add(FastMath.PI).subtract(reducedM).multiply(e));
313 }
314 }
315
316 final UnivariateDerivative2 e1 = e.negate().add(1.0);
317 final boolean noCancellationRisk = (e1.getValue() + ek.getValue() * ek.getValue() / 6) >= 0.1;
318
319
320 for (int j = 0; j < 2; ++j) {
321 final UnivariateDerivative2 f;
322 UnivariateDerivative2 fd;
323 final UnivariateDerivative2 fdd = ek.sin().multiply(e);
324 final UnivariateDerivative2 fddd = ek.cos().multiply(e);
325 if (noCancellationRisk) {
326 f = ek.subtract(fdd).subtract(reducedM);
327 fd = fddd.subtract(1).negate();
328 } else {
329 f = eMeSinE(ek, e).subtract(reducedM);
330 final UnivariateDerivative2 s = ek.multiply(0.5).sin();
331 fd = s.multiply(s).multiply(e.multiply(2.0)).add(e1);
332 }
333 final UnivariateDerivative2 dee = f.multiply(fd).divide(f.multiply(0.5).multiply(fdd).subtract(fd.multiply(fd)));
334
335
336 final UnivariateDerivative2 w = fd.add(dee.multiply(0.5).multiply(fdd.add(dee.multiply(fdd).divide(3))));
337 fd = fd.add(dee.multiply(fdd.add(dee.multiply(0.5).multiply(fdd))));
338 ek = ek.subtract(f.subtract(dee.multiply(fd.subtract(w))).divide(fd));
339 }
340
341
342 ek = ek.add(mk.getValue() - reducedM.getValue());
343
344
345 return ek;
346 }
347
348
349
350
351
352
353
354
355 private UnivariateDerivative2 eMeSinE(final UnivariateDerivative2 E, final UnivariateDerivative2 ecc) {
356 UnivariateDerivative2 x = E.sin().multiply(ecc.negate().add(1.0));
357 final UnivariateDerivative2 mE2 = E.negate().multiply(E);
358 UnivariateDerivative2 term = E;
359 UnivariateDerivative2 d = E.getField().getZero();
360
361 for (UnivariateDerivative2 x0 = d.add(Double.NaN); !Double.valueOf(x.getValue()).equals(x0.getValue());) {
362 d = d.add(2);
363 term = term.multiply(mE2.divide(d.multiply(d.add(1))));
364 x0 = x;
365 x = x.subtract(term);
366 }
367 return x;
368 }
369
370
371
372
373
374
375
376 private UnivariateDerivative2 getTrueAnomaly(final UnivariateDerivative2 ek, final UnivariateDerivative2 ecc) {
377 final UnivariateDerivative2 svk = ek.sin().multiply(FastMath.sqrt( ecc.square().negate().add(1.0)));
378 final UnivariateDerivative2 cvk = ek.cos().subtract(ecc);
379 return svk.atan2(cvk);
380 }
381
382
383
384
385
386
387
388 private UnivariateDerivative2 getdTpr(final AbsoluteDate date) {
389 final TimeScale glonass = dataContext.getTimeScales().getGLONASS();
390 final GLONASSDate tEnd = new GLONASSDate(date, glonass);
391 final GLONASSDate tSta = new GLONASSDate(glonassOrbit.getDate(), glonass);
392 final int n = tEnd.getDayNumber();
393 final int na = tSta.getDayNumber();
394 final int deltaN;
395 if (na == 27) {
396 deltaN = n - na - FastMath.round((float) (n - na) / 1460) * 1460;
397 } else {
398 deltaN = n - na - FastMath.round((float) (n - na) / 1461) * 1461;
399 }
400 final UnivariateDerivative2 ti = new UnivariateDerivative2(tEnd.getSecInDay(), 1.0, 0.0);
401
402 return ti.subtract(glonassOrbit.getTime()).add(86400 * deltaN);
403 }
404
405
406
407
408
409
410
411
412 private UnivariateDerivative2 computeSma(final UnivariateDerivative2 tDR,
413 final UnivariateDerivative2 i,
414 final UnivariateDerivative2 e) {
415
416
417 final UnivariateDerivative2 zero = tDR.getField().getZero();
418
419
420
421
422 if (Double.isNaN(tDR.getValue()) || Double.isNaN(i.getValue()) || Double.isNaN(e.getValue())) {
423 return zero.add(Double.NaN);
424 }
425
426
427 final UnivariateDerivative2 sinI = FastMath.sin(i);
428 final UnivariateDerivative2 sin2I = sinI.multiply(sinI);
429 final UnivariateDerivative2 ome2 = e.multiply(e).negate().add(1.0);
430 final UnivariateDerivative2 ome2Pow3o2 = FastMath.sqrt(ome2).multiply(ome2);
431 final UnivariateDerivative2 pa = zero.newInstance(glonassOrbit.getPa());
432 final UnivariateDerivative2 cosPA = FastMath.cos(pa);
433 final UnivariateDerivative2 opecosPA = e.multiply(cosPA).add(1.0);
434 final UnivariateDerivative2 opecosPAPow2 = opecosPA.multiply(opecosPA);
435 final UnivariateDerivative2 opecosPAPow3 = opecosPAPow2.multiply(opecosPA);
436
437
438 UnivariateDerivative2 tOCK = tDR;
439
440
441
442 UnivariateDerivative2 an = zero;
443 UnivariateDerivative2 anp1 = zero;
444 boolean isLastStep = false;
445 while (!isLastStep) {
446
447
448 final UnivariateDerivative2 tOCKo2p = tOCK.divide(2.0 * GNSSConstants.GLONASS_PI);
449 final UnivariateDerivative2 tOCKo2pPow2 = tOCKo2p.multiply(tOCKo2p);
450 anp1 = FastMath.cbrt(tOCKo2pPow2.multiply(GNSSConstants.GLONASS_MU));
451
452
453 final UnivariateDerivative2 p = anp1.multiply(ome2);
454
455
456 final UnivariateDerivative2 aeop = p.divide(GLONASS_EARTH_EQUATORIAL_RADIUS).reciprocal();
457 final UnivariateDerivative2 aeop2 = aeop.multiply(aeop);
458 final UnivariateDerivative2 term1 = aeop2.multiply(GLONASS_J20).multiply(1.5);
459 final UnivariateDerivative2 term2 = sin2I.multiply(2.5).negate().add(2.0);
460 final UnivariateDerivative2 term3 = ome2Pow3o2.divide(opecosPAPow2);
461 final UnivariateDerivative2 term4 = opecosPAPow3.divide(ome2);
462 tOCK = tDR.divide(term1.multiply(term2.multiply(term3).add(term4)).negate().add(1.0));
463
464
465 if (FastMath.abs(anp1.subtract(an).getReal()) <= 0.01) {
466 isLastStep = true;
467 }
468
469 an = anp1;
470 }
471
472 return an;
473
474 }
475
476
477
478
479
480
481
482
483
484 private UnivariateDerivative2 computeLambda(final UnivariateDerivative2 dTpr,
485 final UnivariateDerivative2 n,
486 final UnivariateDerivative2 aeop2,
487 final UnivariateDerivative2 i) {
488 final UnivariateDerivative2 cosI = FastMath.cos(i);
489 final UnivariateDerivative2 precession = aeop2.multiply(n).multiply(cosI).multiply(1.5 * GLONASS_J20);
490 return dTpr.multiply(precession.add(GLONASS_AV)).negate().add(glonassOrbit.getLambda());
491 }
492
493
494
495
496
497
498
499
500
501 private UnivariateDerivative2 computePA(final UnivariateDerivative2 dTpr,
502 final UnivariateDerivative2 n,
503 final UnivariateDerivative2 aeop2,
504 final UnivariateDerivative2 i) {
505 final UnivariateDerivative2 cosI = FastMath.cos(i);
506 final UnivariateDerivative2 cos2I = cosI.multiply(cosI);
507 final UnivariateDerivative2 precession = aeop2.multiply(n).multiply(cos2I.multiply(5.0).negate().add(1.0)).multiply(0.75 * GLONASS_J20);
508 return dTpr.multiply(precession).negate().add(glonassOrbit.getPa());
509 }
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524 private UnivariateDerivative2[] getParameterDifferentials(final UnivariateDerivative2 a, final UnivariateDerivative2 i,
525 final UnivariateDerivative2 h, final UnivariateDerivative2 l,
526 final UnivariateDerivative2 m) {
527
528
529 final UnivariateDerivative2 aeoa = a.divide(GLONASS_EARTH_EQUATORIAL_RADIUS).reciprocal();
530 final UnivariateDerivative2 aeoa2 = aeoa.multiply(aeoa);
531 final UnivariateDerivative2 b = aeoa2.multiply(1.5 * GLONASS_J20);
532
533
534 final FieldSinCos<UnivariateDerivative2> scI = FastMath.sinCos(i);
535 final FieldSinCos<UnivariateDerivative2> scLk = FastMath.sinCos(m);
536 final FieldSinCos<UnivariateDerivative2> sc2Lk = FieldSinCos.sum(scLk, scLk);
537 final FieldSinCos<UnivariateDerivative2> sc3Lk = FieldSinCos.sum(scLk, sc2Lk);
538 final FieldSinCos<UnivariateDerivative2> sc4Lk = FieldSinCos.sum(sc2Lk, sc2Lk);
539 final UnivariateDerivative2 cosI = scI.cos();
540 final UnivariateDerivative2 sinI = scI.sin();
541 final UnivariateDerivative2 cosI2 = cosI.multiply(cosI);
542 final UnivariateDerivative2 sinI2 = sinI.multiply(sinI);
543 final UnivariateDerivative2 cosLk = scLk.cos();
544 final UnivariateDerivative2 sinLk = scLk.sin();
545 final UnivariateDerivative2 cos2Lk = sc2Lk.cos();
546 final UnivariateDerivative2 sin2Lk = sc2Lk.sin();
547 final UnivariateDerivative2 cos3Lk = sc3Lk.cos();
548 final UnivariateDerivative2 sin3Lk = sc3Lk.sin();
549 final UnivariateDerivative2 cos4Lk = sc4Lk.cos();
550 final UnivariateDerivative2 sin4Lk = sc4Lk.sin();
551
552
553
554 final UnivariateDerivative2 hCosLk = h.multiply(cosLk);
555 final UnivariateDerivative2 hSinLk = h.multiply(sinLk);
556 final UnivariateDerivative2 lCosLk = l.multiply(cosLk);
557 final UnivariateDerivative2 lSinLk = l.multiply(sinLk);
558
559 final UnivariateDerivative2 hCos2Lk = h.multiply(cos2Lk);
560 final UnivariateDerivative2 hSin2Lk = h.multiply(sin2Lk);
561 final UnivariateDerivative2 lCos2Lk = l.multiply(cos2Lk);
562 final UnivariateDerivative2 lSin2Lk = l.multiply(sin2Lk);
563
564 final UnivariateDerivative2 hCos3Lk = h.multiply(cos3Lk);
565 final UnivariateDerivative2 hSin3Lk = h.multiply(sin3Lk);
566 final UnivariateDerivative2 lCos3Lk = l.multiply(cos3Lk);
567 final UnivariateDerivative2 lSin3Lk = l.multiply(sin3Lk);
568
569 final UnivariateDerivative2 hCos4Lk = h.multiply(cos4Lk);
570 final UnivariateDerivative2 hSin4Lk = h.multiply(sin4Lk);
571 final UnivariateDerivative2 lCos4Lk = l.multiply(cos4Lk);
572 final UnivariateDerivative2 lSin4Lk = l.multiply(sin4Lk);
573
574
575 final UnivariateDerivative2 om3o2xSinI2 = sinI2.multiply(1.5).negate().add(1.0);
576
577
578
579 final UnivariateDerivative2 dakT1 = b.multiply(2.0).multiply(om3o2xSinI2).multiply(lCosLk.add(hSinLk));
580 final UnivariateDerivative2 dakT2 = b.multiply(sinI2).multiply(hSinLk.multiply(0.5).subtract(lCosLk.multiply(0.5)).
581 add(cos2Lk).add(lCos3Lk.multiply(3.5)).add(hSin3Lk.multiply(3.5)));
582 final UnivariateDerivative2 dak = dakT1.add(dakT2);
583
584
585 final UnivariateDerivative2 dhkT1 = b.multiply(om3o2xSinI2).multiply(sinLk.add(lSin2Lk.multiply(1.5)).subtract(hCos2Lk.multiply(1.5)));
586 final UnivariateDerivative2 dhkT2 = b.multiply(sinI2).multiply(0.25).multiply(sinLk.subtract(sin3Lk.multiply(SEVEN_THIRD)).add(lSin2Lk.multiply(5.0)).
587 subtract(lSin4Lk.multiply(8.5)).add(hCos4Lk.multiply(8.5)).add(hCos2Lk));
588 final UnivariateDerivative2 dhkT3 = lSin2Lk.multiply(cosI2).multiply(b).multiply(0.5).negate();
589 final UnivariateDerivative2 dhk = dhkT1.subtract(dhkT2).add(dhkT3);
590
591
592 final UnivariateDerivative2 dlkT1 = b.multiply(om3o2xSinI2).multiply(cosLk.add(lCos2Lk.multiply(1.5)).add(hSin2Lk.multiply(1.5)));
593 final UnivariateDerivative2 dlkT2 = b.multiply(sinI2).multiply(0.25).multiply(cosLk.negate().subtract(cos3Lk.multiply(SEVEN_THIRD)).subtract(hSin2Lk.multiply(5.0)).
594 subtract(lCos4Lk.multiply(8.5)).subtract(hSin4Lk.multiply(8.5)).add(lCos2Lk));
595 final UnivariateDerivative2 dlkT3 = hSin2Lk.multiply(cosI2).multiply(b).multiply(0.5);
596 final UnivariateDerivative2 dlk = dlkT1.subtract(dlkT2).add(dlkT3);
597
598
599 final UnivariateDerivative2 dokT1 = b.negate().multiply(cosI);
600 final UnivariateDerivative2 dokT2 = lSinLk.multiply(3.5).subtract(hCosLk.multiply(2.5)).subtract(sin2Lk.multiply(0.5)).
601 subtract(lSin3Lk.multiply(SEVEN_SIXTH)).add(hCos3Lk.multiply(SEVEN_SIXTH));
602 final UnivariateDerivative2 dok = dokT1.multiply(dokT2);
603
604
605 final UnivariateDerivative2 dik = b.multiply(sinI).multiply(cosI).multiply(0.5).
606 multiply(lCosLk.negate().add(hSinLk).add(cos2Lk).add(lCos3Lk.multiply(SEVEN_THIRD)).add(hSin3Lk.multiply(SEVEN_THIRD)));
607
608
609 final UnivariateDerivative2 dLkT1 = b.multiply(2.0).multiply(om3o2xSinI2).multiply(lSinLk.multiply(1.75).subtract(hCosLk.multiply(1.75)));
610 final UnivariateDerivative2 dLkT2 = b.multiply(sinI2).multiply(3.0).multiply(hCosLk.multiply(SEVEN_24TH).negate().subtract(lSinLk.multiply(SEVEN_24TH)).
611 subtract(hCos3Lk.multiply(FN_72TH)).add(lSin3Lk.multiply(FN_72TH)).add(sin2Lk.multiply(0.25)));
612 final UnivariateDerivative2 dLkT3 = b.multiply(cosI2).multiply(lSinLk.multiply(3.5).subtract(hCosLk.multiply(2.5)).subtract(sin2Lk.multiply(0.5)).
613 subtract(lSin3Lk.multiply(SEVEN_SIXTH)).add(hCos3Lk.multiply(SEVEN_SIXTH)));
614 final UnivariateDerivative2 dLk = dLkT1.add(dLkT2).add(dLkT3);
615
616
617 final UnivariateDerivative2[] differentials = MathArrays.buildArray(a.getField(), 6);
618 differentials[0] = dak.multiply(a);
619 differentials[1] = dhk;
620 differentials[2] = dlk;
621 differentials[3] = dok;
622 differentials[4] = dik;
623 differentials[5] = dLk;
624
625 return differentials;
626 }
627
628
629 protected double getMass(final AbsoluteDate date) {
630 return mass;
631 }
632
633
634
635
636
637 public static double getMU() {
638 return GNSSConstants.GLONASS_MU;
639 }
640
641
642
643
644
645
646 public GLONASSOrbitalElements getGLONASSOrbitalElements() {
647 return glonassOrbit;
648 }
649
650
651
652
653
654 public Frame getECI() {
655 return eci;
656 }
657
658
659
660
661
662 public Frame getECEF() {
663 return ecef;
664 }
665
666
667 public Frame getFrame() {
668 return eci;
669 }
670
671
672 public void resetInitialState(final SpacecraftState state) {
673 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
674 }
675
676
677 protected void resetIntermediateState(final SpacecraftState state, final boolean forward) {
678 throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
679 }
680
681
682 public Orbit propagateOrbit(final AbsoluteDate date) {
683
684 final PVCoordinates pvaInECEF = propagateInEcef(date);
685
686 final PVCoordinates pvaInECI = ecef.getTransformTo(eci, date).transformPVCoordinates(pvaInECEF);
687
688 return new CartesianOrbit(pvaInECI, eci, date, GNSSConstants.GLONASS_MU);
689 }
690
691 }