1   /* Copyright 2002-2025 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.hipparchus.Field;
20  import org.hipparchus.CalculusFieldElement;
21  import org.hipparchus.geometry.euclidean.threed.FieldRotation;
22  import org.hipparchus.geometry.euclidean.threed.Rotation;
23  import org.hipparchus.geometry.euclidean.threed.RotationConvention;
24  import org.orekit.frames.FieldStaticTransform;
25  import org.orekit.frames.Frame;
26  import org.orekit.frames.StaticTransform;
27  import org.orekit.time.AbsoluteDate;
28  import org.orekit.time.FieldAbsoluteDate;
29  import org.orekit.utils.FieldPVCoordinatesProvider;
30  import org.orekit.utils.PVCoordinatesProvider;
31  
32  
33  /**
34   * This class handles a simple attitude provider at constant rate around a fixed axis.
35   * <p>This attitude provider is a simple linear extrapolation from an initial
36   * orientation, a rotation axis and a rotation rate. All this elements can be
37   * specified as a simple {@link Attitude reference attitude}.</p>
38   * <p>Instances of this class are guaranteed to be immutable.</p>
39   * @author Luc Maisonobe
40   */
41  public class FixedRate implements AttitudeProvider {
42  
43      /** Reference attitude.  */
44      private final Attitude referenceAttitude;
45  
46      /** Creates a new instance.
47       * @param referenceAttitude attitude at reference date
48       */
49      public FixedRate(final Attitude referenceAttitude) {
50          this.referenceAttitude = referenceAttitude;
51      }
52  
53      /** {@inheritDoc} */
54      @Override
55      public Rotation getAttitudeRotation(final PVCoordinatesProvider pvProv, final AbsoluteDate date,
56                                          final Frame frame) {
57          final Rotation rotation = getShiftedAttitude(date).getRotation();
58          final StaticTransform transform = referenceAttitude.getReferenceFrame().getStaticTransformTo(frame, date);
59          return rotation.compose(transform.getRotation(), RotationConvention.FRAME_TRANSFORM);
60      }
61  
62      /** {@inheritDoc} */
63      @Override
64      public Attitude getAttitude(final PVCoordinatesProvider pvProv,
65                                  final AbsoluteDate date, final Frame frame) {
66          final Attitude shifted = getShiftedAttitude(date);
67          return shifted.withReferenceFrame(frame);
68      }
69  
70      /**
71       * Get shifted reference attitude.
72       * @param date date of shift
73       * @return shifted attitude
74       */
75      private Attitude getShiftedAttitude(final AbsoluteDate date) {
76          final double timeShift = date.durationFrom(referenceAttitude.getDate());
77          return referenceAttitude.shiftedBy(timeShift);
78      }
79  
80      /** {@inheritDoc} */
81      @Override
82      public <T extends CalculusFieldElement<T>> FieldRotation<T> getAttitudeRotation(final FieldPVCoordinatesProvider<T> pvProv,
83                                                                                      final FieldAbsoluteDate<T> date,
84                                                                                      final Frame frame) {
85          final FieldRotation<T> rotation = getShiftedAttitude(date).getRotation();
86          final FieldStaticTransform<T> transform = referenceAttitude.getReferenceFrame().getStaticTransformTo(frame, date);
87          return rotation.compose(transform.getRotation(), RotationConvention.FRAME_TRANSFORM);
88      }
89  
90      /** {@inheritDoc} */
91      @Override
92      public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
93                                                                              final FieldAbsoluteDate<T> date,
94                                                                              final Frame frame) {
95          final FieldAttitude<T> shifted = getShiftedAttitude(date);
96          return shifted.withReferenceFrame(frame);
97      }
98  
99      /**
100      * Get shifted reference attitude.
101      * @param date date of shift
102      * @param <T> field type
103      * @return shifted attitude
104      */
105     private <T extends CalculusFieldElement<T>> FieldAttitude<T> getShiftedAttitude(final FieldAbsoluteDate<T> date) {
106         final Field<T> field = date.getField();
107         final T timeShift = date.durationFrom(referenceAttitude.getDate());
108         return new FieldAttitude<>(field, referenceAttitude).shiftedBy(timeShift);
109     }
110 
111     /** Get the reference attitude.
112      * @return reference attitude
113      */
114     public Attitude getReferenceAttitude() {
115         return referenceAttitude;
116     }
117 
118 }