1   /* Copyright 2002-2018 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.gnss.attitude;
18  
19  import org.hipparchus.RealFieldElement;
20  import org.orekit.attitudes.Attitude;
21  import org.orekit.attitudes.FieldAttitude;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.frames.Frame;
24  import org.orekit.time.AbsoluteDate;
25  import org.orekit.time.FieldAbsoluteDate;
26  import org.orekit.utils.ExtendedPVCoordinatesProvider;
27  import org.orekit.utils.FieldPVCoordinatesProvider;
28  import org.orekit.utils.PVCoordinatesProvider;
29  import org.orekit.utils.TimeStampedAngularCoordinates;
30  import org.orekit.utils.TimeStampedFieldAngularCoordinates;
31  import org.orekit.utils.TimeStampedFieldPVCoordinates;
32  import org.orekit.utils.TimeStampedPVCoordinates;
33  
34  /**
35   * Base class for attitude providers for navigation satellites.
36   *
37   * @author Luc Maisonobe
38   * @since 9.2
39   */
40  public abstract class AbstractGNSSAttitudeProvider implements GNSSAttitudeProvider {
41  
42      /** Serializable UID. */
43      private static final long serialVersionUID = 20171114L;
44  
45      /** Start of validity for this provider. */
46      private final AbsoluteDate validityStart;
47  
48      /** End of validity for this provider. */
49      private final AbsoluteDate validityEnd;
50  
51      /** Provider for Sun position. */
52      private final ExtendedPVCoordinatesProvider sun;
53  
54      /** Inertial frame where velocity are computed. */
55      private final Frame inertialFrame;
56  
57      /** Simple constructor.
58       * @param validityStart start of validity for this provider
59       * @param validityEnd end of validity for this provider
60       * @param sun provider for Sun position
61       * @param inertialFrame inertial frame where velocity are computed
62       */
63      protected AbstractGNSSAttitudeProvider(final AbsoluteDate validityStart,
64                                             final AbsoluteDate validityEnd,
65                                             final ExtendedPVCoordinatesProvider sun,
66                                             final Frame inertialFrame) {
67          this.validityStart = validityStart;
68          this.validityEnd   = validityEnd;
69          this.sun           = sun;
70          this.inertialFrame = inertialFrame;
71      }
72  
73      /** {@inheritDoc} */
74      @Override
75      public AbsoluteDate validityStart() {
76          return validityStart;
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public AbsoluteDate validityEnd() {
82          return validityEnd;
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      public Attitude getAttitude(final PVCoordinatesProvider pvProv,
88                                  final AbsoluteDate date,
89                                  final Frame frame)
90          throws OrekitException {
91  
92          // Sun/spacecraft geometry
93          // computed in inertial frame so orbital plane (which depends on spacecraft velocity) is correct
94          final TimeStampedPVCoordinates sunPV = sun.getPVCoordinates(date, inertialFrame);
95          final TimeStampedPVCoordinates svPV  = pvProv.getPVCoordinates(date, inertialFrame);
96  
97          // compute yaw correction
98          final TimeStampedAngularCoordinates corrected = correctedYaw(new GNSSAttitudeContext(sunPV, svPV));
99  
100         return new Attitude(inertialFrame, corrected).withReferenceFrame(frame);
101 
102     }
103 
104     /** {@inheritDoc} */
105     @Override
106     public <T extends RealFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
107                                                                         final FieldAbsoluteDate<T> date,
108                                                                         final Frame frame)
109         throws OrekitException {
110 
111         // Sun/spacecraft geometry
112         // computed in inertial frame so orbital plane (which depends on spacecraft velocity) is correct
113         final TimeStampedFieldPVCoordinates<T> sunPV = sun.getPVCoordinates(date, inertialFrame);
114         final TimeStampedFieldPVCoordinates<T> svPV  = pvProv.getPVCoordinates(date, inertialFrame);
115 
116         // compute yaw correction
117         final TimeStampedFieldAngularCoordinates<T> corrected = correctedYaw(new GNSSFieldAttitudeContext<>(sunPV, svPV));
118 
119         return new FieldAttitude<>(inertialFrame, corrected).withReferenceFrame(frame);
120 
121     }
122 
123     /** Compute GNSS attitude with midnight/noon yaw turn correction.
124      * @param context context data for attitude computation
125      * @return corrected yaw, using inertial frame as the reference
126      * @exception OrekitException if yaw corrected attitude cannot be computed
127      */
128     protected abstract TimeStampedAngularCoordinates correctedYaw(GNSSAttitudeContext context)
129         throws OrekitException;
130 
131     /** Compute GNSS attitude with midnight/noon yaw turn correction.
132      * @param context context data for attitude computation
133      * @param <T> type of the field elements
134      * @return corrected yaw, using inertial frame as the reference
135      * @exception OrekitException if yaw corrected attitude cannot be computed
136      */
137     protected abstract <T extends RealFieldElement<T>> TimeStampedFieldAngularCoordinates<T>
138         correctedYaw(GNSSFieldAttitudeContext<T> context)
139         throws OrekitException;
140 
141 }