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