1 /* Copyright 2002-2021 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.utils;
18
19 import java.util.Collection;
20 import java.util.stream.Stream;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.analysis.differentiation.FieldDerivative;
24 import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
25 import org.hipparchus.analysis.interpolation.FieldHermiteInterpolator;
26 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
27 import org.orekit.annotation.DefaultDataContext;
28 import org.orekit.data.DataContext;
29 import org.orekit.errors.OrekitInternalError;
30 import org.orekit.time.AbsoluteDate;
31 import org.orekit.time.FieldAbsoluteDate;
32 import org.orekit.time.FieldTimeStamped;
33 import org.orekit.time.TimeScale;
34 import org.orekit.time.TimeStamped;
35
36 /** {@link TimeStamped time-stamped} version of {@link FieldPVCoordinates}.
37 * <p>Instances of this class are guaranteed to be immutable.</p>
38 * @param <T> the type of the field elements
39 * @author Luc Maisonobe
40 * @since 7.0
41 */
42 public class TimeStampedFieldPVCoordinates<T extends CalculusFieldElement<T>>
43 extends FieldPVCoordinates<T> implements FieldTimeStamped<T> {
44
45 /** The date. */
46 private final FieldAbsoluteDate<T> date;
47
48 /** Builds a PVCoordinates pair.
49 * @param date coordinates date
50 * @param position the position vector (m)
51 * @param velocity the velocity vector (m/s)
52 * @param acceleration the acceleration vector (m/s²)
53 */
54 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
55 final FieldVector3D<T> position,
56 final FieldVector3D<T> velocity,
57 final FieldVector3D<T> acceleration) {
58 this(new FieldAbsoluteDate<>(position.getX().getField(), date),
59 position, velocity, acceleration);
60 }
61
62 /** Builds a PVCoordinates pair.
63 * @param date coordinates date
64 * @param position the position vector (m)
65 * @param velocity the velocity vector (m/s)
66 * @param acceleration the acceleration vector (m/s²)
67 */
68 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
69 final FieldVector3D<T> position,
70 final FieldVector3D<T> velocity,
71 final FieldVector3D<T> acceleration) {
72 super(position, velocity, acceleration);
73 this.date = date;
74 }
75
76 /** Basic constructor.
77 * <p>Build a PVCoordinates from another one at a given date</p>
78 * <p>The PVCoordinates built will be pv</p>
79 * @param date date of the built coordinates
80 * @param pv base (unscaled) PVCoordinates
81 */
82 public TimeStampedFieldPVCoordinates(final AbsoluteDate date, final FieldPVCoordinates<T> pv) {
83 this(new FieldAbsoluteDate<>(pv.getPosition().getX().getField(), date), pv);
84 }
85
86 /** Basic constructor.
87 * <p>Build a PVCoordinates from another one at a given date</p>
88 * <p>The PVCoordinates built will be pv</p>
89 * @param date date of the built coordinates
90 * @param pv base (unscaled) PVCoordinates
91 */
92 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date, final FieldPVCoordinates<T> pv) {
93 super(pv.getPosition(),
94 pv.getVelocity(),
95 pv.getAcceleration());
96 this.date = date;
97 }
98
99 /** Multiplicative constructor
100 * <p>Build a PVCoordinates from another one and a scale factor.</p>
101 * <p>The PVCoordinates built will be a * pv</p>
102 * @param date date of the built coordinates
103 * @param a scale factor
104 * @param pv base (unscaled) PVCoordinates
105 */
106 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
107 final double a, final FieldPVCoordinates<T> pv) {
108 this(new FieldAbsoluteDate<>(pv.getPosition().getX().getField(), date), a, pv);
109 }
110
111 /** Multiplicative constructor
112 * <p>Build a PVCoordinates from another one and a scale factor.</p>
113 * <p>The PVCoordinates built will be a * pv</p>
114 * @param date date of the built coordinates
115 * @param a scale factor
116 * @param pv base (unscaled) PVCoordinates
117 */
118 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
119 final double a, final FieldPVCoordinates<T> pv) {
120 super(new FieldVector3D<>(a, pv.getPosition()),
121 new FieldVector3D<>(a, pv.getVelocity()),
122 new FieldVector3D<>(a, pv.getAcceleration()));
123 this.date = date;
124 }
125
126 /** Multiplicative constructor
127 * <p>Build a PVCoordinates from another one and a scale factor.</p>
128 * <p>The PVCoordinates built will be a * pv</p>
129 * @param date date of the built coordinates
130 * @param a scale factor
131 * @param pv base (unscaled) PVCoordinates
132 */
133 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
134 final T a, final FieldPVCoordinates<T> pv) {
135 this(new FieldAbsoluteDate<>(a.getField(), date), a, pv);
136 }
137
138 /** Multiplicative constructor
139 * <p>Build a PVCoordinates from another one and a scale factor.</p>
140 * <p>The PVCoordinates built will be a * pv</p>
141 * @param date date of the built coordinates
142 * @param a scale factor
143 * @param pv base (unscaled) PVCoordinates
144 */
145 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
146 final T a, final FieldPVCoordinates<T> pv) {
147 super(new FieldVector3D<>(a, pv.getPosition()),
148 new FieldVector3D<>(a, pv.getVelocity()),
149 new FieldVector3D<>(a, pv.getAcceleration()));
150 this.date = date;
151 }
152
153 /** Multiplicative constructor
154 * <p>Build a PVCoordinates from another one and a scale factor.</p>
155 * <p>The PVCoordinates built will be a * pv</p>
156 * @param date date of the built coordinates
157 * @param a scale factor
158 * @param pv base (unscaled) PVCoordinates
159 */
160 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
161 final T a, final PVCoordinates pv) {
162 this(new FieldAbsoluteDate<>(a.getField(), date), a, pv);
163 }
164
165 /** Multiplicative constructor
166 * <p>Build a PVCoordinates from another one and a scale factor.</p>
167 * <p>The PVCoordinates built will be a * pv</p>
168 * @param date date of the built coordinates
169 * @param a scale factor
170 * @param pv base (unscaled) PVCoordinates
171 */
172 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
173 final T a, final PVCoordinates pv) {
174 super(new FieldVector3D<>(a, pv.getPosition()),
175 new FieldVector3D<>(a, pv.getVelocity()),
176 new FieldVector3D<>(a, pv.getAcceleration()));
177 this.date = date;
178 }
179
180 /** Subtractive constructor
181 * <p>Build a relative PVCoordinates from a start and an end position.</p>
182 * <p>The PVCoordinates built will be end - start.</p>
183 * @param date date of the built coordinates
184 * @param start Starting PVCoordinates
185 * @param end ending PVCoordinates
186 */
187 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
188 final FieldPVCoordinates<T> start, final FieldPVCoordinates<T> end) {
189 this(new FieldAbsoluteDate<>(start.getPosition().getX().getField(), date), start, end);
190 }
191
192 /** Subtractive constructor
193 * <p>Build a relative PVCoordinates from a start and an end position.</p>
194 * <p>The PVCoordinates built will be end - start.</p>
195 * @param date date of the built coordinates
196 * @param start Starting PVCoordinates
197 * @param end ending PVCoordinates
198 */
199 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
200 final FieldPVCoordinates<T> start, final FieldPVCoordinates<T> end) {
201 super(end.getPosition().subtract(start.getPosition()),
202 end.getVelocity().subtract(start.getVelocity()),
203 end.getAcceleration().subtract(start.getAcceleration()));
204 this.date = date;
205 }
206
207 /** Linear constructor
208 * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
209 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
210 * @param date date of the built coordinates
211 * @param a1 first scale factor
212 * @param pv1 first base (unscaled) PVCoordinates
213 * @param a2 second scale factor
214 * @param pv2 second base (unscaled) PVCoordinates
215 */
216 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
217 final double a1, final FieldPVCoordinates<T> pv1,
218 final double a2, final FieldPVCoordinates<T> pv2) {
219 this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
220 a1, pv1, a2, pv2);
221 }
222
223 /** Linear constructor
224 * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
225 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
226 * @param date date of the built coordinates
227 * @param a1 first scale factor
228 * @param pv1 first base (unscaled) PVCoordinates
229 * @param a2 second scale factor
230 * @param pv2 second base (unscaled) PVCoordinates
231 */
232 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
233 final double a1, final FieldPVCoordinates<T> pv1,
234 final double a2, final FieldPVCoordinates<T> pv2) {
235 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition()),
236 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity()),
237 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
238 this.date = date;
239 }
240
241 /** Linear constructor
242 * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
243 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
244 * @param date date of the built coordinates
245 * @param a1 first scale factor
246 * @param pv1 first base (unscaled) PVCoordinates
247 * @param a2 second scale factor
248 * @param pv2 second base (unscaled) PVCoordinates
249 */
250 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
251 final T a1, final FieldPVCoordinates<T> pv1,
252 final T a2, final FieldPVCoordinates<T> pv2) {
253 this(new FieldAbsoluteDate<>(a1.getField(), date),
254 a1, pv1, a2, pv2);
255 }
256
257 /** Linear constructor
258 * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
259 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
260 * @param date date of the built coordinates
261 * @param a1 first scale factor
262 * @param pv1 first base (unscaled) PVCoordinates
263 * @param a2 second scale factor
264 * @param pv2 second base (unscaled) PVCoordinates
265 */
266 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
267 final T a1, final FieldPVCoordinates<T> pv1,
268 final T a2, final FieldPVCoordinates<T> pv2) {
269 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition()),
270 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity()),
271 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
272 this.date = date;
273 }
274
275 /** Linear constructor
276 * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
277 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
278 * @param date date of the built coordinates
279 * @param a1 first scale factor
280 * @param pv1 first base (unscaled) PVCoordinates
281 * @param a2 second scale factor
282 * @param pv2 second base (unscaled) PVCoordinates
283 */
284 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
285 final T a1, final PVCoordinates pv1,
286 final T a2, final PVCoordinates pv2) {
287 this(new FieldAbsoluteDate<>(a1.getField(), date),
288 a1, pv1, a2, pv2);
289 }
290
291 /** Linear constructor
292 * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
293 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
294 * @param date date of the built coordinates
295 * @param a1 first scale factor
296 * @param pv1 first base (unscaled) PVCoordinates
297 * @param a2 second scale factor
298 * @param pv2 second base (unscaled) PVCoordinates
299 */
300 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
301 final T a1, final PVCoordinates pv1,
302 final T a2, final PVCoordinates pv2) {
303 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition()),
304 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity()),
305 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
306 this.date = date;
307 }
308
309 /** Linear constructor
310 * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
311 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
312 * @param date date of the built coordinates
313 * @param a1 first scale factor
314 * @param pv1 first base (unscaled) PVCoordinates
315 * @param a2 second scale factor
316 * @param pv2 second base (unscaled) PVCoordinates
317 * @param a3 third scale factor
318 * @param pv3 third base (unscaled) PVCoordinates
319 */
320 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
321 final double a1, final FieldPVCoordinates<T> pv1,
322 final double a2, final FieldPVCoordinates<T> pv2,
323 final double a3, final FieldPVCoordinates<T> pv3) {
324 this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
325 a1, pv1, a2, pv2, a3, pv3);
326 }
327
328 /** Linear constructor
329 * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
330 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
331 * @param date date of the built coordinates
332 * @param a1 first scale factor
333 * @param pv1 first base (unscaled) PVCoordinates
334 * @param a2 second scale factor
335 * @param pv2 second base (unscaled) PVCoordinates
336 * @param a3 third scale factor
337 * @param pv3 third base (unscaled) PVCoordinates
338 */
339 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
340 final double a1, final FieldPVCoordinates<T> pv1,
341 final double a2, final FieldPVCoordinates<T> pv2,
342 final double a3, final FieldPVCoordinates<T> pv3) {
343 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition(), a3, pv3.getPosition()),
344 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity(), a3, pv3.getVelocity()),
345 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
346 this.date = date;
347 }
348
349 /** Linear constructor
350 * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
351 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
352 * @param date date of the built coordinates
353 * @param a1 first scale factor
354 * @param pv1 first base (unscaled) PVCoordinates
355 * @param a2 second scale factor
356 * @param pv2 second base (unscaled) PVCoordinates
357 * @param a3 third scale factor
358 * @param pv3 third base (unscaled) PVCoordinates
359 */
360 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
361 final T a1, final FieldPVCoordinates<T> pv1,
362 final T a2, final FieldPVCoordinates<T> pv2,
363 final T a3, final FieldPVCoordinates<T> pv3) {
364 this(new FieldAbsoluteDate<>(a1.getField(), date),
365 a1, pv1, a2, pv2, a3, pv3);
366 }
367
368 /** Linear constructor
369 * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
370 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
371 * @param date date of the built coordinates
372 * @param a1 first scale factor
373 * @param pv1 first base (unscaled) PVCoordinates
374 * @param a2 second scale factor
375 * @param pv2 second base (unscaled) PVCoordinates
376 * @param a3 third scale factor
377 * @param pv3 third base (unscaled) PVCoordinates
378 */
379 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
380 final T a1, final FieldPVCoordinates<T> pv1,
381 final T a2, final FieldPVCoordinates<T> pv2,
382 final T a3, final FieldPVCoordinates<T> pv3) {
383 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition(), a3, pv3.getPosition()),
384 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity(), a3, pv3.getVelocity()),
385 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
386 this.date = date;
387 }
388
389 /** Linear constructor
390 * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
391 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
392 * @param date date of the built coordinates
393 * @param a1 first scale factor
394 * @param pv1 first base (unscaled) PVCoordinates
395 * @param a2 second scale factor
396 * @param pv2 second base (unscaled) PVCoordinates
397 * @param a3 third scale factor
398 * @param pv3 third base (unscaled) PVCoordinates
399 */
400 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
401 final T a1, final PVCoordinates pv1,
402 final T a2, final PVCoordinates pv2,
403 final T a3, final PVCoordinates pv3) {
404 this(new FieldAbsoluteDate<>(a1.getField(), date),
405 a1, pv1, a2, pv2, a3, pv3);
406 }
407
408 /** Linear constructor
409 * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
410 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
411 * @param date date of the built coordinates
412 * @param a1 first scale factor
413 * @param pv1 first base (unscaled) PVCoordinates
414 * @param a2 second scale factor
415 * @param pv2 second base (unscaled) PVCoordinates
416 * @param a3 third scale factor
417 * @param pv3 third base (unscaled) PVCoordinates
418 */
419 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
420 final T a1, final PVCoordinates pv1,
421 final T a2, final PVCoordinates pv2,
422 final T a3, final PVCoordinates pv3) {
423 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition(), a3, pv3.getPosition()),
424 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity(), a3, pv3.getVelocity()),
425 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
426 this.date = date;
427 }
428
429 /** Linear constructor
430 * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
431 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
432 * @param date date of the built coordinates
433 * @param a1 first scale factor
434 * @param pv1 first base (unscaled) PVCoordinates
435 * @param a2 second scale factor
436 * @param pv2 second base (unscaled) PVCoordinates
437 * @param a3 third scale factor
438 * @param pv3 third base (unscaled) PVCoordinates
439 * @param a4 fourth scale factor
440 * @param pv4 fourth base (unscaled) PVCoordinates
441 */
442 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
443 final double a1, final FieldPVCoordinates<T> pv1,
444 final double a2, final FieldPVCoordinates<T> pv2,
445 final double a3, final FieldPVCoordinates<T> pv3,
446 final double a4, final FieldPVCoordinates<T> pv4) {
447 this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
448 a1, pv1, a2, pv2, a3, pv3, a4, pv4);
449 }
450
451 /** Linear constructor
452 * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
453 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
454 * @param date date of the built coordinates
455 * @param a1 first scale factor
456 * @param pv1 first base (unscaled) PVCoordinates
457 * @param a2 second scale factor
458 * @param pv2 second base (unscaled) PVCoordinates
459 * @param a3 third scale factor
460 * @param pv3 third base (unscaled) PVCoordinates
461 * @param a4 fourth scale factor
462 * @param pv4 fourth base (unscaled) PVCoordinates
463 */
464 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
465 final double a1, final FieldPVCoordinates<T> pv1,
466 final double a2, final FieldPVCoordinates<T> pv2,
467 final double a3, final FieldPVCoordinates<T> pv3,
468 final double a4, final FieldPVCoordinates<T> pv4) {
469 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition(),
470 a3, pv3.getPosition(), a4, pv4.getPosition()),
471 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity(),
472 a3, pv3.getVelocity(), a4, pv4.getVelocity()),
473 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
474 a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
475 this.date = date;
476 }
477
478 /** Linear constructor
479 * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
480 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
481 * @param date date of the built coordinates
482 * @param a1 first scale factor
483 * @param pv1 first base (unscaled) PVCoordinates
484 * @param a2 second scale factor
485 * @param pv2 second base (unscaled) PVCoordinates
486 * @param a3 third scale factor
487 * @param pv3 third base (unscaled) PVCoordinates
488 * @param a4 fourth scale factor
489 * @param pv4 fourth base (unscaled) PVCoordinates
490 */
491 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
492 final T a1, final FieldPVCoordinates<T> pv1,
493 final T a2, final FieldPVCoordinates<T> pv2,
494 final T a3, final FieldPVCoordinates<T> pv3,
495 final T a4, final FieldPVCoordinates<T> pv4) {
496 this(new FieldAbsoluteDate<>(a1.getField(), date),
497 a1, pv1, a2, pv2, a3, pv3, a4, pv4);
498 }
499
500 /** Linear constructor
501 * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
502 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
503 * @param date date of the built coordinates
504 * @param a1 first scale factor
505 * @param pv1 first base (unscaled) PVCoordinates
506 * @param a2 second scale factor
507 * @param pv2 second base (unscaled) PVCoordinates
508 * @param a3 third scale factor
509 * @param pv3 third base (unscaled) PVCoordinates
510 * @param a4 fourth scale factor
511 * @param pv4 fourth base (unscaled) PVCoordinates
512 */
513 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
514 final T a1, final FieldPVCoordinates<T> pv1,
515 final T a2, final FieldPVCoordinates<T> pv2,
516 final T a3, final FieldPVCoordinates<T> pv3,
517 final T a4, final FieldPVCoordinates<T> pv4) {
518 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition(),
519 a3, pv3.getPosition(), a4, pv4.getPosition()),
520 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity(),
521 a3, pv3.getVelocity(), a4, pv4.getVelocity()),
522 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
523 a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
524 this.date = date;
525 }
526
527 /** Linear constructor
528 * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
529 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
530 * @param date date of the built coordinates
531 * @param a1 first scale factor
532 * @param pv1 first base (unscaled) PVCoordinates
533 * @param a2 second scale factor
534 * @param pv2 second base (unscaled) PVCoordinates
535 * @param a3 third scale factor
536 * @param pv3 third base (unscaled) PVCoordinates
537 * @param a4 fourth scale factor
538 * @param pv4 fourth base (unscaled) PVCoordinates
539 */
540 public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
541 final T a1, final PVCoordinates pv1,
542 final T a2, final PVCoordinates pv2,
543 final T a3, final PVCoordinates pv3,
544 final T a4, final PVCoordinates pv4) {
545 this(new FieldAbsoluteDate<>(a1.getField(), date),
546 a1, pv1, a2, pv2, a3, pv3, a4, pv4);
547 }
548
549 /** Linear constructor
550 * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
551 * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
552 * @param date date of the built coordinates
553 * @param a1 first scale factor
554 * @param pv1 first base (unscaled) PVCoordinates
555 * @param a2 second scale factor
556 * @param pv2 second base (unscaled) PVCoordinates
557 * @param a3 third scale factor
558 * @param pv3 third base (unscaled) PVCoordinates
559 * @param a4 fourth scale factor
560 * @param pv4 fourth base (unscaled) PVCoordinates
561 */
562 public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
563 final T a1, final PVCoordinates pv1,
564 final T a2, final PVCoordinates pv2,
565 final T a3, final PVCoordinates pv3,
566 final T a4, final PVCoordinates pv4) {
567 super(new FieldVector3D<>(a1, pv1.getPosition(), a2, pv2.getPosition(),
568 a3, pv3.getPosition(), a4, pv4.getPosition()),
569 new FieldVector3D<>(a1, pv1.getVelocity(), a2, pv2.getVelocity(),
570 a3, pv3.getVelocity(), a4, pv4.getVelocity()),
571 new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
572 a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
573 this.date = date;
574 }
575
576 /** Builds a TimeStampedFieldPVCoordinates triplet from a {@link FieldVector3D}<{@link FieldDerivativeStructure}>.
577 * <p>
578 * The vector components must have time as their only derivation parameter and
579 * have consistent derivation orders.
580 * </p>
581 * @param date date of the built coordinates
582 * @param <U> type of the derivative
583 * @param p vector with time-derivatives embedded within the coordinates
584 */
585 public <U extends FieldDerivative<T, U>> TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
586 final FieldVector3D<U> p) {
587 super(p);
588 this.date = date;
589 }
590
591 /** {@inheritDoc} */
592 @Override
593 public FieldAbsoluteDate<T> getDate() {
594 return date;
595 }
596
597 /** Get a time-shifted state.
598 * <p>
599 * The state can be slightly shifted to close dates. This shift is based on
600 * a simple linear model. It is <em>not</em> intended as a replacement for
601 * proper orbit propagation (it is not even Keplerian!) but should be sufficient
602 * for either small time shifts or coarse accuracy.
603 * </p>
604 * @param dt time shift in seconds
605 * @return a new state, shifted with respect to the instance (which is immutable)
606 */
607 public TimeStampedFieldPVCoordinates<T> shiftedBy(final double dt) {
608 final FieldPVCoordinates<T> spv = super.shiftedBy(dt);
609 return new TimeStampedFieldPVCoordinates<>(date.shiftedBy(dt),
610 spv.getPosition(), spv.getVelocity(), spv.getAcceleration());
611 }
612
613 /** Get a time-shifted state.
614 * <p>
615 * The state can be slightly shifted to close dates. This shift is based on
616 * a simple linear model. It is <em>not</em> intended as a replacement for
617 * proper orbit propagation (it is not even Keplerian!) but should be sufficient
618 * for either small time shifts or coarse accuracy.
619 * </p>
620 * @param dt time shift in seconds
621 * @return a new state, shifted with respect to the instance (which is immutable)
622 */
623 public TimeStampedFieldPVCoordinates<T> shiftedBy(final T dt) {
624 final FieldPVCoordinates<T> spv = super.shiftedBy(dt);
625 return new TimeStampedFieldPVCoordinates<>(date.shiftedBy(dt),
626 spv.getPosition(), spv.getVelocity(), spv.getAcceleration());
627 }
628
629 /** Interpolate position-velocity.
630 * <p>
631 * The interpolated instance is created by polynomial Hermite interpolation
632 * ensuring velocity remains the exact derivative of position.
633 * </p>
634 * <p>
635 * Note that even if first time derivatives (velocities)
636 * from sample can be ignored, the interpolated instance always includes
637 * interpolated derivatives. This feature can be used explicitly to
638 * compute these derivatives when it would be too complex to compute them
639 * from an analytical formula: just compute a few sample points from the
640 * explicit formula and set the derivatives to zero in these sample points,
641 * then use interpolation to add derivatives consistent with the positions.
642 * </p>
643 * @param date interpolation date
644 * @param filter filter for derivatives from the sample to use in interpolation
645 * @param sample sample points on which interpolation should be done
646 * @param <T> the type of the field elements
647 * @return a new position-velocity, interpolated at specified date
648 */
649 public static <T extends CalculusFieldElement<T>>
650 TimeStampedFieldPVCoordinates<T> interpolate(final FieldAbsoluteDate<T> date,
651 final CartesianDerivativesFilter filter,
652 final Collection<TimeStampedFieldPVCoordinates<T>> sample) {
653 return interpolate(date, filter, sample.stream());
654 }
655
656 /** Interpolate position-velocity.
657 * <p>
658 * The interpolated instance is created by polynomial Hermite interpolation
659 * ensuring velocity remains the exact derivative of position.
660 * </p>
661 * <p>
662 * Note that even if first time derivatives (velocities)
663 * from sample can be ignored, the interpolated instance always includes
664 * interpolated derivatives. This feature can be used explicitly to
665 * compute these derivatives when it would be too complex to compute them
666 * from an analytical formula: just compute a few sample points from the
667 * explicit formula and set the derivatives to zero in these sample points,
668 * then use interpolation to add derivatives consistent with the positions.
669 * </p>
670 * @param date interpolation date
671 * @param filter filter for derivatives from the sample to use in interpolation
672 * @param sample sample points on which interpolation should be done
673 * @param <T> the type of the field elements
674 * @return a new position-velocity, interpolated at specified date
675 */
676 public static <T extends CalculusFieldElement<T>>
677 TimeStampedFieldPVCoordinates<T> interpolate(final FieldAbsoluteDate<T> date,
678 final CartesianDerivativesFilter filter,
679 final Stream<TimeStampedFieldPVCoordinates<T>> sample) {
680
681 // set up an interpolator taking derivatives into account
682 final FieldHermiteInterpolator<T> interpolator = new FieldHermiteInterpolator<>();
683
684 // add sample points
685 switch (filter) {
686 case USE_P :
687 // populate sample with position data, ignoring velocity
688 sample.forEach(pv -> {
689 final FieldVector3D<T> position = pv.getPosition();
690 interpolator.addSamplePoint(pv.getDate().durationFrom(date),
691 position.toArray());
692 });
693 break;
694 case USE_PV :
695 // populate sample with position and velocity data
696 sample.forEach(pv -> {
697 final FieldVector3D<T> position = pv.getPosition();
698 final FieldVector3D<T> velocity = pv.getVelocity();
699 interpolator.addSamplePoint(pv.getDate().durationFrom(date),
700 position.toArray(), velocity.toArray());
701 });
702 break;
703 case USE_PVA :
704 // populate sample with position, velocity and acceleration data
705 sample.forEach(pv -> {
706 final FieldVector3D<T> position = pv.getPosition();
707 final FieldVector3D<T> velocity = pv.getVelocity();
708 final FieldVector3D<T> acceleration = pv.getAcceleration();
709 interpolator.addSamplePoint(pv.getDate().durationFrom(date),
710 position.toArray(), velocity.toArray(), acceleration.toArray());
711 });
712 break;
713 default :
714 // this should never happen
715 throw new OrekitInternalError(null);
716 }
717
718 // interpolate
719 final T[][] p = interpolator.derivatives(date.getField().getZero(), 2);
720
721 // build a new interpolated instance
722
723 return new TimeStampedFieldPVCoordinates<>(date,
724 new FieldVector3D<>(p[0]),
725 new FieldVector3D<>(p[1]),
726 new FieldVector3D<>(p[2]));
727
728 }
729
730 /** Convert to a constant position-velocity.
731 * @return a constant position-velocity
732 * @since 9.0
733 */
734 public TimeStampedPVCoordinates toTimeStampedPVCoordinates() {
735 return new TimeStampedPVCoordinates(date.toAbsoluteDate(),
736 getPosition().toVector3D(),
737 getVelocity().toVector3D(),
738 getAcceleration().toVector3D());
739 }
740
741 /** Return a string representation of this date, position, velocity, and acceleration.
742 *
743 * <p>This method uses the {@link DataContext#getDefault() default data context}.
744 *
745 * @return string representation of this.
746 */
747 @Override
748 @DefaultDataContext
749 public String toString() {
750 return toTimeStampedPVCoordinates().toString();
751 }
752
753 /**
754 * Return a string representation of this date, position, velocity, and acceleration.
755 *
756 * @param utc time scale used to print the date.
757 * @return string representation of this.
758 */
759 public String toString(final TimeScale utc) {
760 return toTimeStampedPVCoordinates().toString(utc);
761 }
762
763 }