1   /* Copyright 2002-2026 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.frames;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative1;
21  import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
22  import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
23  import org.hipparchus.analysis.differentiation.UnivariateDerivative1Field;
24  import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
25  import org.hipparchus.analysis.differentiation.UnivariateDerivative2Field;
26  import org.hipparchus.geometry.euclidean.threed.FieldRotation;
27  import org.hipparchus.util.Binary64;
28  import org.hipparchus.util.Binary64Field;
29  import org.orekit.time.AbsoluteDate;
30  import org.orekit.time.FieldAbsoluteDate;
31  import org.orekit.utils.AngularCoordinates;
32  import org.orekit.utils.FieldAngularCoordinates;
33  
34  /** Interface for geocentric frame transform providers using automatic differentiation.
35   * @author Davide Degavi
36   * @author Romain Serra
37   * @since 13.1.8
38   */
39  interface FieldBasedTransformProvider extends TransformProvider {
40  
41      /** {@inheritDoc} */
42      @Override
43      default Transform getTransform(final AbsoluteDate date) {
44  
45          // use automatic differentiation to compute the rotation derivatives
46          final UnivariateDerivative2Field field = UnivariateDerivative2Field.getInstance();
47          final UnivariateDerivative2 dt = new UnivariateDerivative2(0, 1, 0);
48          final FieldAbsoluteDate<UnivariateDerivative2> ud2Date =
49                          new FieldAbsoluteDate<>(field, date).shiftedBy(dt);
50  
51          // set up the transform from parent frame
52          return new Transform(date, new AngularCoordinates(getRotation(ud2Date)));
53  
54      }
55  
56      /** {@inheritDoc} */
57      @Override
58      default KinematicTransform getKinematicTransform(final AbsoluteDate date) {
59  
60          // use automatic differentiation to compute the rotation rate
61          final UnivariateDerivative1Field field = UnivariateDerivative1Field.getInstance();
62          final UnivariateDerivative1 dt = new UnivariateDerivative1(0, 1);
63          final FieldAbsoluteDate<UnivariateDerivative1> ud1Date =
64                          new FieldAbsoluteDate<>(field, date).shiftedBy(dt);
65          final AngularCoordinates derivatives = new AngularCoordinates(getRotation(ud1Date));
66  
67          // set up the kinematic transform from parent frame
68          return KinematicTransform.of(date, derivatives.getRotation(), derivatives.getRotationRate());
69  
70      }
71  
72      /** {@inheritDoc} */
73      @Override
74      default StaticTransform getStaticTransform(final AbsoluteDate date) {
75          final FieldAbsoluteDate<Binary64> fieldDate = new FieldAbsoluteDate<>(Binary64Field.getInstance(), date);
76          return StaticTransform.of(date, getRotation(fieldDate).toRotation());
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      default <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
82  
83          // compute the rotation while preserving the derivatives already present in the field date
84          final FieldRotation<T> rotation = getRotation(date);
85  
86          // use automatic differentiation to compute the rotation derivatives
87          final FieldAbsoluteDate<FieldUnivariateDerivative2<T>> fud2Date = date.toFUD2Field();
88          final FieldAngularCoordinates<T> derivatives = new FieldAngularCoordinates<>(getRotation(fud2Date));
89  
90          // set up the transform from parent frame
91          return new FieldTransform<>(date,
92                                      new FieldAngularCoordinates<>(rotation,
93                                                                    derivatives.getRotationRate(),
94                                                                    derivatives.getRotationAcceleration()));
95  
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     default <T extends CalculusFieldElement<T>> FieldKinematicTransform<T> getKinematicTransform(final FieldAbsoluteDate<T> date) {
101 
102         // compute the rotation while preserving the derivatives already present in the field date
103         final FieldRotation<T> rotation = getRotation(date);
104 
105         // use automatic differentiation to compute the rotation rate
106         final FieldAbsoluteDate<FieldUnivariateDerivative1<T>> fud1Date = date.toFUD1Field();
107         final FieldAngularCoordinates<T> derivatives = new FieldAngularCoordinates<>(getRotation(fud1Date));
108 
109         // set up the kinematic transform from parent frame
110         return FieldKinematicTransform.of(date, rotation, derivatives.getRotationRate());
111 
112     }
113 
114     /** {@inheritDoc} */
115     @Override
116     default <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getStaticTransform(final FieldAbsoluteDate<T> date) {
117         return FieldStaticTransform.of(date, getRotation(date));
118     }
119 
120     /** Compute the complete rotation from parent.
121      * @param date current date
122      * @param <T> type of the field elements
123      * @return rotation
124      */
125     <T extends CalculusFieldElement<T>> FieldRotation<T> getRotation(FieldAbsoluteDate<T> date);
126 
127 }