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  
18  package org.orekit.bodies;
19  
20  import org.hipparchus.analysis.differentiation.Gradient;
21  import org.hipparchus.analysis.differentiation.GradientField;
22  import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
23  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24  import org.hipparchus.geometry.euclidean.threed.Vector3D;
25  import org.junit.jupiter.api.Assertions;
26  import org.junit.jupiter.api.BeforeEach;
27  import org.junit.jupiter.api.Test;
28  import org.orekit.Utils;
29  import org.orekit.time.AbsoluteDate;
30  import org.orekit.time.FieldAbsoluteDate;
31  import org.orekit.time.TimeScale;
32  import org.orekit.time.TimeScalesFactory;
33  import org.orekit.utils.FieldPVCoordinates;
34  import org.orekit.utils.PVCoordinates;
35  
36  import java.util.Arrays;
37  
38  class PosVelChebyshevTest {
39  
40      private static final double DURATION = 10.;
41  
42      @BeforeEach
43      public void setUp() {
44          Utils.setDataRoot("regular-data/de405-ephemerides");
45      }
46  
47      @Test
48      void testGetPosition() {
49          // Given
50          final PosVelChebyshev chebyshev = createPolynomial();
51          final AbsoluteDate date = chebyshev.getDate().shiftedBy(DURATION / 2);
52          // When
53          final double[] actualPositionArray = chebyshev.getPosition(date).toArray();
54          // Then
55          final double[] expectedPositionArray = chebyshev.getPositionVelocityAcceleration(date).getPosition().toArray();
56          for (int i = 0; i < expectedPositionArray.length; i++) {
57              Assertions.assertEquals(expectedPositionArray[i], actualPositionArray[i]);
58          }
59      }
60  
61      @Test
62      void testFieldGetPositionWithGradient() {
63          // Given
64          final PosVelChebyshev chebyshev = createPolynomial();
65          final AbsoluteDate date = chebyshev.getDate().shiftedBy(DURATION / 2);
66          final int freeParameters = 1;
67          final GradientField field = GradientField.getField(freeParameters);
68          final Gradient variable = Gradient.variable(freeParameters, 0, 0);
69          final FieldAbsoluteDate<Gradient> fieldDate = new FieldAbsoluteDate<>(field, date).shiftedBy(variable);
70          // When
71          final Gradient[] actualPositionArray = chebyshev.getPosition(fieldDate).toArray();
72          // Then
73          final Gradient[] expectedPositionArray = chebyshev.getPositionVelocityAcceleration(fieldDate).getPosition().toArray();
74          for (int i = 0; i < expectedPositionArray.length; i++) {
75              Assertions.assertEquals(expectedPositionArray[i], actualPositionArray[i]);
76          }
77      }
78  
79      @Test
80      void testFieldWithGradientVersusNonField() {
81          // Given
82          final PosVelChebyshev chebyshev = createPolynomial();
83          final AbsoluteDate date = chebyshev.getDate().shiftedBy(DURATION / 2);
84          final int freeParameters = 1;
85          final GradientField field = GradientField.getField(freeParameters);
86          final Gradient variable = Gradient.variable(freeParameters, 0, 0);
87          final FieldAbsoluteDate<Gradient> fieldDate = new FieldAbsoluteDate<>(field, date).shiftedBy(variable);
88          // When
89          final FieldPVCoordinates<Gradient> fieldPVCoordinates = chebyshev.getPositionVelocityAcceleration(fieldDate);
90          // Then
91          final PVCoordinates expectedPVCoordinates = chebyshev.getPositionVelocityAcceleration(fieldDate.toAbsoluteDate());
92          final PVCoordinates actualPVCoordinates = fieldPVCoordinates.toPVCoordinates();
93          Assertions.assertEquals(expectedPVCoordinates.getPosition(), actualPVCoordinates.getPosition());
94          Assertions.assertEquals(expectedPVCoordinates.getVelocity(), actualPVCoordinates.getVelocity());
95          Assertions.assertEquals(expectedPVCoordinates.getAcceleration(), actualPVCoordinates.getAcceleration());
96      }
97  
98      @Test
99      void testVelocityAndAccelerationAreDerivativesOfPosition() {
100         // Given
101         final PosVelChebyshev chebyshev = createPolynomial();
102         final AbsoluteDate date = chebyshev.getDate().shiftedBy(DURATION / 2);
103         final UnivariateDerivative2 variable = new UnivariateDerivative2(0., 1., 0.);
104         final FieldAbsoluteDate<UnivariateDerivative2> fieldDate =
105                 new FieldAbsoluteDate<>(variable.getField(), date).shiftedBy(variable);
106         // When
107         final FieldPVCoordinates<UnivariateDerivative2> fieldPVCoordinates = chebyshev.getPositionVelocityAcceleration(fieldDate);
108         // Then
109         final PVCoordinates expectedPVCoordinates = chebyshev.getPositionVelocityAcceleration(fieldDate.toAbsoluteDate());
110         final Vector3D expectedVelocity = expectedPVCoordinates.getVelocity();
111         final Vector3D expectedAcceleration = expectedPVCoordinates.getAcceleration();
112         final FieldVector3D<UnivariateDerivative2> fieldPosition = fieldPVCoordinates.getPosition();
113         final double tolerance = 1e-15;
114         Assertions.assertEquals(expectedVelocity.getX(), fieldPosition.getX().getDerivative(1), tolerance);
115         Assertions.assertEquals(expectedVelocity.getY(), fieldPosition.getY().getDerivative(1), tolerance);
116         Assertions.assertEquals(expectedVelocity.getZ(), fieldPosition.getZ().getDerivative(1), tolerance);
117         Assertions.assertEquals(expectedAcceleration.getX(), fieldPosition.getX().getDerivative(2), tolerance);
118         Assertions.assertEquals(expectedAcceleration.getY(), fieldPosition.getY().getDerivative(2), tolerance);
119         Assertions.assertEquals(expectedAcceleration.getZ(), fieldPosition.getZ().getDerivative(2), tolerance);
120     }
121 
122     private PosVelChebyshev createPolynomial() {
123         final AbsoluteDate start = AbsoluteDate.ARBITRARY_EPOCH;
124         final TimeScale timeScale = TimeScalesFactory.getTAI();
125         final int degree = 10;
126         final double[] firstComponents = new double[degree];
127         final double[] secondComponents = new double[degree];
128         final double[] thirdComponents = new double[degree];
129         final double arbitraryCoefficient = 1.;
130         Arrays.fill(firstComponents, arbitraryCoefficient);
131         Arrays.fill(secondComponents, arbitraryCoefficient);
132         Arrays.fill(thirdComponents, arbitraryCoefficient);
133         return new PosVelChebyshev(start, timeScale, DURATION, firstComponents, secondComponents, thirdComponents);
134     }
135 }