1   /* Copyright 2002-2021 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 java.util.List;
20  import java.util.stream.Collectors;
21  
22  import org.hipparchus.CalculusFieldElement;
23  import org.orekit.frames.Frame;
24  import org.orekit.time.AbsoluteDate;
25  import org.orekit.time.FieldAbsoluteDate;
26  import org.orekit.utils.AngularDerivativesFilter;
27  import org.orekit.utils.FieldPVCoordinatesProvider;
28  import org.orekit.utils.ImmutableTimeStampedCache;
29  import org.orekit.utils.PVCoordinatesProvider;
30  import org.orekit.utils.TimeStampedAngularCoordinates;
31  import org.orekit.utils.TimeStampedFieldAngularCoordinates;
32  
33  
34  /**
35   * This class handles an attitude provider interpolating from a predefined table.
36   * <p>Instances of this class are guaranteed to be immutable.</p>
37   * @author Luc Maisonobe
38   * @see TabulatedLofOffset
39   * @since 6.1
40   */
41  public class TabulatedProvider implements BoundedAttitudeProvider {
42  
43      /** Cached attitude table. */
44      private final transient ImmutableTimeStampedCache<? extends TimeStampedAngularCoordinates> table;
45  
46      /** Filter for derivatives from the sample to use in interpolation. */
47      private final AngularDerivativesFilter filter;
48  
49      /** First date of the range. */
50      private final AbsoluteDate minDate;
51  
52      /** Last date of the range. */
53      private final AbsoluteDate maxDate;
54  
55      /** Builder for filtered attitudes. */
56      private final AttitudeBuilder builder;
57  
58      /** Creates new instance.
59       * <p>
60       * This constructor uses the first and last point samples as the min and max dates.
61       * </p>
62       * @param referenceFrame reference frame for tabulated attitudes
63       * @param table tabulated attitudes
64       * @param n number of attitude to use for interpolation
65       * @param filter filter for derivatives from the sample to use in interpolation
66       * @see #TabulatedProvider(List, int, AngularDerivativesFilter, AbsoluteDate, AbsoluteDate, AttitudeBuilder)
67       */
68      public TabulatedProvider(final Frame referenceFrame, final List<? extends TimeStampedAngularCoordinates> table,
69                               final int n, final AngularDerivativesFilter filter) {
70          this(table, n, filter, table.get(0).getDate(), table.get(table.size() - 1).getDate(),
71               new FixedFrameBuilder(referenceFrame));
72      }
73  
74      /** Creates new instance.
75       * @param table tabulated attitudes
76       * @param n number of attitude to use for interpolation
77       * @param filter filter for derivatives from the sample to use in interpolation
78       * @param minDate min date to use
79       * @param maxDate max date to use
80       * @param builder builder to use
81       * @since 11.0
82       */
83      public TabulatedProvider(final List<? extends TimeStampedAngularCoordinates> table,
84                               final int n, final AngularDerivativesFilter filter,
85                               final AbsoluteDate minDate, final AbsoluteDate maxDate,
86                               final AttitudeBuilder builder) {
87          this.table          = new ImmutableTimeStampedCache<TimeStampedAngularCoordinates>(n, table);
88          this.filter         = filter;
89          this.minDate        = minDate;
90          this.maxDate        = maxDate;
91          this.builder        = builder;
92      }
93  
94      /** {@inheritDoc} */
95      public Attitude getAttitude(final PVCoordinatesProvider pvProv,
96                                  final AbsoluteDate date, final Frame frame) {
97  
98          // get attitudes sample on which interpolation will be performed
99          final List<TimeStampedAngularCoordinates> sample = table.getNeighbors(date).collect(Collectors.toList());
100 
101         // interpolate
102         final TimeStampedAngularCoordinates interpolated =
103                 TimeStampedAngularCoordinates.interpolate(date, filter, sample);
104 
105         // build the attitude
106         return builder.build(frame, pvProv, interpolated);
107 
108     }
109 
110     /** {@inheritDoc} */
111     public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
112                                                                         final FieldAbsoluteDate<T> date,
113                                                                         final Frame frame) {
114 
115         // get attitudes sample on which interpolation will be performed
116         final List<TimeStampedFieldAngularCoordinates<T>> sample =
117                         table.
118                         getNeighbors(date.toAbsoluteDate()).
119                         map(ac -> new TimeStampedFieldAngularCoordinates<>(date.getField(), ac)).
120                         collect(Collectors.toList());
121 
122         // interpolate
123         final TimeStampedFieldAngularCoordinates<T> interpolated =
124                 TimeStampedFieldAngularCoordinates.interpolate(date, filter, sample);
125 
126         // build the attitude
127         return builder.build(frame, pvProv, interpolated);
128 
129     }
130 
131     /** {@inheritDoc} */
132     public AbsoluteDate getMinDate() {
133         return minDate;
134     }
135 
136     /** {@inheritDoc} */
137     public AbsoluteDate getMaxDate() {
138         return maxDate;
139     }
140 
141 }