1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.frames;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.geometry.euclidean.threed.Rotation;
21 import org.orekit.time.AbsoluteDate;
22 import org.orekit.utils.PVCoordinates;
23 import org.orekit.utils.TimeStampedPVCoordinates;
24
25 import java.util.Arrays;
26
27
28
29
30
31
32
33
34
35
36 public interface KinematicTransform extends StaticTransform {
37
38
39
40
41
42
43 static KinematicTransform getIdentity() {
44 return Transform.IDENTITY;
45 }
46
47
48
49
50
51
52 static Vector3D compositeVelocity(final KinematicTransform first, final KinematicTransform second) {
53
54 final Vector3D v1 = first.getVelocity();
55 final Rotation r1 = first.getRotation();
56 final Vector3D o1 = first.getRotationRate();
57 final Vector3D p2 = second.getTranslation();
58 final Vector3D v2 = second.getVelocity();
59
60 final Vector3D crossP = Vector3D.crossProduct(o1, p2);
61
62 return v1.add(r1.applyInverseTo(v2.add(crossP)));
63 }
64
65
66
67
68
69
70 static Vector3D compositeRotationRate(final KinematicTransform first, final KinematicTransform second) {
71
72 final Vector3D o1 = first.getRotationRate();
73 final Rotation r2 = second.getRotation();
74 final Vector3D o2 = second.getRotationRate();
75
76 return o2.add(r2.applyTo(o1));
77 }
78
79
80
81
82
83 default PVCoordinates transformOnlyPV(final PVCoordinates pv) {
84 final Vector3D transformedP = transformPosition(pv.getPosition());
85 final Vector3D crossP = Vector3D.crossProduct(getRotationRate(), transformedP);
86 final Vector3D transformedV = getRotation().applyTo(pv.getVelocity().add(getVelocity())).subtract(crossP);
87 return new PVCoordinates(transformedP, transformedV);
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101 default TimeStampedPVCoordinates transformOnlyPV(final TimeStampedPVCoordinates pv) {
102 final Vector3D transformedP = transformPosition(pv.getPosition());
103 final Vector3D crossP = Vector3D.crossProduct(getRotationRate(), transformedP);
104 final Vector3D transformedV = getRotation().applyTo(pv.getVelocity().add(getVelocity())).subtract(crossP);
105 return new TimeStampedPVCoordinates(pv.getDate(), transformedP, transformedV);
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 default double[][] getPVJacobian() {
129 final double[][] jacobian = new double[6][6];
130
131
132 final double[][] mData = getRotation().getMatrix();
133
134
135 System.arraycopy(mData[0], 0, jacobian[0], 0, 3);
136 System.arraycopy(mData[1], 0, jacobian[1], 0, 3);
137 System.arraycopy(mData[2], 0, jacobian[2], 0, 3);
138
139
140 Arrays.fill(jacobian[0], 3, 6, 0.0);
141 Arrays.fill(jacobian[1], 3, 6, 0.0);
142 Arrays.fill(jacobian[2], 3, 6, 0.0);
143
144
145 final Vector3D o = getRotationRate();
146 final double ox = o.getX();
147 final double oy = o.getY();
148 final double oz = o.getZ();
149 for (int i = 0; i < 3; ++i) {
150 jacobian[3][i] = -(oy * mData[2][i] - oz * mData[1][i]);
151 jacobian[4][i] = -(oz * mData[0][i] - ox * mData[2][i]);
152 jacobian[5][i] = -(ox * mData[1][i] - oy * mData[0][i]);
153 }
154
155
156 System.arraycopy(mData[0], 0, jacobian[3], 3, 3);
157 System.arraycopy(mData[1], 0, jacobian[4], 3, 3);
158 System.arraycopy(mData[2], 0, jacobian[5], 3, 3);
159
160 return jacobian;
161 }
162
163
164
165
166
167 Vector3D getVelocity();
168
169
170
171
172
173
174 Vector3D getRotationRate();
175
176
177
178
179
180
181 KinematicTransform getInverse();
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 static KinematicTransform compose(final AbsoluteDate date,
200 final KinematicTransform first,
201 final KinematicTransform second) {
202 final Vector3D composedTranslation = StaticTransform.compositeTranslation(first, second);
203 final Vector3D composedTranslationRate = KinematicTransform.compositeVelocity(first, second);
204 return of(date, new PVCoordinates(composedTranslation, composedTranslationRate),
205 StaticTransform.compositeRotation(first, second),
206 KinematicTransform.compositeRotationRate(first, second));
207 }
208
209
210
211
212
213
214
215
216
217
218
219
220 static KinematicTransform of(final AbsoluteDate date,
221 final Rotation rotation,
222 final Vector3D rotationRate) {
223 return of(date, PVCoordinates.ZERO, rotation, rotationRate);
224 }
225
226
227
228
229
230
231
232
233
234
235
236 static KinematicTransform of(final AbsoluteDate date,
237 final PVCoordinates pvCoordinates) {
238 return of(date, pvCoordinates, Rotation.IDENTITY, Vector3D.ZERO);
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257 static KinematicTransform of(final AbsoluteDate date, final PVCoordinates pvCoordinates,
258 final Rotation rotation, final Vector3D rotationRate) {
259 return new KinematicTransform() {
260
261 @Override
262 public KinematicTransform getInverse() {
263 final Rotation r = getRotation();
264 final Vector3D rp = r.applyTo(getTranslation());
265 final Vector3D pInv = rp.negate();
266 final Vector3D crossP = Vector3D.crossProduct(getRotationRate(), rp);
267 final Vector3D vInv = crossP.subtract(getRotation().applyTo(getVelocity()));
268 final Rotation rInv = r.revert();
269 return KinematicTransform.of(getDate(), new PVCoordinates(pInv, vInv),
270 rInv, rInv.applyTo(getRotationRate()).negate());
271 }
272
273 @Override
274 public AbsoluteDate getDate() {
275 return date;
276 }
277
278 @Override
279 public Vector3D getTranslation() {
280 return pvCoordinates.getPosition();
281 }
282
283 @Override
284 public Rotation getRotation() {
285 return rotation;
286 }
287
288 @Override
289 public Vector3D getVelocity() {
290 return pvCoordinates.getVelocity();
291 }
292
293 @Override
294 public Vector3D getRotationRate() {
295 return rotationRate;
296 }
297 };
298 }
299
300 }