1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.orbits;
18
19 import java.io.Serializable;
20
21 import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.hipparchus.util.FastMath;
24 import org.hipparchus.util.SinCos;
25 import org.orekit.annotation.DefaultDataContext;
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.frames.KinematicTransform;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.time.TimeOffset;
33 import org.orekit.utils.PVCoordinates;
34 import org.orekit.utils.TimeStampedPVCoordinates;
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
76 public class CircularOrbit extends Orbit implements PositionAngleBased {
77
78
79 private static final long serialVersionUID = 20231217L;
80
81
82 private final double a;
83
84
85 private final double ex;
86
87
88 private final double ey;
89
90
91 private final double i;
92
93
94 private final double raan;
95
96
97 private final double cachedAlpha;
98
99
100 private final PositionAngleType cachedPositionAngleType;
101
102
103 private final double aDot;
104
105
106 private final double exDot;
107
108
109 private final double eyDot;
110
111
112 private final double iDot;
113
114
115 private final double raanDot;
116
117
118 private final double cachedAlphaDot;
119
120
121 private final boolean serializePV;
122
123
124 private transient PVCoordinates partialPV;
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public CircularOrbit(final double a, final double ex, final double ey,
144 final double i, final double raan, final double alpha,
145 final PositionAngleType type, final PositionAngleType cachedPositionAngleType,
146 final Frame frame, final AbsoluteDate date, final double mu)
147 throws IllegalArgumentException {
148 this(a, ex, ey, i, raan, alpha, 0., 0., 0., 0., 0.,
149 computeKeplerianAlphaDot(type, a, ex, ey, mu, alpha, type),
150 type, cachedPositionAngleType, frame, date, mu);
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 public CircularOrbit(final double a, final double ex, final double ey,
169 final double i, final double raan, final double alpha,
170 final PositionAngleType type,
171 final Frame frame, final AbsoluteDate date, final double mu)
172 throws IllegalArgumentException {
173 this(a, ex, ey, i, raan, alpha, type, type, frame, date, mu);
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 public CircularOrbit(final double a, final double ex, final double ey,
200 final double i, final double raan, final double alpha,
201 final double aDot, final double exDot, final double eyDot,
202 final double iDot, final double raanDot, final double alphaDot,
203 final PositionAngleType type, final PositionAngleType cachedPositionAngleType,
204 final Frame frame, final AbsoluteDate date, final double mu)
205 throws IllegalArgumentException {
206 super(frame, date, mu);
207 if (ex * ex + ey * ey >= 1.0) {
208 throw new OrekitIllegalArgumentException(OrekitMessages.HYPERBOLIC_ORBIT_NOT_HANDLED_AS,
209 getClass().getName());
210 }
211 this.a = a;
212 this.aDot = aDot;
213 this.ex = ex;
214 this.exDot = exDot;
215 this.ey = ey;
216 this.eyDot = eyDot;
217 this.i = i;
218 this.iDot = iDot;
219 this.raan = raan;
220 this.raanDot = raanDot;
221 this.cachedPositionAngleType = cachedPositionAngleType;
222
223 final UnivariateDerivative1 alphaUD = initializeCachedAlpha(alpha, alphaDot, type);
224 this.cachedAlpha = alphaUD.getValue();
225 this.cachedAlphaDot = alphaUD.getFirstDerivative();
226
227 serializePV = false;
228 partialPV = null;
229
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253 public CircularOrbit(final double a, final double ex, final double ey,
254 final double i, final double raan, final double alpha,
255 final double aDot, final double exDot, final double eyDot,
256 final double iDot, final double raanDot, final double alphaDot,
257 final PositionAngleType type,
258 final Frame frame, final AbsoluteDate date, final double mu)
259 throws IllegalArgumentException {
260 this(a, ex, ey, i, raan, alpha, aDot, exDot, eyDot, iDot, raanDot, alphaDot, type, type,
261 frame, date, mu);
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285 private CircularOrbit(final double a, final double ex, final double ey,
286 final double i, final double raan, final double alpha,
287 final double aDot, final double exDot, final double eyDot,
288 final double iDot, final double raanDot, final double alphaDot,
289 final TimeStampedPVCoordinates pvCoordinates,
290 final PositionAngleType positionAngleType, final Frame frame, final double mu)
291 throws IllegalArgumentException {
292 super(pvCoordinates, frame, mu);
293 this.a = a;
294 this.aDot = aDot;
295 this.ex = ex;
296 this.exDot = exDot;
297 this.ey = ey;
298 this.eyDot = eyDot;
299 this.i = i;
300 this.iDot = iDot;
301 this.raan = raan;
302 this.raanDot = raanDot;
303 this.cachedAlpha = alpha;
304 this.cachedAlphaDot = alphaDot;
305 this.cachedPositionAngleType = positionAngleType;
306 this.serializePV = true;
307 this.partialPV = null;
308 }
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 public CircularOrbit(final TimeStampedPVCoordinates pvCoordinates, final Frame frame, final double mu)
325 throws IllegalArgumentException {
326 super(pvCoordinates, frame, mu);
327 this.cachedPositionAngleType = PositionAngleType.TRUE;
328
329
330 final Vector3D pvP = pvCoordinates.getPosition();
331 final Vector3D pvV = pvCoordinates.getVelocity();
332 final Vector3D pvA = pvCoordinates.getAcceleration();
333 final double r2 = pvP.getNormSq();
334 final double r = FastMath.sqrt(r2);
335 final double V2 = pvV.getNormSq();
336 final double rV2OnMu = r * V2 / mu;
337 a = r / (2 - rV2OnMu);
338
339 if (!isElliptical()) {
340 throw new OrekitIllegalArgumentException(OrekitMessages.HYPERBOLIC_ORBIT_NOT_HANDLED_AS,
341 getClass().getName());
342 }
343
344
345 final Vector3D momentum = pvCoordinates.getMomentum();
346 i = Vector3D.angle(momentum, Vector3D.PLUS_K);
347
348
349 final Vector3D node = Vector3D.crossProduct(Vector3D.PLUS_K, momentum);
350 raan = FastMath.atan2(node.getY(), node.getX());
351
352
353 final SinCos scRaan = FastMath.sinCos(raan);
354 final SinCos scI = FastMath.sinCos(i);
355 final double xP = pvP.getX();
356 final double yP = pvP.getY();
357 final double zP = pvP.getZ();
358 final double x2 = (xP * scRaan.cos() + yP * scRaan.sin()) / a;
359 final double y2 = ((yP * scRaan.cos() - xP * scRaan.sin()) * scI.cos() + zP * scI.sin()) / a;
360
361
362 final double eSE = Vector3D.dotProduct(pvP, pvV) / FastMath.sqrt(mu * a);
363 final double eCE = rV2OnMu - 1;
364 final double e2 = eCE * eCE + eSE * eSE;
365 final double f = eCE - e2;
366 final double g = FastMath.sqrt(1 - e2) * eSE;
367 final double aOnR = a / r;
368 final double a2OnR2 = aOnR * aOnR;
369 ex = a2OnR2 * (f * x2 + g * y2);
370 ey = a2OnR2 * (f * y2 - g * x2);
371
372
373 final double beta = 1 / (1 + FastMath.sqrt(1 - ex * ex - ey * ey));
374 cachedAlpha = CircularLatitudeArgumentUtility.eccentricToTrue(ex, ey, FastMath.atan2(y2 + ey + eSE * beta * ex, x2 + ex - eSE * beta * ey));
375
376 partialPV = pvCoordinates;
377
378 if (hasNonKeplerianAcceleration(pvCoordinates, mu)) {
379
380
381 final double[][] jacobian = new double[6][6];
382 getJacobianWrtCartesian(PositionAngleType.MEAN, jacobian);
383
384 final Vector3D keplerianAcceleration = new Vector3D(-mu / (r * r2), pvP);
385 final Vector3D nonKeplerianAcceleration = pvA.subtract(keplerianAcceleration);
386 final double aX = nonKeplerianAcceleration.getX();
387 final double aY = nonKeplerianAcceleration.getY();
388 final double aZ = nonKeplerianAcceleration.getZ();
389 aDot = jacobian[0][3] * aX + jacobian[0][4] * aY + jacobian[0][5] * aZ;
390 exDot = jacobian[1][3] * aX + jacobian[1][4] * aY + jacobian[1][5] * aZ;
391 eyDot = jacobian[2][3] * aX + jacobian[2][4] * aY + jacobian[2][5] * aZ;
392 iDot = jacobian[3][3] * aX + jacobian[3][4] * aY + jacobian[3][5] * aZ;
393 raanDot = jacobian[4][3] * aX + jacobian[4][4] * aY + jacobian[4][5] * aZ;
394
395
396
397 final double alphaMDot = getKeplerianMeanMotion() +
398 jacobian[5][3] * aX + jacobian[5][4] * aY + jacobian[5][5] * aZ;
399 final UnivariateDerivative1 exUD = new UnivariateDerivative1(ex, exDot);
400 final UnivariateDerivative1 eyUD = new UnivariateDerivative1(ey, eyDot);
401 final UnivariateDerivative1 alphaMUD = new UnivariateDerivative1(getAlphaM(), alphaMDot);
402 final UnivariateDerivative1 alphavUD = FieldCircularLatitudeArgumentUtility.meanToTrue(exUD, eyUD, alphaMUD);
403 cachedAlphaDot = alphavUD.getFirstDerivative();
404
405 } else {
406
407
408
409 aDot = 0.;
410 exDot = 0.;
411 eyDot = 0.;
412 iDot = 0.;
413 raanDot = 0.;
414 cachedAlphaDot = computeKeplerianAlphaDot(cachedPositionAngleType, a, ex, ey, mu, cachedAlpha, cachedPositionAngleType);
415 }
416
417 serializePV = true;
418
419 }
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 public CircularOrbit(final PVCoordinates pvCoordinates, final Frame frame,
437 final AbsoluteDate date, final double mu)
438 throws IllegalArgumentException {
439 this(new TimeStampedPVCoordinates(date, pvCoordinates), frame, mu);
440 }
441
442
443
444
445 public CircularOrbit(final Orbit op) {
446
447 super(op.getFrame(), op.getDate(), op.getMu());
448
449 a = op.getA();
450 i = op.getI();
451 final double hx = op.getHx();
452 final double hy = op.getHy();
453 final double h2 = hx * hx + hy * hy;
454 final double h = FastMath.sqrt(h2);
455 raan = FastMath.atan2(hy, hx);
456 final SinCos scRaan = FastMath.sinCos(raan);
457 final double cosRaan = h == 0 ? scRaan.cos() : hx / h;
458 final double sinRaan = h == 0 ? scRaan.sin() : hy / h;
459 final double equiEx = op.getEquinoctialEx();
460 final double equiEy = op.getEquinoctialEy();
461 ex = equiEx * cosRaan + equiEy * sinRaan;
462 ey = equiEy * cosRaan - equiEx * sinRaan;
463 cachedPositionAngleType = PositionAngleType.TRUE;
464 cachedAlpha = op.getLv() - raan;
465
466 if (op.hasNonKeplerianAcceleration()) {
467 aDot = op.getADot();
468 final double hxDot = op.getHxDot();
469 final double hyDot = op.getHyDot();
470 iDot = 2 * (cosRaan * hxDot + sinRaan * hyDot) / (1 + h2);
471 raanDot = (hx * hyDot - hy * hxDot) / h2;
472 final double equiExDot = op.getEquinoctialExDot();
473 final double equiEyDot = op.getEquinoctialEyDot();
474 exDot = (equiExDot + equiEy * raanDot) * cosRaan +
475 (equiEyDot - equiEx * raanDot) * sinRaan;
476 eyDot = (equiEyDot - equiEx * raanDot) * cosRaan -
477 (equiExDot + equiEy * raanDot) * sinRaan;
478 cachedAlphaDot = op.getLvDot() - raanDot;
479 } else {
480 aDot = 0.;
481 exDot = 0.;
482 eyDot = 0.;
483 iDot = 0.;
484 raanDot = 0.;
485 cachedAlphaDot = computeKeplerianAlphaDot(cachedPositionAngleType, a, ex, ey, getMu(), cachedAlpha, cachedPositionAngleType);
486 }
487
488 serializePV = false;
489 partialPV = null;
490
491 }
492
493
494 @Override
495 public boolean hasNonKeplerianAcceleration() {
496 return aDot != 0. || exDot != 0. || eyDot != 0. || iDot != 0. || raanDot != 0. ||
497 FastMath.abs(cachedAlphaDot - computeKeplerianAlphaDot(cachedPositionAngleType, a, ex, ey, getMu(), cachedAlpha, cachedPositionAngleType)) > TOLERANCE_POSITION_ANGLE_RATE;
498 }
499
500
501 @Override
502 public OrbitType getType() {
503 return OrbitType.CIRCULAR;
504 }
505
506
507 @Override
508 public double getA() {
509 return a;
510 }
511
512
513 @Override
514 public double getADot() {
515 return aDot;
516 }
517
518
519 @Override
520 public double getEquinoctialEx() {
521 final SinCos sc = FastMath.sinCos(raan);
522 return ex * sc.cos() - ey * sc.sin();
523 }
524
525
526 @Override
527 public double getEquinoctialExDot() {
528 if (!hasNonKeplerianAcceleration()) {
529 return 0.;
530 }
531 final SinCos sc = FastMath.sinCos(raan);
532 return (exDot - ey * raanDot) * sc.cos() - (eyDot + ex * raanDot) * sc.sin();
533 }
534
535
536 @Override
537 public double getEquinoctialEy() {
538 final SinCos sc = FastMath.sinCos(raan);
539 return ey * sc.cos() + ex * sc.sin();
540 }
541
542
543 @Override
544 public double getEquinoctialEyDot() {
545 if (!hasNonKeplerianAcceleration()) {
546 return 0.;
547 }
548 final SinCos sc = FastMath.sinCos(raan);
549 return (eyDot + ex * raanDot) * sc.cos() + (exDot - ey * raanDot) * sc.sin();
550 }
551
552
553
554
555 public double getCircularEx() {
556 return ex;
557 }
558
559
560
561
562
563 public double getCircularExDot() {
564 return exDot;
565 }
566
567
568
569
570 public double getCircularEy() {
571 return ey;
572 }
573
574
575
576
577 public double getCircularEyDot() {
578 return eyDot;
579 }
580
581
582 @Override
583 public double getHx() {
584
585 if (FastMath.abs(i - FastMath.PI) < 1.0e-10) {
586 return Double.NaN;
587 }
588 return FastMath.cos(raan) * FastMath.tan(i / 2);
589 }
590
591
592 @Override
593 public double getHxDot() {
594
595 if (FastMath.abs(i - FastMath.PI) < 1.0e-10) {
596 return Double.NaN;
597 }
598 if (!hasNonKeplerianAcceleration()) {
599 return 0.;
600 }
601 final SinCos sc = FastMath.sinCos(raan);
602 final double tan = FastMath.tan(0.5 * i);
603 return 0.5 * sc.cos() * (1 + tan * tan) * iDot - sc.sin() * tan * raanDot;
604 }
605
606
607 @Override
608 public double getHy() {
609
610 if (FastMath.abs(i - FastMath.PI) < 1.0e-10) {
611 return Double.NaN;
612 }
613 return FastMath.sin(raan) * FastMath.tan(i / 2);
614 }
615
616
617 @Override
618 public double getHyDot() {
619
620 if (FastMath.abs(i - FastMath.PI) < 1.0e-10) {
621 return Double.NaN;
622 }
623 if (!hasNonKeplerianAcceleration()) {
624 return 0.;
625 }
626 final SinCos sc = FastMath.sinCos(raan);
627 final double tan = FastMath.tan(0.5 * i);
628 return 0.5 * sc.sin() * (1 + tan * tan) * iDot + sc.cos() * tan * raanDot;
629 }
630
631
632
633
634 public double getAlphaV() {
635 switch (cachedPositionAngleType) {
636 case TRUE:
637 return cachedAlpha;
638
639 case ECCENTRIC:
640 return CircularLatitudeArgumentUtility.eccentricToTrue(ex, ey, cachedAlpha);
641
642 case MEAN:
643 return CircularLatitudeArgumentUtility.meanToTrue(ex, ey, cachedAlpha);
644
645 default:
646 throw new OrekitInternalError(null);
647 }
648 }
649
650
651
652
653
654
655
656
657 public double getAlphaVDot() {
658 switch (cachedPositionAngleType) {
659 case ECCENTRIC:
660 final UnivariateDerivative1 alphaEUD = new UnivariateDerivative1(cachedAlpha, cachedAlphaDot);
661 final UnivariateDerivative1 exUD = new UnivariateDerivative1(ex, exDot);
662 final UnivariateDerivative1 eyUD = new UnivariateDerivative1(ey, eyDot);
663 final UnivariateDerivative1 alphaVUD = FieldCircularLatitudeArgumentUtility.eccentricToTrue(exUD, eyUD,
664 alphaEUD);
665 return alphaVUD.getFirstDerivative();
666
667 case TRUE:
668 return cachedAlphaDot;
669
670 case MEAN:
671 final UnivariateDerivative1 alphaMUD = new UnivariateDerivative1(cachedAlpha, cachedAlphaDot);
672 final UnivariateDerivative1 exUD2 = new UnivariateDerivative1(ex, exDot);
673 final UnivariateDerivative1 eyUD2 = new UnivariateDerivative1(ey, eyDot);
674 final UnivariateDerivative1 alphaVUD2 = FieldCircularLatitudeArgumentUtility.meanToTrue(exUD2,
675 eyUD2, alphaMUD);
676 return alphaVUD2.getFirstDerivative();
677
678 default:
679 throw new OrekitInternalError(null);
680 }
681 }
682
683
684
685
686 public double getAlphaE() {
687 switch (cachedPositionAngleType) {
688 case TRUE:
689 return CircularLatitudeArgumentUtility.trueToEccentric(ex, ey, cachedAlpha);
690
691 case ECCENTRIC:
692 return cachedAlpha;
693
694 case MEAN:
695 return CircularLatitudeArgumentUtility.meanToEccentric(ex, ey, cachedAlpha);
696
697 default:
698 throw new OrekitInternalError(null);
699 }
700 }
701
702
703
704
705
706
707
708
709 public double getAlphaEDot() {
710 switch (cachedPositionAngleType) {
711 case TRUE:
712 final UnivariateDerivative1 alphaVUD = new UnivariateDerivative1(cachedAlpha, cachedAlphaDot);
713 final UnivariateDerivative1 exUD = new UnivariateDerivative1(ex, exDot);
714 final UnivariateDerivative1 eyUD = new UnivariateDerivative1(ey, eyDot);
715 final UnivariateDerivative1 alphaEUD = FieldCircularLatitudeArgumentUtility.trueToEccentric(exUD, eyUD,
716 alphaVUD);
717 return alphaEUD.getFirstDerivative();
718
719 case ECCENTRIC:
720 return cachedAlphaDot;
721
722 case MEAN:
723 final UnivariateDerivative1 alphaMUD = new UnivariateDerivative1(cachedAlpha, cachedAlphaDot);
724 final UnivariateDerivative1 exUD2 = new UnivariateDerivative1(ex, exDot);
725 final UnivariateDerivative1 eyUD2 = new UnivariateDerivative1(ey, eyDot);
726 final UnivariateDerivative1 alphaVUD2 = FieldCircularLatitudeArgumentUtility.meanToEccentric(exUD2,
727 eyUD2, alphaMUD);
728 return alphaVUD2.getFirstDerivative();
729
730 default:
731 throw new OrekitInternalError(null);
732 }
733 }
734
735
736
737
738 public double getAlphaM() {
739 switch (cachedPositionAngleType) {
740 case TRUE:
741 return CircularLatitudeArgumentUtility.trueToMean(ex, ey, cachedAlpha);
742
743 case MEAN:
744 return cachedAlpha;
745
746 case ECCENTRIC:
747 return CircularLatitudeArgumentUtility.eccentricToMean(ex, ey, cachedAlpha);
748
749 default:
750 throw new OrekitInternalError(null);
751 }
752 }
753
754
755
756
757
758
759
760
761 public double getAlphaMDot() {
762 switch (cachedPositionAngleType) {
763 case TRUE:
764 final UnivariateDerivative1 alphaVUD = new UnivariateDerivative1(cachedAlpha, cachedAlphaDot);
765 final UnivariateDerivative1 exUD = new UnivariateDerivative1(ex, exDot);
766 final UnivariateDerivative1 eyUD = new UnivariateDerivative1(ey, eyDot);
767 final UnivariateDerivative1 alphaMUD = FieldCircularLatitudeArgumentUtility.trueToMean(exUD, eyUD,
768 alphaVUD);
769 return alphaMUD.getFirstDerivative();
770
771 case MEAN:
772 return cachedAlphaDot;
773
774 case ECCENTRIC:
775 final UnivariateDerivative1 alphaEUD = new UnivariateDerivative1(cachedAlpha, cachedAlphaDot);
776 final UnivariateDerivative1 exUD2 = new UnivariateDerivative1(ex, exDot);
777 final UnivariateDerivative1 eyUD2 = new UnivariateDerivative1(ey, eyDot);
778 final UnivariateDerivative1 alphaMUD2 = FieldCircularLatitudeArgumentUtility.eccentricToMean(exUD2,
779 eyUD2, alphaEUD);
780 return alphaMUD2.getFirstDerivative();
781
782 default:
783 throw new OrekitInternalError(null);
784 }
785 }
786
787
788
789
790
791 public double getAlpha(final PositionAngleType type) {
792 return (type == PositionAngleType.MEAN) ? getAlphaM() :
793 ((type == PositionAngleType.ECCENTRIC) ? getAlphaE() :
794 getAlphaV());
795 }
796
797
798
799
800
801
802
803
804
805 public double getAlphaDot(final PositionAngleType type) {
806 return (type == PositionAngleType.MEAN) ? getAlphaMDot() :
807 ((type == PositionAngleType.ECCENTRIC) ? getAlphaEDot() :
808 getAlphaVDot());
809 }
810
811
812 @Override
813 public double getE() {
814 return FastMath.sqrt(ex * ex + ey * ey);
815 }
816
817
818 @Override
819 public double getEDot() {
820 if (!hasNonKeplerianAcceleration()) {
821 return 0.;
822 }
823 return (ex * exDot + ey * eyDot) / getE();
824 }
825
826
827 @Override
828 public double getI() {
829 return i;
830 }
831
832
833 @Override
834 public double getIDot() {
835 return iDot;
836 }
837
838
839
840
841 public double getRightAscensionOfAscendingNode() {
842 return raan;
843 }
844
845
846
847
848
849
850
851
852 public double getRightAscensionOfAscendingNodeDot() {
853 return raanDot;
854 }
855
856
857 @Override
858 public double getLv() {
859 return getAlphaV() + raan;
860 }
861
862
863 @Override
864 public double getLvDot() {
865 return getAlphaVDot() + raanDot;
866 }
867
868
869 @Override
870 public double getLE() {
871 return getAlphaE() + raan;
872 }
873
874
875 @Override
876 public double getLEDot() {
877 return getAlphaEDot() + raanDot;
878 }
879
880
881 @Override
882 public double getLM() {
883 return getAlphaM() + raan;
884 }
885
886
887 @Override
888 public double getLMDot() {
889 return getAlphaMDot() + raanDot;
890 }
891
892
893
894 private void computePVWithoutA() {
895
896 if (partialPV != null) {
897
898 return;
899 }
900
901
902 final double equEx = getEquinoctialEx();
903 final double equEy = getEquinoctialEy();
904 final double hx = getHx();
905 final double hy = getHy();
906 final double lE = getLE();
907
908
909 final double hx2 = hx * hx;
910 final double hy2 = hy * hy;
911 final double factH = 1. / (1 + hx2 + hy2);
912
913
914 final double ux = (1 + hx2 - hy2) * factH;
915 final double uy = 2 * hx * hy * factH;
916 final double uz = -2 * hy * factH;
917
918 final double vx = uy;
919 final double vy = (1 - hx2 + hy2) * factH;
920 final double vz = 2 * hx * factH;
921
922
923 final double exey = equEx * equEy;
924 final double ex2 = equEx * equEx;
925 final double ey2 = equEy * equEy;
926 final double e2 = ex2 + ey2;
927 final double eta = 1 + FastMath.sqrt(1 - e2);
928 final double beta = 1. / eta;
929
930
931 final SinCos scLe = FastMath.sinCos(lE);
932 final double cLe = scLe.cos();
933 final double sLe = scLe.sin();
934 final double exCeyS = equEx * cLe + equEy * sLe;
935
936
937 final double x = a * ((1 - beta * ey2) * cLe + beta * exey * sLe - equEx);
938 final double y = a * ((1 - beta * ex2) * sLe + beta * exey * cLe - equEy);
939
940 final double factor = FastMath.sqrt(getMu() / a) / (1 - exCeyS);
941 final double xdot = factor * (-sLe + beta * equEy * exCeyS);
942 final double ydot = factor * ( cLe - beta * equEx * exCeyS);
943
944 final Vector3D position =
945 new Vector3D(x * ux + y * vx, x * uy + y * vy, x * uz + y * vz);
946 final Vector3D velocity =
947 new Vector3D(xdot * ux + ydot * vx, xdot * uy + ydot * vy, xdot * uz + ydot * vz);
948
949 partialPV = new PVCoordinates(position, velocity);
950
951 }
952
953
954
955
956
957
958
959
960 private UnivariateDerivative1 initializeCachedAlpha(final double alpha, final double alphaDot,
961 final PositionAngleType inputType) {
962 if (cachedPositionAngleType == inputType) {
963 return new UnivariateDerivative1(alpha, alphaDot);
964
965 } else {
966 final UnivariateDerivative1 exUD = new UnivariateDerivative1(ex, exDot);
967 final UnivariateDerivative1 eyUD = new UnivariateDerivative1(ey, eyDot);
968 final UnivariateDerivative1 alphaUD = new UnivariateDerivative1(alpha, alphaDot);
969
970 switch (cachedPositionAngleType) {
971
972 case ECCENTRIC:
973 if (inputType == PositionAngleType.MEAN) {
974 return FieldCircularLatitudeArgumentUtility.meanToEccentric(exUD, eyUD, alphaUD);
975 } else {
976 return FieldCircularLatitudeArgumentUtility.trueToEccentric(exUD, eyUD, alphaUD);
977 }
978
979 case TRUE:
980 if (inputType == PositionAngleType.MEAN) {
981 return FieldCircularLatitudeArgumentUtility.meanToTrue(exUD, eyUD, alphaUD);
982 } else {
983 return FieldCircularLatitudeArgumentUtility.eccentricToTrue(exUD, eyUD, alphaUD);
984 }
985
986 case MEAN:
987 if (inputType == PositionAngleType.TRUE) {
988 return FieldCircularLatitudeArgumentUtility.trueToMean(exUD, eyUD, alphaUD);
989 } else {
990 return FieldCircularLatitudeArgumentUtility.eccentricToMean(exUD, eyUD, alphaUD);
991 }
992
993 default:
994 throw new OrekitInternalError(null);
995
996 }
997
998 }
999
1000 }
1001
1002
1003
1004
1005
1006
1007
1008 private double initializeCachedAlpha(final double alpha, final PositionAngleType positionAngleType) {
1009 return CircularLatitudeArgumentUtility.convertAlpha(positionAngleType, alpha, ex, ey, cachedPositionAngleType);
1010 }
1011
1012
1013
1014
1015 private Vector3D nonKeplerianAcceleration() {
1016
1017 final double[][] dCdP = new double[6][6];
1018 getJacobianWrtParameters(PositionAngleType.MEAN, dCdP);
1019
1020 final double nonKeplerianMeanMotion = getAlphaMDot() - getKeplerianMeanMotion();
1021 final double nonKeplerianAx = dCdP[3][0] * aDot + dCdP[3][1] * exDot + dCdP[3][2] * eyDot +
1022 dCdP[3][3] * iDot + dCdP[3][4] * raanDot + dCdP[3][5] * nonKeplerianMeanMotion;
1023 final double nonKeplerianAy = dCdP[4][0] * aDot + dCdP[4][1] * exDot + dCdP[4][2] * eyDot +
1024 dCdP[4][3] * iDot + dCdP[4][4] * raanDot + dCdP[4][5] * nonKeplerianMeanMotion;
1025 final double nonKeplerianAz = dCdP[5][0] * aDot + dCdP[5][1] * exDot + dCdP[5][2] * eyDot +
1026 dCdP[5][3] * iDot + dCdP[5][4] * raanDot + dCdP[5][5] * nonKeplerianMeanMotion;
1027
1028 return new Vector3D(nonKeplerianAx, nonKeplerianAy, nonKeplerianAz);
1029
1030 }
1031
1032
1033 @Override
1034 protected Vector3D initPosition() {
1035
1036
1037 final double equEx = getEquinoctialEx();
1038 final double equEy = getEquinoctialEy();
1039 final double hx = getHx();
1040 final double hy = getHy();
1041 final double lE = getLE();
1042
1043
1044 final double hx2 = hx * hx;
1045 final double hy2 = hy * hy;
1046 final double factH = 1. / (1 + hx2 + hy2);
1047
1048
1049 final double ux = (1 + hx2 - hy2) * factH;
1050 final double uy = 2 * hx * hy * factH;
1051 final double uz = -2 * hy * factH;
1052
1053 final double vx = uy;
1054 final double vy = (1 - hx2 + hy2) * factH;
1055 final double vz = 2 * hx * factH;
1056
1057
1058 final double exey = equEx * equEy;
1059 final double ex2 = equEx * equEx;
1060 final double ey2 = equEy * equEy;
1061 final double e2 = ex2 + ey2;
1062 final double eta = 1 + FastMath.sqrt(1 - e2);
1063 final double beta = 1. / eta;
1064
1065
1066 final SinCos scLe = FastMath.sinCos(lE);
1067 final double cLe = scLe.cos();
1068 final double sLe = scLe.sin();
1069
1070
1071 final double x = a * ((1 - beta * ey2) * cLe + beta * exey * sLe - equEx);
1072 final double y = a * ((1 - beta * ex2) * sLe + beta * exey * cLe - equEy);
1073
1074 return new Vector3D(x * ux + y * vx, x * uy + y * vy, x * uz + y * vz);
1075
1076 }
1077
1078
1079 @Override
1080 protected TimeStampedPVCoordinates initPVCoordinates() {
1081
1082
1083 computePVWithoutA();
1084
1085
1086 final double r2 = partialPV.getPosition().getNormSq();
1087 final Vector3D keplerianAcceleration = new Vector3D(-getMu() / (r2 * FastMath.sqrt(r2)), partialPV.getPosition());
1088 final Vector3D acceleration = hasNonKeplerianRates() ?
1089 keplerianAcceleration.add(nonKeplerianAcceleration()) :
1090 keplerianAcceleration;
1091
1092 return new TimeStampedPVCoordinates(getDate(), partialPV.getPosition(), partialPV.getVelocity(), acceleration);
1093
1094 }
1095
1096
1097 @Override
1098 public CircularOrbit withFrame(final Frame inertialFrame) {
1099 if (hasNonKeplerianAcceleration()) {
1100 return new CircularOrbit(getPVCoordinates(inertialFrame), inertialFrame, getMu());
1101 } else {
1102 final KinematicTransform transform = getFrame().getKinematicTransformTo(inertialFrame, getDate());
1103 return new CircularOrbit(transform.transformOnlyPV(getPVCoordinates()), inertialFrame, getDate(), getMu());
1104 }
1105 }
1106
1107
1108 @Override
1109 public CircularOrbit shiftedBy(final double dt) {
1110 return shiftedBy(new TimeOffset(dt));
1111 }
1112
1113
1114 @Override
1115 public CircularOrbit shiftedBy(final TimeOffset dt) {
1116
1117 final double dtS = dt.toDouble();
1118
1119
1120 final CircularOrbit keplerianShifted = new CircularOrbit(a, ex, ey, i, raan,
1121 getAlphaM() + getKeplerianMeanMotion() * dtS,
1122 PositionAngleType.MEAN, cachedPositionAngleType,
1123 getFrame(), getDate().shiftedBy(dt), getMu());
1124
1125 if (hasNonKeplerianRates()) {
1126
1127
1128 final Vector3D nonKeplerianAcceleration = nonKeplerianAcceleration();
1129
1130
1131 keplerianShifted.computePVWithoutA();
1132 final Vector3D fixedP = new Vector3D(1, keplerianShifted.partialPV.getPosition(),
1133 0.5 * dtS * dtS, nonKeplerianAcceleration);
1134 final double fixedR2 = fixedP.getNormSq();
1135 final double fixedR = FastMath.sqrt(fixedR2);
1136 final Vector3D fixedV = new Vector3D(1, keplerianShifted.partialPV.getVelocity(),
1137 dtS, nonKeplerianAcceleration);
1138 final Vector3D fixedA = new Vector3D(-getMu() / (fixedR2 * fixedR), keplerianShifted.partialPV.getPosition(),
1139 1, nonKeplerianAcceleration);
1140
1141
1142 return new CircularOrbit(new TimeStampedPVCoordinates(keplerianShifted.getDate(),
1143 fixedP, fixedV, fixedA),
1144 keplerianShifted.getFrame(), keplerianShifted.getMu());
1145
1146 } else {
1147
1148 return keplerianShifted;
1149 }
1150
1151 }
1152
1153
1154 @Override
1155 protected double[][] computeJacobianMeanWrtCartesian() {
1156
1157
1158 final double[][] jacobian = new double[6][6];
1159
1160 computePVWithoutA();
1161 final Vector3D position = partialPV.getPosition();
1162 final Vector3D velocity = partialPV.getVelocity();
1163 final double x = position.getX();
1164 final double y = position.getY();
1165 final double z = position.getZ();
1166 final double vx = velocity.getX();
1167 final double vy = velocity.getY();
1168 final double vz = velocity.getZ();
1169 final double pv = Vector3D.dotProduct(position, velocity);
1170 final double r2 = position.getNormSq();
1171 final double r = FastMath.sqrt(r2);
1172 final double v2 = velocity.getNormSq();
1173
1174 final double mu = getMu();
1175 final double oOsqrtMuA = 1 / FastMath.sqrt(mu * a);
1176 final double rOa = r / a;
1177 final double aOr = a / r;
1178 final double aOr2 = a / r2;
1179 final double a2 = a * a;
1180
1181 final double ex2 = ex * ex;
1182 final double ey2 = ey * ey;
1183 final double e2 = ex2 + ey2;
1184 final double epsilon = FastMath.sqrt(1 - e2);
1185 final double beta = 1 / (1 + epsilon);
1186
1187 final double eCosE = 1 - rOa;
1188 final double eSinE = pv * oOsqrtMuA;
1189
1190 final SinCos scI = FastMath.sinCos(i);
1191 final SinCos scRaan = FastMath.sinCos(raan);
1192 final double cosI = scI.cos();
1193 final double sinI = scI.sin();
1194 final double cosRaan = scRaan.cos();
1195 final double sinRaan = scRaan.sin();
1196
1197
1198 fillHalfRow(2 * aOr * aOr2, position, jacobian[0], 0);
1199 fillHalfRow(2 * a2 / mu, velocity, jacobian[0], 3);
1200
1201
1202 final Vector3D danP = new Vector3D(v2, position, -pv, velocity);
1203 final Vector3D danV = new Vector3D(r2, velocity, -pv, position);
1204 final double recip = 1 / partialPV.getMomentum().getNorm();
1205 final double recip2 = recip * recip;
1206 final Vector3D dwXP = new Vector3D(recip, new Vector3D( 0, vz, -vy), -recip2 * sinRaan * sinI, danP);
1207 final Vector3D dwYP = new Vector3D(recip, new Vector3D(-vz, 0, vx), recip2 * cosRaan * sinI, danP);
1208 final Vector3D dwZP = new Vector3D(recip, new Vector3D( vy, -vx, 0), -recip2 * cosI, danP);
1209 final Vector3D dwXV = new Vector3D(recip, new Vector3D( 0, -z, y), -recip2 * sinRaan * sinI, danV);
1210 final Vector3D dwYV = new Vector3D(recip, new Vector3D( z, 0, -x), recip2 * cosRaan * sinI, danV);
1211 final Vector3D dwZV = new Vector3D(recip, new Vector3D( -y, x, 0), -recip2 * cosI, danV);
1212
1213
1214 fillHalfRow(sinRaan * cosI, dwXP, -cosRaan * cosI, dwYP, -sinI, dwZP, jacobian[3], 0);
1215 fillHalfRow(sinRaan * cosI, dwXV, -cosRaan * cosI, dwYV, -sinI, dwZV, jacobian[3], 3);
1216
1217
1218 fillHalfRow(sinRaan / sinI, dwYP, cosRaan / sinI, dwXP, jacobian[4], 0);
1219 fillHalfRow(sinRaan / sinI, dwYV, cosRaan / sinI, dwXV, jacobian[4], 3);
1220
1221
1222
1223 final double u = x * cosRaan + y * sinRaan;
1224 final double cv = -x * sinRaan + y * cosRaan;
1225 final double v = cv * cosI + z * sinI;
1226
1227
1228 final Vector3D duP = new Vector3D(cv * cosRaan / sinI, dwXP,
1229 cv * sinRaan / sinI, dwYP,
1230 1, new Vector3D(cosRaan, sinRaan, 0));
1231 final Vector3D duV = new Vector3D(cv * cosRaan / sinI, dwXV,
1232 cv * sinRaan / sinI, dwYV);
1233
1234
1235 final Vector3D dvP = new Vector3D(-u * cosRaan * cosI / sinI + sinRaan * z, dwXP,
1236 -u * sinRaan * cosI / sinI - cosRaan * z, dwYP,
1237 cv, dwZP,
1238 1, new Vector3D(-sinRaan * cosI, cosRaan * cosI, sinI));
1239 final Vector3D dvV = new Vector3D(-u * cosRaan * cosI / sinI + sinRaan * z, dwXV,
1240 -u * sinRaan * cosI / sinI - cosRaan * z, dwYV,
1241 cv, dwZV);
1242
1243 final Vector3D dc1P = new Vector3D(aOr2 * (2 * eSinE * eSinE + 1 - eCosE) / r2, position,
1244 -2 * aOr2 * eSinE * oOsqrtMuA, velocity);
1245 final Vector3D dc1V = new Vector3D(-2 * aOr2 * eSinE * oOsqrtMuA, position,
1246 2 / mu, velocity);
1247 final Vector3D dc2P = new Vector3D(aOr2 * eSinE * (eSinE * eSinE - (1 - e2)) / (r2 * epsilon), position,
1248 aOr2 * (1 - e2 - eSinE * eSinE) * oOsqrtMuA / epsilon, velocity);
1249 final Vector3D dc2V = new Vector3D(aOr2 * (1 - e2 - eSinE * eSinE) * oOsqrtMuA / epsilon, position,
1250 eSinE / (mu * epsilon), velocity);
1251
1252 final double cof1 = aOr2 * (eCosE - e2);
1253 final double cof2 = aOr2 * epsilon * eSinE;
1254 final Vector3D dexP = new Vector3D(u, dc1P, v, dc2P, cof1, duP, cof2, dvP);
1255 final Vector3D dexV = new Vector3D(u, dc1V, v, dc2V, cof1, duV, cof2, dvV);
1256 final Vector3D deyP = new Vector3D(v, dc1P, -u, dc2P, cof1, dvP, -cof2, duP);
1257 final Vector3D deyV = new Vector3D(v, dc1V, -u, dc2V, cof1, dvV, -cof2, duV);
1258 fillHalfRow(1, dexP, jacobian[1], 0);
1259 fillHalfRow(1, dexV, jacobian[1], 3);
1260 fillHalfRow(1, deyP, jacobian[2], 0);
1261 fillHalfRow(1, deyV, jacobian[2], 3);
1262
1263 final double cle = u / a + ex - eSinE * beta * ey;
1264 final double sle = v / a + ey + eSinE * beta * ex;
1265 final double m1 = beta * eCosE;
1266 final double m2 = 1 - m1 * eCosE;
1267 final double m3 = (u * ey - v * ex) + eSinE * beta * (u * ex + v * ey);
1268 final double m4 = -sle + cle * eSinE * beta;
1269 final double m5 = cle + sle * eSinE * beta;
1270 fillHalfRow((2 * m3 / r + aOr * eSinE + m1 * eSinE * (1 + m1 - (1 + aOr) * m2) / epsilon) / r2, position,
1271 (m1 * m2 / epsilon - 1) * oOsqrtMuA, velocity,
1272 m4, dexP, m5, deyP, -sle / a, duP, cle / a, dvP,
1273 jacobian[5], 0);
1274 fillHalfRow((m1 * m2 / epsilon - 1) * oOsqrtMuA, position,
1275 (2 * m3 + eSinE * a + m1 * eSinE * r * (eCosE * beta * 2 - aOr * m2) / epsilon) / mu, velocity,
1276 m4, dexV, m5, deyV, -sle / a, duV, cle / a, dvV,
1277 jacobian[5], 3);
1278
1279 return jacobian;
1280
1281 }
1282
1283
1284 @Override
1285 protected double[][] computeJacobianEccentricWrtCartesian() {
1286
1287
1288 final double[][] jacobian = computeJacobianMeanWrtCartesian();
1289
1290
1291
1292
1293
1294 final double alphaE = getAlphaE();
1295 final SinCos scAe = FastMath.sinCos(alphaE);
1296 final double cosAe = scAe.cos();
1297 final double sinAe = scAe.sin();
1298 final double aOr = 1 / (1 - ex * cosAe - ey * sinAe);
1299
1300
1301 final double[] rowEx = jacobian[1];
1302 final double[] rowEy = jacobian[2];
1303 final double[] rowL = jacobian[5];
1304 for (int j = 0; j < 6; ++j) {
1305 rowL[j] = aOr * (rowL[j] + sinAe * rowEx[j] - cosAe * rowEy[j]);
1306 }
1307
1308 return jacobian;
1309
1310 }
1311
1312
1313 @Override
1314 protected double[][] computeJacobianTrueWrtCartesian() {
1315
1316
1317 final double[][] jacobian = computeJacobianEccentricWrtCartesian();
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 final double alphaE = getAlphaE();
1332 final SinCos scAe = FastMath.sinCos(alphaE);
1333 final double cosAe = scAe.cos();
1334 final double sinAe = scAe.sin();
1335 final double eSinE = ex * sinAe - ey * cosAe;
1336 final double ecosE = ex * cosAe + ey * sinAe;
1337 final double e2 = ex * ex + ey * ey;
1338 final double epsilon = FastMath.sqrt(1 - e2);
1339 final double onePeps = 1 + epsilon;
1340 final double d = onePeps - ecosE;
1341 final double cT = (d * d + eSinE * eSinE) / 2;
1342 final double cE = ecosE * onePeps - e2;
1343 final double cX = ex * eSinE / epsilon - ey + sinAe * onePeps;
1344 final double cY = ey * eSinE / epsilon + ex - cosAe * onePeps;
1345 final double factorLe = (cT + cE) / cT;
1346 final double factorEx = cX / cT;
1347 final double factorEy = cY / cT;
1348
1349
1350 final double[] rowEx = jacobian[1];
1351 final double[] rowEy = jacobian[2];
1352 final double[] rowA = jacobian[5];
1353 for (int j = 0; j < 6; ++j) {
1354 rowA[j] = factorLe * rowA[j] + factorEx * rowEx[j] + factorEy * rowEy[j];
1355 }
1356
1357 return jacobian;
1358
1359 }
1360
1361
1362 @Override
1363 public void addKeplerContribution(final PositionAngleType type, final double gm,
1364 final double[] pDot) {
1365 pDot[5] += computeKeplerianAlphaDot(type, a, ex, ey, gm, cachedAlpha, cachedPositionAngleType);
1366 }
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380 private static double computeKeplerianAlphaDot(final PositionAngleType type, final double a, final double ex,
1381 final double ey, final double mu,
1382 final double alpha, final PositionAngleType cachedType) {
1383 final double n = FastMath.sqrt(mu / a) / a;
1384 if (type == PositionAngleType.MEAN) {
1385 return n;
1386 }
1387 final double ksi;
1388 final SinCos sc;
1389 if (type == PositionAngleType.ECCENTRIC) {
1390 sc = FastMath.sinCos(CircularLatitudeArgumentUtility.convertAlpha(cachedType, alpha, ex, ey, type));
1391 ksi = 1. / (1 - ex * sc.cos() - ey * sc.sin());
1392 return n * ksi;
1393 } else {
1394 sc = FastMath.sinCos(CircularLatitudeArgumentUtility.convertAlpha(cachedType, alpha, ex, ey, type));
1395 final double oMe2 = 1 - ex * ex - ey * ey;
1396 ksi = 1 + ex * sc.cos() + ey * sc.sin();
1397 return n * ksi * ksi / (oMe2 * FastMath.sqrt(oMe2));
1398 }
1399 }
1400
1401
1402
1403
1404 public String toString() {
1405 return new StringBuilder().append("circular parameters: ").append('{').
1406 append("a: ").append(a).
1407 append(", ex: ").append(ex).append(", ey: ").append(ey).
1408 append(", i: ").append(FastMath.toDegrees(i)).
1409 append(", raan: ").append(FastMath.toDegrees(raan)).
1410 append(", alphaV: ").append(FastMath.toDegrees(getAlphaV())).
1411 append(";}").toString();
1412 }
1413
1414
1415 @Override
1416 public PositionAngleType getCachedPositionAngleType() {
1417 return cachedPositionAngleType;
1418 }
1419
1420
1421 @Override
1422 public boolean hasNonKeplerianRates() {
1423 return hasNonKeplerianAcceleration();
1424 }
1425
1426
1427 @Override
1428 public CircularOrbit withKeplerianRates() {
1429 final PositionAngleType positionAngleType = getCachedPositionAngleType();
1430 return new CircularOrbit(a, ex, ey, i, raan, cachedAlpha, positionAngleType, positionAngleType,
1431 getFrame(), getDate(), getMu());
1432 }
1433
1434
1435
1436
1437 @DefaultDataContext
1438 private Object writeReplace() {
1439 return new DTO(this);
1440 }
1441
1442
1443 @DefaultDataContext
1444 private static class DTO implements Serializable {
1445
1446
1447 private static final long serialVersionUID = 20241114L;
1448
1449
1450 private final long seconds;
1451
1452
1453 private final long attoseconds;
1454
1455
1456 private final double[] d;
1457
1458
1459 private final Frame frame;
1460
1461
1462 private final PositionAngleType positionAngleType;
1463
1464
1465
1466
1467 private DTO(final CircularOrbit orbit) {
1468
1469 positionAngleType = orbit.getCachedPositionAngleType();
1470
1471
1472 this.seconds = orbit.getDate().getSeconds();
1473 this.attoseconds = orbit.getDate().getAttoSeconds();
1474
1475 if (orbit.serializePV) {
1476 final TimeStampedPVCoordinates pv = orbit.getPVCoordinates();
1477 this.d = new double[] {
1478
1479 orbit.getMu(),
1480 orbit.a, orbit.ex, orbit.ey,
1481 orbit.i, orbit.raan, orbit.cachedAlpha,
1482 orbit.aDot, orbit.exDot, orbit.eyDot,
1483 orbit.iDot, orbit.raanDot, orbit.cachedAlphaDot,
1484 pv.getPosition().getX(), pv.getPosition().getY(), pv.getPosition().getZ(),
1485 pv.getVelocity().getX(), pv.getVelocity().getY(), pv.getVelocity().getZ(),
1486 pv.getAcceleration().getX(), pv.getAcceleration().getY(), pv.getAcceleration().getZ(),
1487 };
1488 } else {
1489
1490 this.d = new double[] {
1491 orbit.getMu(),
1492 orbit.a, orbit.ex, orbit.ey,
1493 orbit.i, orbit.raan, orbit.cachedAlpha,
1494 orbit.aDot, orbit.exDot, orbit.eyDot,
1495 orbit.iDot, orbit.raanDot, orbit.cachedAlphaDot
1496 };
1497 }
1498
1499 this.frame = orbit.getFrame();
1500
1501 }
1502
1503
1504
1505
1506 private Object readResolve() {
1507 if (d.length == 22) {
1508 return new CircularOrbit(d[1], d[2], d[3], d[4], d[5], d[6],
1509 d[7], d[8], d[9], d[10], d[11], d[12],
1510 new TimeStampedPVCoordinates(new AbsoluteDate(new TimeOffset(seconds, attoseconds)),
1511 new Vector3D(d[13], d[14], d[15]),
1512 new Vector3D(d[16], d[17], d[18]),
1513 new Vector3D(d[19], d[20], d[21])),
1514 positionAngleType, frame,
1515 d[0]);
1516 }
1517 return new CircularOrbit(d[1], d[2], d[3], d[4], d[5], d[6],
1518 d[7], d[8], d[9], d[10], d[11], d[12],
1519 positionAngleType, positionAngleType,
1520 frame, new AbsoluteDate(new TimeOffset(seconds, attoseconds)),
1521 d[0]);
1522 }
1523
1524 }
1525
1526 }