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.attitudes;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.orekit.frames.Frame;
21  import org.orekit.time.AbstractFieldTimeInterpolator;
22  import org.orekit.time.FieldTimeInterpolator;
23  import org.orekit.time.FieldTimeStamped;
24  import org.orekit.utils.TimeStampedFieldAngularCoordinates;
25  
26  import java.util.Collections;
27  import java.util.List;
28  import java.util.stream.Collectors;
29  import java.util.stream.Stream;
30  
31  /**
32   * Class for attitude interpolation.
33   * <p>
34   * The type of interpolation used is defined by given time stamped angular coordinates interpolator at construction.
35   *
36   * @param <KK> type of the field element
37   *
38   * @author Vincent Cucchietti
39   * @see TimeStampedFieldAngularCoordinates
40   * @see FieldTimeInterpolator
41   */
42  public class FieldAttitudeInterpolator<KK extends CalculusFieldElement<KK>>
43          extends AbstractFieldTimeInterpolator<FieldAttitude<KK>, KK> {
44  
45      /** Reference frame from which attitude is defined. */
46      private final Frame referenceFrame;
47  
48      /** Time stamped angular coordinates interpolator. */
49      private final FieldTimeInterpolator<TimeStampedFieldAngularCoordinates<KK>, KK> interpolator;
50  
51      /**
52       * Constructor.
53       *
54       * @param referenceFrame reference frame from which attitude is defined
55       * @param interpolator time stamped angular coordinates interpolator
56       */
57      public FieldAttitudeInterpolator(final Frame referenceFrame,
58                                       final FieldTimeInterpolator<TimeStampedFieldAngularCoordinates<KK>, KK> interpolator) {
59          super(interpolator.getNbInterpolationPoints(), interpolator.getExtrapolationThreshold());
60          this.referenceFrame = referenceFrame;
61          this.interpolator   = interpolator;
62      }
63  
64      /** Get reference frame from which attitude is defined.
65       * @return reference frame from which attitude is defined
66       */
67      public Frame getReferenceFrame() {
68          return referenceFrame;
69      }
70  
71      /** Get time stamped angular coordinates interpolator.
72       * @return time stamped angular coordinates interpolator
73       */
74      public FieldTimeInterpolator<TimeStampedFieldAngularCoordinates<KK>, KK> getAngularInterpolator() {
75          return interpolator;
76      }
77  
78      /** {@inheritDoc} */
79      @Override
80      protected FieldAttitude<KK> interpolate(final InterpolationData interpolationData) {
81  
82          // Convert sample to stream
83          final Stream<FieldAttitude<KK>> sample = interpolationData.getNeighborList().stream();
84  
85          // Express all attitudes in the same reference frame
86          final Stream<FieldAttitude<KK>> consistentSample =
87                  sample.map(attitude -> attitude.withReferenceFrame(referenceFrame));
88  
89          // Map time stamped angular coordinates
90          final List<TimeStampedFieldAngularCoordinates<KK>> angularSample =
91                  consistentSample.map(FieldAttitude::getOrientation).collect(Collectors.toList());
92  
93          // Interpolate
94          final TimeStampedFieldAngularCoordinates<KK> interpolated =
95                  interpolator.interpolate(interpolationData.getInterpolationDate(), angularSample);
96  
97          return new FieldAttitude<>(referenceFrame, interpolated);
98      }
99  
100     @Override
101     public List<FieldTimeInterpolator<? extends FieldTimeStamped<KK>, KK>> getSubInterpolators() {
102         return Collections.singletonList(interpolator);
103     }
104 }