1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.orbits;
18
19
20 import org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.Field;
22 import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative1;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.util.FastMath;
25 import org.hipparchus.util.FieldSinCos;
26 import org.hipparchus.util.MathArrays;
27 import org.orekit.errors.OrekitException;
28 import org.orekit.errors.OrekitIllegalArgumentException;
29 import org.orekit.errors.OrekitInternalError;
30 import org.orekit.errors.OrekitMessages;
31 import org.orekit.frames.FieldKinematicTransform;
32 import org.orekit.frames.Frame;
33 import org.orekit.time.FieldAbsoluteDate;
34 import org.orekit.time.TimeOffset;
35 import org.orekit.utils.FieldPVCoordinates;
36 import org.orekit.utils.TimeStampedFieldPVCoordinates;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public class FieldKeplerianOrbit<T extends CalculusFieldElement<T>> extends FieldOrbit<T>
81 implements PositionAngleBased<FieldKeplerianOrbit<T>> {
82
83
84 private static final String ECCENTRICITY = "eccentricity";
85
86
87 private final T a;
88
89
90 private final T e;
91
92
93 private final T i;
94
95
96 private final T pa;
97
98
99 private final T raan;
100
101
102 private final T cachedAnomaly;
103
104
105 private final T aDot;
106
107
108 private final T eDot;
109
110
111 private final T iDot;
112
113
114 private final T paDot;
115
116
117 private final T raanDot;
118
119
120 private final T cachedAnomalyDot;
121
122
123 private final PositionAngleType cachedPositionAngleType;
124
125
126 private FieldPVCoordinates<T> partialPV;
127
128
129 private final FieldVector3D<T> plusK;
130
131
132
133
134
135
136
137
138
139
140
141
142 public FieldKeplerianOrbit(final FieldKeplerianParameters<T> elements, final Frame frame,
143 final FieldAbsoluteDate<T> date, final T mu)
144 throws IllegalArgumentException {
145 this(elements, mu.getField().getZero(), mu.getField().getZero(),
146 mu.getField().getZero(), mu.getField().getZero(), mu.getField().getZero(),
147 computeKeplerianAnomalyDot(elements.positionAngleType(), elements.a(), elements.e(), mu, elements.anomaly(), elements.positionAngleType()),
148 elements.positionAngleType(), frame, date, mu);
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 public FieldKeplerianOrbit(final T a, final T e, final T i, final T pa, final T raan,
169 final T anomaly, final PositionAngleType type, final Frame frame,
170 final FieldAbsoluteDate<T> date, final T mu)
171 throws IllegalArgumentException {
172 this(new FieldKeplerianParameters<>(a, e, i, pa, raan, anomaly, type), frame, date, mu);
173 }
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 public FieldKeplerianOrbit(final FieldKeplerianParameters<T> elements,
194 final T aDot, final T eDot, final T iDot,
195 final T paDot, final T raanDot, final T anomalyDot,
196 final PositionAngleType cachedPositionAngleType,
197 final Frame frame, final FieldAbsoluteDate<T> date, final T mu)
198 throws IllegalArgumentException {
199 super(frame, date, mu);
200 this.cachedPositionAngleType = cachedPositionAngleType;
201
202 this.a = elements.a();
203 this.e = elements.e();
204 if (a.multiply(e.negate().add(1)).getReal() < 0) {
205 throw new OrekitIllegalArgumentException(OrekitMessages.ORBIT_A_E_MISMATCH_WITH_CONIC_TYPE, a.getReal(), e.getReal());
206 }
207
208
209 checkParameterRangeInclusive(ECCENTRICITY, e.getReal(), 0.0, Double.POSITIVE_INFINITY);
210
211 this.aDot = aDot;
212 this.eDot = eDot;
213 this.i = elements.i();
214 this.iDot = iDot;
215 this.pa = elements.pa();
216 this.paDot = paDot;
217 this.raan = elements.raan();
218 this.raanDot = raanDot;
219
220 this.plusK = FieldVector3D.getPlusK(a.getField());
221
222 final FieldUnivariateDerivative1<T> cachedAnomalyUD = initializeCachedAnomaly(elements.anomaly(), anomalyDot,
223 elements.positionAngleType());
224 this.cachedAnomaly = cachedAnomalyUD.getValue();
225 this.cachedAnomalyDot = cachedAnomalyUD.getFirstDerivative();
226
227
228 if (!isElliptical()) {
229 final T trueAnomaly = getTrueAnomaly();
230 if (e.multiply(trueAnomaly.cos()).add(1).getReal() <= 0) {
231 final double vMax = e.reciprocal().negate().acos().getReal();
232 throw new OrekitIllegalArgumentException(OrekitMessages.ORBIT_ANOMALY_OUT_OF_HYPERBOLIC_RANGE,
233 trueAnomaly.getReal(), e.getReal(), -vMax, vMax);
234 }
235 }
236
237 this.partialPV = null;
238
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 public FieldKeplerianOrbit(final T a, final T e, final T i,
264 final T pa, final T raan, final T anomaly,
265 final T aDot, final T eDot, final T iDot,
266 final T paDot, final T raanDot, final T anomalyDot,
267 final PositionAngleType type,
268 final Frame frame, final FieldAbsoluteDate<T> date, final T mu)
269 throws IllegalArgumentException {
270 this(new FieldKeplerianParameters<>(a, e, i, pa, raan, anomaly, type), aDot, eDot, iDot, paDot, raanDot, anomalyDot,
271 type, frame, date, mu);
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 public FieldKeplerianOrbit(final TimeStampedFieldPVCoordinates<T> pvCoordinates,
289 final Frame frame, final T mu)
290 throws IllegalArgumentException {
291 this(pvCoordinates, frame, mu, hasNonKeplerianAcceleration(pvCoordinates, mu));
292 }
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309 private FieldKeplerianOrbit(final TimeStampedFieldPVCoordinates<T> pvCoordinates,
310 final Frame frame, final T mu,
311 final boolean reliableAcceleration)
312 throws IllegalArgumentException {
313
314 super(pvCoordinates, frame, mu);
315 plusK = FieldVector3D.getPlusK(mu.getField());
316
317
318 final FieldKeplerianParametersConverter<T> converter = new FieldKeplerianParametersConverter<>(mu);
319 cachedPositionAngleType = PositionAngleType.ECCENTRIC;
320 final FieldKeplerianParameters<T> elements = converter.toParameters(pvCoordinates, cachedPositionAngleType);
321 a = elements.a();
322 e = elements.e();
323 i = elements.i();
324 pa = elements.pa();
325 raan = elements.raan();
326 cachedAnomaly = elements.anomaly();
327
328
329 checkParameterRangeInclusive(ECCENTRICITY, e.getReal(), 0.0, Double.POSITIVE_INFINITY);
330
331 partialPV = pvCoordinates;
332
333 if (reliableAcceleration) {
334
335
336 final T[][] jacobian = MathArrays.buildArray(a.getField(), 6, 6);
337 getJacobianWrtCartesian(PositionAngleType.MEAN, jacobian);
338
339 final FieldVector3D<T> pvP = pvCoordinates.getPosition();
340 final T r2 = pvP.getNorm2Sq();
341 final T r = FastMath.sqrt(r2);
342 final FieldVector3D<T> keplerianAcceleration = new FieldVector3D<>(r.multiply(r2).reciprocal().multiply(mu.negate()), pvP);
343 final FieldVector3D<T> nonKeplerianAcceleration = pvCoordinates.getAcceleration().subtract(keplerianAcceleration);
344 final T aX = nonKeplerianAcceleration.getX();
345 final T aY = nonKeplerianAcceleration.getY();
346 final T aZ = nonKeplerianAcceleration.getZ();
347 aDot = jacobian[0][3].multiply(aX).add(jacobian[0][4].multiply(aY)).add(jacobian[0][5].multiply(aZ));
348 eDot = jacobian[1][3].multiply(aX).add(jacobian[1][4].multiply(aY)).add(jacobian[1][5].multiply(aZ));
349 iDot = jacobian[2][3].multiply(aX).add(jacobian[2][4].multiply(aY)).add(jacobian[2][5].multiply(aZ));
350 paDot = jacobian[3][3].multiply(aX).add(jacobian[3][4].multiply(aY)).add(jacobian[3][5].multiply(aZ));
351 raanDot = jacobian[4][3].multiply(aX).add(jacobian[4][4].multiply(aY)).add(jacobian[4][5].multiply(aZ));
352
353
354
355 final T MDot = getKeplerianMeanMotion().
356 add(jacobian[5][3].multiply(aX)).add(jacobian[5][4].multiply(aY)).add(jacobian[5][5].multiply(aZ));
357 final FieldUnivariateDerivative1<T> eUD = new FieldUnivariateDerivative1<>(e, eDot);
358 final FieldUnivariateDerivative1<T> MUD = new FieldUnivariateDerivative1<>(getMeanAnomaly(), MDot);
359 final FieldUnivariateDerivative1<T> EUD = (a.getReal() < 0) ?
360 FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(eUD, MUD) :
361 FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(eUD, MUD);
362 cachedAnomalyDot = EUD.getFirstDerivative();
363
364 } else {
365
366
367
368 aDot = getZero();
369 eDot = getZero();
370 iDot = getZero();
371 paDot = getZero();
372 raanDot = getZero();
373 cachedAnomalyDot = computeKeplerianAnomalyDot(cachedPositionAngleType, a, e, mu, cachedAnomaly, cachedPositionAngleType);
374 }
375
376 }
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393 public FieldKeplerianOrbit(final FieldPVCoordinates<T> FieldPVCoordinates,
394 final Frame frame, final FieldAbsoluteDate<T> date, final T mu)
395 throws IllegalArgumentException {
396 this(new TimeStampedFieldPVCoordinates<>(date, FieldPVCoordinates), frame, mu);
397 }
398
399
400
401
402 public FieldKeplerianOrbit(final FieldOrbit<T> op) {
403 this(op.getPVCoordinates(), op.getFrame(), op.getMu());
404 }
405
406
407
408
409
410
411
412 public FieldKeplerianOrbit(final Field<T> field, final KeplerianOrbit op) {
413 this(new FieldKeplerianParameters<>(field, op.getKeplerianParameters()),
414 field.getZero().newInstance(op.getADot()),
415 field.getZero().newInstance(op.getEDot()),
416 field.getZero().newInstance(op.getIDot()),
417 field.getZero().newInstance(op.getPeriapsisArgumentDot()),
418 field.getZero().newInstance(op.getRightAscensionOfAscendingNodeDot()),
419 field.getZero().newInstance(op.getAnomalyDot(op.getCachedPositionAngleType())),
420 op.getCachedPositionAngleType(), op.getFrame(),
421 new FieldAbsoluteDate<>(field, op.getDate()), field.getZero().newInstance(op.getMu()));
422 }
423
424
425
426
427
428
429
430 public FieldKeplerianOrbit(final Field<T> field, final Orbit op) {
431 this(field, (KeplerianOrbit) OrbitParamsType.KEPLERIAN.convertType(op));
432 }
433
434
435 @Override
436 public OrbitParamsType getType() {
437 return OrbitParamsType.KEPLERIAN;
438 }
439
440
441 @Override
442 public T getA() {
443 return a;
444 }
445
446
447 @Override
448 public T getADot() {
449 return aDot;
450 }
451
452
453 @Override
454 public T getE() {
455 return e;
456 }
457
458
459 @Override
460 public T getEDot() {
461 return eDot;
462 }
463
464
465 @Override
466 public T getI() {
467 return i;
468 }
469
470
471 @Override
472 public T getIDot() {
473 return iDot;
474 }
475
476
477
478
479 public T getPeriapsisArgument() {
480 return pa;
481 }
482
483
484
485
486 public T getPeriapsisArgumentDot() {
487 return paDot;
488 }
489
490
491
492
493 public T getRightAscensionOfAscendingNode() {
494 return raan;
495 }
496
497
498
499
500 public T getRightAscensionOfAscendingNodeDot() {
501 return raanDot;
502 }
503
504
505
506
507 public T getTrueAnomaly() {
508 return getAnomaly(PositionAngleType.TRUE);
509 }
510
511
512
513
514 public T getTrueAnomalyDot() {
515 return switch (cachedPositionAngleType) {
516 case MEAN -> {
517 final FieldUnivariateDerivative1<T> eUD = new FieldUnivariateDerivative1<>(e, eDot);
518 final FieldUnivariateDerivative1<T> MUD = new FieldUnivariateDerivative1<>(cachedAnomaly, cachedAnomalyDot);
519 final FieldUnivariateDerivative1<T> vUD = (a.getReal() < 0) ?
520 FieldKeplerianAnomalyUtility.hyperbolicMeanToTrue(eUD, MUD) :
521 FieldKeplerianAnomalyUtility.ellipticMeanToTrue(eUD, MUD);
522 yield vUD.getFirstDerivative();
523 }
524
525 case TRUE -> cachedAnomalyDot;
526
527 case ECCENTRIC -> {
528 final FieldUnivariateDerivative1<T> eUD2 = new FieldUnivariateDerivative1<>(e, eDot);
529 final FieldUnivariateDerivative1<T> EUD = new FieldUnivariateDerivative1<>(cachedAnomaly, cachedAnomalyDot);
530 final FieldUnivariateDerivative1<T> vUD2 = (a.getReal() < 0) ?
531 FieldKeplerianAnomalyUtility.hyperbolicEccentricToTrue(eUD2, EUD) :
532 FieldKeplerianAnomalyUtility.ellipticEccentricToTrue(eUD2, EUD);
533 yield vUD2.getFirstDerivative();
534 }
535 };
536 }
537
538
539
540
541 public T getEccentricAnomaly() {
542 return getAnomaly(PositionAngleType.ECCENTRIC);
543 }
544
545
546
547
548 public T getEccentricAnomalyDot() {
549 return switch (cachedPositionAngleType) {
550 case ECCENTRIC -> cachedAnomalyDot;
551
552 case TRUE -> {
553 final FieldUnivariateDerivative1<T> eUD = new FieldUnivariateDerivative1<>(e, eDot);
554 final FieldUnivariateDerivative1<T> vUD = new FieldUnivariateDerivative1<>(cachedAnomaly, cachedAnomalyDot);
555 final FieldUnivariateDerivative1<T> EUD = (a.getReal() < 0) ?
556 FieldKeplerianAnomalyUtility.hyperbolicTrueToEccentric(eUD, vUD) :
557 FieldKeplerianAnomalyUtility.ellipticTrueToEccentric(eUD, vUD);
558 yield EUD.getFirstDerivative();
559 }
560
561 case MEAN -> {
562 final FieldUnivariateDerivative1<T> eUD2 = new FieldUnivariateDerivative1<>(e, eDot);
563 final FieldUnivariateDerivative1<T> MUD = new FieldUnivariateDerivative1<>(cachedAnomaly, cachedAnomalyDot);
564 final FieldUnivariateDerivative1<T> EUD2 = (a.getReal() < 0) ?
565 FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(eUD2, MUD) :
566 FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(eUD2, MUD);
567 yield EUD2.getFirstDerivative();
568 }
569 };
570 }
571
572
573
574
575 public T getMeanAnomaly() {
576 return getAnomaly(PositionAngleType.MEAN);
577 }
578
579
580
581
582
583 public T getMeanAnomalyDot() {
584 return switch (cachedPositionAngleType) {
585 case MEAN -> cachedAnomalyDot;
586
587 case ECCENTRIC -> {
588 final FieldUnivariateDerivative1<T> eUD = new FieldUnivariateDerivative1<>(e, eDot);
589 final FieldUnivariateDerivative1<T> EUD = new FieldUnivariateDerivative1<>(cachedAnomaly, cachedAnomalyDot);
590 final FieldUnivariateDerivative1<T> MUD = (a.getReal() < 0) ?
591 FieldKeplerianAnomalyUtility.hyperbolicEccentricToMean(eUD, EUD) :
592 FieldKeplerianAnomalyUtility.ellipticEccentricToMean(eUD, EUD);
593 yield MUD.getFirstDerivative();
594 }
595
596 case TRUE -> {
597 final FieldUnivariateDerivative1<T> eUD2 = new FieldUnivariateDerivative1<>(e, eDot);
598 final FieldUnivariateDerivative1<T> vUD = new FieldUnivariateDerivative1<>(cachedAnomaly, cachedAnomalyDot);
599 final FieldUnivariateDerivative1<T> MUD2 = (a.getReal() < 0) ?
600 FieldKeplerianAnomalyUtility.hyperbolicTrueToMean(eUD2, vUD) :
601 FieldKeplerianAnomalyUtility.ellipticTrueToMean(eUD2, vUD);
602 yield MUD2.getFirstDerivative();
603 }
604 };
605 }
606
607
608
609
610
611 public T getAnomaly(final PositionAngleType type) {
612 return getKeplerianParameters().withPositionAngleType(type).anomaly();
613 }
614
615
616
617
618
619 public T getAnomalyDot(final PositionAngleType type) {
620 return switch (type) {
621 case MEAN -> getMeanAnomalyDot();
622 case ECCENTRIC -> getEccentricAnomalyDot();
623 case TRUE -> getTrueAnomalyDot();
624 };
625 }
626
627
628
629
630
631
632 public FieldKeplerianParameters<T> getKeplerianParameters() {
633 return new FieldKeplerianParameters<>(a, e, i, pa, raan, cachedAnomaly, cachedPositionAngleType);
634 }
635
636
637 @Override
638 public boolean hasNonKeplerianAcceleration() {
639 return aDot.getReal() != 0. || eDot.getReal() != 0 || iDot.getReal() != 0. || raanDot.getReal() != 0. || paDot.getReal() != 0. ||
640 FastMath.abs(cachedAnomalyDot.subtract(computeKeplerianAnomalyDot(cachedPositionAngleType, a, e, getMu(), cachedAnomaly, cachedPositionAngleType)).getReal()) > TOLERANCE_POSITION_ANGLE_RATE;
641 }
642
643
644 @Override
645 public T getEquinoctialEx() {
646 return e.multiply(pa.add(raan).cos());
647 }
648
649
650 @Override
651 public T getEquinoctialExDot() {
652 if (!hasNonKeplerianRates()) {
653 return getZero();
654 }
655 final FieldUnivariateDerivative1<T> eUD = new FieldUnivariateDerivative1<>(e, eDot);
656 final FieldUnivariateDerivative1<T> paUD = new FieldUnivariateDerivative1<>(pa, paDot);
657 final FieldUnivariateDerivative1<T> raanUD = new FieldUnivariateDerivative1<>(raan, raanDot);
658 return eUD.multiply(paUD.add(raanUD).cos()).getFirstDerivative();
659
660 }
661
662
663 @Override
664 public T getEquinoctialEy() {
665 return e.multiply((pa.add(raan)).sin());
666 }
667
668
669 @Override
670 public T getEquinoctialEyDot() {
671 if (!hasNonKeplerianRates()) {
672 return getZero();
673 }
674 final FieldUnivariateDerivative1<T> eUD = new FieldUnivariateDerivative1<>(e, eDot);
675 final FieldUnivariateDerivative1<T> paUD = new FieldUnivariateDerivative1<>(pa, paDot);
676 final FieldUnivariateDerivative1<T> raanUD = new FieldUnivariateDerivative1<>(raan, raanDot);
677 return eUD.multiply(paUD.add(raanUD).sin()).getFirstDerivative();
678
679 }
680
681
682 @Override
683 public T getHx() {
684
685 if (FastMath.abs(i.subtract(i.getPi()).getReal()) < 1.0e-10) {
686 return getZero().add(Double.NaN);
687 }
688 return raan.cos().multiply(i.divide(2).tan());
689 }
690
691
692 @Override
693 public T getHxDot() {
694
695
696 if (FastMath.abs(i.subtract(i.getPi()).getReal()) < 1.0e-10) {
697 return getZero().add(Double.NaN);
698 }
699 if (!hasNonKeplerianRates()) {
700 return getZero();
701 }
702
703 final FieldUnivariateDerivative1<T> iUD = new FieldUnivariateDerivative1<>(i, iDot);
704 final FieldUnivariateDerivative1<T> raanUD = new FieldUnivariateDerivative1<>(raan, raanDot);
705 return raanUD.cos().multiply(iUD.multiply(0.5).tan()).getFirstDerivative();
706
707 }
708
709
710 @Override
711 public T getHy() {
712
713 if (FastMath.abs(i.subtract(i.getPi()).getReal()) < 1.0e-10) {
714 return getZero().add(Double.NaN);
715 }
716 return raan.sin().multiply(i.divide(2).tan());
717 }
718
719
720 @Override
721 public T getHyDot() {
722
723
724 if (FastMath.abs(i.subtract(i.getPi()).getReal()) < 1.0e-10) {
725 return getZero().add(Double.NaN);
726 }
727 if (!hasNonKeplerianRates()) {
728 return getZero();
729 }
730
731 final FieldUnivariateDerivative1<T> iUD = new FieldUnivariateDerivative1<>(i, iDot);
732 final FieldUnivariateDerivative1<T> raanUD = new FieldUnivariateDerivative1<>(raan, raanDot);
733 return raanUD.sin().multiply(iUD.multiply(0.5).tan()).getFirstDerivative();
734
735 }
736
737
738 @Override
739 public T getLv() {
740 return pa.add(raan).add(getTrueAnomaly());
741 }
742
743
744 @Override
745 public T getLvDot() {
746 return paDot.add(raanDot).add(getTrueAnomalyDot());
747 }
748
749
750 @Override
751 public T getLE() {
752 return pa.add(raan).add(getEccentricAnomaly());
753 }
754
755
756 @Override
757 public T getLEDot() {
758 return paDot.add(raanDot).add(getEccentricAnomalyDot());
759 }
760
761
762 @Override
763 public T getLM() {
764 return pa.add(raan).add(getMeanAnomaly());
765 }
766
767
768 @Override
769 public T getLMDot() {
770 return paDot.add(raanDot).add(getMeanAnomalyDot());
771 }
772
773
774
775
776
777
778
779
780 private FieldUnivariateDerivative1<T> initializeCachedAnomaly(final T anomaly, final T anomalyDot,
781 final PositionAngleType inputType) {
782 if (cachedPositionAngleType == inputType) {
783 return new FieldUnivariateDerivative1<>(anomaly, anomalyDot);
784
785 } else {
786 final FieldUnivariateDerivative1<T> eUD = new FieldUnivariateDerivative1<>(e, eDot);
787 final FieldUnivariateDerivative1<T> anomalyUD = new FieldUnivariateDerivative1<>(anomaly, anomalyDot);
788
789 if (a.getReal() < 0) {
790 switch (cachedPositionAngleType) {
791 case MEAN:
792 if (inputType == PositionAngleType.ECCENTRIC) {
793 return FieldKeplerianAnomalyUtility.hyperbolicEccentricToMean(eUD, anomalyUD);
794 } else {
795 return FieldKeplerianAnomalyUtility.hyperbolicTrueToMean(eUD, anomalyUD);
796 }
797
798 case ECCENTRIC:
799 if (inputType == PositionAngleType.MEAN) {
800 return FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(eUD, anomalyUD);
801 } else {
802 return FieldKeplerianAnomalyUtility.hyperbolicTrueToEccentric(eUD, anomalyUD);
803 }
804
805 case TRUE:
806 if (inputType == PositionAngleType.MEAN) {
807 return FieldKeplerianAnomalyUtility.hyperbolicMeanToTrue(eUD, anomalyUD);
808 } else {
809 return FieldKeplerianAnomalyUtility.hyperbolicEccentricToTrue(eUD, anomalyUD);
810 }
811
812 default:
813 break;
814 }
815
816 } else {
817 switch (cachedPositionAngleType) {
818 case MEAN:
819 if (inputType == PositionAngleType.ECCENTRIC) {
820 return FieldKeplerianAnomalyUtility.ellipticEccentricToMean(eUD, anomalyUD);
821 } else {
822 return FieldKeplerianAnomalyUtility.ellipticTrueToMean(eUD, anomalyUD);
823 }
824
825 case ECCENTRIC:
826 if (inputType == PositionAngleType.MEAN) {
827 return FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(eUD, anomalyUD);
828 } else {
829 return FieldKeplerianAnomalyUtility.ellipticTrueToEccentric(eUD, anomalyUD);
830 }
831
832 case TRUE:
833 if (inputType == PositionAngleType.MEAN) {
834 return FieldKeplerianAnomalyUtility.ellipticMeanToTrue(eUD, anomalyUD);
835 } else {
836 return FieldKeplerianAnomalyUtility.ellipticEccentricToTrue(eUD, anomalyUD);
837 }
838
839 default:
840 break;
841 }
842
843 }
844 throw new OrekitInternalError(null);
845 }
846
847 }
848
849
850
851 private void computePVWithoutA() {
852
853 if (partialPV != null) {
854
855 return;
856 }
857
858 final FieldKeplerianParametersConverter<T> converter = new FieldKeplerianParametersConverter<>(getMu());
859 partialPV = converter.toCartesian(getKeplerianParameters());
860
861 }
862
863
864 @Override
865 protected FieldVector3D<T> initPosition() {
866 final FieldVector3D<T>[] axes = FieldKeplerianParametersConverter.referenceAxes(i, pa, raan);
867
868 if (isElliptical()) {
869
870
871
872
873 final T uME2 = e.negate().add(1).multiply(e.add(1));
874 final T s1Me2 = uME2.sqrt();
875 final FieldSinCos<T> scE = FastMath.sinCos(getEccentricAnomaly());
876 final T cosE = scE.cos();
877 final T sinE = scE.sin();
878
879 return new FieldVector3D<>(a.multiply(cosE.subtract(e)), axes[0], a.multiply(sinE).multiply(s1Me2), axes[1]);
880
881 } else {
882
883
884
885
886 final FieldSinCos<T> scV = FastMath.sinCos(getTrueAnomaly());
887 final T sinV = scV.sin();
888 final T cosV = scV.cos();
889 final T f = a.multiply(e.square().negate().add(1));
890 final T posFactor = f.divide(e.multiply(cosV).add(1));
891
892 return new FieldVector3D<>(posFactor.multiply(cosV), axes[0], posFactor.multiply(sinV), axes[1]);
893
894 }
895
896 }
897
898
899 @Override
900 protected TimeStampedFieldPVCoordinates<T> initPVCoordinates() {
901
902
903 computePVWithoutA();
904
905
906 final T r2 = partialPV.getPosition().getNorm2Sq();
907 final FieldVector3D<T> keplerianAcceleration = new FieldVector3D<>(r2.multiply(FastMath.sqrt(r2)).reciprocal().multiply(getMu().negate()),
908 partialPV.getPosition());
909 final FieldVector3D<T> acceleration = hasNonKeplerianRates() ?
910 keplerianAcceleration.add(nonKeplerianAcceleration()) :
911 keplerianAcceleration;
912
913 return new TimeStampedFieldPVCoordinates<>(getDate(), partialPV.getPosition(), partialPV.getVelocity(), acceleration);
914
915 }
916
917
918 @Override
919 public FieldKeplerianOrbit<T> inFrame(final Frame inertialFrame) {
920 final FieldPVCoordinates<T> fieldPVCoordinates;
921 if (hasNonKeplerianAcceleration()) {
922 fieldPVCoordinates = getPVCoordinates(inertialFrame);
923 } else {
924 final FieldKinematicTransform<T> transform = getFrame().getKinematicTransformTo(inertialFrame, getDate());
925 fieldPVCoordinates = transform.transformOnlyPV(getPVCoordinates());
926 }
927 final FieldKeplerianOrbit<T> fieldOrbit = new FieldKeplerianOrbit<>(fieldPVCoordinates, inertialFrame, getDate(), getMu());
928 if (fieldOrbit.getCachedPositionAngleType() == getCachedPositionAngleType()) {
929 return fieldOrbit;
930 } else {
931 return fieldOrbit.withCachedPositionAngleType(getCachedPositionAngleType());
932 }
933 }
934
935
936 @Override
937 public FieldKeplerianOrbit<T> withCachedPositionAngleType(final PositionAngleType positionAngleType) {
938 return new FieldKeplerianOrbit<>(a, e, i, pa, raan, getAnomaly(positionAngleType), aDot, eDot, iDot, paDot, raanDot,
939 getAnomalyDot(positionAngleType), positionAngleType, getFrame(), getDate(), getMu());
940 }
941
942
943 @Override
944 public FieldKeplerianOrbit<T> shiftedBy(final double dt) {
945 return shiftedBy(getZero().newInstance(dt));
946 }
947
948
949 @Override
950 public FieldKeplerianOrbit<T> shiftedBy(final T dt) {
951
952
953 final FieldKeplerianOrbit<T> keplerianShifted = keplerianShiftedBy(dt);
954
955
956 if (!dt.isZero() && hasNonKeplerianRates()) {
957 return new FieldKeplerianOrbit<>(shiftPVNonKeplerian(keplerianShifted.getPVCoordinates(), dt),
958 getFrame(), getDate().shiftedBy(dt), getMu());
959 }
960
961 else {
962 return keplerianShifted;
963 }
964
965 }
966
967
968 @Override
969 public FieldKeplerianOrbit<T> shiftedBy(final TimeOffset dt) {
970
971
972 final Field<T> field = getField();
973 final T dtValue = field.getOne().newInstance(dt.toDouble());
974
975
976 final FieldKeplerianOrbit<T> keplerianShifted = keplerianShiftedBy(dt);
977
978
979 if (!dtValue.isZero() && hasNonKeplerianRates()) {
980 return new FieldKeplerianOrbit<>(shiftPVNonKeplerian(keplerianShifted.getPVCoordinates(), dtValue),
981 getFrame(), getDate().shiftedBy(dt), getMu());
982 }
983
984 else {
985 return keplerianShifted;
986 }
987
988 }
989
990
991
992
993
994
995
996 protected FieldKeplerianOrbit<T> keplerianShiftedBy(final T dt) {
997 final FieldKeplerianParameters<T> shiftedElements = new FieldKeplerianParameters<>(a, e, i, pa, raan,
998 getKeplerianMeanMotion().multiply(dt).add(getMeanAnomaly()), PositionAngleType.MEAN);
999 return new FieldKeplerianOrbit<>(shiftedElements.withPositionAngleType(cachedPositionAngleType), getFrame(),
1000 getDate().shiftedBy(dt), getMu());
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010 private FieldKeplerianOrbit<T> keplerianShiftedBy(final TimeOffset dt) {
1011 final FieldKeplerianParameters<T> shiftedElements = new FieldKeplerianParameters<>(a, e, i, pa, raan,
1012 getKeplerianMeanMotion().multiply(dt.toDouble()).add(getMeanAnomaly()), PositionAngleType.MEAN);
1013 return new FieldKeplerianOrbit<>(shiftedElements.withPositionAngleType(cachedPositionAngleType), getFrame(),
1014 getDate().shiftedBy(dt), getMu());
1015 }
1016
1017
1018 @Override
1019 protected T[][] computeJacobianMeanWrtCartesian() {
1020 if (isElliptical()) {
1021 return computeJacobianMeanWrtCartesianElliptical();
1022 } else {
1023 return computeJacobianMeanWrtCartesianHyperbolic();
1024 }
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 private T[][] computeJacobianMeanWrtCartesianElliptical() {
1036
1037 final T[][] jacobian = MathArrays.buildArray(getA().getField(), 6, 6);
1038
1039
1040 computePVWithoutA();
1041 final FieldVector3D<T> position = partialPV.getPosition();
1042 final FieldVector3D<T> velocity = partialPV.getVelocity();
1043 final FieldVector3D<T> momentum = partialPV.getMomentum();
1044 final T v2 = velocity.getNorm2Sq();
1045 final T r2 = position.getNorm2Sq();
1046 final T r = r2.sqrt();
1047 final T r3 = r.multiply(r2);
1048
1049 final T px = position.getX();
1050 final T py = position.getY();
1051 final T pz = position.getZ();
1052 final T vx = velocity.getX();
1053 final T vy = velocity.getY();
1054 final T vz = velocity.getZ();
1055 final T mx = momentum.getX();
1056 final T my = momentum.getY();
1057 final T mz = momentum.getZ();
1058
1059 final T mu = getMu();
1060 final T sqrtMuA = FastMath.sqrt(a.multiply(mu));
1061 final T sqrtAoMu = FastMath.sqrt(a.divide(mu));
1062 final T a2 = a.square();
1063 final T twoA = a.multiply(2);
1064 final T rOnA = r.divide(a);
1065
1066 final T oMe2 = e.square().negate().add(1);
1067 final T epsilon = oMe2.sqrt();
1068 final T sqrtRec = epsilon.reciprocal();
1069
1070 final FieldSinCos<T> scI = FastMath.sinCos(i);
1071 final FieldSinCos<T> scPA = FastMath.sinCos(pa);
1072 final T cosI = scI.cos();
1073 final T sinI = scI.sin();
1074 final T cosPA = scPA.cos();
1075 final T sinPA = scPA.sin();
1076
1077 final T pv = FieldVector3D.dotProduct(position, velocity);
1078 final T cosE = a.subtract(r).divide(a.multiply(e));
1079 final T sinE = pv.divide(e.multiply(sqrtMuA));
1080
1081
1082 final FieldVector3D<T> vectorAR = new FieldVector3D<>(a2.multiply(2).divide(r3), position);
1083 final FieldVector3D<T> vectorARDot = velocity.scalarMultiply(a2.multiply(mu.divide(2.).reciprocal()));
1084 fillHalfRow(getOne(), vectorAR, jacobian[0], 0);
1085 fillHalfRow(getOne(), vectorARDot, jacobian[0], 3);
1086
1087
1088 final T factorER3 = pv.divide(twoA);
1089 final FieldVector3D<T> vectorER = new FieldVector3D<>(cosE.multiply(v2).divide(r.multiply(mu)), position,
1090 sinE.divide(sqrtMuA), velocity,
1091 factorER3.negate().multiply(sinE).divide(sqrtMuA), vectorAR);
1092 final FieldVector3D<T> vectorERDot = new FieldVector3D<>(sinE.divide(sqrtMuA), position,
1093 cosE.multiply(mu.divide(2.).reciprocal()).multiply(r), velocity,
1094 factorER3.negate().multiply(sinE).divide(sqrtMuA), vectorARDot);
1095 fillHalfRow(getOne(), vectorER, jacobian[1], 0);
1096 fillHalfRow(getOne(), vectorERDot, jacobian[1], 3);
1097
1098
1099 final T coefE = cosE.divide(e.multiply(sqrtMuA));
1100 final FieldVector3D<T> vectorEAnR =
1101 new FieldVector3D<>(sinE.negate().multiply(v2).divide(e.multiply(r).multiply(mu)), position, coefE, velocity,
1102 factorER3.negate().multiply(coefE), vectorAR);
1103
1104
1105 final FieldVector3D<T> vectorEAnRDot =
1106 new FieldVector3D<>(sinE.multiply(-2).multiply(r).divide(e.multiply(mu)), velocity, coefE, position,
1107 factorER3.negate().multiply(coefE), vectorARDot);
1108
1109
1110 final T s1 = sinE.negate().multiply(pz).divide(r).subtract(cosE.multiply(vz).multiply(sqrtAoMu));
1111 final T s2 = cosE.negate().multiply(pz).divide(r3);
1112 final T s3 = sinE.multiply(vz).divide(sqrtMuA.multiply(-2));
1113 final T t1 = sqrtRec.multiply(cosE.multiply(pz).divide(r).subtract(sinE.multiply(vz).multiply(sqrtAoMu)));
1114 final T t2 = sqrtRec.multiply(sinE.negate().multiply(pz).divide(r3));
1115 final T t3 = sqrtRec.multiply(cosE.subtract(e)).multiply(vz).divide(sqrtMuA.multiply(2));
1116 final T t4 = sqrtRec.multiply(e.multiply(sinI).multiply(cosPA).multiply(sqrtRec).subtract(vz.multiply(sqrtAoMu)));
1117 final FieldVector3D<T> s = new FieldVector3D<>(cosE.divide(r), this.plusK,
1118 s1, vectorEAnR,
1119 s2, position,
1120 s3, vectorAR);
1121 final FieldVector3D<T> sDot = new FieldVector3D<>(sinE.negate().multiply(sqrtAoMu), this.plusK,
1122 s1, vectorEAnRDot,
1123 s3, vectorARDot);
1124 final FieldVector3D<T> t =
1125 new FieldVector3D<>(sqrtRec.multiply(sinE).divide(r), this.plusK).add(new FieldVector3D<>(t1, vectorEAnR,
1126 t2, position,
1127 t3, vectorAR,
1128 t4, vectorER));
1129 final FieldVector3D<T> tDot = new FieldVector3D<>(sqrtRec.multiply(cosE.subtract(e)).multiply(sqrtAoMu), this.plusK,
1130 t1, vectorEAnRDot,
1131 t3, vectorARDot,
1132 t4, vectorERDot);
1133
1134
1135 final T factorI1 = sinI.negate().multiply(sqrtRec).divide(sqrtMuA);
1136 final T i1 = factorI1;
1137 final T i2 = factorI1.negate().multiply(mz).divide(twoA);
1138 final T i3 = factorI1.multiply(mz).multiply(e).divide(oMe2);
1139 final T i4 = cosI.multiply(sinPA);
1140 final T i5 = cosI.multiply(cosPA);
1141 fillHalfRow(i1, new FieldVector3D<>(vy, vx.negate(), getZero()), i2, vectorAR, i3, vectorER, i4, s, i5, t,
1142 jacobian[2], 0);
1143 fillHalfRow(i1, new FieldVector3D<>(py.negate(), px, getZero()), i2, vectorARDot, i3, vectorERDot, i4, sDot, i5, tDot,
1144 jacobian[2], 3);
1145
1146
1147 fillHalfRow(cosPA.divide(sinI), s, sinPA.negate().divide(sinI), t, jacobian[3], 0);
1148 fillHalfRow(cosPA.divide(sinI), sDot, sinPA.negate().divide(sinI), tDot, jacobian[3], 3);
1149
1150
1151 final T factorRaanR = (a.multiply(mu).multiply(oMe2).multiply(sinI).multiply(sinI)).reciprocal();
1152 fillHalfRow( factorRaanR.negate().multiply(my), new FieldVector3D<>(getZero(), vz, vy.negate()),
1153 factorRaanR.multiply(mx), new FieldVector3D<>(vz.negate(), getZero(), vx),
1154 jacobian[4], 0);
1155 fillHalfRow(factorRaanR.negate().multiply(my), new FieldVector3D<>(getZero(), pz.negate(), py),
1156 factorRaanR.multiply(mx), new FieldVector3D<>(pz, getZero(), px.negate()),
1157 jacobian[4], 3);
1158
1159
1160 fillHalfRow(rOnA, vectorEAnR, sinE.negate(), vectorER, jacobian[5], 0);
1161 fillHalfRow(rOnA, vectorEAnRDot, sinE.negate(), vectorERDot, jacobian[5], 3);
1162
1163 return jacobian;
1164
1165 }
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175 private T[][] computeJacobianMeanWrtCartesianHyperbolic() {
1176
1177 final T[][] jacobian = MathArrays.buildArray(getA().getField(), 6, 6);
1178
1179
1180 computePVWithoutA();
1181 final FieldVector3D<T> position = partialPV.getPosition();
1182 final FieldVector3D<T> velocity = partialPV.getVelocity();
1183 final FieldVector3D<T> momentum = partialPV.getMomentum();
1184 final T r2 = position.getNorm2Sq();
1185 final T r = r2.sqrt();
1186 final T r3 = r.multiply(r2);
1187
1188 final T x = position.getX();
1189 final T y = position.getY();
1190 final T z = position.getZ();
1191 final T vx = velocity.getX();
1192 final T vy = velocity.getY();
1193 final T vz = velocity.getZ();
1194 final T mx = momentum.getX();
1195 final T my = momentum.getY();
1196 final T mz = momentum.getZ();
1197
1198 final T mu = getMu();
1199 final T absA = a.negate();
1200 final T sqrtMuA = absA.multiply(mu).sqrt();
1201 final T a2 = a.square();
1202 final T rOa = r.divide(absA);
1203
1204 final FieldSinCos<T> scI = FastMath.sinCos(i);
1205 final T cosI = scI.cos();
1206 final T sinI = scI.sin();
1207
1208 final T pv = FieldVector3D.dotProduct(position, velocity);
1209
1210
1211 final FieldVector3D<T> vectorAR = new FieldVector3D<>(a2.multiply(-2).divide(r3), position);
1212 final FieldVector3D<T> vectorARDot = velocity.scalarMultiply(a2.multiply(-2).divide(mu));
1213 fillHalfRow(getOne().negate(), vectorAR, jacobian[0], 0);
1214 fillHalfRow(getOne().negate(), vectorARDot, jacobian[0], 3);
1215
1216
1217 final T m = momentum.getNorm();
1218 final T oOm = m.reciprocal();
1219 final FieldVector3D<T> dcXP = new FieldVector3D<>(getZero(), vz, vy.negate());
1220 final FieldVector3D<T> dcYP = new FieldVector3D<>(vz.negate(), getZero(), vx);
1221 final FieldVector3D<T> dcZP = new FieldVector3D<>( vy, vx.negate(), getZero());
1222 final FieldVector3D<T> dcXV = new FieldVector3D<>( getZero(), z.negate(), y);
1223 final FieldVector3D<T> dcYV = new FieldVector3D<>( z, getZero(), x.negate());
1224 final FieldVector3D<T> dcZV = new FieldVector3D<>( y.negate(), x, getZero());
1225 final FieldVector3D<T> dCP = new FieldVector3D<>(mx.multiply(oOm), dcXP, my.multiply(oOm), dcYP, mz.multiply(oOm), dcZP);
1226 final FieldVector3D<T> dCV = new FieldVector3D<>(mx.multiply(oOm), dcXV, my.multiply(oOm), dcYV, mz.multiply(oOm), dcZV);
1227
1228
1229 final T mOMu = m.divide(mu);
1230 final FieldVector3D<T> dpP = new FieldVector3D<>(mOMu.multiply(2), dCP);
1231 final FieldVector3D<T> dpV = new FieldVector3D<>(mOMu.multiply(2), dCV);
1232
1233
1234 final T p = m.multiply(mOMu);
1235 final T moO2ae = absA.multiply(2).multiply(e).reciprocal();
1236 final T m2OaMu = p.negate().divide(absA);
1237 fillHalfRow(moO2ae, dpP, m2OaMu.multiply(moO2ae), vectorAR, jacobian[1], 0);
1238 fillHalfRow(moO2ae, dpV, m2OaMu.multiply(moO2ae), vectorARDot, jacobian[1], 3);
1239
1240
1241 final T cI1 = m.multiply(sinI).reciprocal();
1242 final T cI2 = cosI.multiply(cI1);
1243 fillHalfRow(cI2, dCP, cI1.negate(), dcZP, jacobian[2], 0);
1244 fillHalfRow(cI2, dCV, cI1.negate(), dcZV, jacobian[2], 3);
1245
1246
1247
1248 final T cP1 = y.multiply(oOm);
1249 final T cP2 = x.negate().multiply(oOm);
1250 final T cP3 = mx.multiply(cP1).add(my.multiply(cP2)).negate();
1251 final T cP4 = cP3.multiply(oOm);
1252 final T cP5 = r2.multiply(sinI).multiply(sinI).negate().reciprocal();
1253 final T cP6 = z.multiply(cP5);
1254 final T cP7 = cP3.multiply(cP5);
1255 final FieldVector3D<T> dacP = new FieldVector3D<>(cP1, dcXP, cP2, dcYP, cP4, dCP, oOm, new FieldVector3D<>(my.negate(), mx, getZero()));
1256 final FieldVector3D<T> dacV = new FieldVector3D<>(cP1, dcXV, cP2, dcYV, cP4, dCV);
1257 final FieldVector3D<T> dpoP = new FieldVector3D<>(cP6, dacP, cP7, this.plusK);
1258 final FieldVector3D<T> dpoV = new FieldVector3D<>(cP6, dacV);
1259
1260 final T re2 = r2.multiply(e.square());
1261 final T recOre2 = p.subtract(r).divide(re2);
1262 final T resOre2 = pv.multiply(mOMu).divide(re2);
1263 final FieldVector3D<T> dreP = new FieldVector3D<>(mOMu, velocity, pv.divide(mu), dCP);
1264 final FieldVector3D<T> dreV = new FieldVector3D<>(mOMu, position, pv.divide(mu), dCV);
1265 final FieldVector3D<T> davP = new FieldVector3D<>(resOre2.negate(), dpP, recOre2, dreP, resOre2.divide(r), position);
1266 final FieldVector3D<T> davV = new FieldVector3D<>(resOre2.negate(), dpV, recOre2, dreV);
1267 fillHalfRow(getOne(), dpoP, getOne().negate(), davP, jacobian[3], 0);
1268 fillHalfRow(getOne(), dpoV, getOne().negate(), davV, jacobian[3], 3);
1269
1270
1271 final T cO0 = cI1.square();
1272 final T cO1 = mx.multiply(cO0);
1273 final T cO2 = my.negate().multiply(cO0);
1274 fillHalfRow(cO1, dcYP, cO2, dcXP, jacobian[4], 0);
1275 fillHalfRow(cO1, dcYV, cO2, dcXV, jacobian[4], 3);
1276
1277
1278 final T s2a = pv.divide(absA.multiply(2));
1279 final T oObux = m.square().add(absA.multiply(mu)).sqrt().reciprocal();
1280 final T scasbu = pv.multiply(oObux);
1281 final FieldVector3D<T> dauP = new FieldVector3D<>(sqrtMuA.reciprocal(), velocity, s2a.negate().divide(sqrtMuA), vectorAR);
1282 final FieldVector3D<T> dauV = new FieldVector3D<>(sqrtMuA.reciprocal(), position, s2a.negate().divide(sqrtMuA), vectorARDot);
1283 final FieldVector3D<T> dbuP = new FieldVector3D<>(oObux.multiply(mu.divide(2.)), vectorAR, m.multiply(oObux), dCP);
1284 final FieldVector3D<T> dbuV = new FieldVector3D<>(oObux.multiply(mu.divide(2.)), vectorARDot, m.multiply(oObux), dCV);
1285 final FieldVector3D<T> dcuP = new FieldVector3D<>(oObux, velocity, scasbu.negate().multiply(oObux), dbuP);
1286 final FieldVector3D<T> dcuV = new FieldVector3D<>(oObux, position, scasbu.negate().multiply(oObux), dbuV);
1287 fillHalfRow(getOne(), dauP, e.negate().divide(rOa.add(1)), dcuP, jacobian[5], 0);
1288 fillHalfRow(getOne(), dauV, e.negate().divide(rOa.add(1)), dcuV, jacobian[5], 3);
1289
1290 return jacobian;
1291
1292 }
1293
1294
1295 @Override
1296 protected T[][] computeJacobianEccentricWrtCartesian() {
1297 if (isElliptical()) {
1298 return computeJacobianEccentricWrtCartesianElliptical();
1299 } else {
1300 return computeJacobianEccentricWrtCartesianHyperbolic();
1301 }
1302 }
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312 private T[][] computeJacobianEccentricWrtCartesianElliptical() {
1313
1314
1315 final T[][] jacobian = computeJacobianMeanWrtCartesianElliptical();
1316
1317
1318
1319
1320
1321 final FieldSinCos<T> scE = FastMath.sinCos(getEccentricAnomaly());
1322 final T aOr = e.negate().multiply(scE.cos()).add(1).reciprocal();
1323
1324
1325 final T[] eRow = jacobian[1];
1326 final T[] anomalyRow = jacobian[5];
1327 for (int j = 0; j < anomalyRow.length; ++j) {
1328 anomalyRow[j] = aOr.multiply(anomalyRow[j].add(scE.sin().multiply(eRow[j])));
1329 }
1330
1331 return jacobian;
1332
1333 }
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343 private T[][] computeJacobianEccentricWrtCartesianHyperbolic() {
1344
1345
1346 final T[][] jacobian = computeJacobianMeanWrtCartesianHyperbolic();
1347
1348
1349
1350
1351
1352 final T H = getEccentricAnomaly();
1353 final T coshH = H.cosh();
1354 final T sinhH = H.sinh();
1355 final T absaOr = e.multiply(coshH).subtract(1).reciprocal();
1356
1357 final T[] eRow = jacobian[1];
1358 final T[] anomalyRow = jacobian[5];
1359
1360 for (int j = 0; j < anomalyRow.length; ++j) {
1361 anomalyRow[j] = absaOr.multiply(anomalyRow[j].subtract(sinhH.multiply(eRow[j])));
1362
1363 }
1364
1365 return jacobian;
1366
1367 }
1368
1369
1370 @Override
1371 protected T[][] computeJacobianTrueWrtCartesian() {
1372 if (isElliptical()) {
1373 return computeJacobianTrueWrtCartesianElliptical();
1374 } else {
1375 return computeJacobianTrueWrtCartesianHyperbolic();
1376 }
1377 }
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387 private T[][] computeJacobianTrueWrtCartesianElliptical() {
1388
1389
1390 final T[][] jacobian = computeJacobianEccentricWrtCartesianElliptical();
1391
1392
1393
1394
1395
1396 final T e2 = e.square();
1397 final T oMe2 = e2.negate().add(1);
1398 final T epsilon = oMe2.sqrt();
1399 final FieldSinCos<T> scE = FastMath.sinCos(getEccentricAnomaly());
1400 final T aOr = e.multiply(scE.cos()).negate().add(1).reciprocal();
1401 final T aFactor = epsilon.multiply(aOr);
1402 final T eFactor = scE.sin().multiply(aOr).divide(epsilon);
1403
1404
1405 final T[] eRow = jacobian[1];
1406 final T[] anomalyRow = jacobian[5];
1407 for (int j = 0; j < anomalyRow.length; ++j) {
1408 anomalyRow[j] = aFactor.multiply(anomalyRow[j]).add(eFactor.multiply(eRow[j]));
1409 }
1410 return jacobian;
1411
1412 }
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422 private T[][] computeJacobianTrueWrtCartesianHyperbolic() {
1423
1424
1425 final T[][] jacobian = computeJacobianEccentricWrtCartesianHyperbolic();
1426
1427
1428
1429
1430
1431
1432 final T e2 = e.square();
1433 final T e2Mo = e2.subtract(1);
1434 final T epsilon = e2Mo.sqrt();
1435 final T H = getEccentricAnomaly();
1436 final T coshH = H.cosh();
1437 final T sinhH = H.sinh();
1438 final T aOr = e.multiply(coshH).subtract(1).reciprocal();
1439 final T aFactor = epsilon.multiply(aOr);
1440 final T eFactor = sinhH.multiply(aOr).divide(epsilon);
1441
1442
1443 final T[] eRow = jacobian[1];
1444 final T[] anomalyRow = jacobian[5];
1445 for (int j = 0; j < anomalyRow.length; ++j) {
1446 anomalyRow[j] = aFactor.multiply(anomalyRow[j]).subtract(eFactor.multiply(eRow[j]));
1447 }
1448
1449 return jacobian;
1450
1451 }
1452
1453
1454 @Override
1455 public void addKeplerContribution(final PositionAngleType type, final T gm,
1456 final T[] pDot) {
1457 pDot[5] = pDot[5].add(computeKeplerianAnomalyDot(type, a, e, gm, cachedAnomaly, cachedPositionAngleType));
1458 }
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472 private static <T extends CalculusFieldElement<T>> T computeKeplerianAnomalyDot(final PositionAngleType type, final T a, final T e,
1473 final T mu, final T anomaly, final PositionAngleType cachedType) {
1474 final T absA = a.abs();
1475 final T n = absA.reciprocal().multiply(mu).sqrt().divide(absA);
1476 if (type == PositionAngleType.MEAN) {
1477 return n;
1478 }
1479 final T ksi;
1480 final T oMe2;
1481 final T trueAnomaly = FieldKeplerianAnomalyUtility.convertAnomaly(cachedType, anomaly, e, PositionAngleType.TRUE);
1482 if (type == PositionAngleType.ECCENTRIC) {
1483 oMe2 = e.square().negate().add(1).abs();
1484 ksi = e.multiply(trueAnomaly.cos()).add(1);
1485 return n.multiply(ksi).divide(oMe2);
1486 } else {
1487 oMe2 = e.square().negate().add(1).abs();
1488 ksi = e.multiply(trueAnomaly.cos()).add(1);
1489 return n.multiply(ksi).multiply(ksi).divide(oMe2.multiply(oMe2.sqrt()));
1490 }
1491 }
1492
1493
1494
1495
1496 public String toString() {
1497 return "Keplerian parameters: " + '{' +
1498 "a: " + a.getReal() +
1499 "; e: " + e.getReal() +
1500 "; i: " + FastMath.toDegrees(i.getReal()) +
1501 "; pa: " + FastMath.toDegrees(pa.getReal()) +
1502 "; raan: " + FastMath.toDegrees(raan.getReal()) +
1503 "; v: " + FastMath.toDegrees(getTrueAnomaly().getReal()) +
1504 ";}";
1505 }
1506
1507
1508 @Override
1509 public PositionAngleType getCachedPositionAngleType() {
1510 return cachedPositionAngleType;
1511 }
1512
1513
1514 @Override
1515 public boolean hasNonKeplerianRates() {
1516 return hasNonKeplerianAcceleration();
1517 }
1518
1519
1520 @Override
1521 public FieldKeplerianOrbit<T> withKeplerianRates() {
1522 return new FieldKeplerianOrbit<>(getKeplerianParameters(), getFrame(), getDate(), getMu());
1523 }
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 private void checkParameterRangeInclusive(final String parameterName, final double parameter,
1540 final double lowerBound, final double upperBound) {
1541 if (parameter < lowerBound || parameter > upperBound) {
1542 throw new OrekitException(OrekitMessages.INVALID_PARAMETER_RANGE, parameterName,
1543 parameter, lowerBound, upperBound);
1544 }
1545 }
1546
1547
1548 @Override
1549 public KeplerianOrbit toOrbit() {
1550 final KeplerianParameters elements = new KeplerianParameters(a.getReal(), e.getReal(), i.getReal(),
1551 pa.getReal(), raan.getReal(), cachedAnomaly.getReal(), cachedPositionAngleType);
1552 return new KeplerianOrbit(elements,
1553 aDot.getReal(), eDot.getReal(), iDot.getReal(), paDot.getReal(), raanDot.getReal(),
1554 cachedAnomalyDot.getReal(), cachedPositionAngleType,
1555 getFrame(), getDate().toAbsoluteDate(), getMu().getReal());
1556 }
1557
1558
1559 }