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