1   /* Copyright 2002-2015 CS Systèmes d'Information
2    * Licensed to CS Systèmes d'Information (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.io.NotSerializableException;
20  import java.io.Serializable;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.orekit.errors.OrekitException;
25  import org.orekit.frames.Frame;
26  import org.orekit.time.AbsoluteDate;
27  import org.orekit.utils.AngularDerivativesFilter;
28  import org.orekit.utils.ImmutableTimeStampedCache;
29  import org.orekit.utils.PVCoordinatesProvider;
30  import org.orekit.utils.TimeStampedAngularCoordinates;
31  
32  
33  /**
34   * This class handles an attitude provider interpolating from a predefined table.
35   * <p>Instances of this class are guaranteed to be immutable.</p>
36   * @author Luc Maisonobe
37   * @since 6.1
38   */
39  public class TabulatedProvider implements AttitudeProvider {
40  
41  
42      /** Serializable UID. */
43      private static final long serialVersionUID = 20140723L;
44  
45      /** Reference frame for tabulated attitudes. */
46      private final Frame referenceFrame;
47  
48      /** Cached attitude table. */
49      private final transient ImmutableTimeStampedCache<TimeStampedAngularCoordinates> table;
50  
51      /** Filter for derivatives from the sample to use in interpolation. */
52      private final AngularDerivativesFilter filter;
53  
54      /** Creates new instance.
55       * @param table tabulated attitudes
56       * @param n number of attitude to use for interpolation
57       * @param useRotationRate if true, rotation rate from the tables are used in
58       * the interpolation, otherwise rates present in the table are ignored
59       * and rate is reconstructed from the rotation angles only
60       * @deprecated as of 7.0, replaced with {@link #TabulatedProvider(Frame, List, int, AngularDerivativesFilter)}
61       */
62      @Deprecated
63      public TabulatedProvider(final List<Attitude> table, final int n, final boolean useRotationRate) {
64          this(table.get(0).getReferenceFrame(),
65               toTimeStampedAngularCoordinates(table),
66               n, useRotationRate ? AngularDerivativesFilter.USE_RR : AngularDerivativesFilter.USE_R);
67      }
68  
69      /** Creates new instance.
70       * @param referenceFrame reference frame for tabulated attitudes
71       * @param table tabulated attitudes
72       * @param n number of attitude to use for interpolation
73       * @param filter filter for derivatives from the sample to use in interpolation
74       */
75      public TabulatedProvider(final Frame referenceFrame, final List<TimeStampedAngularCoordinates> table,
76                               final int n, final AngularDerivativesFilter filter) {
77          this.referenceFrame  = referenceFrame;
78          this.table           = new ImmutableTimeStampedCache<TimeStampedAngularCoordinates>(n, table);
79          this.filter          = filter;
80      }
81  
82      /** {@inheritDoc} */
83      public Attitude getAttitude(final PVCoordinatesProvider pvProv,
84                                  final AbsoluteDate date, final Frame frame)
85          throws OrekitException {
86  
87          // get attitudes sample on which interpolation will be performed
88          final List<TimeStampedAngularCoordinates> sample = table.getNeighbors(date);
89  
90          // interpolate
91          final TimeStampedAngularCoordinates interpolated =
92                  TimeStampedAngularCoordinates.interpolate(date, filter, sample);
93  
94          // build the attitude
95          return new Attitude(referenceFrame, interpolated);
96  
97      }
98  
99      /** Convert an attitude list into a time-stamped angular coordinates list.
100      * @param attitudes attitudes list
101      * @return converted list
102      */
103     private static List<TimeStampedAngularCoordinates> toTimeStampedAngularCoordinates(final List<Attitude> attitudes) {
104         final List<TimeStampedAngularCoordinates> converted =
105                 new ArrayList<TimeStampedAngularCoordinates>(attitudes.size());
106         for (final Attitude attitude : attitudes) {
107             converted.add(attitude.getOrientation());
108         }
109         return converted;
110     }
111 
112     /** Replace the instance with a data transfer object for serialization.
113      * @return data transfer object that will be serialized
114      * @exception NotSerializableException if the state mapper cannot be serialized (typically for DSST propagator)
115      */
116     private Object writeReplace() throws NotSerializableException {
117         return new DataTransferObject(referenceFrame, table.getAll(), table.getNeighborsSize(), filter);
118     }
119 
120     /** Internal class used only for serialization. */
121     private static class DataTransferObject implements Serializable {
122 
123         /** Serializable UID. */
124         private static final long serialVersionUID = 20140723L;
125 
126         /** Reference frame for tabulated attitudes. */
127         private final Frame referenceFrame;
128 
129         /** Cached attitude table. */
130         private final List<TimeStampedAngularCoordinates> list;
131 
132         /** Number of attitude to use for interpolation. */
133         private final int n;
134 
135         /** Filter for derivatives from the sample to use in interpolation. */
136         private final AngularDerivativesFilter filter;
137 
138         /** Simple constructor.
139          * @param referenceFrame reference frame for tabulated attitudes
140          * @param list tabulated attitudes
141          * @param n number of attitude to use for interpolation
142          * @param filter filter for derivatives from the sample to use in interpolation
143          */
144         public DataTransferObject(final Frame referenceFrame, final List<TimeStampedAngularCoordinates> list,
145                                   final int n, final AngularDerivativesFilter filter) {
146             this.referenceFrame  = referenceFrame;
147             this.list            = list;
148             this.n               = n;
149             this.filter          = filter;
150         }
151 
152         /** Replace the deserialized data transfer object with a {@link TabulatedProvider}.
153          * @return replacement {@link TabulatedProvider}
154          */
155         private Object readResolve() {
156             return new TabulatedProvider(referenceFrame, list, n, filter);
157         }
158 
159     }
160 
161 }