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