1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.frames;
18
19 import java.io.Serializable;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.List;
24 import java.util.stream.Collectors;
25 import java.util.stream.Stream;
26
27 import org.hipparchus.CalculusFieldElement;
28 import org.hipparchus.geometry.euclidean.threed.Line;
29 import org.hipparchus.geometry.euclidean.threed.Rotation;
30 import org.hipparchus.geometry.euclidean.threed.Vector3D;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.time.TimeInterpolator;
33 import org.orekit.time.TimeShiftable;
34 import org.orekit.utils.AngularCoordinates;
35 import org.orekit.utils.AngularDerivativesFilter;
36 import org.orekit.utils.CartesianDerivativesFilter;
37 import org.orekit.utils.FieldPVCoordinates;
38 import org.orekit.utils.PVCoordinates;
39 import org.orekit.utils.TimeStampedAngularCoordinates;
40 import org.orekit.utils.TimeStampedAngularCoordinatesHermiteInterpolator;
41 import org.orekit.utils.TimeStampedFieldPVCoordinates;
42 import org.orekit.utils.TimeStampedPVCoordinates;
43 import org.orekit.utils.TimeStampedPVCoordinatesHermiteInterpolator;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public class Transform implements
102 TimeShiftable<Transform>,
103 Serializable,
104 KinematicTransform {
105
106
107 public static final Transform IDENTITY = new IdentityTransform();
108
109
110 private static final long serialVersionUID = 210140410L;
111
112
113 private final AbsoluteDate date;
114
115
116 private final PVCoordinates cartesian;
117
118
119 private final AngularCoordinates angular;
120
121
122
123
124
125
126 public Transform(final AbsoluteDate date, final PVCoordinates cartesian, final AngularCoordinates angular) {
127 this.date = date;
128 this.cartesian = cartesian;
129 this.angular = angular;
130 }
131
132
133
134
135
136
137
138 public Transform(final AbsoluteDate date, final Vector3D translation) {
139 this(date,
140 new PVCoordinates(translation),
141 AngularCoordinates.IDENTITY);
142 }
143
144
145
146
147
148
149
150 public Transform(final AbsoluteDate date, final Rotation rotation) {
151 this(date,
152 PVCoordinates.ZERO,
153 new AngularCoordinates(rotation));
154 }
155
156
157
158
159
160
161
162
163
164
165
166 public Transform(final AbsoluteDate date, final Vector3D translation, final Rotation rotation) {
167 this(date, new PVCoordinates(translation), new AngularCoordinates(rotation));
168 }
169
170
171
172
173
174
175
176
177
178 public Transform(final AbsoluteDate date, final Vector3D translation,
179 final Vector3D velocity) {
180 this(date,
181 new PVCoordinates(translation, velocity, Vector3D.ZERO),
182 AngularCoordinates.IDENTITY);
183 }
184
185
186
187
188
189
190
191
192
193
194
195 public Transform(final AbsoluteDate date, final Vector3D translation,
196 final Vector3D velocity, final Vector3D acceleration) {
197 this(date,
198 new PVCoordinates(translation, velocity, acceleration),
199 AngularCoordinates.IDENTITY);
200 }
201
202
203
204
205
206
207
208 public Transform(final AbsoluteDate date, final PVCoordinates cartesian) {
209 this(date,
210 cartesian,
211 AngularCoordinates.IDENTITY);
212 }
213
214
215
216
217
218
219
220
221
222 public Transform(final AbsoluteDate date, final Rotation rotation, final Vector3D rotationRate) {
223 this(date,
224 PVCoordinates.ZERO,
225 new AngularCoordinates(rotation, rotationRate, Vector3D.ZERO));
226 }
227
228
229
230
231
232
233
234
235
236
237 public Transform(final AbsoluteDate date, final Rotation rotation, final Vector3D rotationRate,
238 final Vector3D rotationAcceleration) {
239 this(date,
240 PVCoordinates.ZERO,
241 new AngularCoordinates(rotation, rotationRate, rotationAcceleration));
242 }
243
244
245
246
247
248
249
250 public Transform(final AbsoluteDate date, final AngularCoordinates angular) {
251 this(date, PVCoordinates.ZERO, angular);
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265 public Transform(final AbsoluteDate date, final Transform first, final Transform second) {
266 this(date,
267 new PVCoordinates(StaticTransform.compositeTranslation(first, second),
268 KinematicTransform.compositeVelocity(first, second),
269 compositeAcceleration(first, second)),
270 new AngularCoordinates(StaticTransform.compositeRotation(first, second),
271 KinematicTransform.compositeRotationRate(first, second),
272 compositeRotationAcceleration(first, second)));
273 }
274
275
276
277
278
279
280 private static Vector3D compositeAcceleration(final Transform first, final Transform second) {
281
282 final Vector3D a1 = first.cartesian.getAcceleration();
283 final Rotation r1 = first.angular.getRotation();
284 final Vector3D o1 = first.angular.getRotationRate();
285 final Vector3D oDot1 = first.angular.getRotationAcceleration();
286 final Vector3D p2 = second.cartesian.getPosition();
287 final Vector3D v2 = second.cartesian.getVelocity();
288 final Vector3D a2 = second.cartesian.getAcceleration();
289
290 final Vector3D crossCrossP = Vector3D.crossProduct(o1, Vector3D.crossProduct(o1, p2));
291 final Vector3D crossV = Vector3D.crossProduct(o1, v2);
292 final Vector3D crossDotP = Vector3D.crossProduct(oDot1, p2);
293
294 return a1.add(r1.applyInverseTo(new Vector3D(1, a2, 2, crossV, 1, crossCrossP, 1, crossDotP)));
295
296 }
297
298
299
300
301
302
303 private static Vector3D compositeRotationAcceleration(final Transform first, final Transform second) {
304
305 final Vector3D o1 = first.angular.getRotationRate();
306 final Vector3D oDot1 = first.angular.getRotationAcceleration();
307 final Rotation r2 = second.angular.getRotation();
308 final Vector3D o2 = second.angular.getRotationRate();
309 final Vector3D oDot2 = second.angular.getRotationAcceleration();
310
311 return new Vector3D( 1, oDot2,
312 1, r2.applyTo(oDot1),
313 -1, Vector3D.crossProduct(o2, r2.applyTo(o1)));
314
315 }
316
317
318 public AbsoluteDate getDate() {
319 return date;
320 }
321
322
323 public Transform shiftedBy(final double dt) {
324 return new Transform(date.shiftedBy(dt), cartesian.shiftedBy(dt), angular.shiftedBy(dt));
325 }
326
327
328
329
330
331
332
333
334
335
336
337 public StaticTransform staticShiftedBy(final double dt) {
338 return StaticTransform.of(
339 date.shiftedBy(dt),
340 cartesian.positionShiftedBy(dt),
341 angular.rotationShiftedBy(dt));
342 }
343
344
345
346
347
348
349
350
351
352 public StaticTransform toStaticTransform() {
353 return StaticTransform.of(date, cartesian.getPosition(), angular.getRotation());
354 }
355
356
357
358
359
360
361
362
363
364
365
366
367
368 public Transform interpolate(final AbsoluteDate interpolationDate, final Stream<Transform> sample) {
369 return interpolate(interpolationDate,
370 CartesianDerivativesFilter.USE_PVA, AngularDerivativesFilter.USE_RRA,
371 sample.collect(Collectors.toList()));
372 }
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398 public static Transform interpolate(final AbsoluteDate date,
399 final CartesianDerivativesFilter cFilter,
400 final AngularDerivativesFilter aFilter,
401 final Collection<Transform> sample) {
402
403
404 final List<TimeStampedPVCoordinates> datedPV = new ArrayList<>(sample.size());
405 final List<TimeStampedAngularCoordinates> datedAC = new ArrayList<>(sample.size());
406 for (final Transform t : sample) {
407 datedPV.add(new TimeStampedPVCoordinates(t.getDate(), t.getTranslation(), t.getVelocity(), t.getAcceleration()));
408 datedAC.add(new TimeStampedAngularCoordinates(t.getDate(), t.getRotation(), t.getRotationRate(), t.getRotationAcceleration()));
409 }
410
411
412 final TimeInterpolator<TimeStampedPVCoordinates> pvInterpolator =
413 new TimeStampedPVCoordinatesHermiteInterpolator(datedPV.size(), cFilter);
414
415 final TimeInterpolator<TimeStampedAngularCoordinates> angularInterpolator =
416 new TimeStampedAngularCoordinatesHermiteInterpolator(datedPV.size(), aFilter);
417
418
419 final TimeStampedPVCoordinates interpolatedPV = pvInterpolator.interpolate(date, datedPV);
420 final TimeStampedAngularCoordinates interpolatedAC = angularInterpolator.interpolate(date, datedAC);
421 return new Transform(date, interpolatedPV, interpolatedAC);
422 }
423
424
425
426
427 @Override
428 public Transform getInverse() {
429
430 final Rotation r = angular.getRotation();
431 final Vector3D o = angular.getRotationRate();
432 final Vector3D oDot = angular.getRotationAcceleration();
433 final Vector3D rp = r.applyTo(cartesian.getPosition());
434 final Vector3D rv = r.applyTo(cartesian.getVelocity());
435 final Vector3D ra = r.applyTo(cartesian.getAcceleration());
436
437 final Vector3D pInv = rp.negate();
438 final Vector3D crossP = Vector3D.crossProduct(o, rp);
439 final Vector3D vInv = crossP.subtract(rv);
440 final Vector3D crossV = Vector3D.crossProduct(o, rv);
441 final Vector3D crossDotP = Vector3D.crossProduct(oDot, rp);
442 final Vector3D crossCrossP = Vector3D.crossProduct(o, crossP);
443 final Vector3D aInv = new Vector3D(-1, ra,
444 2, crossV,
445 1, crossDotP,
446 -1, crossCrossP);
447
448 return new Transform(getDate(), new PVCoordinates(pInv, vInv, aInv), angular.revert());
449
450 }
451
452
453
454
455
456
457
458
459 public Transform freeze() {
460 return new Transform(date,
461 new PVCoordinates(cartesian.getPosition(), Vector3D.ZERO, Vector3D.ZERO),
462 new AngularCoordinates(angular.getRotation(), Vector3D.ZERO, Vector3D.ZERO));
463 }
464
465
466
467
468
469 public PVCoordinates transformPVCoordinates(final PVCoordinates pva) {
470 return angular.applyTo(new PVCoordinates(1, pva, 1, cartesian));
471 }
472
473
474
475
476
477
478
479
480
481
482
483
484
485 public TimeStampedPVCoordinates transformPVCoordinates(final TimeStampedPVCoordinates pv) {
486 return angular.applyTo(new TimeStampedPVCoordinates(pv.getDate(), 1, pv, 1, cartesian));
487 }
488
489
490
491
492
493
494 public <T extends CalculusFieldElement<T>> FieldPVCoordinates<T> transformPVCoordinates(final FieldPVCoordinates<T> pv) {
495 return angular.applyTo(new FieldPVCoordinates<>(pv.getPosition().add(cartesian.getPosition()),
496 pv.getVelocity().add(cartesian.getVelocity()),
497 pv.getAcceleration().add(cartesian.getAcceleration())));
498 }
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513 public <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T> transformPVCoordinates(final TimeStampedFieldPVCoordinates<T> pv) {
514 return angular.applyTo(new TimeStampedFieldPVCoordinates<>(pv.getDate(),
515 pv.getPosition().add(cartesian.getPosition()),
516 pv.getVelocity().add(cartesian.getVelocity()),
517 pv.getAcceleration().add(cartesian.getAcceleration())));
518 }
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 public void getJacobian(final CartesianDerivativesFilter selector, final double[][] jacobian) {
545
546
547 final double[][] mData = angular.getRotation().getMatrix();
548
549
550 System.arraycopy(mData[0], 0, jacobian[0], 0, 3);
551 System.arraycopy(mData[1], 0, jacobian[1], 0, 3);
552 System.arraycopy(mData[2], 0, jacobian[2], 0, 3);
553
554 if (selector.getMaxOrder() >= 1) {
555
556
557 Arrays.fill(jacobian[0], 3, 6, 0.0);
558 Arrays.fill(jacobian[1], 3, 6, 0.0);
559 Arrays.fill(jacobian[2], 3, 6, 0.0);
560
561
562 final Vector3D o = angular.getRotationRate();
563 final double ox = o.getX();
564 final double oy = o.getY();
565 final double oz = o.getZ();
566 for (int i = 0; i < 3; ++i) {
567 jacobian[3][i] = -(oy * mData[2][i] - oz * mData[1][i]);
568 jacobian[4][i] = -(oz * mData[0][i] - ox * mData[2][i]);
569 jacobian[5][i] = -(ox * mData[1][i] - oy * mData[0][i]);
570 }
571
572
573 System.arraycopy(mData[0], 0, jacobian[3], 3, 3);
574 System.arraycopy(mData[1], 0, jacobian[4], 3, 3);
575 System.arraycopy(mData[2], 0, jacobian[5], 3, 3);
576
577 if (selector.getMaxOrder() >= 2) {
578
579
580 Arrays.fill(jacobian[0], 6, 9, 0.0);
581 Arrays.fill(jacobian[1], 6, 9, 0.0);
582 Arrays.fill(jacobian[2], 6, 9, 0.0);
583
584
585 Arrays.fill(jacobian[3], 6, 9, 0.0);
586 Arrays.fill(jacobian[4], 6, 9, 0.0);
587 Arrays.fill(jacobian[5], 6, 9, 0.0);
588
589
590 final Vector3D oDot = angular.getRotationAcceleration();
591 final double oDotx = oDot.getX();
592 final double oDoty = oDot.getY();
593 final double oDotz = oDot.getZ();
594 for (int i = 0; i < 3; ++i) {
595 jacobian[6][i] = -(oDoty * mData[2][i] - oDotz * mData[1][i]) - (oy * jacobian[5][i] - oz * jacobian[4][i]);
596 jacobian[7][i] = -(oDotz * mData[0][i] - oDotx * mData[2][i]) - (oz * jacobian[3][i] - ox * jacobian[5][i]);
597 jacobian[8][i] = -(oDotx * mData[1][i] - oDoty * mData[0][i]) - (ox * jacobian[4][i] - oy * jacobian[3][i]);
598 }
599
600
601 for (int i = 0; i < 3; ++i) {
602 jacobian[6][i + 3] = -2 * (oy * mData[2][i] - oz * mData[1][i]);
603 jacobian[7][i + 3] = -2 * (oz * mData[0][i] - ox * mData[2][i]);
604 jacobian[8][i + 3] = -2 * (ox * mData[1][i] - oy * mData[0][i]);
605 }
606
607
608 System.arraycopy(mData[0], 0, jacobian[6], 6, 3);
609 System.arraycopy(mData[1], 0, jacobian[7], 6, 3);
610 System.arraycopy(mData[2], 0, jacobian[8], 6, 3);
611
612 }
613
614 }
615
616 }
617
618
619
620
621
622
623
624
625
626 public PVCoordinates getCartesian() {
627 return cartesian;
628 }
629
630
631
632
633
634
635
636
637
638
639 public Vector3D getTranslation() {
640 return cartesian.getPosition();
641 }
642
643
644
645
646
647
648
649 public Vector3D getVelocity() {
650 return cartesian.getVelocity();
651 }
652
653
654
655
656
657
658
659 public Vector3D getAcceleration() {
660 return cartesian.getAcceleration();
661 }
662
663
664
665
666
667
668
669
670
671
672 public AngularCoordinates getAngular() {
673 return angular;
674 }
675
676
677
678
679
680
681
682
683
684
685 public Rotation getRotation() {
686 return angular.getRotation();
687 }
688
689
690
691
692
693
694
695
696 public Vector3D getRotationRate() {
697 return angular.getRotationRate();
698 }
699
700
701
702
703
704
705
706 public Vector3D getRotationAcceleration() {
707 return angular.getRotationAcceleration();
708 }
709
710
711 private static class IdentityTransform extends Transform {
712
713
714 private static final long serialVersionUID = -9042082036141830517L;
715
716
717 IdentityTransform() {
718 super(AbsoluteDate.ARBITRARY_EPOCH, PVCoordinates.ZERO, AngularCoordinates.IDENTITY);
719 }
720
721
722 @Override
723 public Transform shiftedBy(final double dt) {
724 return this;
725 }
726
727
728 @Override
729 public Transform getInverse() {
730 return this;
731 }
732
733
734 @Override
735 public Vector3D transformPosition(final Vector3D position) {
736 return position;
737 }
738
739
740 @Override
741 public Vector3D transformVector(final Vector3D vector) {
742 return vector;
743 }
744
745
746 @Override
747 public Line transformLine(final Line line) {
748 return line;
749 }
750
751
752 @Override
753 public PVCoordinates transformPVCoordinates(final PVCoordinates pv) {
754 return pv;
755 }
756
757 @Override
758 public Transform freeze() {
759 return this;
760 }
761
762 @Override
763 public TimeStampedPVCoordinates transformPVCoordinates(
764 final TimeStampedPVCoordinates pv) {
765 return pv;
766 }
767
768 @Override
769 public <T extends CalculusFieldElement<T>> FieldPVCoordinates<T>
770 transformPVCoordinates(final FieldPVCoordinates<T> pv) {
771 return pv;
772 }
773
774 @Override
775 public <T extends CalculusFieldElement<T>>
776 TimeStampedFieldPVCoordinates<T> transformPVCoordinates(
777 final TimeStampedFieldPVCoordinates<T> pv) {
778 return pv;
779 }
780
781
782 @Override
783 public void getJacobian(final CartesianDerivativesFilter selector, final double[][] jacobian) {
784 final int n = 3 * (selector.getMaxOrder() + 1);
785 for (int i = 0; i < n; ++i) {
786 Arrays.fill(jacobian[i], 0, n, 0.0);
787 jacobian[i][i] = 1.0;
788 }
789 }
790
791 }
792
793 }