1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.utils;
18
19 import java.io.Serializable;
20
21 import org.hipparchus.analysis.differentiation.DerivativeStructure;
22 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23 import org.hipparchus.geometry.euclidean.threed.Vector3D;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.errors.OrekitMessages;
26 import org.orekit.time.TimeShiftable;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class PVCoordinates implements TimeShiftable<PVCoordinates>, Serializable {
43
44
45 public static final PVCoordinates ZERO = new PVCoordinates(Vector3D.ZERO, Vector3D.ZERO, Vector3D.ZERO);
46
47
48 private static final long serialVersionUID = 20140407L;
49
50
51 private final Vector3D position;
52
53
54 private final Vector3D velocity;
55
56
57 private final Vector3D acceleration;
58
59
60
61
62 public PVCoordinates() {
63 position = Vector3D.ZERO;
64 velocity = Vector3D.ZERO;
65 acceleration = Vector3D.ZERO;
66 }
67
68
69
70
71
72
73 public PVCoordinates(final Vector3D position, final Vector3D velocity) {
74 this.position = position;
75 this.velocity = velocity;
76 this.acceleration = Vector3D.ZERO;
77 }
78
79
80
81
82
83
84 public PVCoordinates(final Vector3D position, final Vector3D velocity, final Vector3D acceleration) {
85 this.position = position;
86 this.velocity = velocity;
87 this.acceleration = acceleration;
88 }
89
90
91
92
93
94
95
96 public PVCoordinates(final double a, final PVCoordinates pv) {
97 position = new Vector3D(a, pv.position);
98 velocity = new Vector3D(a, pv.velocity);
99 acceleration = new Vector3D(a, pv.acceleration);
100 }
101
102
103
104
105
106
107
108 public PVCoordinates(final PVCoordinates start, final PVCoordinates end) {
109 this.position = end.position.subtract(start.position);
110 this.velocity = end.velocity.subtract(start.velocity);
111 this.acceleration = end.acceleration.subtract(start.acceleration);
112 }
113
114
115
116
117
118
119
120
121
122 public PVCoordinates(final double a1, final PVCoordinates pv1,
123 final double a2, final PVCoordinates pv2) {
124 position = new Vector3D(a1, pv1.position, a2, pv2.position);
125 velocity = new Vector3D(a1, pv1.velocity, a2, pv2.velocity);
126 acceleration = new Vector3D(a1, pv1.acceleration, a2, pv2.acceleration);
127 }
128
129
130
131
132
133
134
135
136
137
138
139 public PVCoordinates(final double a1, final PVCoordinates pv1,
140 final double a2, final PVCoordinates pv2,
141 final double a3, final PVCoordinates pv3) {
142 position = new Vector3D(a1, pv1.position, a2, pv2.position, a3, pv3.position);
143 velocity = new Vector3D(a1, pv1.velocity, a2, pv2.velocity, a3, pv3.velocity);
144 acceleration = new Vector3D(a1, pv1.acceleration, a2, pv2.acceleration, a3, pv3.acceleration);
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158
159 public PVCoordinates(final double a1, final PVCoordinates pv1,
160 final double a2, final PVCoordinates pv2,
161 final double a3, final PVCoordinates pv3,
162 final double a4, final PVCoordinates pv4) {
163 position = new Vector3D(a1, pv1.position, a2, pv2.position,
164 a3, pv3.position, a4, pv4.position);
165 velocity = new Vector3D(a1, pv1.velocity, a2, pv2.velocity,
166 a3, pv3.velocity, a4, pv4.velocity);
167 acceleration = new Vector3D(a1, pv1.acceleration, a2, pv2.acceleration,
168 a3, pv3.acceleration, a4, pv4.acceleration);
169 }
170
171
172
173
174
175
176
177
178 public PVCoordinates(final FieldVector3D<DerivativeStructure> p) {
179 position = new Vector3D(p.getX().getReal(), p.getY().getReal(), p.getZ().getReal());
180 if (p.getX().getOrder() >= 1) {
181 velocity = new Vector3D(p.getX().getPartialDerivative(1),
182 p.getY().getPartialDerivative(1),
183 p.getZ().getPartialDerivative(1));
184 if (p.getX().getOrder() >= 2) {
185 acceleration = new Vector3D(p.getX().getPartialDerivative(2),
186 p.getY().getPartialDerivative(2),
187 p.getZ().getPartialDerivative(2));
188 } else {
189 acceleration = Vector3D.ZERO;
190 }
191 } else {
192 velocity = Vector3D.ZERO;
193 acceleration = Vector3D.ZERO;
194 }
195 }
196
197
198
199
200
201
202
203
204
205
206 public FieldVector3D<DerivativeStructure> toDerivativeStructureVector(final int order)
207 throws OrekitException {
208
209 final DerivativeStructure x;
210 final DerivativeStructure y;
211 final DerivativeStructure z;
212 switch(order) {
213 case 0 :
214 x = new DerivativeStructure(1, 0, position.getX());
215 y = new DerivativeStructure(1, 0, position.getY());
216 z = new DerivativeStructure(1, 0, position.getZ());
217 break;
218 case 1 :
219 x = new DerivativeStructure(1, 1, position.getX(), velocity.getX());
220 y = new DerivativeStructure(1, 1, position.getY(), velocity.getY());
221 z = new DerivativeStructure(1, 1, position.getZ(), velocity.getZ());
222 break;
223 case 2 :
224 x = new DerivativeStructure(1, 2, position.getX(), velocity.getX(), acceleration.getX());
225 y = new DerivativeStructure(1, 2, position.getY(), velocity.getY(), acceleration.getY());
226 z = new DerivativeStructure(1, 2, position.getZ(), velocity.getZ(), acceleration.getZ());
227 break;
228 default :
229 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_DERIVATION_ORDER, order);
230 }
231
232 return new FieldVector3D<DerivativeStructure>(x, y, z);
233
234 }
235
236
237
238
239
240
241
242
243
244 public static Vector3D estimateVelocity(final Vector3D start, final Vector3D end, final double dt) {
245 final double scale = 1.0 / dt;
246 return new Vector3D(scale, end, -scale, start);
247 }
248
249
250
251
252
253
254
255
256
257
258
259 public PVCoordinates shiftedBy(final double dt) {
260 return new PVCoordinates(new Vector3D(1, position, dt, velocity, 0.5 * dt * dt, acceleration),
261 new Vector3D(1, velocity, dt, acceleration),
262 acceleration);
263 }
264
265
266
267
268 public Vector3D getPosition() {
269 return position;
270 }
271
272
273
274
275 public Vector3D getVelocity() {
276 return velocity;
277 }
278
279
280
281
282 public Vector3D getAcceleration() {
283 return acceleration;
284 }
285
286
287
288
289
290
291
292
293
294 public Vector3D getMomentum() {
295 return Vector3D.crossProduct(position, velocity);
296 }
297
298
299
300
301
302
303
304
305
306
307
308 public Vector3D getAngularVelocity() {
309 return this.getMomentum().scalarMultiply(1.0 / this.getPosition().getNormSq());
310 }
311
312
313
314
315 public PVCoordinates negate() {
316 return new PVCoordinates(position.negate(), velocity.negate(), acceleration.negate());
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330
331 public PVCoordinates normalize() {
332 final double inv = 1.0 / position.getNorm();
333 final Vector3D u = new Vector3D(inv, position);
334 final Vector3D v = new Vector3D(inv, velocity);
335 final Vector3D w = new Vector3D(inv, acceleration);
336 final double uv = Vector3D.dotProduct(u, v);
337 final double v2 = Vector3D.dotProduct(v, v);
338 final double uw = Vector3D.dotProduct(u, w);
339 final Vector3D uDot = new Vector3D(1, v, -uv, u);
340 final Vector3D uDotDot = new Vector3D(1, w, -2 * uv, v, 3 * uv * uv - v2 - uw, u);
341 return new PVCoordinates(u, uDot, uDotDot);
342 }
343
344
345
346
347
348
349 public static PVCoordinates crossProduct(final PVCoordinates pv1, final PVCoordinates pv2) {
350 final Vector3D p1 = pv1.position;
351 final Vector3D v1 = pv1.velocity;
352 final Vector3D a1 = pv1.acceleration;
353 final Vector3D p2 = pv2.position;
354 final Vector3D v2 = pv2.velocity;
355 final Vector3D a2 = pv2.acceleration;
356 return new PVCoordinates(Vector3D.crossProduct(p1, p2),
357 new Vector3D(1, Vector3D.crossProduct(p1, v2),
358 1, Vector3D.crossProduct(v1, p2)),
359 new Vector3D(1, Vector3D.crossProduct(p1, a2),
360 2, Vector3D.crossProduct(v1, v2),
361 1, Vector3D.crossProduct(a1, p2)));
362 }
363
364
365
366
367 public String toString() {
368 final String comma = ", ";
369 return new StringBuffer().append('{').append("P(").
370 append(position.getX()).append(comma).
371 append(position.getY()).append(comma).
372 append(position.getZ()).append("), V(").
373 append(velocity.getX()).append(comma).
374 append(velocity.getY()).append(comma).
375 append(velocity.getZ()).append("), A(").
376 append(acceleration.getX()).append(comma).
377 append(acceleration.getY()).append(comma).
378 append(acceleration.getZ()).append(")}").toString();
379 }
380
381
382
383
384 private Object writeReplace() {
385 return new DTO(this);
386 }
387
388
389 private static class DTO implements Serializable {
390
391
392 private static final long serialVersionUID = 20140723L;
393
394
395 private double[] d;
396
397
398
399
400 private DTO(final PVCoordinates pv) {
401 this.d = new double[] {
402 pv.getPosition().getX(), pv.getPosition().getY(), pv.getPosition().getZ(),
403 pv.getVelocity().getX(), pv.getVelocity().getY(), pv.getVelocity().getZ(),
404 pv.getAcceleration().getX(), pv.getAcceleration().getY(), pv.getAcceleration().getZ(),
405 };
406 }
407
408
409
410
411 private Object readResolve() {
412 return new PVCoordinates(new Vector3D(d[0], d[1], d[2]),
413 new Vector3D(d[3], d[4], d[5]),
414 new Vector3D(d[6], d[7], d[8]));
415 }
416
417 }
418
419 }