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
25 import org.apache.commons.math3.RealFieldElement;
26 import org.apache.commons.math3.geometry.euclidean.threed.FieldRotation;
27 import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D;
28 import org.apache.commons.math3.geometry.euclidean.threed.Line;
29 import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
30 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
31 import org.apache.commons.math3.util.Pair;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.TimeInterpolable;
34 import org.orekit.time.TimeShiftable;
35 import org.orekit.time.TimeStamped;
36 import org.orekit.utils.AngularCoordinates;
37 import org.orekit.utils.PVCoordinates;
38 import org.orekit.utils.FieldPVCoordinates;
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 public class Transform
95 implements TimeStamped, TimeShiftable<Transform>, TimeInterpolable<Transform>, Serializable {
96
97
98 public static final Transform IDENTITY = new IdentityTransform();
99
100
101 private static final long serialVersionUID = -8809893979516295102L;
102
103
104 private final AbsoluteDate date;
105
106
107 private final PVCoordinates cartesian;
108
109
110 private final AngularCoordinates angular;
111
112
113
114
115
116
117 private Transform(final AbsoluteDate date,
118 final PVCoordinates cartesian, final AngularCoordinates angular) {
119 this.date = date;
120 this.cartesian = cartesian;
121 this.angular = angular;
122 }
123
124
125
126
127
128
129
130 public Transform(final AbsoluteDate date, final Vector3D translation) {
131 this(date, new PVCoordinates(translation, Vector3D.ZERO), AngularCoordinates.IDENTITY);
132 }
133
134
135
136
137
138
139
140 public Transform(final AbsoluteDate date, final Rotation rotation) {
141 this(date, PVCoordinates.ZERO, new AngularCoordinates(rotation, Vector3D.ZERO));
142 }
143
144
145
146
147
148
149
150
151
152 public Transform(final AbsoluteDate date, final Vector3D translation, final Vector3D velocity) {
153 this(date, new PVCoordinates(translation, velocity), AngularCoordinates.IDENTITY);
154 }
155
156
157
158
159
160
161
162 public Transform(final AbsoluteDate date, final PVCoordinates cartesian) {
163 this(date, cartesian, AngularCoordinates.IDENTITY);
164 }
165
166
167
168
169
170
171
172
173
174 public Transform(final AbsoluteDate date, final Rotation rotation, final Vector3D rotationRate) {
175 this(date, PVCoordinates.ZERO, new AngularCoordinates(rotation, rotationRate));
176 }
177
178
179
180
181
182
183
184 public Transform(final AbsoluteDate date, final AngularCoordinates angular) {
185 this(date, PVCoordinates.ZERO, angular);
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199 public Transform(final AbsoluteDate date, final Transform first, final Transform second) {
200 this(date,
201 new PVCoordinates(compositeTranslation(first, second),
202 compositeVelocity(first, second)),
203 new AngularCoordinates(compositeRotation(first, second),
204 compositeRotationRate(first, second)));
205 }
206
207
208
209
210
211
212 private static Vector3D compositeTranslation(final Transform first, final Transform second) {
213
214 final Vector3D p1 = first.cartesian.getPosition();
215 final Rotation r1 = first.angular.getRotation();
216 final Vector3D p2 = second.cartesian.getPosition();
217
218 return p1.add(r1.applyInverseTo(p2));
219
220 }
221
222
223
224
225
226
227 private static Vector3D compositeVelocity(final Transform first, final Transform second) {
228
229 final Vector3D v1 = first.cartesian.getVelocity();
230 final Rotation r1 = first.angular.getRotation();
231 final Vector3D o1 = first.angular.getRotationRate();
232 final Vector3D p2 = second.cartesian.getPosition();
233 final Vector3D v2 = second.cartesian.getVelocity();
234
235 return v1.add(r1.applyInverseTo(v2.add(Vector3D.crossProduct(o1, p2))));
236
237 }
238
239
240
241
242
243
244 private static Rotation compositeRotation(final Transform first, final Transform second) {
245
246 final Rotation r1 = first.angular.getRotation();
247 final Rotation r2 = second.angular.getRotation();
248
249 return r2.applyTo(r1);
250
251 }
252
253
254
255
256
257
258 private static Vector3D compositeRotationRate(final Transform first, final Transform second) {
259
260 final Vector3D o1 = first.angular.getRotationRate();
261 final Rotation r2 = second.angular.getRotation();
262 final Vector3D o2 = second.angular.getRotationRate();
263
264 return o2.add(r2.applyTo(o1));
265
266 }
267
268
269 public AbsoluteDate getDate() {
270 return date;
271 }
272
273
274 public Transform shiftedBy(final double dt) {
275 return new Transform(date.shiftedBy(dt), cartesian.shiftedBy(dt), angular.shiftedBy(dt));
276 };
277
278
279
280
281
282
283
284
285 public Transform interpolate(final AbsoluteDate interpolationDate,
286 final Collection<Transform> sample) {
287 return interpolate(interpolationDate, true, true, sample);
288 }
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315 public static Transform interpolate(final AbsoluteDate date,
316 final boolean useVelocities, final boolean useRotationRates,
317 final Collection<Transform> sample) {
318 final List<Pair<AbsoluteDate, PVCoordinates>> datedPV =
319 new ArrayList<Pair<AbsoluteDate, PVCoordinates>>(sample.size());
320 final List<Pair<AbsoluteDate, AngularCoordinates>> datedAC =
321 new ArrayList<Pair<AbsoluteDate, AngularCoordinates>>(sample.size());
322 for (final Transform transform : sample) {
323 datedPV.add(new Pair<AbsoluteDate, PVCoordinates>(transform.getDate(),
324 transform.getCartesian()));
325 datedAC.add(new Pair<AbsoluteDate, AngularCoordinates>(transform.getDate(),
326 transform.getAngular()));
327 }
328 final PVCoordinates interpolatedPV = PVCoordinates.interpolate(date, useVelocities, datedPV);
329 final AngularCoordinates interpolatedAC = AngularCoordinates.interpolate(date, useRotationRates, datedAC);
330 return new Transform(date, interpolatedPV, interpolatedAC);
331 }
332
333
334
335
336 public Transform getInverse() {
337
338 final Vector3D p = cartesian.getPosition();
339 final Vector3D v = cartesian.getVelocity();
340 final Rotation r = angular.getRotation();
341 final Vector3D o = angular.getRotationRate();
342
343 final Vector3D rT = r.applyTo(p);
344 return new Transform(date,
345 new PVCoordinates(rT.negate(),
346 Vector3D.crossProduct(o, rT).subtract(r.applyTo(v))),
347 angular.revert());
348
349 }
350
351
352
353
354
355
356
357
358 public Transform freeze() {
359 return new Transform(date,
360 new PVCoordinates(cartesian.getPosition(), Vector3D.ZERO),
361 new AngularCoordinates(angular.getRotation(), Vector3D.ZERO));
362 }
363
364
365
366
367
368 public Vector3D transformPosition(final Vector3D position) {
369 return angular.getRotation().applyTo(cartesian.getPosition().add(position));
370 }
371
372
373
374
375
376
377 public <T extends RealFieldElement<T>> FieldVector3D<T> transformPosition(final FieldVector3D<T> position) {
378 return FieldRotation.applyTo(angular.getRotation(), position.add(cartesian.getPosition()));
379 }
380
381
382
383
384
385 public Vector3D transformVector(final Vector3D vector) {
386 return angular.getRotation().applyTo(vector);
387 }
388
389
390
391
392
393
394 public <T extends RealFieldElement<T>> FieldVector3D<T> transformVector(final FieldVector3D<T> vector) {
395 return FieldRotation.applyTo(angular.getRotation(), vector);
396 }
397
398
399
400
401
402 public Line transformLine(final Line line) {
403 final Vector3D transformedP0 = transformPosition(line.getOrigin());
404 final Vector3D transformedP1 = transformPosition(line.pointAt(1.0e6));
405 return new Line(transformedP0, transformedP1);
406 }
407
408
409
410
411
412 public PVCoordinates transformPVCoordinates(final PVCoordinates pv) {
413 final Vector3D p = pv.getPosition();
414 final Vector3D v = pv.getVelocity();
415 final Vector3D transformedP = angular.getRotation().applyTo(cartesian.getPosition().add(p));
416 final Vector3D cross = Vector3D.crossProduct(angular.getRotationRate(), transformedP);
417 return new PVCoordinates(transformedP,
418 angular.getRotation().applyTo(v.add(cartesian.getVelocity())).subtract(cross));
419 }
420
421
422
423
424
425
426 public <T extends RealFieldElement<T>> FieldPVCoordinates<T> transformPVCoordinates(final FieldPVCoordinates<T> pv) {
427 final FieldVector3D<T> p = pv.getPosition();
428 final FieldVector3D<T> v = pv.getVelocity();
429 final FieldVector3D<T> transformedP = FieldRotation.applyTo(angular.getRotation(),
430 p.add(cartesian.getPosition()));
431 final FieldVector3D<T> cross = FieldVector3D.crossProduct(angular.getRotationRate(), transformedP);
432 return new FieldPVCoordinates<T>(transformedP,
433 FieldRotation.applyTo(angular.getRotation(),
434 v.add(cartesian.getVelocity())).subtract(cross));
435 }
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458 public void getJacobian(final double[][] jacobian) {
459
460
461 final double[][] mData = angular.getRotation().getMatrix();
462
463
464 System.arraycopy(mData[0], 0, jacobian[0], 0, 3);
465 System.arraycopy(mData[1], 0, jacobian[1], 0, 3);
466 System.arraycopy(mData[2], 0, jacobian[2], 0, 3);
467
468
469 Arrays.fill(jacobian[0], 3, 6, 0.0);
470 Arrays.fill(jacobian[1], 3, 6, 0.0);
471 Arrays.fill(jacobian[2], 3, 6, 0.0);
472
473
474 final Vector3D o = angular.getRotationRate();
475 final double mOx = -o.getX();
476 final double mOy = -o.getY();
477 final double mOz = -o.getZ();
478 for (int i = 0; i < 3; ++i) {
479 jacobian[3][i] = mOy * mData[2][i] - mOz * mData[1][i];
480 jacobian[4][i] = mOz * mData[0][i] - mOx * mData[2][i];
481 jacobian[5][i] = mOx * mData[1][i] - mOy * mData[0][i];
482 }
483
484
485 System.arraycopy(mData[0], 0, jacobian[3], 3, 3);
486 System.arraycopy(mData[1], 0, jacobian[4], 3, 3);
487 System.arraycopy(mData[2], 0, jacobian[5], 3, 3);
488
489 }
490
491
492
493
494
495
496
497
498
499 public PVCoordinates getCartesian() {
500 return cartesian;
501 }
502
503
504
505
506
507
508
509
510
511 public Vector3D getTranslation() {
512 return cartesian.getPosition();
513 }
514
515
516
517
518
519
520 public Vector3D getVelocity() {
521 return cartesian.getVelocity();
522 }
523
524
525
526
527
528
529
530
531
532 public AngularCoordinates getAngular() {
533 return angular;
534 }
535
536
537
538
539
540
541
542
543
544 public Rotation getRotation() {
545 return angular.getRotation();
546 }
547
548
549
550
551
552
553
554 public Vector3D getRotationRate() {
555 return angular.getRotationRate();
556 }
557
558
559 private static class IdentityTransform extends Transform {
560
561
562 private static final long serialVersionUID = -9042082036141830517L;
563
564
565 public IdentityTransform() {
566 super(AbsoluteDate.J2000_EPOCH, PVCoordinates.ZERO, AngularCoordinates.IDENTITY);
567 }
568
569
570 @Override
571 public Transform shiftedBy(final double dt) {
572 return this;
573 }
574
575
576 @Override
577 public Transform getInverse() {
578 return this;
579 };
580
581
582 @Override
583 public Vector3D transformPosition(final Vector3D position) {
584 return position;
585 }
586
587
588 @Override
589 public Vector3D transformVector(final Vector3D vector) {
590 return vector;
591 }
592
593
594 @Override
595 public Line transformLine(final Line line) {
596 return line;
597 }
598
599
600 @Override
601 public PVCoordinates transformPVCoordinates(final PVCoordinates pv) {
602 return pv;
603 }
604
605
606 @Override
607 public void getJacobian(final double[][] jacobian) {
608 for (int i = 0; i < 6; ++i) {
609 Arrays.fill(jacobian[i], 0, 6, 0.0);
610 jacobian[i][i] = 1.0;
611 }
612 }
613
614 }
615
616 }