1   /* Copyright 2022-2024 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.FieldUnivariateDerivative2Field;
24  import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
25  import org.hipparchus.analysis.differentiation.UnivariateDerivative2Field;
26  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
27  import org.hipparchus.geometry.euclidean.threed.Vector3D;
28  import org.orekit.frames.Frame;
29  import org.orekit.time.AbsoluteDate;
30  import org.orekit.time.FieldAbsoluteDate;
31  
32  /**
33   * Interface for position providers (including for Field).
34   * Emulates position (and derivatives) vector as a function of time.
35   * @author Romain Serra
36   * @since 12.1
37   */
38  public interface ExtendedPositionProvider extends PVCoordinatesProvider {
39  
40      /** Get the position in the selected frame.
41       * @param date current date
42       * @param frame the frame where to define the position
43       * @param <T> field type
44       * @return position
45       */
46      <T extends CalculusFieldElement<T>> FieldVector3D<T> getPosition(FieldAbsoluteDate<T> date, Frame frame);
47  
48      /** {@inheritDoc} */
49      @Override
50      default TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame frame) {
51          final UnivariateDerivative2Field ud2Field = UnivariateDerivative2Field.getInstance();
52          final UnivariateDerivative2 ud2Shift = new UnivariateDerivative2(0., 1., 0.);
53          final FieldAbsoluteDate<UnivariateDerivative2> fieldDate = new FieldAbsoluteDate<>(ud2Field, date).shiftedBy(ud2Shift);
54          final FieldVector3D<UnivariateDerivative2> ud2Position = getPosition(fieldDate, frame);
55          final Vector3D position = ud2Position.toVector3D();
56          final Vector3D velocity = new Vector3D(ud2Position.getX().getFirstDerivative(), ud2Position.getY().getFirstDerivative(),
57              ud2Position.getZ().getFirstDerivative());
58          final Vector3D acceleration = new Vector3D(ud2Position.getX().getSecondDerivative(), ud2Position.getY().getSecondDerivative(),
59                  ud2Position.getZ().getSecondDerivative());
60          return new TimeStampedPVCoordinates(date, new PVCoordinates(position, velocity, acceleration));
61      }
62  
63      /** Get the position-velocity-acceleration in the selected frame.
64       * @param date current date
65       * @param frame the frame where to define the position
66       * @param <T> field type
67       * @return position-velocity-acceleration vector
68       */
69      default <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date,
70                                                                                                    final Frame frame) {
71          final Field<T> field = date.getField();
72          final FieldUnivariateDerivative2Field<T> fud2Field = FieldUnivariateDerivative2Field.getUnivariateDerivative2Field(field);
73          final T fieldShift = date.durationFrom(date.toAbsoluteDate());
74          final FieldUnivariateDerivative2<T> fud2Shift = new FieldUnivariateDerivative2<>(fieldShift, field.getOne(),
75              field.getZero());
76          final FieldAbsoluteDate<FieldUnivariateDerivative2<T>> fud2Date = new FieldAbsoluteDate<>(fud2Field,
77              date.toAbsoluteDate()).shiftedBy(fud2Shift);
78          final FieldVector3D<FieldUnivariateDerivative2<T>> fud2Position = getPosition(fud2Date, frame);
79          final FieldVector3D<T> position = new FieldVector3D<>(fud2Position.getX().getValue(), fud2Position.getY().getValue(),
80              fud2Position.getZ().getValue());
81          final FieldVector3D<T> velocity = new FieldVector3D<>(fud2Position.getX().getFirstDerivative(), fud2Position.getY().getFirstDerivative(),
82              fud2Position.getZ().getFirstDerivative());
83          final FieldVector3D<T> acceleration = new FieldVector3D<>(fud2Position.getX().getSecondDerivative(), fud2Position.getY().getSecondDerivative(),
84              fud2Position.getZ().getSecondDerivative());
85          return new TimeStampedFieldPVCoordinates<>(date, position, velocity, acceleration);
86      }
87  
88      /** Convert to a {@link FieldPVCoordinatesProvider} with a specific type.
89       * @param <T> the type of the field elements
90       * @param field field for the argument and value
91       * @return converted function
92       */
93      default <T extends CalculusFieldElement<T>> FieldPVCoordinatesProvider<T> toFieldPVCoordinatesProvider(Field<T> field) {
94          return new FieldPVCoordinatesProvider<T>() {
95  
96              @Override
97              public FieldVector3D<T> getPosition(final FieldAbsoluteDate<T> date, final Frame frame) {
98                  return ExtendedPositionProvider.this.getPosition(date, frame);
99              }
100 
101             @Override
102             public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date,
103                                                                      final Frame frame) {
104                 return ExtendedPositionProvider.this.getPVCoordinates(date, frame);
105             }
106         };
107     }
108 }