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  
20  import org.hipparchus.CalculusFieldElement;
21  import org.hipparchus.Field;
22  import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
23  import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative1;
24  import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
25  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26  import org.hipparchus.geometry.euclidean.threed.Vector3D;
27  import org.hipparchus.util.Binary64Field;
28  import org.junit.jupiter.api.Assertions;
29  import org.junit.jupiter.api.BeforeEach;
30  import org.junit.jupiter.api.Test;
31  import org.orekit.Utils;
32  import org.orekit.errors.OrekitIllegalArgumentException;
33  import org.orekit.errors.OrekitMessages;
34  import org.orekit.frames.Frame;
35  import org.orekit.frames.FramesFactory;
36  import org.orekit.frames.Transform;
37  import org.orekit.time.FieldAbsoluteDate;
38  
39  public class FieldAbsolutePVCoordinatesTest {
40  
41      @BeforeEach
42      public void setUp() {
43          Utils.setDataRoot("regular-data");
44      }
45  
46      @Test
47      public void TestPVOnlyConstructor() {
48          doTestPVOnlyConstructor(Binary64Field.getInstance());
49      }
50  
51      @Test
52      public void testPVCoordinatesCopyConstructor() {
53          doTestPVCoordinatesCopyConstructor(Binary64Field.getInstance());
54      }
55  
56      @Test
57      public void testLinearConstructors() {
58          doTestLinearConstructors(Binary64Field.getInstance());
59      }
60  
61      @Test
62      public void testDifferentFrames() {
63          doTestDifferentFrames(Binary64Field.getInstance());
64      }
65  
66      @Test
67      public void testToDerivativeStructureVector1() {
68          doTestToDerivativeStructureVector1(Binary64Field.getInstance());
69      }
70  
71      @Test
72      public void testToDerivativeStructureVector2() {
73          doTestToDerivativeStructureVector2(Binary64Field.getInstance());
74      }
75  
76      @Test
77      public void testToUnivariateDerivative1Vector() {
78          doTestToUnivariateDerivative1Vector(Binary64Field.getInstance());
79      }
80  
81      @Test
82      public void testToUnivariateDerivative2Vector() {
83          doTestToUnivariateDerivative2Vector(Binary64Field.getInstance());
84      }
85  
86      @Test
87      public void testShift() {
88          doTestShift(Binary64Field.getInstance());
89      }
90  
91      @Test
92      public void testToString() {
93          doTestToString(Binary64Field.getInstance());
94      }
95  
96      @Test
97      public void testSamePV() {
98          doTestSamePV(Binary64Field.getInstance());
99      }
100 
101     @Test
102     public void testTaylorProvider() {
103         doTestTaylorProvider(Binary64Field.getInstance());
104     }
105 
106     private <T extends CalculusFieldElement<T>> void doTestPVOnlyConstructor(Field<T> field) {
107         //setup
108         FieldAbsoluteDate<T> date = FieldAbsoluteDate.getJ2000Epoch(field);
109         Frame frame = FramesFactory.getEME2000();
110         final T one = field.getOne();
111         FieldVector3D<T> p = new FieldVector3D<>(one, one.multiply(2.0), one.multiply(3.0));
112         FieldVector3D<T> v = new FieldVector3D<>(one.multiply(4.0), one.multiply(5.0), one.multiply(6.0));
113 
114         //action
115         FieldAbsolutePVCoordinates<T> actual = new FieldAbsolutePVCoordinates<>(frame, date, p, v);
116 
117         //verify
118         Assertions.assertEquals(date, actual.getDate());
119         Assertions.assertEquals(1.0, actual.getPosition().getX().getReal(), 0.0);
120         Assertions.assertEquals(2.0, actual.getPosition().getY().getReal(), 0.0);
121         Assertions.assertEquals(3.0, actual.getPosition().getZ().getReal(), 0.0);
122         Assertions.assertEquals(4.0, actual.getVelocity().getX().getReal(), 0.0);
123         Assertions.assertEquals(5.0, actual.getVelocity().getY().getReal(), 0.0);
124         Assertions.assertEquals(6.0, actual.getVelocity().getZ().getReal(), 0.0);
125         Assertions.assertEquals(FieldVector3D.getZero(field), actual.getAcceleration());
126     }
127 
128     private <T extends CalculusFieldElement<T>> void doTestPVCoordinatesCopyConstructor(Field<T> field) {
129         //setup
130         FieldAbsoluteDate<T> date = FieldAbsoluteDate.getJ2000Epoch(field);
131         Frame frame = FramesFactory.getEME2000();
132         final T one = field.getOne();
133         FieldPVCoordinates<T> pv = new FieldPVCoordinates<>(new FieldVector3D<>(one, one.multiply(2), one.multiply(3)), new FieldVector3D<>(one.multiply(4), one.multiply(5), one.multiply(6)));
134 
135         //action
136         FieldAbsolutePVCoordinates<T> actual = new FieldAbsolutePVCoordinates<>(frame, date, pv);
137 
138         //verify
139         Assertions.assertEquals(date, actual.getDate());
140         Assertions.assertEquals(1.0, actual.getPosition().getX().getReal(), 0.0);
141         Assertions.assertEquals(2.0, actual.getPosition().getY().getReal(), 0.0);
142         Assertions.assertEquals(3.0, actual.getPosition().getZ().getReal(), 0.0);
143         Assertions.assertEquals(4.0, actual.getVelocity().getX().getReal(), 0.0);
144         Assertions.assertEquals(5.0, actual.getVelocity().getY().getReal(), 0.0);
145         Assertions.assertEquals(6.0, actual.getVelocity().getZ().getReal(), 0.0);
146         Assertions.assertEquals(FieldVector3D.getZero(field), actual.getAcceleration());
147     }
148 
149     private <T extends CalculusFieldElement<T>> void doTestLinearConstructors(Field<T> field) {
150         Frame frame = FramesFactory.getEME2000();
151         final T one = field.getOne();
152         FieldAbsolutePVCoordinates<T> pv1 = new FieldAbsolutePVCoordinates<>(frame,FieldAbsoluteDate.getCCSDSEpoch(field),
153                                                               new FieldVector3D<>(one, one.multiply(0.1), one.multiply(10.0)),
154                                                               new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
155                                                               new FieldVector3D<>(one.multiply(10.0), one.multiply(-1.0), one.multiply(-100.0)));
156         FieldAbsolutePVCoordinates<T> pv2 = new FieldAbsolutePVCoordinates<>(frame,FieldAbsoluteDate.getFiftiesEpoch(field),
157                                                               new FieldVector3D<>(one.multiply(2.0), one.multiply(0.2), one.multiply(20.0)),
158                                                               new FieldVector3D<>(one.multiply(-2.0), one.multiply(-0.2), one.multiply(-20.0)),
159                                                               new FieldVector3D<>(one.multiply(20.0), one.multiply(-2.0), one.multiply(-200.0)));
160         FieldAbsolutePVCoordinates<T> pv3 = new FieldAbsolutePVCoordinates<>(frame,FieldAbsoluteDate.getGalileoEpoch(field),
161                                                                 new FieldVector3D<>(one.multiply(3.0), one.multiply(0.3), one.multiply(30.0)),
162                                                                 new FieldVector3D<>(one.multiply(-3.0), one.multiply(-0.3), one.multiply(-30.0)),
163                                                                 new FieldVector3D<>(one.multiply(30.0), one.multiply(-3.0), one.multiply(-300.0)));
164         FieldAbsolutePVCoordinates<T> pv4 = new FieldAbsolutePVCoordinates<>(frame,FieldAbsoluteDate.getJulianEpoch(field),
165                                                                 new FieldVector3D<>(one.multiply(4.0), one.multiply(0.4), one.multiply(40.0)),
166                                                                 new FieldVector3D<>(one.multiply(-4.0), one.multiply(-0.4), one.multiply(-40.0)),
167                                                                 new FieldVector3D<>(one.multiply(40.0), one.multiply(-4.0), one.multiply(-400.0)));
168         checkPV(pv4, new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getJulianEpoch(field), one.multiply(4.0), pv1), 1.0e-15);
169         checkPV(pv2, new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getFiftiesEpoch(field), pv1, pv3), 1.0e-15);
170         checkPV(pv3, new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getGalileoEpoch(field), one, pv1, one, pv2), 1.0e-15);
171         checkPV(new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), one.multiply(2.0), pv4),
172                 new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), one.multiply(3.0), pv1, one, pv2, one, pv3),
173                 1.0e-15);
174         checkPV(new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), one.multiply(3.0), pv3),
175                 new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), one.multiply(3.0), pv1, one, pv2, one, pv4),
176                 1.0e-15);
177         checkPV(new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), one.multiply(5.0), pv4),
178                 new FieldAbsolutePVCoordinates<T>(FieldAbsoluteDate.getJ2000Epoch(field), one.multiply(4.0), pv1, one.multiply(3.0), pv2, one.multiply(2.0), pv3, one, pv4),
179                 1.0e-15);
180     }
181 
182     private <T extends CalculusFieldElement<T>> void doTestDifferentFrames(Field<T> field) {
183         final FieldVector3D<T> zero = FieldVector3D.getZero(field);
184         FieldAbsolutePVCoordinates<T> apv1 = new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
185                                                                               FieldAbsoluteDate.getArbitraryEpoch(field),
186                                                                               zero, zero, zero);
187         FieldAbsolutePVCoordinates<T> apv2 = new FieldAbsolutePVCoordinates<>(FramesFactory.getGCRF(),
188                                                                               FieldAbsoluteDate.getArbitraryEpoch(field),
189                                                                               zero, zero, zero);
190         try {
191             new FieldAbsolutePVCoordinates<>(FieldAbsoluteDate.getArbitraryEpoch(field), apv1, apv2);
192             Assertions.fail("an exception should have been thrown");
193         } catch (OrekitIllegalArgumentException oe) {
194             Assertions.assertEquals(OrekitMessages.INCOMPATIBLE_FRAMES, oe.getSpecifier());
195             Assertions.assertEquals(apv1.getFrame().getName(), oe.getParts()[0]);
196             Assertions.assertEquals(apv2.getFrame().getName(), oe.getParts()[1]);
197         }
198     }
199 
200     private <T extends CalculusFieldElement<T>> void doTestToDerivativeStructureVector1(Field<T> field) {
201         final T one = field.getOne();
202         FieldVector3D<FieldDerivativeStructure<T>> fv =
203                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
204                                         FieldAbsoluteDate.getGalileoEpoch(field),
205                                         new FieldVector3D<>(one, one.multiply(0.1), one.multiply(10.0)),
206                                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
207                                         new FieldVector3D<>(one.multiply(10.0), one.multiply(-1.0), one.multiply(-100.0))).toDerivativeStructureVector(1);
208 
209         Assertions.assertEquals(1, fv.getX().getFreeParameters());
210         Assertions.assertEquals(1, fv.getX().getOrder());
211         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
212         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
213         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
214         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).getReal(), 1.0e-15);
215         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).getReal(), 1.0e-15);
216         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).getReal(), 1.0e-15);
217         checkPV(new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
218                         FieldAbsoluteDate.getGalileoEpoch(field),
219                         new FieldVector3D<>(one,  one.multiply(0.1), one.multiply(10.0)),
220                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
221                         FieldVector3D.getZero(field)),
222                 new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
223                                 FieldAbsoluteDate.getGalileoEpoch(field), fv), 1.0e-15);
224 
225         for (double dt = 0; dt < 10; dt += 0.125) {
226             Vector3D p = new PVCoordinates(new Vector3D( 1,  0.1,  10),
227                                            new Vector3D(-1, -0.1, -10)).shiftedBy(dt).getPosition();
228             Assertions.assertEquals(p.getX(), fv.getX().taylor(dt).getReal(), 1.0e-14);
229             Assertions.assertEquals(p.getY(), fv.getY().taylor(dt).getReal(), 1.0e-14);
230             Assertions.assertEquals(p.getZ(), fv.getZ().taylor(dt).getReal(), 1.0e-14);
231         }
232 
233         FieldAbsolutePVCoordinates<T> pv =
234                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
235                                         FieldAbsoluteDate.getGalileoEpoch(field),
236                                         fv);
237         Assertions.assertEquals(   1.0, pv.getPosition().getX().getReal(), 1.0e-10);
238         Assertions.assertEquals(   0.1, pv.getPosition().getY().getReal(), 1.0e-10);
239         Assertions.assertEquals(  10.0, pv.getPosition().getZ().getReal(), 1.0e-10);
240         Assertions.assertEquals(  -1.0, pv.getVelocity().getX().getReal(), 1.0e-15);
241         Assertions.assertEquals(  -0.1, pv.getVelocity().getY().getReal(), 1.0e-15);
242         Assertions.assertEquals( -10.0, pv.getVelocity().getZ().getReal(), 1.0e-15);
243 
244     }
245 
246     private <T extends CalculusFieldElement<T>> void doTestToDerivativeStructureVector2(Field<T> field) {
247         final T one = field.getOne();
248         FieldVector3D<FieldDerivativeStructure<T>> fv =
249                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
250                                         FieldAbsoluteDate.getGalileoEpoch(field),
251                                         new FieldVector3D<>(one, one.multiply(0.1), one.multiply(10.0)),
252                                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
253                                         new FieldVector3D<>(one.multiply(10.0), one.multiply(-1.0), one.multiply(-100.0))).toDerivativeStructureVector(2);
254 
255         Assertions.assertEquals(1, fv.getX().getFreeParameters());
256         Assertions.assertEquals(2, fv.getX().getOrder());
257         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
258         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
259         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
260         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).getReal(), 1.0e-15);
261         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).getReal(), 1.0e-15);
262         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).getReal(), 1.0e-15);
263         Assertions.assertEquals(  10.0, fv.getX().getPartialDerivative(2).getReal(), 1.0e-15);
264         Assertions.assertEquals(  -1.0, fv.getY().getPartialDerivative(2).getReal(), 1.0e-15);
265         Assertions.assertEquals(-100.0, fv.getZ().getPartialDerivative(2).getReal(), 1.0e-15);
266         checkPV(new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
267                         FieldAbsoluteDate.getGalileoEpoch(field),
268                         new FieldVector3D<>(one,  one.multiply(0.1), one.multiply(10.0)),
269                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
270                         new FieldVector3D<>(one.multiply(10.0), one.multiply(-1.0), one.multiply(-100.0))),
271                 new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
272                                 FieldAbsoluteDate.getGalileoEpoch(field), fv), 1.0e-15);
273 
274         for (double dt = 0; dt < 10; dt += 0.125) {
275             Vector3D p = new PVCoordinates(new Vector3D( 1,  0.1,  10),
276                                            new Vector3D(-1, -0.1, -10),
277                                            new Vector3D(10, -1.0, -100)).shiftedBy(dt).getPosition();
278             Assertions.assertEquals(p.getX(), fv.getX().taylor(dt).getReal(), 1.0e-14);
279             Assertions.assertEquals(p.getY(), fv.getY().taylor(dt).getReal(), 1.0e-14);
280             Assertions.assertEquals(p.getZ(), fv.getZ().taylor(dt).getReal(), 1.0e-14);
281         }
282 
283         FieldAbsolutePVCoordinates<T> pv =
284                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
285                                         FieldAbsoluteDate.getGalileoEpoch(field),
286                                         fv);
287         Assertions.assertEquals(   1.0, pv.getPosition().getX().getReal(), 1.0e-10);
288         Assertions.assertEquals(   0.1, pv.getPosition().getY().getReal(), 1.0e-10);
289         Assertions.assertEquals(  10.0, pv.getPosition().getZ().getReal(), 1.0e-10);
290         Assertions.assertEquals(  -1.0, pv.getVelocity().getX().getReal(), 1.0e-15);
291         Assertions.assertEquals(  -0.1, pv.getVelocity().getY().getReal(), 1.0e-15);
292         Assertions.assertEquals( -10.0, pv.getVelocity().getZ().getReal(), 1.0e-15);
293         Assertions.assertEquals(  10.0, pv.getAcceleration().getX().getReal(), 1.0e-15);
294         Assertions.assertEquals(  -1.0, pv.getAcceleration().getY().getReal(), 1.0e-15);
295         Assertions.assertEquals(-100.0, pv.getAcceleration().getZ().getReal(), 1.0e-15);
296 
297     }
298 
299     private <T extends CalculusFieldElement<T>> void doTestToUnivariateDerivative1Vector(Field<T> field) {
300         final T one = field.getOne();
301         FieldVector3D<FieldUnivariateDerivative1<T>> fv =
302                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
303                                         FieldAbsoluteDate.getGalileoEpoch(field),
304                                         new FieldVector3D<>(one, one.multiply(0.1), one.multiply(10.0)),
305                                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
306                                         new FieldVector3D<>(one.multiply(10.0), one.multiply(-1.0), one.multiply(-100.0))).toUnivariateDerivative1Vector();
307 
308         Assertions.assertEquals(1, fv.getX().getFreeParameters());
309         Assertions.assertEquals(1, fv.getX().getOrder());
310         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
311         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
312         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
313         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).getReal(), 1.0e-15);
314         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).getReal(), 1.0e-15);
315         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).getReal(), 1.0e-15);
316         checkPV(new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
317                         FieldAbsoluteDate.getGalileoEpoch(field),
318                         new FieldVector3D<>(one,  one.multiply(0.1), one.multiply(10.0)),
319                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
320                         FieldVector3D.getZero(field)),
321                 new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
322                                 FieldAbsoluteDate.getGalileoEpoch(field), fv), 1.0e-15);
323 
324         for (double dt = 0; dt < 10; dt += 0.125) {
325             Vector3D p = new PVCoordinates(new Vector3D( 1,  0.1,  10),
326                                            new Vector3D(-1, -0.1, -10)).shiftedBy(dt).getPosition();
327             Assertions.assertEquals(p.getX(), fv.getX().taylor(dt).getReal(), 1.0e-14);
328             Assertions.assertEquals(p.getY(), fv.getY().taylor(dt).getReal(), 1.0e-14);
329             Assertions.assertEquals(p.getZ(), fv.getZ().taylor(dt).getReal(), 1.0e-14);
330         }
331 
332         FieldAbsolutePVCoordinates<T> pv =
333                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
334                                         FieldAbsoluteDate.getGalileoEpoch(field),
335                                         fv);
336         Assertions.assertEquals(   1.0, pv.getPosition().getX().getReal(), 1.0e-10);
337         Assertions.assertEquals(   0.1, pv.getPosition().getY().getReal(), 1.0e-10);
338         Assertions.assertEquals(  10.0, pv.getPosition().getZ().getReal(), 1.0e-10);
339         Assertions.assertEquals(  -1.0, pv.getVelocity().getX().getReal(), 1.0e-15);
340         Assertions.assertEquals(  -0.1, pv.getVelocity().getY().getReal(), 1.0e-15);
341         Assertions.assertEquals( -10.0, pv.getVelocity().getZ().getReal(), 1.0e-15);
342 
343     }
344 
345     private <T extends CalculusFieldElement<T>> void doTestToUnivariateDerivative2Vector(Field<T> field) {
346         final T one = field.getOne();
347         FieldVector3D<FieldUnivariateDerivative2<T>> fv =
348                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
349                                         FieldAbsoluteDate.getGalileoEpoch(field),
350                                         new FieldVector3D<>(one, one.multiply(0.1), one.multiply(10.0)),
351                                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
352                                         new FieldVector3D<>(one.multiply(10.0), one.multiply(-1.0), one.multiply(-100.0))).toUnivariateDerivative2Vector();
353 
354         Assertions.assertEquals(1, fv.getX().getFreeParameters());
355         Assertions.assertEquals(2, fv.getX().getOrder());
356         Assertions.assertEquals(   1.0, fv.getX().getReal(), 1.0e-10);
357         Assertions.assertEquals(   0.1, fv.getY().getReal(), 1.0e-10);
358         Assertions.assertEquals(  10.0, fv.getZ().getReal(), 1.0e-10);
359         Assertions.assertEquals(  -1.0, fv.getX().getPartialDerivative(1).getReal(), 1.0e-15);
360         Assertions.assertEquals(  -0.1, fv.getY().getPartialDerivative(1).getReal(), 1.0e-15);
361         Assertions.assertEquals( -10.0, fv.getZ().getPartialDerivative(1).getReal(), 1.0e-15);
362         Assertions.assertEquals(  10.0, fv.getX().getPartialDerivative(2).getReal(), 1.0e-15);
363         Assertions.assertEquals(  -1.0, fv.getY().getPartialDerivative(2).getReal(), 1.0e-15);
364         Assertions.assertEquals(-100.0, fv.getZ().getPartialDerivative(2).getReal(), 1.0e-15);
365         checkPV(new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
366                         FieldAbsoluteDate.getGalileoEpoch(field),
367                         new FieldVector3D<>(one,  one.multiply(0.1), one.multiply(10.0)),
368                         new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10.0)),
369                         new FieldVector3D<>(one.multiply(10.0), one.multiply(-1.0), one.multiply(-100.0))),
370                 new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
371                                 FieldAbsoluteDate.getGalileoEpoch(field), fv), 1.0e-15);
372 
373         for (double dt = 0; dt < 10; dt += 0.125) {
374             Vector3D p = new PVCoordinates(new Vector3D( 1,  0.1,  10),
375                                            new Vector3D(-1, -0.1, -10),
376                                            new Vector3D(10, -1.0, -100)).shiftedBy(dt).getPosition();
377             Assertions.assertEquals(p.getX(), fv.getX().taylor(dt).getReal(), 1.0e-14);
378             Assertions.assertEquals(p.getY(), fv.getY().taylor(dt).getReal(), 1.0e-14);
379             Assertions.assertEquals(p.getZ(), fv.getZ().taylor(dt).getReal(), 1.0e-14);
380         }
381 
382         FieldAbsolutePVCoordinates<T> pv =
383                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
384                                         FieldAbsoluteDate.getGalileoEpoch(field),
385                                         fv);
386         Assertions.assertEquals(   1.0, pv.getPosition().getX().getReal(), 1.0e-10);
387         Assertions.assertEquals(   0.1, pv.getPosition().getY().getReal(), 1.0e-10);
388         Assertions.assertEquals(  10.0, pv.getPosition().getZ().getReal(), 1.0e-10);
389         Assertions.assertEquals(  -1.0, pv.getVelocity().getX().getReal(), 1.0e-15);
390         Assertions.assertEquals(  -0.1, pv.getVelocity().getY().getReal(), 1.0e-15);
391         Assertions.assertEquals( -10.0, pv.getVelocity().getZ().getReal(), 1.0e-15);
392         Assertions.assertEquals(  10.0, pv.getAcceleration().getX().getReal(), 1.0e-15);
393         Assertions.assertEquals(  -1.0, pv.getAcceleration().getY().getReal(), 1.0e-15);
394         Assertions.assertEquals(-100.0, pv.getAcceleration().getZ().getReal(), 1.0e-15);
395 
396     }
397 
398     private <T extends CalculusFieldElement<T>> void doTestShift(Field<T> field) {
399         final T one = field.getOne();
400         FieldVector3D<T> p1 = new FieldVector3D<>(one, one.multiply(0.1), one.multiply(10.0));
401         FieldVector3D<T> v1 = new FieldVector3D<>(one.multiply(-1.0), one.multiply(-0.1), one.multiply(-10));
402         FieldVector3D<T> a1 = new FieldVector3D<>(one.multiply(10.0), one, one.multiply(100.0));
403         FieldVector3D<T> p2 = new FieldVector3D<>(one.multiply(7.0), one.multiply(0.7), one.multiply(70.0));
404         FieldVector3D<T> v2 = new FieldVector3D<>(one.multiply(-11.0), one.multiply(-1.1), one.multiply(-110.0));
405         FieldVector3D<T> a2 = new FieldVector3D<>(one.multiply(10.0), one, one.multiply(100.0));
406         checkPV(new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(), FieldAbsoluteDate.getJ2000Epoch(field), p2, v2, a2),
407                 new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(), FieldAbsoluteDate.getJ2000Epoch(field).shiftedBy(1.0), p1, v1, a1).shiftedBy(one.multiply(-1.0)), 1.0e-15);
408         Assertions.assertEquals(0.0, FieldAbsolutePVCoordinates.estimateVelocity(p1, p2, -1.0).subtract(new Vector3D(-6, -0.6, -60)).getNorm().getReal(), 1.0e-15);
409     }
410 
411     private <T extends CalculusFieldElement<T>> void doTestToString(Field<T> field) {
412         final T one = field.getOne();
413         FieldAbsolutePVCoordinates<T> pv =
414                         new FieldAbsolutePVCoordinates<>(FramesFactory.getEME2000(),
415                                         FieldAbsoluteDate.getJ2000Epoch(field),
416                                         new FieldVector3D<>(one.multiply(1.0),   one.multiply(0.1),  one.multiply(10.0)),
417                                         new FieldVector3D<>(one.multiply(-1.0),  one.multiply(-0.1), one.multiply(-10.0)),
418                                         new FieldVector3D<>(one.multiply(10.0),  one.multiply(1.0),  one.multiply(100.0)));
419         Assertions.assertEquals("{2000-01-01T11:58:55.816, P(1.0, 0.1, 10.0), V(-1.0, -0.1, -10.0), A(10.0, 1.0, 100.0)}", pv.toString());
420     }
421 
422     private <T extends CalculusFieldElement<T>> void doTestSamePV(Field<T> field) {
423         //setup
424         final T one = field.getOne();
425         FieldAbsoluteDate<T> date = FieldAbsoluteDate.getJ2000Epoch(field);
426         Frame frame = FramesFactory.getEME2000();
427         Frame otherEme2000 = new Frame(frame, Transform.IDENTITY, "other-EME2000");
428         FieldVector3D<T> p = new FieldVector3D<>(one.multiply(1), one.multiply(2), one.multiply(3));
429         FieldVector3D<T> v = new FieldVector3D<>(one.multiply(4), one.multiply(5), one.multiply(6));
430 
431         //action
432         FieldAbsolutePVCoordinates<T> actual = new FieldAbsolutePVCoordinates<>(frame, date, p, v);
433 
434         //verify
435         Assertions.assertSame(actual.getPosition(), actual.getPosition(frame));
436         Assertions.assertNotSame(actual.getPosition(), actual.getPosition(otherEme2000));
437         Assertions.assertEquals(0.0,
438                                 FieldVector3D.distance(actual.getPosition(frame),
439                                                        actual.getPosition(otherEme2000)).getReal(),
440                                 1.0e-15);
441         Assertions.assertEquals(0.0,
442                                 FieldVector3D.distance(actual.getPVCoordinates(frame).getPosition(),
443                                                        actual.getPVCoordinates(date, frame).getPosition()).getReal(),
444                                 1.0e-15);
445         Assertions.assertEquals(0.0,
446                                 FieldVector3D.distance(actual.getPVCoordinates(frame).getVelocity(),
447                                                        actual.getPVCoordinates(date, frame).getVelocity()).getReal(),
448                                 1.0e-15);
449         Assertions.assertEquals(0.0,
450                                 FieldVector3D.distance(actual.getPVCoordinates(frame).getAcceleration(),
451                                                        actual.getPVCoordinates(date, frame).getAcceleration()).getReal(),
452                                 1.0e-15);
453         Assertions.assertEquals(0.0,
454                                 FieldVector3D.distance(actual.getPVCoordinates(frame).getPosition(),
455                                                        actual.getPVCoordinates(date, otherEme2000).getPosition()).getReal(),
456                                 1.0e-15);
457         Assertions.assertEquals(0.0,
458                                 FieldVector3D.distance(actual.getPVCoordinates(frame).getVelocity(),
459                                                        actual.getPVCoordinates(date, otherEme2000).getVelocity()).getReal(),
460                                 1.0e-15);
461         Assertions.assertEquals(0.0,
462                                 FieldVector3D.distance(actual.getPVCoordinates(frame).getAcceleration(),
463                                                        actual.getPVCoordinates(date, otherEme2000).getAcceleration()).getReal(),
464                                 1.0e-15);
465     }
466 
467     private <T extends CalculusFieldElement<T>> void doTestTaylorProvider(Field<T> field) {
468         //setup
469         final T one = field.getOne();
470         FieldAbsoluteDate<T> date = FieldAbsoluteDate.getJ2000Epoch(field);
471         Frame frame = FramesFactory.getEME2000();
472         FieldVector3D<T> p = new FieldVector3D<>(one.multiply(1), one.multiply(2), one.multiply(3));
473         FieldVector3D<T> v = new FieldVector3D<>(one.multiply(4), one.multiply(5), one.multiply(6));
474 
475         //action
476         FieldAbsolutePVCoordinates<T> actual = new FieldAbsolutePVCoordinates<>(frame, date, p, v);
477         final FieldPVCoordinatesProvider<T> pv = actual.toTaylorProvider();
478 
479         //verify
480         Assertions.assertEquals(0.0,
481                                 FieldVector3D.distance(actual.getPosition(date, frame), pv.getPosition(date, frame)).getReal(),
482                                 1.0e-15);
483         Assertions.assertEquals(actual.getPVCoordinates(date, frame).toString(), pv.getPVCoordinates(date, frame).toString());
484     }
485 
486     private <T extends CalculusFieldElement<T>> void checkPV(FieldAbsolutePVCoordinates<T> expected, FieldAbsolutePVCoordinates<T> real, double epsilon) {
487         Assertions.assertEquals(expected.getDate(), real.getDate());
488         Assertions.assertEquals(expected.getPosition().getX().getReal(),     real.getPosition().getX().getReal(),     epsilon);
489         Assertions.assertEquals(expected.getPosition().getY().getReal(),     real.getPosition().getY().getReal(),     epsilon);
490         Assertions.assertEquals(expected.getPosition().getZ().getReal(),     real.getPosition().getZ().getReal(),     epsilon);
491         Assertions.assertEquals(expected.getVelocity().getX().getReal(),     real.getVelocity().getX().getReal(),     epsilon);
492         Assertions.assertEquals(expected.getVelocity().getY().getReal(),     real.getVelocity().getY().getReal(),     epsilon);
493         Assertions.assertEquals(expected.getVelocity().getZ().getReal(),     real.getVelocity().getZ().getReal(),     epsilon);
494         Assertions.assertEquals(expected.getAcceleration().getX().getReal(), real.getAcceleration().getX().getReal(), epsilon);
495         Assertions.assertEquals(expected.getAcceleration().getY().getReal(), real.getAcceleration().getY().getReal(), epsilon);
496         Assertions.assertEquals(expected.getAcceleration().getZ().getReal(), real.getAcceleration().getZ().getReal(), epsilon);
497     }
498 
499 }