1   /* Copyright 2002-2025 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 org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.analysis.differentiation.FieldDerivative;
22  import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
23  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24  import org.orekit.annotation.DefaultDataContext;
25  import org.orekit.data.DataContext;
26  import org.orekit.time.AbsoluteDate;
27  import org.orekit.time.FieldAbsoluteDate;
28  import org.orekit.time.FieldTimeStamped;
29  import org.orekit.time.TimeScale;
30  import org.orekit.time.TimeStamped;
31  
32  /** {@link TimeStamped time-stamped} version of {@link FieldPVCoordinates}.
33   * <p>Instances of this class are guaranteed to be immutable.</p>
34   * @param <T> the type of the field elements
35   * @author Luc Maisonobe
36   * @since 7.0
37   */
38  public class TimeStampedFieldPVCoordinates<T extends CalculusFieldElement<T>>
39      extends FieldPVCoordinates<T> implements FieldTimeStamped<T> {
40  
41      /** The date. */
42      private final FieldAbsoluteDate<T> date;
43  
44      /** Builds a PVCoordinates pair.
45       * @param date coordinates date
46       * @param position the position vector (m)
47       * @param velocity the velocity vector (m/s)
48       * @param acceleration the acceleration vector (m/s²)
49       */
50      public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
51                                           final FieldVector3D<T> position,
52                                           final FieldVector3D<T> velocity,
53                                           final FieldVector3D<T> acceleration) {
54          this(new FieldAbsoluteDate<>(position.getX().getField(), date),
55               position, velocity, acceleration);
56      }
57  
58      /** Builds a PVCoordinates pair.
59       * @param date coordinates date
60       * @param position the position vector (m)
61       * @param velocity the velocity vector (m/s)
62       * @param acceleration the acceleration vector (m/s²)
63       */
64      public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
65                                           final FieldVector3D<T> position,
66                                           final FieldVector3D<T> velocity,
67                                           final FieldVector3D<T> acceleration) {
68          super(position, velocity, acceleration);
69          this.date = date;
70      }
71  
72      /** Basic constructor.
73       * <p>Build a PVCoordinates from another one at a given date</p>
74       * <p>The PVCoordinates built will be pv</p>
75       * @param date date of the built coordinates
76       * @param pv base (unscaled) PVCoordinates
77       */
78      public TimeStampedFieldPVCoordinates(final AbsoluteDate date, final FieldPVCoordinates<T> pv) {
79          this(new FieldAbsoluteDate<>(pv.getPosition().getX().getField(), date), pv);
80      }
81  
82      /** Basic constructor.
83       * <p>Build a PVCoordinates from another one at a given date</p>
84       * <p>The PVCoordinates built will be pv</p>
85       * @param date date of the built coordinates
86       * @param pv base (unscaled) PVCoordinates
87       */
88      public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date, final FieldPVCoordinates<T> pv) {
89          super(pv.getPosition(),
90                pv.getVelocity(),
91                pv.getAcceleration());
92          this.date = date;
93      }
94  
95      /** Constructor from Field and TimeStampedPVCoordinates.
96       * <p>Build a TimeStampedFieldPVCoordinates from non-Field one.</p>
97       * @param field CalculusField to base object on
98       * @param pv non-field, time-stamped Position-Velocity coordinates
99       */
100     public TimeStampedFieldPVCoordinates(final Field<T> field, final TimeStampedPVCoordinates pv) {
101         this(pv.getDate(), new FieldPVCoordinates<>(field, pv));
102     }
103 
104     /** Multiplicative constructor
105      * <p>Build a PVCoordinates from another one and a scale factor.</p>
106      * <p>The PVCoordinates built will be a * pv</p>
107      * @param date date of the built coordinates
108      * @param a scale factor
109      * @param pv base (unscaled) PVCoordinates
110      */
111     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
112                                          final double a, final FieldPVCoordinates<T> pv) {
113         this(new FieldAbsoluteDate<>(pv.getPosition().getX().getField(), date), a, pv);
114     }
115 
116     /** Multiplicative constructor
117      * <p>Build a PVCoordinates from another one and a scale factor.</p>
118      * <p>The PVCoordinates built will be a * pv</p>
119      * @param date date of the built coordinates
120      * @param a scale factor
121      * @param pv base (unscaled) PVCoordinates
122      */
123     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
124                                          final double a, final FieldPVCoordinates<T> pv) {
125         super(new FieldVector3D<>(a, pv.getPosition()),
126               new FieldVector3D<>(a, pv.getVelocity()),
127               new FieldVector3D<>(a, pv.getAcceleration()));
128         this.date = date;
129     }
130 
131     /** Multiplicative constructor
132      * <p>Build a PVCoordinates from another one and a scale factor.</p>
133      * <p>The PVCoordinates built will be a * pv</p>
134      * @param date date of the built coordinates
135      * @param a scale factor
136      * @param pv base (unscaled) PVCoordinates
137      */
138     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
139                                          final T a, final FieldPVCoordinates<T> pv) {
140         this(new FieldAbsoluteDate<>(a.getField(), date), a, pv);
141     }
142 
143     /** Multiplicative constructor
144      * <p>Build a PVCoordinates from another one and a scale factor.</p>
145      * <p>The PVCoordinates built will be a * pv</p>
146      * @param date date of the built coordinates
147      * @param a scale factor
148      * @param pv base (unscaled) PVCoordinates
149      */
150     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
151                                          final T a, final FieldPVCoordinates<T> pv) {
152         super(new FieldVector3D<>(a, pv.getPosition()),
153               new FieldVector3D<>(a, pv.getVelocity()),
154               new FieldVector3D<>(a, pv.getAcceleration()));
155         this.date = date;
156     }
157 
158     /** Multiplicative constructor
159      * <p>Build a PVCoordinates from another one and a scale factor.</p>
160      * <p>The PVCoordinates built will be a * pv</p>
161      * @param date date of the built coordinates
162      * @param a scale factor
163      * @param pv base (unscaled) PVCoordinates
164      */
165     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
166                                          final T a, final PVCoordinates pv) {
167         this(new FieldAbsoluteDate<>(a.getField(), date), a, pv);
168     }
169 
170     /** Multiplicative constructor
171      * <p>Build a PVCoordinates from another one and a scale factor.</p>
172      * <p>The PVCoordinates built will be a * pv</p>
173      * @param date date of the built coordinates
174      * @param a scale factor
175      * @param pv base (unscaled) PVCoordinates
176      */
177     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
178                                          final T a, final PVCoordinates pv) {
179         super(new FieldVector3D<>(a, pv.getPosition()),
180               new FieldVector3D<>(a, pv.getVelocity()),
181               new FieldVector3D<>(a, pv.getAcceleration()));
182         this.date = date;
183     }
184 
185     /** Subtractive constructor
186      * <p>Build a relative PVCoordinates from a start and an end position.</p>
187      * <p>The PVCoordinates built will be end - start.</p>
188      * @param date date of the built coordinates
189      * @param start Starting PVCoordinates
190      * @param end ending PVCoordinates
191      */
192     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
193                                          final FieldPVCoordinates<T> start, final FieldPVCoordinates<T> end) {
194         this(new FieldAbsoluteDate<>(start.getPosition().getX().getField(), date), start, end);
195     }
196 
197     /** Subtractive constructor
198      * <p>Build a relative PVCoordinates from a start and an end position.</p>
199      * <p>The PVCoordinates built will be end - start.</p>
200      * @param date date of the built coordinates
201      * @param start Starting PVCoordinates
202      * @param end ending PVCoordinates
203      */
204     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
205                                          final FieldPVCoordinates<T> start, final FieldPVCoordinates<T> end) {
206         super(end.getPosition().subtract(start.getPosition()),
207               end.getVelocity().subtract(start.getVelocity()),
208               end.getAcceleration().subtract(start.getAcceleration()));
209         this.date = date;
210     }
211 
212     /** Linear constructor
213      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
214      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
215      * @param date date of the built coordinates
216      * @param a1 first scale factor
217      * @param pv1 first base (unscaled) PVCoordinates
218      * @param a2 second scale factor
219      * @param pv2 second base (unscaled) PVCoordinates
220      */
221     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
222                                          final double a1, final FieldPVCoordinates<T> pv1,
223                                          final double a2, final FieldPVCoordinates<T> pv2) {
224         this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
225              a1, pv1, a2, pv2);
226     }
227 
228     /** Linear constructor
229      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
230      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
231      * @param date date of the built coordinates
232      * @param a1 first scale factor
233      * @param pv1 first base (unscaled) PVCoordinates
234      * @param a2 second scale factor
235      * @param pv2 second base (unscaled) PVCoordinates
236      */
237     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
238                                          final double a1, final FieldPVCoordinates<T> pv1,
239                                          final double a2, final FieldPVCoordinates<T> pv2) {
240         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition()),
241               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity()),
242               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
243         this.date = date;
244     }
245 
246     /** Linear constructor
247      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
248      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
249      * @param date date of the built coordinates
250      * @param a1 first scale factor
251      * @param pv1 first base (unscaled) PVCoordinates
252      * @param a2 second scale factor
253      * @param pv2 second base (unscaled) PVCoordinates
254      */
255     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
256                                          final T a1, final FieldPVCoordinates<T> pv1,
257                                          final T a2, final FieldPVCoordinates<T> pv2) {
258         this(new FieldAbsoluteDate<>(a1.getField(), date),
259              a1, pv1, a2, pv2);
260     }
261 
262     /** Linear constructor
263      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
264      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
265      * @param date date of the built coordinates
266      * @param a1 first scale factor
267      * @param pv1 first base (unscaled) PVCoordinates
268      * @param a2 second scale factor
269      * @param pv2 second base (unscaled) PVCoordinates
270      */
271     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
272                                          final T a1, final FieldPVCoordinates<T> pv1,
273                                          final T a2, final FieldPVCoordinates<T> pv2) {
274         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition()),
275               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity()),
276               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
277         this.date = date;
278     }
279 
280     /** Linear constructor
281      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
282      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
283      * @param date date of the built coordinates
284      * @param a1 first scale factor
285      * @param pv1 first base (unscaled) PVCoordinates
286      * @param a2 second scale factor
287      * @param pv2 second base (unscaled) PVCoordinates
288      */
289     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
290                                          final T a1, final PVCoordinates pv1,
291                                          final T a2, final PVCoordinates pv2) {
292         this(new FieldAbsoluteDate<>(a1.getField(), date),
293              a1, pv1, a2, pv2);
294     }
295 
296     /** Linear constructor
297      * <p>Build a PVCoordinates from two other ones and corresponding scale factors.</p>
298      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2</p>
299      * @param date date of the built coordinates
300      * @param a1 first scale factor
301      * @param pv1 first base (unscaled) PVCoordinates
302      * @param a2 second scale factor
303      * @param pv2 second base (unscaled) PVCoordinates
304      */
305     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
306                                          final T a1, final PVCoordinates pv1,
307                                          final T a2, final PVCoordinates pv2) {
308         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition()),
309               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity()),
310               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration()));
311         this.date = date;
312     }
313 
314     /** Linear constructor
315      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
316      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
317      * @param date date of the built coordinates
318      * @param a1 first scale factor
319      * @param pv1 first base (unscaled) PVCoordinates
320      * @param a2 second scale factor
321      * @param pv2 second base (unscaled) PVCoordinates
322      * @param a3 third scale factor
323      * @param pv3 third base (unscaled) PVCoordinates
324      */
325     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
326                                          final double a1, final FieldPVCoordinates<T> pv1,
327                                          final double a2, final FieldPVCoordinates<T> pv2,
328                                          final double a3, final FieldPVCoordinates<T> pv3) {
329         this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
330              a1, pv1, a2, pv2, a3, pv3);
331     }
332 
333     /** Linear constructor
334      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
335      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
336      * @param date date of the built coordinates
337      * @param a1 first scale factor
338      * @param pv1 first base (unscaled) PVCoordinates
339      * @param a2 second scale factor
340      * @param pv2 second base (unscaled) PVCoordinates
341      * @param a3 third scale factor
342      * @param pv3 third base (unscaled) PVCoordinates
343      */
344     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
345                                          final double a1, final FieldPVCoordinates<T> pv1,
346                                          final double a2, final FieldPVCoordinates<T> pv2,
347                                          final double a3, final FieldPVCoordinates<T> pv3) {
348         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),     a3, pv3.getPosition()),
349               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),     a3, pv3.getVelocity()),
350               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
351         this.date = date;
352     }
353 
354     /** Linear constructor
355      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
356      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
357      * @param date date of the built coordinates
358      * @param a1 first scale factor
359      * @param pv1 first base (unscaled) PVCoordinates
360      * @param a2 second scale factor
361      * @param pv2 second base (unscaled) PVCoordinates
362      * @param a3 third scale factor
363      * @param pv3 third base (unscaled) PVCoordinates
364      */
365     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
366                                          final T a1, final FieldPVCoordinates<T> pv1,
367                                          final T a2, final FieldPVCoordinates<T> pv2,
368                                          final T a3, final FieldPVCoordinates<T> pv3) {
369         this(new FieldAbsoluteDate<>(a1.getField(), date),
370              a1, pv1, a2, pv2, a3, pv3);
371     }
372 
373     /** Linear constructor
374      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
375      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
376      * @param date date of the built coordinates
377      * @param a1 first scale factor
378      * @param pv1 first base (unscaled) PVCoordinates
379      * @param a2 second scale factor
380      * @param pv2 second base (unscaled) PVCoordinates
381      * @param a3 third scale factor
382      * @param pv3 third base (unscaled) PVCoordinates
383      */
384     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
385                                          final T a1, final FieldPVCoordinates<T> pv1,
386                                          final T a2, final FieldPVCoordinates<T> pv2,
387                                          final T a3, final FieldPVCoordinates<T> pv3) {
388         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),     a3, pv3.getPosition()),
389               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),     a3, pv3.getVelocity()),
390               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
391         this.date = date;
392     }
393 
394     /** Linear constructor
395      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
396      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
397      * @param date date of the built coordinates
398      * @param a1 first scale factor
399      * @param pv1 first base (unscaled) PVCoordinates
400      * @param a2 second scale factor
401      * @param pv2 second base (unscaled) PVCoordinates
402      * @param a3 third scale factor
403      * @param pv3 third base (unscaled) PVCoordinates
404      */
405     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
406                                          final T a1, final PVCoordinates pv1,
407                                          final T a2, final PVCoordinates pv2,
408                                          final T a3, final PVCoordinates pv3) {
409         this(new FieldAbsoluteDate<>(a1.getField(), date),
410              a1, pv1, a2, pv2, a3, pv3);
411     }
412 
413     /** Linear constructor
414      * <p>Build a PVCoordinates from three other ones and corresponding scale factors.</p>
415      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3</p>
416      * @param date date of the built coordinates
417      * @param a1 first scale factor
418      * @param pv1 first base (unscaled) PVCoordinates
419      * @param a2 second scale factor
420      * @param pv2 second base (unscaled) PVCoordinates
421      * @param a3 third scale factor
422      * @param pv3 third base (unscaled) PVCoordinates
423      */
424     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
425                                          final T a1, final PVCoordinates pv1,
426                                          final T a2, final PVCoordinates pv2,
427                                          final T a3, final PVCoordinates pv3) {
428         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),     a3, pv3.getPosition()),
429               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),     a3, pv3.getVelocity()),
430               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(), a3, pv3.getAcceleration()));
431         this.date = date;
432     }
433 
434     /** Linear constructor
435      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
436      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
437      * @param date date of the built coordinates
438      * @param a1 first scale factor
439      * @param pv1 first base (unscaled) PVCoordinates
440      * @param a2 second scale factor
441      * @param pv2 second base (unscaled) PVCoordinates
442      * @param a3 third scale factor
443      * @param pv3 third base (unscaled) PVCoordinates
444      * @param a4 fourth scale factor
445      * @param pv4 fourth base (unscaled) PVCoordinates
446      */
447     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
448                                          final double a1, final FieldPVCoordinates<T> pv1,
449                                          final double a2, final FieldPVCoordinates<T> pv2,
450                                          final double a3, final FieldPVCoordinates<T> pv3,
451                                          final double a4, final FieldPVCoordinates<T> pv4) {
452         this(new FieldAbsoluteDate<>(pv1.getPosition().getX().getField(), date),
453              a1, pv1, a2, pv2, a3, pv3, a4, pv4);
454     }
455 
456     /** Linear constructor
457      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
458      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
459      * @param date date of the built coordinates
460      * @param a1 first scale factor
461      * @param pv1 first base (unscaled) PVCoordinates
462      * @param a2 second scale factor
463      * @param pv2 second base (unscaled) PVCoordinates
464      * @param a3 third scale factor
465      * @param pv3 third base (unscaled) PVCoordinates
466      * @param a4 fourth scale factor
467      * @param pv4 fourth base (unscaled) PVCoordinates
468      */
469     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
470                                          final double a1, final FieldPVCoordinates<T> pv1,
471                                          final double a2, final FieldPVCoordinates<T> pv2,
472                                          final double a3, final FieldPVCoordinates<T> pv3,
473                                          final double a4, final FieldPVCoordinates<T> pv4) {
474         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),
475                                   a3, pv3.getPosition(),     a4, pv4.getPosition()),
476               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),
477                                   a3, pv3.getVelocity(),     a4, pv4.getVelocity()),
478               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
479                                   a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
480         this.date = date;
481     }
482 
483     /** Linear constructor
484      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
485      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
486      * @param date date of the built coordinates
487      * @param a1 first scale factor
488      * @param pv1 first base (unscaled) PVCoordinates
489      * @param a2 second scale factor
490      * @param pv2 second base (unscaled) PVCoordinates
491      * @param a3 third scale factor
492      * @param pv3 third base (unscaled) PVCoordinates
493      * @param a4 fourth scale factor
494      * @param pv4 fourth base (unscaled) PVCoordinates
495      */
496     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
497                                          final T a1, final FieldPVCoordinates<T> pv1,
498                                          final T a2, final FieldPVCoordinates<T> pv2,
499                                          final T a3, final FieldPVCoordinates<T> pv3,
500                                          final T a4, final FieldPVCoordinates<T> pv4) {
501         this(new FieldAbsoluteDate<>(a1.getField(), date),
502              a1, pv1, a2, pv2, a3, pv3, a4, pv4);
503     }
504 
505     /** Linear constructor
506      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
507      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
508      * @param date date of the built coordinates
509      * @param a1 first scale factor
510      * @param pv1 first base (unscaled) PVCoordinates
511      * @param a2 second scale factor
512      * @param pv2 second base (unscaled) PVCoordinates
513      * @param a3 third scale factor
514      * @param pv3 third base (unscaled) PVCoordinates
515      * @param a4 fourth scale factor
516      * @param pv4 fourth base (unscaled) PVCoordinates
517      */
518     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
519                                          final T a1, final FieldPVCoordinates<T> pv1,
520                                          final T a2, final FieldPVCoordinates<T> pv2,
521                                          final T a3, final FieldPVCoordinates<T> pv3,
522                                          final T a4, final FieldPVCoordinates<T> pv4) {
523         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),
524                                   a3, pv3.getPosition(),     a4, pv4.getPosition()),
525               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),
526                                   a3, pv3.getVelocity(),     a4, pv4.getVelocity()),
527               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
528                                   a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
529         this.date = date;
530     }
531 
532     /** Linear constructor
533      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
534      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
535      * @param date date of the built coordinates
536      * @param a1 first scale factor
537      * @param pv1 first base (unscaled) PVCoordinates
538      * @param a2 second scale factor
539      * @param pv2 second base (unscaled) PVCoordinates
540      * @param a3 third scale factor
541      * @param pv3 third base (unscaled) PVCoordinates
542      * @param a4 fourth scale factor
543      * @param pv4 fourth base (unscaled) PVCoordinates
544      */
545     public TimeStampedFieldPVCoordinates(final AbsoluteDate date,
546                                          final T a1, final PVCoordinates pv1,
547                                          final T a2, final PVCoordinates pv2,
548                                          final T a3, final PVCoordinates pv3,
549                                          final T a4, final PVCoordinates pv4) {
550         this(new FieldAbsoluteDate<>(a1.getField(), date),
551              a1, pv1, a2, pv2, a3, pv3, a4, pv4);
552     }
553 
554     /** Linear constructor
555      * <p>Build a PVCoordinates from four other ones and corresponding scale factors.</p>
556      * <p>The PVCoordinates built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4</p>
557      * @param date date of the built coordinates
558      * @param a1 first scale factor
559      * @param pv1 first base (unscaled) PVCoordinates
560      * @param a2 second scale factor
561      * @param pv2 second base (unscaled) PVCoordinates
562      * @param a3 third scale factor
563      * @param pv3 third base (unscaled) PVCoordinates
564      * @param a4 fourth scale factor
565      * @param pv4 fourth base (unscaled) PVCoordinates
566      */
567     public TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
568                                          final T a1, final PVCoordinates pv1,
569                                          final T a2, final PVCoordinates pv2,
570                                          final T a3, final PVCoordinates pv3,
571                                          final T a4, final PVCoordinates pv4) {
572         super(new FieldVector3D<>(a1, pv1.getPosition(),     a2, pv2.getPosition(),
573                                   a3, pv3.getPosition(),     a4, pv4.getPosition()),
574               new FieldVector3D<>(a1, pv1.getVelocity(),     a2, pv2.getVelocity(),
575                                   a3, pv3.getVelocity(),     a4, pv4.getVelocity()),
576               new FieldVector3D<>(a1, pv1.getAcceleration(), a2, pv2.getAcceleration(),
577                                   a3, pv3.getAcceleration(), a4, pv4.getAcceleration()));
578         this.date = date;
579     }
580 
581     /** Builds a TimeStampedFieldPVCoordinates triplet from  a {@link FieldVector3D}&lt;{@link FieldDerivativeStructure}&gt;.
582      * <p>
583      * The vector components must have time as their only derivation parameter and
584      * have consistent derivation orders.
585      * </p>
586      * @param date date of the built coordinates
587      * @param <U> type of the derivative
588      * @param p vector with time-derivatives embedded within the coordinates
589      */
590     public <U extends FieldDerivative<T, U>> TimeStampedFieldPVCoordinates(final FieldAbsoluteDate<T> date,
591                                                                            final FieldVector3D<U> p) {
592         super(p);
593         this.date = date;
594     }
595 
596     /** {@inheritDoc} */
597     @Override
598     public FieldAbsoluteDate<T> getDate() {
599         return date;
600     }
601 
602     /** Get a time-shifted state.
603      * <p>
604      * The state can be slightly shifted to close dates. This shift is based on
605      * a simple linear model. It is <em>not</em> intended as a replacement for
606      * proper orbit propagation (it is not even Keplerian!) but should be sufficient
607      * for either small time shifts or coarse accuracy.
608      * </p>
609      * @param dt time shift in seconds
610      * @return a new state, shifted with respect to the instance (which is immutable)
611      */
612     public TimeStampedFieldPVCoordinates<T> shiftedBy(final double dt) {
613         final FieldPVCoordinates<T> spv = super.shiftedBy(dt);
614         return new TimeStampedFieldPVCoordinates<>(date.shiftedBy(dt),
615                                                    spv.getPosition(), spv.getVelocity(), spv.getAcceleration());
616     }
617 
618     /** Get a time-shifted state.
619      * <p>
620      * The state can be slightly shifted to close dates. This shift is based on
621      * a simple linear model. It is <em>not</em> intended as a replacement for
622      * proper orbit propagation (it is not even Keplerian!) but should be sufficient
623      * for either small time shifts or coarse accuracy.
624      * </p>
625      * @param dt time shift in seconds
626      * @return a new state, shifted with respect to the instance (which is immutable)
627      */
628     public TimeStampedFieldPVCoordinates<T> shiftedBy(final T dt) {
629         final FieldPVCoordinates<T> spv = super.shiftedBy(dt);
630         return new TimeStampedFieldPVCoordinates<>(date.shiftedBy(dt),
631                                                    spv.getPosition(), spv.getVelocity(), spv.getAcceleration());
632     }
633 
634     /** Convert to a constant position-velocity.
635      * @return a constant position-velocity
636      * @since 9.0
637      */
638     public TimeStampedPVCoordinates toTimeStampedPVCoordinates() {
639         return new TimeStampedPVCoordinates(date.toAbsoluteDate(),
640                                             getPosition().toVector3D(),
641                                             getVelocity().toVector3D(),
642                                             getAcceleration().toVector3D());
643     }
644 
645     /** Return a string representation of this date, position, velocity, and acceleration.
646      *
647      * <p>This method uses the {@link DataContext#getDefault() default data context}.
648      *
649      * @return string representation of this.
650      */
651     @Override
652     @DefaultDataContext
653     public String toString() {
654         return toTimeStampedPVCoordinates().toString();
655     }
656 
657     /**
658      * Return a string representation of this date, position, velocity, and acceleration.
659      *
660      * @param utc time scale used to print the date.
661      * @return string representation of this.
662      */
663     public String toString(final TimeScale utc) {
664         return toTimeStampedPVCoordinates().toString(utc);
665     }
666 
667 }