1   /* Copyright 2022-2025 Romain Serra
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.utils;
19  
20  import org.hipparchus.CalculusFieldElement;
21  import org.hipparchus.Field;
22  import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
23  import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
24  import org.hipparchus.analysis.differentiation.UnivariateDerivative1Field;
25  import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
26  import org.hipparchus.analysis.differentiation.UnivariateDerivative2Field;
27  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
28  import org.hipparchus.geometry.euclidean.threed.Vector3D;
29  import org.orekit.frames.Frame;
30  import org.orekit.time.AbsoluteDate;
31  import org.orekit.time.FieldAbsoluteDate;
32  
33  /**
34   * Interface for position providers (including for Field).
35   * Emulates position (and derivatives) vector as a function of time.
36   * @author Romain Serra
37   * @since 12.1
38   */
39  public interface ExtendedPositionProvider extends PVCoordinatesProvider {
40  
41      /** Get the position in the selected frame.
42       * @param date current date
43       * @param frame the frame where to define the position
44       * @param <T> field type
45       * @return position
46       */
47      <T extends CalculusFieldElement<T>> FieldVector3D<T> getPosition(FieldAbsoluteDate<T> date, Frame frame);
48  
49      /** {@inheritDoc} */
50      @Override
51      default Vector3D getVelocity(final AbsoluteDate date, final Frame frame) {
52          final UnivariateDerivative1Field ud1Field = UnivariateDerivative1Field.getInstance();
53          final UnivariateDerivative1 ud1Shift = new UnivariateDerivative1(0., 1.);
54          final FieldAbsoluteDate<UnivariateDerivative1> fieldDate = new FieldAbsoluteDate<>(ud1Field, date).shiftedBy(ud1Shift);
55          final FieldVector3D<UnivariateDerivative1> ud1Position = getPosition(fieldDate, frame);
56          return new Vector3D(ud1Position.getX().getFirstDerivative(), ud1Position.getY().getFirstDerivative(),
57                  ud1Position.getZ().getFirstDerivative());
58      }
59  
60      /** {@inheritDoc} */
61      @Override
62      default TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame frame) {
63          final UnivariateDerivative2Field ud2Field = UnivariateDerivative2Field.getInstance();
64          final UnivariateDerivative2 ud2Shift = new UnivariateDerivative2(0., 1., 0.);
65          final FieldAbsoluteDate<UnivariateDerivative2> fieldDate = new FieldAbsoluteDate<>(ud2Field, date).shiftedBy(ud2Shift);
66          final FieldVector3D<UnivariateDerivative2> ud2Position = getPosition(fieldDate, frame);
67          final Vector3D position = ud2Position.toVector3D();
68          final Vector3D velocity = new Vector3D(ud2Position.getX().getFirstDerivative(), ud2Position.getY().getFirstDerivative(),
69              ud2Position.getZ().getFirstDerivative());
70          final Vector3D acceleration = new Vector3D(ud2Position.getX().getSecondDerivative(), ud2Position.getY().getSecondDerivative(),
71                  ud2Position.getZ().getSecondDerivative());
72          return new TimeStampedPVCoordinates(date, new PVCoordinates(position, velocity, acceleration));
73      }
74  
75      /** Get the position-velocity-acceleration in the selected frame.
76       * @param date current date
77       * @param frame the frame where to define the position
78       * @param <T> field type
79       * @return position-velocity-acceleration vector
80       */
81      default <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date,
82                                                                                                    final Frame frame) {
83          final FieldAbsoluteDate<FieldUnivariateDerivative2<T>> fud2Date = date.toFUD2Field();
84          final FieldVector3D<FieldUnivariateDerivative2<T>> fud2Position = getPosition(fud2Date, frame);
85          final FieldVector3D<T> position = new FieldVector3D<>(fud2Position.getX().getValue(), fud2Position.getY().getValue(),
86              fud2Position.getZ().getValue());
87          final FieldVector3D<T> velocity = new FieldVector3D<>(fud2Position.getX().getFirstDerivative(), fud2Position.getY().getFirstDerivative(),
88              fud2Position.getZ().getFirstDerivative());
89          final FieldVector3D<T> acceleration = new FieldVector3D<>(fud2Position.getX().getSecondDerivative(), fud2Position.getY().getSecondDerivative(),
90              fud2Position.getZ().getSecondDerivative());
91          return new TimeStampedFieldPVCoordinates<>(date, position, velocity, acceleration);
92      }
93  
94      /** Convert to a {@link FieldPVCoordinatesProvider} with a specific type.
95       * @param <T> the type of the field elements
96       * @param field field for the argument and value
97       * @return converted function
98       */
99      default <T extends CalculusFieldElement<T>> FieldPVCoordinatesProvider<T> toFieldPVCoordinatesProvider(final Field<T> field) {
100         return new FieldPVCoordinatesProvider<T>() {
101 
102             @Override
103             public FieldVector3D<T> getPosition(final FieldAbsoluteDate<T> date, final Frame frame) {
104                 return ExtendedPositionProvider.this.getPosition(date, frame);
105             }
106 
107             @Override
108             public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date,
109                                                                      final Frame frame) {
110                 return ExtendedPositionProvider.this.getPVCoordinates(date, frame);
111             }
112         };
113     }
114 
115     /**
116      * Method to convert as {@link ExtendedPVCoordinatesProvider}.
117      * @return converted object
118      * @since 13.0
119      * @deprecated since 13.0. Only there to help transition out.
120      */
121     @Deprecated
122     default ExtendedPVCoordinatesProvider toExtendedPVCoordinatesProvider() {
123         return ExtendedPositionProvider.this::getPVCoordinates;
124     }
125 }