1   /* Copyright 2002-2013 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.apache.commons.math3.util.Pair;
25  import org.orekit.errors.OrekitException;
26  import org.orekit.frames.Frame;
27  import org.orekit.time.AbsoluteDate;
28  import org.orekit.utils.AngularCoordinates;
29  import org.orekit.utils.ImmutableTimeStampedCache;
30  import org.orekit.utils.PVCoordinatesProvider;
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 = 20131128L;
44  
45      /** Cached attitude table. */
46      private final transient ImmutableTimeStampedCache<Attitude> table;
47  
48      /** Indicator for rate use. */
49      private final boolean useRotationRate;
50  
51      /** Creates new instance.
52       * @param table tabulated attitudes
53       * @param n number of attitude to use for interpolation
54       * @param useRotationRate if true, rotation rate from the tables are used in
55       * the interpolation, ortherwise rates present in the table are ignored
56       * and rate is reconstructed from the rotation angles only
57       */
58      public TabulatedProvider(final List<Attitude> table, final int n, final boolean useRotationRate) {
59          this.table           = new ImmutableTimeStampedCache<Attitude>(n, table);
60          this.useRotationRate = useRotationRate;
61      }
62  
63      /** {@inheritDoc} */
64      public Attitude getAttitude(final PVCoordinatesProvider pvProv,
65                                  final AbsoluteDate date, final Frame frame)
66          throws OrekitException {
67  
68          // get attitudes sample on which interpolation will be performed
69          final List<Attitude> sample = table.getNeighbors(date);
70  
71          // interpolate
72          final List<Pair<AbsoluteDate, AngularCoordinates>> datedAC =
73                  new ArrayList<Pair<AbsoluteDate, AngularCoordinates>>(sample.size());
74          for (final Attitude attitude : sample) {
75              datedAC.add(new Pair<AbsoluteDate, AngularCoordinates>(attitude.getDate(), attitude.getOrientation()));
76          }
77          final AngularCoordinates interpolated = AngularCoordinates.interpolate(date, useRotationRate, datedAC);
78  
79          // build the attitude
80          return new Attitude(date, sample.get(0).getReferenceFrame(), interpolated);
81  
82      }
83  
84      /** Replace the instance with a data transfer object for serialization.
85       * @return data transfer object that will be serialized
86       * @exception NotSerializableException if the state mapper cannot be serialized (typically for DSST propagator)
87       */
88      private Object writeReplace() throws NotSerializableException {
89          return new DataTransferObject(table.getAll(), table.getNeighborsSize(), useRotationRate);
90      }
91  
92      /** Internal class used only for serialization. */
93      private static class DataTransferObject implements Serializable {
94  
95          /** Serializable UID. */
96          private static final long serialVersionUID = 20131205L;
97  
98          /** Tabulated attitudes. */
99          private final List<Attitude> list;
100 
101         /** Number of attitude to use for interpolation. */
102         private final int n;
103 
104         /** Indicator for rate use. */
105         private final boolean useRotationRate;
106 
107         /** Simple constructor.
108          * @param list tabulated attitudes
109          * @param n number of attitude to use for interpolation
110          * @param useRotationRate indicator for rate use
111          */
112         public DataTransferObject(final List<Attitude> list, final int n, final boolean useRotationRate) {
113             this.list            = list;
114             this.n               = n;
115             this.useRotationRate = useRotationRate;
116         }
117 
118         /** Replace the deserialized data transfer object with a {@link TabulatedProvider}.
119          * @return replacement {@link TabulatedProvider}
120          */
121         private Object readResolve() {
122             return new TabulatedProvider(list, n, useRotationRate);
123         }
124 
125     }
126 
127 }