1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.orbits;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative1;
22 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23 import org.hipparchus.util.FastMath;
24 import org.hipparchus.util.FieldSinCos;
25 import org.hipparchus.util.MathArrays;
26 import org.orekit.errors.OrekitIllegalArgumentException;
27 import org.orekit.errors.OrekitInternalError;
28 import org.orekit.errors.OrekitMessages;
29 import org.orekit.frames.Frame;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.utils.FieldPVCoordinates;
32 import org.orekit.utils.TimeStampedFieldPVCoordinates;
33
34
35
36
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 public class FieldEquinoctialOrbit<T extends CalculusFieldElement<T>> extends FieldOrbit<T>
76 implements PositionAngleBased {
77
78
79 private final T a;
80
81
82 private final T ex;
83
84
85 private final T ey;
86
87
88 private final T hx;
89
90
91 private final T hy;
92
93
94 private final T cachedL;
95
96
97 private final PositionAngleType cachedPositionAngleType;
98
99
100 private final T aDot;
101
102
103 private final T exDot;
104
105
106 private final T eyDot;
107
108
109 private final T hxDot;
110
111
112 private final T hyDot;
113
114
115 private final T cachedLDot;
116
117
118 private FieldPVCoordinates<T> partialPV;
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public FieldEquinoctialOrbit(final T a, final T ex, final T ey,
138 final T hx, final T hy, final T l,
139 final PositionAngleType type, final PositionAngleType cachedPositionAngleType,
140 final Frame frame, final FieldAbsoluteDate<T> date, final T mu)
141 throws IllegalArgumentException {
142 this(a, ex, ey, hx, hy, l,
143 null, null, null, null, null, null,
144 type, cachedPositionAngleType, frame, date, mu);
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 public FieldEquinoctialOrbit(final T a, final T ex, final T ey,
163 final T hx, final T hy, final T l,
164 final PositionAngleType type,
165 final Frame frame, final FieldAbsoluteDate<T> date, final T mu)
166 throws IllegalArgumentException {
167 this(a, ex, ey, hx, hy, l,
168 null, null, null, null, null, null,
169 type, type, frame, date, mu);
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 public FieldEquinoctialOrbit(final T a, final T ex, final T ey,
196 final T hx, final T hy, final T l,
197 final T aDot, final T exDot, final T eyDot,
198 final T hxDot, final T hyDot, final T lDot,
199 final PositionAngleType type, final PositionAngleType cachedPositionAngleType,
200 final Frame frame, final FieldAbsoluteDate<T> date, final T mu)
201 throws IllegalArgumentException {
202 super(frame, date, mu);
203
204 if (ex.getReal() * ex.getReal() + ey.getReal() * ey.getReal() >= 1.0) {
205 throw new OrekitIllegalArgumentException(OrekitMessages.HYPERBOLIC_ORBIT_NOT_HANDLED_AS,
206 getClass().getName());
207 }
208 this.cachedPositionAngleType = cachedPositionAngleType;
209 this.a = a;
210 this.aDot = aDot;
211 this.ex = ex;
212 this.exDot = exDot;
213 this.ey = ey;
214 this.eyDot = eyDot;
215 this.hx = hx;
216 this.hxDot = hxDot;
217 this.hy = hy;
218 this.hyDot = hyDot;
219
220 if (hasDerivatives()) {
221 final FieldUnivariateDerivative1<T> alphaUD = initializeCachedL(l, lDot, type);
222 this.cachedL = alphaUD.getValue();
223 this.cachedLDot = alphaUD.getFirstDerivative();
224 } else {
225 this.cachedL = initializeCachedL(l, type);
226 this.cachedLDot = null;
227 }
228
229 this.partialPV = null;
230
231 }
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 public FieldEquinoctialOrbit(final T a, final T ex, final T ey,
256 final T hx, final T hy, final T l,
257 final T aDot, final T exDot, final T eyDot,
258 final T hxDot, final T hyDot, final T lDot,
259 final PositionAngleType type,
260 final Frame frame, final FieldAbsoluteDate<T> date, final T mu)
261 throws IllegalArgumentException {
262 this(a, ex, ey, hx, hy, l, aDot, exDot, eyDot, hxDot, hyDot, lDot, type, type, frame, date, mu);
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279 public FieldEquinoctialOrbit(final TimeStampedFieldPVCoordinates<T> pvCoordinates,
280 final Frame frame, final T mu)
281 throws IllegalArgumentException {
282 super(pvCoordinates, frame, mu);
283
284
285 final FieldVector3D<T> pvP = pvCoordinates.getPosition();
286 final FieldVector3D<T> pvV = pvCoordinates.getVelocity();
287 final FieldVector3D<T> pvA = pvCoordinates.getAcceleration();
288 final T r2 = pvP.getNormSq();
289 final T r = r2.sqrt();
290 final T V2 = pvV.getNormSq();
291 final T rV2OnMu = r.multiply(V2).divide(mu);
292
293
294 a = r.divide(rV2OnMu.negate().add(2));
295
296 if (!isElliptical()) {
297 throw new OrekitIllegalArgumentException(OrekitMessages.HYPERBOLIC_ORBIT_NOT_HANDLED_AS,
298 getClass().getName());
299 }
300
301
302 final FieldVector3D<T> w = pvCoordinates.getMomentum().normalize();
303 final T d = getOne().divide(getOne().add(w.getZ()));
304 hx = d.negate().multiply(w.getY());
305 hy = d.multiply(w.getX());
306
307
308 cachedPositionAngleType = PositionAngleType.TRUE;
309 final T cLv = (pvP.getX().subtract(d.multiply(pvP.getZ()).multiply(w.getX()))).divide(r);
310 final T sLv = (pvP.getY().subtract(d.multiply(pvP.getZ()).multiply(w.getY()))).divide(r);
311 cachedL = sLv.atan2(cLv);
312
313
314 final T eSE = FieldVector3D.dotProduct(pvP, pvV).divide(a.multiply(mu).sqrt());
315 final T eCE = rV2OnMu.subtract(1);
316 final T e2 = eCE.square().add(eSE.square());
317 final T f = eCE.subtract(e2);
318 final T g = e2.negate().add(1).sqrt().multiply(eSE);
319 ex = a.multiply(f.multiply(cLv).add( g.multiply(sLv))).divide(r);
320 ey = a.multiply(f.multiply(sLv).subtract(g.multiply(cLv))).divide(r);
321
322 partialPV = pvCoordinates;
323
324 if (hasNonKeplerianAcceleration(pvCoordinates, mu)) {
325
326
327 final T[][] jacobian = MathArrays.buildArray(a.getField(), 6, 6);
328 getJacobianWrtCartesian(PositionAngleType.MEAN, jacobian);
329
330 final FieldVector3D<T> keplerianAcceleration = new FieldVector3D<>(r.multiply(r2).reciprocal().multiply(mu.negate()), pvP);
331 final FieldVector3D<T> nonKeplerianAcceleration = pvA.subtract(keplerianAcceleration);
332 final T aX = nonKeplerianAcceleration.getX();
333 final T aY = nonKeplerianAcceleration.getY();
334 final T aZ = nonKeplerianAcceleration.getZ();
335 aDot = jacobian[0][3].multiply(aX).add(jacobian[0][4].multiply(aY)).add(jacobian[0][5].multiply(aZ));
336 exDot = jacobian[1][3].multiply(aX).add(jacobian[1][4].multiply(aY)).add(jacobian[1][5].multiply(aZ));
337 eyDot = jacobian[2][3].multiply(aX).add(jacobian[2][4].multiply(aY)).add(jacobian[2][5].multiply(aZ));
338 hxDot = jacobian[3][3].multiply(aX).add(jacobian[3][4].multiply(aY)).add(jacobian[3][5].multiply(aZ));
339 hyDot = jacobian[4][3].multiply(aX).add(jacobian[4][4].multiply(aY)).add(jacobian[4][5].multiply(aZ));
340
341
342
343 final T lMDot = getKeplerianMeanMotion().
344 add(jacobian[5][3].multiply(aX)).add(jacobian[5][4].multiply(aY)).add(jacobian[5][5].multiply(aZ));
345 final FieldUnivariateDerivative1<T> exUD = new FieldUnivariateDerivative1<>(ex, exDot);
346 final FieldUnivariateDerivative1<T> eyUD = new FieldUnivariateDerivative1<>(ey, eyDot);
347 final FieldUnivariateDerivative1<T> lMUD = new FieldUnivariateDerivative1<>(getLM(), lMDot);
348 final FieldUnivariateDerivative1<T> lvUD = FieldEquinoctialLongitudeArgumentUtility.meanToTrue(exUD, eyUD, lMUD);
349 cachedLDot = lvUD.getFirstDerivative();
350
351 } else {
352
353
354
355 aDot = null;
356 exDot = null;
357 eyDot = null;
358 hxDot = null;
359 hyDot = null;
360 cachedLDot = null;
361 }
362
363 }
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380 public FieldEquinoctialOrbit(final FieldPVCoordinates<T> pvCoordinates, final Frame frame,
381 final FieldAbsoluteDate<T> date, final T mu)
382 throws IllegalArgumentException {
383 this(new TimeStampedFieldPVCoordinates<>(date, pvCoordinates), frame, mu);
384 }
385
386
387
388
389 public FieldEquinoctialOrbit(final FieldOrbit<T> op) {
390 super(op.getFrame(), op.getDate(), op.getMu());
391
392 a = op.getA();
393 ex = op.getEquinoctialEx();
394 ey = op.getEquinoctialEy();
395 hx = op.getHx();
396 hy = op.getHy();
397 cachedPositionAngleType = PositionAngleType.TRUE;
398 cachedL = op.getLv();
399
400 aDot = op.getADot();
401 exDot = op.getEquinoctialExDot();
402 eyDot = op.getEquinoctialEyDot();
403 hxDot = op.getHxDot();
404 hyDot = op.getHyDot();
405 cachedLDot = op.getLvDot();
406 }
407
408
409
410
411
412
413
414 public FieldEquinoctialOrbit(final Field<T> field, final EquinoctialOrbit op) {
415 super(op.getFrame(), new FieldAbsoluteDate<>(field, op.getDate()), field.getZero().newInstance(op.getMu()));
416
417 a = getZero().newInstance(op.getA());
418 ex = getZero().newInstance(op.getEquinoctialEx());
419 ey = getZero().newInstance(op.getEquinoctialEy());
420 hx = getZero().newInstance(op.getHx());
421 hy = getZero().newInstance(op.getHy());
422 cachedPositionAngleType = op.getCachedPositionAngleType();
423 cachedL = getZero().newInstance(op.getL(cachedPositionAngleType));
424
425 if (op.hasDerivatives()) {
426 aDot = getZero().newInstance(op.getADot());
427 exDot = getZero().newInstance(op.getEquinoctialExDot());
428 eyDot = getZero().newInstance(op.getEquinoctialEyDot());
429 hxDot = getZero().newInstance(op.getHxDot());
430 hyDot = getZero().newInstance(op.getHyDot());
431 cachedLDot = getZero().newInstance(op.getLDot(cachedPositionAngleType));
432 } else {
433 aDot = null;
434 exDot = null;
435 eyDot = null;
436 hxDot = null;
437 hyDot = null;
438 cachedLDot = null;
439 }
440
441 }
442
443
444
445
446
447
448
449 public FieldEquinoctialOrbit(final Field<T> field, final Orbit op) {
450 this(field, (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(op));
451 }
452
453
454 @Override
455 public OrbitType getType() {
456 return OrbitType.EQUINOCTIAL;
457 }
458
459
460 @Override
461 public T getA() {
462 return a;
463 }
464
465
466 @Override
467 public T getADot() {
468 return aDot;
469 }
470
471
472 @Override
473 public T getEquinoctialEx() {
474 return ex;
475 }
476
477
478 @Override
479 public T getEquinoctialExDot() {
480 return exDot;
481 }
482
483
484 @Override
485 public T getEquinoctialEy() {
486 return ey;
487 }
488
489
490 @Override
491 public T getEquinoctialEyDot() {
492 return eyDot;
493 }
494
495
496 @Override
497 public T getHx() {
498 return hx;
499 }
500
501
502 @Override
503 public T getHxDot() {
504 return hxDot;
505 }
506
507
508 @Override
509 public T getHy() {
510 return hy;
511 }
512
513
514 @Override
515 public T getHyDot() {
516 return hyDot;
517 }
518
519
520 @Override
521 public T getLv() {
522 switch (cachedPositionAngleType) {
523 case TRUE:
524 return cachedL;
525
526 case ECCENTRIC:
527 return FieldEquinoctialLongitudeArgumentUtility.eccentricToTrue(ex, ey, cachedL);
528
529 case MEAN:
530 return FieldEquinoctialLongitudeArgumentUtility.meanToTrue(ex, ey, cachedL);
531
532 default:
533 throw new OrekitInternalError(null);
534 }
535 }
536
537
538 @Override
539 public T getLvDot() {
540
541 if (!hasDerivatives()) {
542 return null;
543 }
544 switch (cachedPositionAngleType) {
545 case ECCENTRIC:
546 final FieldUnivariateDerivative1<T> lEUD = new FieldUnivariateDerivative1<>(cachedL, cachedLDot);
547 final FieldUnivariateDerivative1<T> exUD = new FieldUnivariateDerivative1<>(ex, exDot);
548 final FieldUnivariateDerivative1<T> eyUD = new FieldUnivariateDerivative1<>(ey, eyDot);
549 final FieldUnivariateDerivative1<T> lvUD = FieldEquinoctialLongitudeArgumentUtility.eccentricToTrue(exUD, eyUD,
550 lEUD);
551 return lvUD.getFirstDerivative();
552
553 case TRUE:
554 return cachedLDot;
555
556 case MEAN:
557 final FieldUnivariateDerivative1<T> lMUD = new FieldUnivariateDerivative1<>(cachedL, cachedLDot);
558 final FieldUnivariateDerivative1<T> exUD2 = new FieldUnivariateDerivative1<>(ex, exDot);
559 final FieldUnivariateDerivative1<T> eyUD2 = new FieldUnivariateDerivative1<>(ey, eyDot);
560 final FieldUnivariateDerivative1<T> lvUD2 = FieldEquinoctialLongitudeArgumentUtility.meanToTrue(exUD2,
561 eyUD2, lMUD);
562 return lvUD2.getFirstDerivative();
563
564 default:
565 throw new OrekitInternalError(null);
566 }
567 }
568
569
570 @Override
571 public T getLE() {
572 switch (cachedPositionAngleType) {
573 case TRUE:
574 return FieldEquinoctialLongitudeArgumentUtility.trueToEccentric(ex, ey, cachedL);
575
576 case ECCENTRIC:
577 return cachedL;
578
579 case MEAN:
580 return FieldEquinoctialLongitudeArgumentUtility.meanToEccentric(ex, ey, cachedL);
581
582 default:
583 throw new OrekitInternalError(null);
584 }
585 }
586
587
588 @Override
589 public T getLEDot() {
590
591 if (!hasDerivatives()) {
592 return null;
593 }
594 switch (cachedPositionAngleType) {
595 case TRUE:
596 final FieldUnivariateDerivative1<T> lvUD = new FieldUnivariateDerivative1<>(cachedL, cachedLDot);
597 final FieldUnivariateDerivative1<T> exUD = new FieldUnivariateDerivative1<>(ex, exDot);
598 final FieldUnivariateDerivative1<T> eyUD = new FieldUnivariateDerivative1<>(ey, eyDot);
599 final FieldUnivariateDerivative1<T> lEUD = FieldEquinoctialLongitudeArgumentUtility.trueToEccentric(exUD, eyUD,
600 lvUD);
601 return lEUD.getFirstDerivative();
602
603 case ECCENTRIC:
604 return cachedLDot;
605
606 case MEAN:
607 final FieldUnivariateDerivative1<T> lMUD = new FieldUnivariateDerivative1<>(cachedL, cachedLDot);
608 final FieldUnivariateDerivative1<T> exUD2 = new FieldUnivariateDerivative1<>(ex, exDot);
609 final FieldUnivariateDerivative1<T> eyUD2 = new FieldUnivariateDerivative1<>(ey, eyDot);
610 final FieldUnivariateDerivative1<T> lEUD2 = FieldEquinoctialLongitudeArgumentUtility.meanToEccentric(exUD2,
611 eyUD2, lMUD);
612 return lEUD2.getFirstDerivative();
613
614 default:
615 throw new OrekitInternalError(null);
616 }
617 }
618
619
620 @Override
621 public T getLM() {
622 switch (cachedPositionAngleType) {
623 case TRUE:
624 return FieldEquinoctialLongitudeArgumentUtility.trueToMean(ex, ey, cachedL);
625
626 case MEAN:
627 return cachedL;
628
629 case ECCENTRIC:
630 return FieldEquinoctialLongitudeArgumentUtility.eccentricToMean(ex, ey, cachedL);
631
632 default:
633 throw new OrekitInternalError(null);
634 }
635 }
636
637
638 @Override
639 public T getLMDot() {
640
641 if (!hasDerivatives()) {
642 return null;
643 }
644 switch (cachedPositionAngleType) {
645 case TRUE:
646 final FieldUnivariateDerivative1<T> lvUD = new FieldUnivariateDerivative1<>(cachedL, cachedLDot);
647 final FieldUnivariateDerivative1<T> exUD = new FieldUnivariateDerivative1<>(ex, exDot);
648 final FieldUnivariateDerivative1<T> eyUD = new FieldUnivariateDerivative1<>(ey, eyDot);
649 final FieldUnivariateDerivative1<T> lMUD = FieldEquinoctialLongitudeArgumentUtility.trueToMean(exUD, eyUD, lvUD);
650 return lMUD.getFirstDerivative();
651
652 case MEAN:
653 return cachedLDot;
654
655 case ECCENTRIC:
656 final FieldUnivariateDerivative1<T> lEUD = new FieldUnivariateDerivative1<>(cachedL, cachedLDot);
657 final FieldUnivariateDerivative1<T> exUD2 = new FieldUnivariateDerivative1<>(ex, exDot);
658 final FieldUnivariateDerivative1<T> eyUD2 = new FieldUnivariateDerivative1<>(ey, eyDot);
659 final FieldUnivariateDerivative1<T> lMUD2 = FieldEquinoctialLongitudeArgumentUtility.eccentricToMean(exUD2,
660 eyUD2, lEUD);
661 return lMUD2.getFirstDerivative();
662
663 default:
664 throw new OrekitInternalError(null);
665 }
666 }
667
668
669
670
671
672 public T getL(final PositionAngleType type) {
673 return (type == PositionAngleType.MEAN) ? getLM() :
674 ((type == PositionAngleType.ECCENTRIC) ? getLE() :
675 getLv());
676 }
677
678
679
680
681
682 public T getLDot(final PositionAngleType type) {
683 return (type == PositionAngleType.MEAN) ? getLMDot() :
684 ((type == PositionAngleType.ECCENTRIC) ? getLEDot() :
685 getLvDot());
686 }
687
688
689 @Override
690 public boolean hasDerivatives() {
691 return aDot != null;
692 }
693
694
695
696
697
698
699
700
701 @Deprecated
702 public static <T extends CalculusFieldElement<T>> T eccentricToTrue(final T lE, final T ex, final T ey) {
703 return FieldEquinoctialLongitudeArgumentUtility.eccentricToTrue(ex, ey, lE);
704 }
705
706
707
708
709
710
711
712
713 @Deprecated
714 public static <T extends CalculusFieldElement<T>> T trueToEccentric(final T lv, final T ex, final T ey) {
715 return FieldEquinoctialLongitudeArgumentUtility.trueToEccentric(ex, ey, lv);
716 }
717
718
719
720
721
722
723
724
725 @Deprecated
726 public static <T extends CalculusFieldElement<T>> T meanToEccentric(final T lM, final T ex, final T ey) {
727 return FieldEquinoctialLongitudeArgumentUtility.meanToEccentric(ex, ey, lM);
728 }
729
730
731
732
733
734
735
736
737 @Deprecated
738 public static <T extends CalculusFieldElement<T>> T eccentricToMean(final T lE, final T ex, final T ey) {
739 return FieldEquinoctialLongitudeArgumentUtility.eccentricToMean(ex, ey, lE);
740 }
741
742
743 @Override
744 public T getE() {
745 return ex.square().add(ey.square()).sqrt();
746 }
747
748
749 @Override
750 public T getEDot() {
751
752 if (!hasDerivatives()) {
753 return null;
754 }
755
756 return ex.multiply(exDot).add(ey.multiply(eyDot)).divide(ex.square().add(ey.square()).sqrt());
757
758 }
759
760
761 @Override
762 public T getI() {
763 return hx.square().add(hy.square()).sqrt().atan().multiply(2);
764 }
765
766
767 @Override
768 public T getIDot() {
769
770 if (!hasDerivatives()) {
771 return null;
772 }
773
774 final T h2 = hx.square().add(hy.square());
775 final T h = h2.sqrt();
776 return hx.multiply(hxDot).add(hy.multiply(hyDot)).multiply(2).divide(h.multiply(h2.add(1)));
777
778 }
779
780
781
782 private void computePVWithoutA() {
783
784 if (partialPV != null) {
785
786 return;
787 }
788
789
790 final T lE = getLE();
791
792
793 final T hx2 = hx.square();
794 final T hy2 = hy.square();
795 final T factH = getOne().divide(hx2.add(1.0).add(hy2));
796
797
798 final T ux = hx2.add(1.0).subtract(hy2).multiply(factH);
799 final T uy = hx.multiply(hy).multiply(factH).multiply(2);
800 final T uz = hy.multiply(-2).multiply(factH);
801
802 final T vx = uy;
803 final T vy = (hy2.subtract(hx2).add(1)).multiply(factH);
804 final T vz = hx.multiply(factH).multiply(2);
805
806
807 final T ex2 = ex.square();
808 final T exey = ex.multiply(ey);
809 final T ey2 = ey.square();
810 final T e2 = ex2.add(ey2);
811 final T eta = getOne().subtract(e2).sqrt().add(1);
812 final T beta = getOne().divide(eta);
813
814
815 final FieldSinCos<T> scLe = FastMath.sinCos(lE);
816 final T cLe = scLe.cos();
817 final T sLe = scLe.sin();
818 final T exCeyS = ex.multiply(cLe).add(ey.multiply(sLe));
819
820
821 final T x = a.multiply(getOne().subtract(beta.multiply(ey2)).multiply(cLe).add(beta.multiply(exey).multiply(sLe)).subtract(ex));
822 final T y = a.multiply(getOne().subtract(beta.multiply(ex2)).multiply(sLe).add(beta .multiply(exey).multiply(cLe)).subtract(ey));
823
824 final T factor = getMu().divide(a).sqrt().divide(getOne().subtract(exCeyS));
825 final T xdot = factor.multiply(sLe.negate().add(beta.multiply(ey).multiply(exCeyS)));
826 final T ydot = factor.multiply(cLe.subtract(beta.multiply(ex).multiply(exCeyS)));
827
828 final FieldVector3D<T> position =
829 new FieldVector3D<>(x.multiply(ux).add(y.multiply(vx)),
830 x.multiply(uy).add(y.multiply(vy)),
831 x.multiply(uz).add(y.multiply(vz)));
832 final FieldVector3D<T> velocity =
833 new FieldVector3D<>(xdot.multiply(ux).add(ydot.multiply(vx)), xdot.multiply(uy).add(ydot.multiply(vy)), xdot.multiply(uz).add(ydot.multiply(vz)));
834
835 partialPV = new FieldPVCoordinates<>(position, velocity);
836
837 }
838
839
840
841
842
843
844
845
846 private FieldUnivariateDerivative1<T> initializeCachedL(final T l, final T lDot,
847 final PositionAngleType inputType) {
848 if (cachedPositionAngleType == inputType) {
849 return new FieldUnivariateDerivative1<>(l, lDot);
850
851 } else {
852 final FieldUnivariateDerivative1<T> exUD = new FieldUnivariateDerivative1<>(ex, exDot);
853 final FieldUnivariateDerivative1<T> eyUD = new FieldUnivariateDerivative1<>(ey, eyDot);
854 final FieldUnivariateDerivative1<T> lUD = new FieldUnivariateDerivative1<>(l, lDot);
855
856 switch (cachedPositionAngleType) {
857
858 case ECCENTRIC:
859 if (inputType == PositionAngleType.MEAN) {
860 return FieldEquinoctialLongitudeArgumentUtility.meanToEccentric(exUD, eyUD, lUD);
861 } else {
862 return FieldEquinoctialLongitudeArgumentUtility.trueToEccentric(exUD, eyUD, lUD);
863 }
864
865 case TRUE:
866 if (inputType == PositionAngleType.MEAN) {
867 return FieldEquinoctialLongitudeArgumentUtility.meanToTrue(exUD, eyUD, lUD);
868 } else {
869 return FieldEquinoctialLongitudeArgumentUtility.eccentricToTrue(exUD, eyUD, lUD);
870 }
871
872 case MEAN:
873 if (inputType == PositionAngleType.TRUE) {
874 return FieldEquinoctialLongitudeArgumentUtility.trueToMean(exUD, eyUD, lUD);
875 } else {
876 return FieldEquinoctialLongitudeArgumentUtility.eccentricToMean(exUD, eyUD, lUD);
877 }
878
879 default:
880 throw new OrekitInternalError(null);
881
882 }
883
884 }
885
886 }
887
888
889
890
891
892
893
894 private T initializeCachedL(final T l, final PositionAngleType positionAngleType) {
895 if (positionAngleType == cachedPositionAngleType) {
896 return l;
897
898 } else {
899 switch (cachedPositionAngleType) {
900
901 case ECCENTRIC:
902 if (positionAngleType == PositionAngleType.MEAN) {
903 return FieldEquinoctialLongitudeArgumentUtility.meanToEccentric(ex, ey, l);
904 } else {
905 return FieldEquinoctialLongitudeArgumentUtility.trueToEccentric(ex, ey, l);
906 }
907
908 case MEAN:
909 if (positionAngleType == PositionAngleType.TRUE) {
910 return FieldEquinoctialLongitudeArgumentUtility.trueToMean(ex, ey, l);
911 } else {
912 return FieldEquinoctialLongitudeArgumentUtility.eccentricToMean(ex, ey, l);
913 }
914
915 case TRUE:
916 if (positionAngleType == PositionAngleType.MEAN) {
917 return FieldEquinoctialLongitudeArgumentUtility.meanToTrue(ex, ey, l);
918 } else {
919 return FieldEquinoctialLongitudeArgumentUtility.eccentricToTrue(ex, ey, l);
920 }
921
922 default:
923 throw new OrekitInternalError(null);
924 }
925 }
926 }
927
928
929
930
931
932
933
934 private FieldVector3D<T> nonKeplerianAcceleration() {
935
936 final T[][] dCdP = MathArrays.buildArray(a.getField(), 6, 6);
937 getJacobianWrtParameters(PositionAngleType.MEAN, dCdP);
938
939 final T nonKeplerianMeanMotion = getLMDot().subtract(getKeplerianMeanMotion());
940 final T nonKeplerianAx = dCdP[3][0].multiply(aDot).
941 add(dCdP[3][1].multiply(exDot)).
942 add(dCdP[3][2].multiply(eyDot)).
943 add(dCdP[3][3].multiply(hxDot)).
944 add(dCdP[3][4].multiply(hyDot)).
945 add(dCdP[3][5].multiply(nonKeplerianMeanMotion));
946 final T nonKeplerianAy = dCdP[4][0].multiply(aDot).
947 add(dCdP[4][1].multiply(exDot)).
948 add(dCdP[4][2].multiply(eyDot)).
949 add(dCdP[4][3].multiply(hxDot)).
950 add(dCdP[4][4].multiply(hyDot)).
951 add(dCdP[4][5].multiply(nonKeplerianMeanMotion));
952 final T nonKeplerianAz = dCdP[5][0].multiply(aDot).
953 add(dCdP[5][1].multiply(exDot)).
954 add(dCdP[5][2].multiply(eyDot)).
955 add(dCdP[5][3].multiply(hxDot)).
956 add(dCdP[5][4].multiply(hyDot)).
957 add(dCdP[5][5].multiply(nonKeplerianMeanMotion));
958
959 return new FieldVector3D<>(nonKeplerianAx, nonKeplerianAy, nonKeplerianAz);
960
961 }
962
963
964 @Override
965 protected FieldVector3D<T> initPosition() {
966
967
968 final T lE = getLE();
969
970
971 final T hx2 = hx.square();
972 final T hy2 = hy.square();
973 final T factH = getOne().divide(hx2.add(1.0).add(hy2));
974
975
976 final T ux = hx2.add(1.0).subtract(hy2).multiply(factH);
977 final T uy = hx.multiply(hy).multiply(factH).multiply(2);
978 final T uz = hy.multiply(-2).multiply(factH);
979
980 final T vx = uy;
981 final T vy = (hy2.subtract(hx2).add(1)).multiply(factH);
982 final T vz = hx.multiply(factH).multiply(2);
983
984
985 final T ex2 = ex.square();
986 final T exey = ex.multiply(ey);
987 final T ey2 = ey.square();
988 final T e2 = ex2.add(ey2);
989 final T eta = getOne().subtract(e2).sqrt().add(1);
990 final T beta = getOne().divide(eta);
991
992
993 final FieldSinCos<T> scLe = FastMath.sinCos(lE);
994 final T cLe = scLe.cos();
995 final T sLe = scLe.sin();
996
997
998 final T x = a.multiply(getOne().subtract(beta.multiply(ey2)).multiply(cLe).add(beta.multiply(exey).multiply(sLe)).subtract(ex));
999 final T y = a.multiply(getOne().subtract(beta.multiply(ex2)).multiply(sLe).add(beta .multiply(exey).multiply(cLe)).subtract(ey));
1000
1001 return new FieldVector3D<>(x.multiply(ux).add(y.multiply(vx)),
1002 x.multiply(uy).add(y.multiply(vy)),
1003 x.multiply(uz).add(y.multiply(vz)));
1004
1005 }
1006
1007
1008 @Override
1009 protected TimeStampedFieldPVCoordinates<T> initPVCoordinates() {
1010
1011
1012 computePVWithoutA();
1013
1014
1015 final T r2 = partialPV.getPosition().getNormSq();
1016 final FieldVector3D<T> keplerianAcceleration = new FieldVector3D<>(r2.multiply(r2.sqrt()).reciprocal().multiply(getMu().negate()),
1017 partialPV.getPosition());
1018 final FieldVector3D<T> acceleration = hasDerivatives() ?
1019 keplerianAcceleration.add(nonKeplerianAcceleration()) :
1020 keplerianAcceleration;
1021
1022 return new TimeStampedFieldPVCoordinates<>(getDate(), partialPV.getPosition(), partialPV.getVelocity(), acceleration);
1023
1024 }
1025
1026
1027 @Override
1028 public FieldEquinoctialOrbit<T> shiftedBy(final double dt) {
1029 return shiftedBy(getZero().newInstance(dt));
1030 }
1031
1032
1033 @Override
1034 public FieldEquinoctialOrbit<T> shiftedBy(final T dt) {
1035
1036
1037 final FieldEquinoctialOrbit<T> keplerianShifted = new FieldEquinoctialOrbit<>(a, ex, ey, hx, hy,
1038 getLM().add(getKeplerianMeanMotion().multiply(dt)),
1039 PositionAngleType.MEAN, cachedPositionAngleType, getFrame(),
1040 getDate().shiftedBy(dt), getMu());
1041
1042 if (hasDerivatives()) {
1043
1044
1045 final FieldVector3D<T> nonKeplerianAcceleration = nonKeplerianAcceleration();
1046
1047
1048 keplerianShifted.computePVWithoutA();
1049 final FieldVector3D<T> fixedP = new FieldVector3D<>(getOne(), keplerianShifted.partialPV.getPosition(),
1050 dt.square().multiply(0.5), nonKeplerianAcceleration);
1051 final T fixedR2 = fixedP.getNormSq();
1052 final T fixedR = fixedR2.sqrt();
1053 final FieldVector3D<T> fixedV = new FieldVector3D<>(getOne(), keplerianShifted.partialPV.getVelocity(),
1054 dt, nonKeplerianAcceleration);
1055 final FieldVector3D<T> fixedA = new FieldVector3D<>(fixedR2.multiply(fixedR).reciprocal().multiply(getMu().negate()),
1056 keplerianShifted.partialPV.getPosition(),
1057 getOne(), nonKeplerianAcceleration);
1058
1059
1060 return new FieldEquinoctialOrbit<>(new TimeStampedFieldPVCoordinates<>(keplerianShifted.getDate(),
1061 fixedP, fixedV, fixedA),
1062 keplerianShifted.getFrame(), keplerianShifted.getMu());
1063
1064 } else {
1065
1066 return keplerianShifted;
1067 }
1068
1069 }
1070
1071
1072 @Override
1073 protected T[][] computeJacobianMeanWrtCartesian() {
1074
1075 final T[][] jacobian = MathArrays.buildArray(getField(), 6, 6);
1076
1077
1078 computePVWithoutA();
1079 final FieldVector3D<T> position = partialPV.getPosition();
1080 final FieldVector3D<T> velocity = partialPV.getVelocity();
1081 final T r2 = position.getNormSq();
1082 final T r = r2.sqrt();
1083 final T r3 = r.multiply(r2);
1084
1085 final T mu = getMu();
1086 final T sqrtMuA = a.multiply(mu).sqrt();
1087 final T a2 = a.square();
1088
1089 final T e2 = ex.square().add(ey.square());
1090 final T oMe2 = getOne().subtract(e2);
1091 final T epsilon = oMe2.sqrt();
1092 final T beta = getOne().divide(epsilon.add(1));
1093 final T ratio = epsilon.multiply(beta);
1094
1095 final T hx2 = hx.square();
1096 final T hy2 = hy.square();
1097 final T hxhy = hx.multiply(hy);
1098
1099
1100 final FieldVector3D<T> f = new FieldVector3D<>(hx2.subtract(hy2).add(1), hxhy.multiply(2), hy.multiply(-2)).normalize();
1101 final FieldVector3D<T> g = new FieldVector3D<>(hxhy.multiply(2), hy2.add(1).subtract(hx2), hx.multiply(2)).normalize();
1102 final FieldVector3D<T> w = FieldVector3D.crossProduct(position, velocity).normalize();
1103
1104
1105 final T x = FieldVector3D.dotProduct(position, f);
1106 final T y = FieldVector3D.dotProduct(position, g);
1107 final T xDot = FieldVector3D.dotProduct(velocity, f);
1108 final T yDot = FieldVector3D.dotProduct(velocity, g);
1109
1110
1111 final T c1 = a.divide(sqrtMuA.multiply(epsilon));
1112 final T c1N = c1.negate();
1113 final T c2 = a.multiply(sqrtMuA).multiply(beta).divide(r3);
1114 final T c3 = sqrtMuA.divide(r3.multiply(epsilon));
1115 final FieldVector3D<T> drDotSdEx = new FieldVector3D<>(c1.multiply(xDot).multiply(yDot).subtract(c2.multiply(ey).multiply(x)).subtract(c3.multiply(x).multiply(y)), f,
1116 c1N.multiply(xDot).multiply(xDot).subtract(c2.multiply(ey).multiply(y)).add(c3.multiply(x).multiply(x)), g);
1117
1118
1119 final FieldVector3D<T> drDotSdEy = new FieldVector3D<>(c1.multiply(yDot).multiply(yDot).add(c2.multiply(ex).multiply(x)).subtract(c3.multiply(y).multiply(y)), f,
1120 c1N.multiply(xDot).multiply(yDot).add(c2.multiply(ex).multiply(y)).add(c3.multiply(x).multiply(y)), g);
1121
1122
1123 final FieldVector3D<T> vectorAR = new FieldVector3D<>(a2.multiply(2).divide(r3), position);
1124 final FieldVector3D<T> vectorARDot = new FieldVector3D<>(a2.multiply(2).divide(mu), velocity);
1125 fillHalfRow(getOne(), vectorAR, jacobian[0], 0);
1126 fillHalfRow(getOne(), vectorARDot, jacobian[0], 3);
1127
1128
1129 final T d1 = a.negate().multiply(ratio).divide(r3);
1130 final T d2 = (hy.multiply(xDot).subtract(hx.multiply(yDot))).divide(sqrtMuA.multiply(epsilon));
1131 final T d3 = hx.multiply(y).subtract(hy.multiply(x)).divide(sqrtMuA);
1132 final FieldVector3D<T> vectorExRDot =
1133 new FieldVector3D<>(x.multiply(2).multiply(yDot).subtract(xDot.multiply(y)).divide(mu), g, y.negate().multiply(yDot).divide(mu), f, ey.negate().multiply(d3).divide(epsilon), w);
1134 fillHalfRow(ex.multiply(d1), position, ey.negate().multiply(d2), w, epsilon.divide(sqrtMuA), drDotSdEy, jacobian[1], 0);
1135 fillHalfRow(getOne(), vectorExRDot, jacobian[1], 3);
1136
1137
1138 final FieldVector3D<T> vectorEyRDot =
1139 new FieldVector3D<>(xDot.multiply(2).multiply(y).subtract(x.multiply(yDot)).divide(mu), f, x.negate().multiply(xDot).divide(mu), g, ex.multiply(d3).divide(epsilon), w);
1140 fillHalfRow(ey.multiply(d1), position, ex.multiply(d2), w, epsilon.negate().divide(sqrtMuA), drDotSdEx, jacobian[2], 0);
1141 fillHalfRow(getOne(), vectorEyRDot, jacobian[2], 3);
1142
1143
1144 final T h = (hx2.add(1).add(hy2)).divide(sqrtMuA.multiply(2).multiply(epsilon));
1145 fillHalfRow( h.negate().multiply(xDot), w, jacobian[3], 0);
1146 fillHalfRow( h.multiply(x), w, jacobian[3], 3);
1147
1148
1149 fillHalfRow( h.negate().multiply(yDot), w, jacobian[4], 0);
1150 fillHalfRow( h.multiply(y), w, jacobian[4], 3);
1151
1152
1153 final T l = ratio.negate().divide(sqrtMuA);
1154 fillHalfRow(getOne().negate().divide(sqrtMuA), velocity, d2, w, l.multiply(ex), drDotSdEx, l.multiply(ey), drDotSdEy, jacobian[5], 0);
1155 fillHalfRow(getZero().newInstance(-2).divide(sqrtMuA), position, ex.multiply(beta), vectorEyRDot, ey.negate().multiply(beta), vectorExRDot, d3, w, jacobian[5], 3);
1156
1157 return jacobian;
1158
1159 }
1160
1161
1162 @Override
1163 protected T[][] computeJacobianEccentricWrtCartesian() {
1164
1165
1166 final T[][] jacobian = computeJacobianMeanWrtCartesian();
1167
1168
1169
1170
1171
1172 final FieldSinCos<T> scLe = FastMath.sinCos(getLE());
1173 final T cosLe = scLe.cos();
1174 final T sinLe = scLe.sin();
1175 final T aOr = getOne().divide(getOne().subtract(ex.multiply(cosLe)).subtract(ey.multiply(sinLe)));
1176
1177
1178 final T[] rowEx = jacobian[1];
1179 final T[] rowEy = jacobian[2];
1180 final T[] rowL = jacobian[5];
1181
1182 for (int j = 0; j < 6; ++j) {
1183 rowL[j] = aOr.multiply(rowL[j].add(sinLe.multiply(rowEx[j])).subtract(cosLe.multiply(rowEy[j])));
1184 }
1185 return jacobian;
1186
1187 }
1188
1189
1190 @Override
1191 protected T[][] computeJacobianTrueWrtCartesian() {
1192
1193
1194 final T[][] jacobian = computeJacobianEccentricWrtCartesian();
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 final FieldSinCos<T> scLe = FastMath.sinCos(getLE());
1209 final T cosLe = scLe.cos();
1210 final T sinLe = scLe.sin();
1211 final T eSinE = ex.multiply(sinLe).subtract(ey.multiply(cosLe));
1212 final T ecosE = ex.multiply(cosLe).add(ey.multiply(sinLe));
1213 final T e2 = ex.square().add(ey.square());
1214 final T epsilon = getOne().subtract(e2).sqrt();
1215 final T onePeps = epsilon.add(1);
1216 final T d = onePeps.subtract(ecosE);
1217 final T cT = d.multiply(d).add(eSinE.multiply(eSinE)).divide(2);
1218 final T cE = ecosE.multiply(onePeps).subtract(e2);
1219 final T cX = ex.multiply(eSinE).divide(epsilon).subtract(ey).add(sinLe.multiply(onePeps));
1220 final T cY = ey.multiply(eSinE).divide(epsilon).add( ex).subtract(cosLe.multiply(onePeps));
1221 final T factorLe = cT.add(cE).divide(cT);
1222 final T factorEx = cX.divide(cT);
1223 final T factorEy = cY.divide(cT);
1224
1225
1226 final T[] rowEx = jacobian[1];
1227 final T[] rowEy = jacobian[2];
1228 final T[] rowL = jacobian[5];
1229 for (int j = 0; j < 6; ++j) {
1230 rowL[j] = factorLe.multiply(rowL[j]).add(factorEx.multiply(rowEx[j])).add(factorEy.multiply(rowEy[j]));
1231 }
1232
1233 return jacobian;
1234
1235 }
1236
1237
1238 @Override
1239 public void addKeplerContribution(final PositionAngleType type, final T gm,
1240 final T[] pDot) {
1241 final T oMe2;
1242 final T ksi;
1243 final T n = gm.divide(a).sqrt().divide(a);
1244 final FieldSinCos<T> sc;
1245 switch (type) {
1246 case MEAN :
1247 pDot[5] = pDot[5].add(n);
1248 break;
1249 case ECCENTRIC :
1250 sc = FastMath.sinCos(getLE());
1251 ksi = ((ex.multiply(sc.cos())).add(ey.multiply(sc.sin()))).negate().add(1).reciprocal();
1252 pDot[5] = pDot[5].add(n.multiply(ksi));
1253 break;
1254 case TRUE :
1255 sc = FastMath.sinCos(getLv());
1256 oMe2 = getOne().subtract(ex.square()).subtract(ey.square());
1257 ksi = ex.multiply(sc.cos()).add(1).add(ey.multiply(sc.sin()));
1258 pDot[5] = pDot[5].add(n.multiply(ksi).multiply(ksi).divide(oMe2.multiply(oMe2.sqrt())));
1259 break;
1260 default :
1261 throw new OrekitInternalError(null);
1262 }
1263 }
1264
1265
1266
1267
1268 public String toString() {
1269 return new StringBuilder().append("equinoctial parameters: ").append('{').
1270 append("a: ").append(a.getReal()).
1271 append("; ex: ").append(ex.getReal()).append("; ey: ").append(ey.getReal()).
1272 append("; hx: ").append(hx.getReal()).append("; hy: ").append(hy.getReal()).
1273 append("; lv: ").append(FastMath.toDegrees(getLv().getReal())).
1274 append(";}").toString();
1275 }
1276
1277
1278 @Override
1279 public PositionAngleType getCachedPositionAngleType() {
1280 return cachedPositionAngleType;
1281 }
1282
1283
1284 @Override
1285 public boolean hasRates() {
1286 return hasDerivatives();
1287 }
1288
1289
1290 @Override
1291 public FieldEquinoctialOrbit<T> removeRates() {
1292 return new FieldEquinoctialOrbit<>(getA(), getEquinoctialEx(), getEquinoctialEy(), getHx(), getHy(),
1293 cachedL, cachedPositionAngleType, getFrame(), getDate(), getMu());
1294 }
1295
1296
1297 @Override
1298 public EquinoctialOrbit toOrbit() {
1299 final double cachedPositionAngle = cachedL.getReal();
1300 if (hasDerivatives()) {
1301 return new EquinoctialOrbit(a.getReal(), ex.getReal(), ey.getReal(),
1302 hx.getReal(), hy.getReal(), cachedPositionAngle,
1303 aDot.getReal(), exDot.getReal(), eyDot.getReal(),
1304 hxDot.getReal(), hyDot.getReal(), cachedLDot.getReal(),
1305 cachedPositionAngleType, getFrame(),
1306 getDate().toAbsoluteDate(), getMu().getReal());
1307 } else {
1308 return new EquinoctialOrbit(a.getReal(), ex.getReal(), ey.getReal(),
1309 hx.getReal(), hy.getReal(), cachedPositionAngle,
1310 cachedPositionAngleType, getFrame(),
1311 getDate().toAbsoluteDate(), getMu().getReal());
1312 }
1313 }
1314
1315 }