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 java.util.Arrays;
21 import java.util.stream.Stream;
22
23 import org.hipparchus.Field;
24 import org.hipparchus.CalculusFieldElement;
25 import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
26 import org.hipparchus.exception.LocalizedCoreFormats;
27 import org.hipparchus.exception.MathIllegalStateException;
28 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
29 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
30 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
31 import org.hipparchus.geometry.euclidean.threed.Vector3D;
32 import org.hipparchus.util.FastMath;
33 import org.hipparchus.util.FieldSinCos;
34 import org.hipparchus.util.MathArrays;
35 import org.orekit.errors.OrekitMessages;
36 import org.orekit.frames.Frame;
37 import org.orekit.time.AbsoluteDate;
38 import org.orekit.time.FieldAbsoluteDate;
39 import org.orekit.utils.CartesianDerivativesFilter;
40 import org.orekit.utils.FieldPVCoordinates;
41 import org.orekit.utils.PVCoordinates;
42 import org.orekit.utils.TimeStampedFieldPVCoordinates;
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 public class FieldCartesianOrbit<T extends CalculusFieldElement<T>> extends FieldOrbit<T> {
80
81
82 private final transient boolean hasNonKeplerianAcceleration;
83
84
85 private transient FieldEquinoctialOrbit<T> equinoctial;
86
87
88 private final Field<T> field;
89
90
91 private final T zero;
92
93
94 private final T one;
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 public FieldCartesianOrbit(final TimeStampedFieldPVCoordinates<T> pvaCoordinates,
111 final Frame frame, final T mu)
112 throws IllegalArgumentException {
113 super(pvaCoordinates, frame, mu);
114 hasNonKeplerianAcceleration = hasNonKeplerianAcceleration(pvaCoordinates, mu);
115 equinoctial = null;
116 field = pvaCoordinates.getPosition().getX().getField();
117 zero = field.getZero();
118 one = field.getOne();
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 public FieldCartesianOrbit(final FieldPVCoordinates<T> pvaCoordinates, final Frame frame,
137 final FieldAbsoluteDate<T> date, final T mu)
138 throws IllegalArgumentException {
139 this(new TimeStampedFieldPVCoordinates<>(date, pvaCoordinates), frame, mu);
140 }
141
142
143
144
145 public FieldCartesianOrbit(final FieldOrbit<T> op) {
146 super(op.getPVCoordinates(), op.getFrame(), op.getMu());
147 hasNonKeplerianAcceleration = op.hasDerivatives();
148 if (op instanceof FieldEquinoctialOrbit) {
149 equinoctial = (FieldEquinoctialOrbit<T>) op;
150 } else if (op instanceof FieldCartesianOrbit) {
151 equinoctial = ((FieldCartesianOrbit<T>) op).equinoctial;
152 } else {
153 equinoctial = null;
154 }
155 field = op.getA().getField();
156 zero = field.getZero();
157 one = field.getOne();
158 }
159
160
161 public OrbitType getType() {
162 return OrbitType.CARTESIAN;
163 }
164
165
166 private void initEquinoctial() {
167 if (equinoctial == null) {
168 if (hasDerivatives()) {
169
170 equinoctial = new FieldEquinoctialOrbit<>(getPVCoordinates(), getFrame(), getDate(), getMu());
171 } else {
172
173
174 equinoctial = new FieldEquinoctialOrbit<>(new FieldPVCoordinates<>(getPVCoordinates().getPosition(),
175 getPVCoordinates().getVelocity()),
176 getFrame(), getDate(), getMu());
177 }
178 }
179 }
180
181
182
183
184
185 private FieldPVCoordinates<FieldUnivariateDerivative2<T>> getPVDerivatives() {
186
187 final FieldPVCoordinates<T> pva = getPVCoordinates();
188 final FieldVector3D<T> p = pva.getPosition();
189 final FieldVector3D<T> v = pva.getVelocity();
190 final FieldVector3D<T> a = pva.getAcceleration();
191
192 final FieldVector3D<FieldUnivariateDerivative2<T>> pG = new FieldVector3D<>(new FieldUnivariateDerivative2<>(p.getX(), v.getX(), a.getX()),
193 new FieldUnivariateDerivative2<>(p.getY(), v.getY(), a.getY()),
194 new FieldUnivariateDerivative2<>(p.getZ(), v.getZ(), a.getZ()));
195 final FieldVector3D<FieldUnivariateDerivative2<T>> vG = new FieldVector3D<>(new FieldUnivariateDerivative2<>(v.getX(), a.getX(), zero),
196 new FieldUnivariateDerivative2<>(v.getY(), a.getY(), zero),
197 new FieldUnivariateDerivative2<>(v.getZ(), a.getZ(), zero));
198 return new FieldPVCoordinates<>(pG, vG);
199 }
200
201
202 public T getA() {
203
204 final T r = getPVCoordinates().getPosition().getNorm();
205 final T V2 = getPVCoordinates().getVelocity().getNormSq();
206 return r.divide(r.negate().multiply(V2).divide(getMu()).add(2));
207 }
208
209
210 public T getADot() {
211 if (hasDerivatives()) {
212 final FieldPVCoordinates<FieldUnivariateDerivative2<T>> pv = getPVDerivatives();
213 final FieldUnivariateDerivative2<T> r = pv.getPosition().getNorm();
214 final FieldUnivariateDerivative2<T> V2 = pv.getVelocity().getNormSq();
215 final FieldUnivariateDerivative2<T> a = r.divide(r.multiply(V2).divide(getMu()).subtract(2).negate());
216 return a.getDerivative(1);
217 } else {
218 return null;
219 }
220 }
221
222
223 public T getE() {
224 final T muA = getA().multiply(getMu());
225 if (muA.getReal() > 0) {
226
227 final FieldVector3D<T> pvP = getPVCoordinates().getPosition();
228 final FieldVector3D<T> pvV = getPVCoordinates().getVelocity();
229 final T rV2OnMu = pvP.getNorm().multiply(pvV.getNormSq()).divide(getMu());
230 final T eSE = FieldVector3D.dotProduct(pvP, pvV).divide(muA.sqrt());
231 final T eCE = rV2OnMu.subtract(1);
232 return (eCE.multiply(eCE).add(eSE.multiply(eSE))).sqrt();
233 } else {
234
235 final FieldVector3D<T> pvM = getPVCoordinates().getMomentum();
236 return pvM.getNormSq().divide(muA).negate().add(1).sqrt();
237 }
238 }
239
240
241 public T getEDot() {
242 if (hasDerivatives()) {
243 final FieldPVCoordinates<FieldUnivariateDerivative2<T>> pv = getPVDerivatives();
244 final FieldUnivariateDerivative2<T> r = pv.getPosition().getNorm();
245 final FieldUnivariateDerivative2<T> V2 = pv.getVelocity().getNormSq();
246 final FieldUnivariateDerivative2<T> rV2OnMu = r.multiply(V2).divide(getMu());
247 final FieldUnivariateDerivative2<T> a = r.divide(rV2OnMu.negate().add(2));
248 final FieldUnivariateDerivative2<T> eSE = FieldVector3D.dotProduct(pv.getPosition(), pv.getVelocity()).divide(a.multiply(getMu()).sqrt());
249 final FieldUnivariateDerivative2<T> eCE = rV2OnMu.subtract(1);
250 final FieldUnivariateDerivative2<T> e = eCE.multiply(eCE).add(eSE.multiply(eSE)).sqrt();
251 return e.getDerivative(1);
252 } else {
253 return null;
254 }
255 }
256
257
258 public T getI() {
259 return FieldVector3D.angle(new FieldVector3D<>(zero, zero, one), getPVCoordinates().getMomentum());
260 }
261
262
263 public T getIDot() {
264 if (hasDerivatives()) {
265 final FieldPVCoordinates<FieldUnivariateDerivative2<T>> pv = getPVDerivatives();
266 final FieldVector3D<FieldUnivariateDerivative2<T>> momentum =
267 FieldVector3D.crossProduct(pv.getPosition(), pv.getVelocity());
268 final FieldUnivariateDerivative2<T> i = FieldVector3D.angle(Vector3D.PLUS_K, momentum);
269 return i.getDerivative(1);
270 } else {
271 return null;
272 }
273 }
274
275
276 public T getEquinoctialEx() {
277 initEquinoctial();
278 return equinoctial.getEquinoctialEx();
279 }
280
281
282 public T getEquinoctialExDot() {
283 initEquinoctial();
284 return equinoctial.getEquinoctialExDot();
285 }
286
287
288 public T getEquinoctialEy() {
289 initEquinoctial();
290 return equinoctial.getEquinoctialEy();
291 }
292
293
294 public T getEquinoctialEyDot() {
295 initEquinoctial();
296 return equinoctial.getEquinoctialEyDot();
297 }
298
299
300 public T getHx() {
301 final FieldVector3D<T> w = getPVCoordinates().getMomentum().normalize();
302
303 final double x = w.getX().getReal();
304 final double y = w.getY().getReal();
305 final double z = w.getZ().getReal();
306 if ((x * x + y * y) == 0 && z < 0) {
307 return zero.add(Double.NaN);
308 }
309 return w.getY().negate().divide(w.getZ().add(1));
310 }
311
312
313 public T getHxDot() {
314 if (hasDerivatives()) {
315 final FieldPVCoordinates<FieldUnivariateDerivative2<T>> pv = getPVDerivatives();
316 final FieldVector3D<FieldUnivariateDerivative2<T>> w =
317 FieldVector3D.crossProduct(pv.getPosition(), pv.getVelocity()).normalize();
318
319 final double x = w.getX().getValue().getReal();
320 final double y = w.getY().getValue().getReal();
321 final double z = w.getZ().getValue().getReal();
322 if ((x * x + y * y) == 0 && z < 0) {
323 return zero.add(Double.NaN);
324 }
325 final FieldUnivariateDerivative2<T> hx = w.getY().negate().divide(w.getZ().add(1));
326 return hx.getDerivative(1);
327 } else {
328 return null;
329 }
330 }
331
332
333 public T getHy() {
334 final FieldVector3D<T> w = getPVCoordinates().getMomentum().normalize();
335
336 final double x = w.getX().getReal();
337 final double y = w.getY().getReal();
338 final double z = w.getZ().getReal();
339 if ((x * x + y * y) == 0 && z < 0) {
340 return zero.add(Double.NaN);
341 }
342 return w.getX().divide(w.getZ().add(1));
343 }
344
345
346 public T getHyDot() {
347 if (hasDerivatives()) {
348 final FieldPVCoordinates<FieldUnivariateDerivative2<T>> pv = getPVDerivatives();
349 final FieldVector3D<FieldUnivariateDerivative2<T>> w =
350 FieldVector3D.crossProduct(pv.getPosition(), pv.getVelocity()).normalize();
351
352 final double x = w.getX().getValue().getReal();
353 final double y = w.getY().getValue().getReal();
354 final double z = w.getZ().getValue().getReal();
355 if ((x * x + y * y) == 0 && z < 0) {
356 return zero.add(Double.NaN);
357 }
358 final FieldUnivariateDerivative2<T> hy = w.getX().divide(w.getZ().add(1));
359 return hy.getDerivative(1);
360 } else {
361 return null;
362 }
363 }
364
365
366 public T getLv() {
367 initEquinoctial();
368 return equinoctial.getLv();
369 }
370
371
372 public T getLvDot() {
373 initEquinoctial();
374 return equinoctial.getLvDot();
375 }
376
377
378 public T getLE() {
379 initEquinoctial();
380 return equinoctial.getLE();
381 }
382
383
384 public T getLEDot() {
385 initEquinoctial();
386 return equinoctial.getLEDot();
387 }
388
389
390 public T getLM() {
391 initEquinoctial();
392 return equinoctial.getLM();
393 }
394
395
396 public T getLMDot() {
397 initEquinoctial();
398 return equinoctial.getLMDot();
399 }
400
401
402 public boolean hasDerivatives() {
403 return hasNonKeplerianAcceleration;
404 }
405
406
407 protected TimeStampedFieldPVCoordinates<T> initPVCoordinates() {
408
409 return getPVCoordinates();
410 }
411
412
413 public FieldCartesianOrbit<T> shiftedBy(final double dt) {
414 return shiftedBy(getDate().getField().getZero().add(dt));
415 }
416
417
418 public FieldCartesianOrbit<T> shiftedBy(final T dt) {
419 final FieldPVCoordinates<T> shiftedPV = (getA().getReal() < 0) ? shiftPVHyperbolic(dt) : shiftPVElliptic(dt);
420 return new FieldCartesianOrbit<>(shiftedPV, getFrame(), getDate().shiftedBy(dt), getMu());
421 }
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442 public FieldCartesianOrbit<T> interpolate(final FieldAbsoluteDate<T> date, final Stream<FieldOrbit<T>> sample) {
443 final TimeStampedFieldPVCoordinates<T> interpolated =
444 TimeStampedFieldPVCoordinates.interpolate(date, CartesianDerivativesFilter.USE_PVA,
445 sample.map(orbit -> orbit.getPVCoordinates()));
446 return new FieldCartesianOrbit<>(interpolated, getFrame(), date, getMu());
447 }
448
449
450
451
452
453 private FieldPVCoordinates<T> shiftPVElliptic(final T dt) {
454
455
456 final FieldVector3D<T> pvP = getPVCoordinates().getPosition();
457 final FieldVector3D<T> pvV = getPVCoordinates().getVelocity();
458 final T r2 = pvP.getNormSq();
459 final T r = r2.sqrt();
460 final T rV2OnMu = r.multiply(pvV.getNormSq()).divide(getMu());
461 final T a = r.divide(rV2OnMu.negate().add(2));
462 final T eSE = FieldVector3D.dotProduct(pvP, pvV).divide(a.multiply(getMu()).sqrt());
463 final T eCE = rV2OnMu.subtract(1);
464 final T e2 = eCE.multiply(eCE).add(eSE.multiply(eSE));
465
466
467
468 final FieldVector3D<T> u = pvP.normalize();
469 final FieldVector3D<T> v = FieldVector3D.crossProduct(FieldVector3D.crossProduct(pvP, pvV), u).normalize();
470
471
472
473 final T ex = eCE.subtract(e2).multiply(a).divide(r);
474 final T s = e2.negate().add(1).sqrt();
475 final T ey = s.negate().multiply(eSE).multiply(a).divide(r);
476 final T beta = s.add(1).reciprocal();
477 final T thetaE0 = ey.add(eSE.multiply(beta).multiply(ex)).atan2(r.divide(a).add(ex).subtract(eSE.multiply(beta).multiply(ey)));
478 final FieldSinCos<T> scThetaE0 = FastMath.sinCos(thetaE0);
479 final T thetaM0 = thetaE0.subtract(ex.multiply(scThetaE0.sin())).add(ey.multiply(scThetaE0.cos()));
480
481
482 final T sqrtMmuOA = a.reciprocal().multiply(getMu()).sqrt();
483 final T thetaM1 = thetaM0.add(sqrtMmuOA.divide(a).multiply(dt));
484 final T thetaE1 = meanToEccentric(thetaM1, ex, ey);
485 final FieldSinCos<T> scTE = FastMath.sinCos(thetaE1);
486 final T cTE = scTE.cos();
487 final T sTE = scTE.sin();
488
489
490 final T exey = ex.multiply(ey);
491 final T exCeyS = ex.multiply(cTE).add(ey.multiply(sTE));
492 final T x = a.multiply(beta.multiply(ey).multiply(ey).negate().add(1).multiply(cTE).add(beta.multiply(exey).multiply(sTE)).subtract(ex));
493 final T y = a.multiply(beta.multiply(ex).multiply(ex).negate().add(1).multiply(sTE).add(beta.multiply(exey).multiply(cTE)).subtract(ey));
494 final T factor = sqrtMmuOA.divide(exCeyS.negate().add(1));
495 final T xDot = factor.multiply(beta.multiply(ey).multiply(exCeyS).subtract(sTE));
496 final T yDot = factor.multiply(cTE.subtract(beta.multiply(ex).multiply(exCeyS)));
497
498 final FieldVector3D<T> shiftedP = new FieldVector3D<>(x, u, y, v);
499 final FieldVector3D<T> shiftedV = new FieldVector3D<>(xDot, u, yDot, v);
500 if (hasNonKeplerianAcceleration) {
501
502
503 final FieldVector3D<T> nonKeplerianAcceleration = new FieldVector3D<>(one, getPVCoordinates().getAcceleration(),
504 r.multiply(r2).reciprocal().multiply(getMu()), pvP);
505
506
507 final FieldVector3D<T> fixedP = new FieldVector3D<>(one, shiftedP,
508 dt.multiply(dt).multiply(0.5), nonKeplerianAcceleration);
509 final T fixedR2 = fixedP.getNormSq();
510 final T fixedR = fixedR2.sqrt();
511 final FieldVector3D<T> fixedV = new FieldVector3D<>(one, shiftedV,
512 dt, nonKeplerianAcceleration);
513 final FieldVector3D<T> fixedA = new FieldVector3D<>(fixedR.multiply(fixedR2).reciprocal().multiply(getMu().negate()), shiftedP,
514 one, nonKeplerianAcceleration);
515
516 return new FieldPVCoordinates<>(fixedP, fixedV, fixedA);
517
518 } else {
519
520
521 return new FieldPVCoordinates<>(shiftedP, shiftedV);
522 }
523
524 }
525
526
527
528
529
530 private FieldPVCoordinates<T> shiftPVHyperbolic(final T dt) {
531
532 final FieldPVCoordinates<T> pv = getPVCoordinates();
533 final FieldVector3D<T> pvP = pv.getPosition();
534 final FieldVector3D<T> pvV = pv.getVelocity();
535 final FieldVector3D<T> pvM = pv.getMomentum();
536 final T r2 = pvP.getNormSq();
537 final T r = r2.sqrt();
538 final T rV2OnMu = r.multiply(pvV.getNormSq()).divide(getMu());
539 final T a = getA();
540 final T muA = a.multiply(getMu());
541 final T e = one.subtract(FieldVector3D.dotProduct(pvM, pvM).divide(muA)).sqrt();
542 final T sqrt = e.add(1).divide(e.subtract(1)).sqrt();
543
544
545 final T eSH = FieldVector3D.dotProduct(pvP, pvV).divide(muA.negate().sqrt());
546 final T eCH = rV2OnMu.subtract(1);
547 final T H0 = eCH.add(eSH).divide(eCH.subtract(eSH)).log().divide(2);
548 final T M0 = e.multiply(H0.sinh()).subtract(H0);
549
550
551 final T v0 = sqrt.multiply(H0.divide(2).tanh()).atan().multiply(2);
552 final FieldVector3D<T> p = new FieldRotation<>(pvM, v0, RotationConvention.FRAME_TRANSFORM).applyTo(pvP).normalize();
553 final FieldVector3D<T> q = FieldVector3D.crossProduct(pvM, p).normalize();
554
555
556 final T M1 = M0.add(getKeplerianMeanMotion().multiply(dt));
557 final T H1 = meanToHyperbolicEccentric(M1, e);
558
559
560 final T cH = H1.cosh();
561 final T sH = H1.sinh();
562 final T sE2m1 = e.subtract(1).multiply(e.add(1)).sqrt();
563
564
565 final T x = a.multiply(cH.subtract(e));
566 final T y = a.negate().multiply(sE2m1).multiply(sH);
567 final T factor = getMu().divide(a.negate()).sqrt().divide(e.multiply(cH).subtract(1));
568 final T xDot = factor.negate().multiply(sH);
569 final T yDot = factor.multiply(sE2m1).multiply(cH);
570
571 final FieldVector3D<T> shiftedP = new FieldVector3D<>(x, p, y, q);
572 final FieldVector3D<T> shiftedV = new FieldVector3D<>(xDot, p, yDot, q);
573 if (hasNonKeplerianAcceleration) {
574
575
576 final FieldVector3D<T> nonKeplerianAcceleration = new FieldVector3D<>(one, getPVCoordinates().getAcceleration(),
577 r.multiply(r2).reciprocal().multiply(getMu()), pvP);
578
579
580 final FieldVector3D<T> fixedP = new FieldVector3D<>(one, shiftedP,
581 dt.multiply(dt).multiply(0.5), nonKeplerianAcceleration);
582 final T fixedR2 = fixedP.getNormSq();
583 final T fixedR = fixedR2.sqrt();
584 final FieldVector3D<T> fixedV = new FieldVector3D<>(one, shiftedV,
585 dt, nonKeplerianAcceleration);
586 final FieldVector3D<T> fixedA = new FieldVector3D<>(fixedR.multiply(fixedR2).reciprocal().multiply(getMu().negate()), shiftedP,
587 one, nonKeplerianAcceleration);
588
589 return new FieldPVCoordinates<>(fixedP, fixedV, fixedA);
590
591 } else {
592
593
594 return new FieldPVCoordinates<>(shiftedP, shiftedV);
595 }
596
597 }
598
599
600
601
602
603
604
605 private T meanToEccentric(final T thetaM, final T ex, final T ey) {
606
607
608
609
610 T thetaE = thetaM;
611 T thetaEMthetaM = zero;
612 int iter = 0;
613 do {
614 final FieldSinCos<T> scThetaE = FastMath.sinCos(thetaE);
615
616 final T f2 = ex.multiply(scThetaE.sin()).subtract(ey.multiply(scThetaE.cos()));
617 final T f1 = one.subtract(ex.multiply(scThetaE.cos())).subtract(ey.multiply(scThetaE.sin()));
618 final T f0 = thetaEMthetaM.subtract(f2);
619
620 final T f12 = f1.multiply(2.0);
621 final T shift = f0.multiply(f12).divide(f1.multiply(f12).subtract(f0.multiply(f2)));
622
623 thetaEMthetaM = thetaEMthetaM.subtract(shift);
624 thetaE = thetaM.add(thetaEMthetaM);
625
626 if (FastMath.abs(shift.getReal()) <= 1.0e-12) {
627 return thetaE;
628 }
629
630 } while (++iter < 50);
631
632 throw new MathIllegalStateException(LocalizedCoreFormats.CONVERGENCE_FAILED);
633
634 }
635
636
637
638
639
640
641
642
643
644
645 private T meanToHyperbolicEccentric(final T M, final T ecc) {
646
647
648
649
650 final T pi = ecc.getPi();
651
652
653 T H;
654 if (ecc.getReal() < 1.6) {
655 if (-pi.getReal() < M.getReal() && M.getReal() < 0. || M.getReal() > pi.getReal()) {
656 H = M.subtract(ecc);
657 } else {
658 H = M.add(ecc);
659 }
660 } else {
661 if (ecc.getReal() < 3.6 && FastMath.abs(M.getReal()) > pi.getReal()) {
662 H = M.subtract(ecc.copySign(M));
663 } else {
664 H = M.divide(ecc.subtract(1.));
665 }
666 }
667
668
669 int iter = 0;
670 do {
671 final T f3 = ecc.multiply(H.cosh());
672 final T f2 = ecc.multiply(H.sinh());
673 final T f1 = f3.subtract(1.);
674 final T f0 = f2.subtract(H).subtract(M);
675 final T f12 = f1.multiply(2);
676 final T d = f0.divide(f12);
677 final T fdf = f1.subtract(d.multiply(f2));
678 final T ds = f0.divide(fdf);
679
680 final T shift = f0.divide(fdf.add(ds.multiply(ds).multiply(f3.divide(6.))));
681
682 H = H.subtract(shift);
683
684 if (FastMath.abs(shift.getReal()) <= 1.0e-12) {
685 return H;
686 }
687
688 } while (++iter < 50);
689
690 throw new MathIllegalStateException(OrekitMessages.UNABLE_TO_COMPUTE_HYPERBOLIC_ECCENTRIC_ANOMALY,
691 iter);
692 }
693
694
695
696
697 private T[][] create6x6Identity() {
698
699 final T[][] identity = MathArrays.buildArray(field, 6, 6);
700 for (int i = 0; i < 6; i++) {
701 Arrays.fill(identity[i], zero);
702 identity[i][i] = one;
703 }
704 return identity;
705 }
706
707 @Override
708 protected T[][] computeJacobianMeanWrtCartesian() {
709 return create6x6Identity();
710 }
711
712 @Override
713 protected T[][] computeJacobianEccentricWrtCartesian() {
714 return create6x6Identity();
715 }
716
717 @Override
718 protected T[][] computeJacobianTrueWrtCartesian() {
719 return create6x6Identity();
720 }
721
722
723 public void addKeplerContribution(final PositionAngle type, final T gm,
724 final T[] pDot) {
725
726 final FieldPVCoordinates<T> pv = getPVCoordinates();
727
728
729 final FieldVector3D<T> velocity = pv.getVelocity();
730 pDot[0] = pDot[0].add(velocity.getX());
731 pDot[1] = pDot[1].add(velocity.getY());
732 pDot[2] = pDot[2].add(velocity.getZ());
733
734
735 final FieldVector3D<T> position = pv.getPosition();
736 final T r2 = position.getNormSq();
737 final T coeff = r2.multiply(r2.sqrt()).reciprocal().negate().multiply(gm);
738 pDot[3] = pDot[3].add(coeff.multiply(position.getX()));
739 pDot[4] = pDot[4].add(coeff.multiply(position.getY()));
740 pDot[5] = pDot[5].add(coeff.multiply(position.getZ()));
741
742 }
743
744
745
746
747 public String toString() {
748
749 final String comma = ", ";
750 final PVCoordinates pv = getPVCoordinates().toPVCoordinates();
751 final Vector3D p = pv.getPosition();
752 final Vector3D v = pv.getVelocity();
753 return "Cartesian parameters: {P(" +
754 p.getX() + comma +
755 p.getY() + comma +
756 p.getZ() + "), V(" +
757 v.getX() + comma +
758 v.getY() + comma +
759 v.getZ() + ")}";
760 }
761
762 @Override
763 public CartesianOrbit toOrbit() {
764 final PVCoordinates pv = getPVCoordinates().toPVCoordinates();
765 final AbsoluteDate date = getPVCoordinates().getDate().toAbsoluteDate();
766 if (hasDerivatives()) {
767
768 return new CartesianOrbit(pv, getFrame(), date, getMu().getReal());
769 } else {
770
771
772 return new CartesianOrbit(new PVCoordinates(pv.getPosition(), pv.getVelocity()),
773 getFrame(), date, getMu().getReal());
774 }
775 }
776
777 }