1   /* Copyright 2002-2024 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.io.Serializable;
20  
21  import org.hipparchus.geometry.euclidean.threed.Rotation;
22  import org.hipparchus.geometry.euclidean.threed.RotationConvention;
23  import org.hipparchus.geometry.euclidean.threed.Vector3D;
24  import org.orekit.frames.Frame;
25  import org.orekit.frames.Transform;
26  import org.orekit.time.AbsoluteDate;
27  import org.orekit.time.TimeShiftable;
28  import org.orekit.time.TimeStamped;
29  import org.orekit.utils.AngularCoordinates;
30  import org.orekit.utils.TimeStampedAngularCoordinates;
31  
32  
33  /** This class handles attitude definition at a given date.
34  
35   * <p>This class represents the rotation between a reference frame and
36   * the satellite frame, as well as the spin of the satellite (axis and
37   * rotation rate).</p>
38   * <p>
39   * The state can be slightly shifted to close dates. This shift is based on
40   * a linear extrapolation for attitude taking the spin rate into account.
41   * It is <em>not</em> intended as a replacement for proper attitude propagation
42   * but should be sufficient for either small time shifts or coarse accuracy.
43   * </p>
44   * <p>The instance <code>Attitude</code> is guaranteed to be immutable.</p>
45   * @see     org.orekit.orbits.Orbit
46   * @see AttitudeProvider
47   * @author V&eacute;ronique Pommier-Maurussane
48   */
49  
50  public class Attitude
51      implements TimeStamped, TimeShiftable<Attitude>, Serializable {
52  
53      /** Serializable UID. */
54      private static final long serialVersionUID = 20140611L;
55  
56      /** Reference frame. */
57      private final Frame referenceFrame;
58  
59       /** Attitude and spin.  */
60      private final TimeStampedAngularCoordinates orientation;
61  
62      /** Creates a new instance.
63       * @param referenceFrame reference frame from which attitude is defined
64       * @param orientation complete orientation between reference frame and satellite frame,
65       * including rotation rate
66       */
67      public Attitude(final Frame referenceFrame, final TimeStampedAngularCoordinates orientation) {
68          this.referenceFrame = referenceFrame;
69          this.orientation    = orientation;
70      }
71  
72      /** Creates a new instance.
73       * @param date date at which attitude is defined
74       * @param referenceFrame reference frame from which attitude is defined
75       * @param orientation complete orientation between reference frame and satellite frame,
76       * including rotation rate
77       */
78      public Attitude(final AbsoluteDate date, final Frame referenceFrame,
79                      final AngularCoordinates orientation) {
80          this(referenceFrame,
81               new TimeStampedAngularCoordinates(date,
82                                                 orientation.getRotation(),
83                                                 orientation.getRotationRate(),
84                                                 orientation.getRotationAcceleration()));
85      }
86  
87      /** Creates a new instance.
88       * @param date date at which attitude is defined
89       * @param referenceFrame reference frame from which attitude is defined
90       * @param attitude rotation between reference frame and satellite frame
91       * @param spin satellite spin (axis and velocity, in <strong>satellite</strong> frame)
92       * @param acceleration satellite rotation acceleration (in <strong>satellite</strong> frame)
93       */
94      public Attitude(final AbsoluteDate date, final Frame referenceFrame,
95                      final Rotation attitude, final Vector3D spin, final Vector3D acceleration) {
96          this(referenceFrame, new TimeStampedAngularCoordinates(date, attitude, spin, acceleration));
97      }
98  
99      /** Get a time-shifted attitude.
100      * <p>
101      * The state can be slightly shifted to close dates. This shift is based on
102      * a linear extrapolation for attitude taking the spin rate into account.
103      * It is <em>not</em> intended as a replacement for proper attitude propagation
104      * but should be sufficient for either small time shifts or coarse accuracy.
105      * </p>
106      * @param dt time shift in seconds
107      * @return a new attitude, shifted with respect to the instance (which is immutable)
108      */
109     public Attitude shiftedBy(final double dt) {
110         return new Attitude(referenceFrame, orientation.shiftedBy(dt));
111     }
112 
113     /** Get a similar attitude with a specific reference frame.
114      * <p>
115      * If the instance reference frame is already the specified one, the instance
116      * itself is returned without any object creation. Otherwise, a new instance
117      * will be created with the specified reference frame. In this case, the
118      * required intermediate rotation and spin between the specified and the
119      * original reference frame will be inserted.
120      * </p>
121      * @param newReferenceFrame desired reference frame for attitude
122      * @return an attitude that has the same orientation and motion as the instance,
123      * but guaranteed to have the specified reference frame
124      */
125     public Attitude withReferenceFrame(final Frame newReferenceFrame) {
126 
127         if (newReferenceFrame == referenceFrame) {
128             // simple case, the instance is already compliant
129             return this;
130         }
131 
132         // we have to take an intermediate rotation into account
133         final Transform t = newReferenceFrame.getTransformTo(referenceFrame, orientation.getDate());
134         return new Attitude(orientation.getDate(), newReferenceFrame,
135                             orientation.getRotation().compose(t.getRotation(), RotationConvention.VECTOR_OPERATOR),
136                             orientation.getRotationRate().add(orientation.getRotation().applyTo(t.getRotationRate())),
137                             orientation.getRotationAcceleration().add(orientation.getRotation().applyTo(t.getRotationAcceleration())));
138 
139     }
140 
141     /** Get the date of attitude parameters.
142      * @return date of the attitude parameters
143      */
144     public AbsoluteDate getDate() {
145         return orientation.getDate();
146     }
147 
148     /** Get the reference frame.
149      * @return referenceFrame reference frame from which attitude is defined.
150      */
151     public Frame getReferenceFrame() {
152         return referenceFrame;
153     }
154 
155     /** Get the complete orientation including spin.
156      * @return complete orientation including spin
157      * @see #getRotation()
158      * @see #getSpin()
159      */
160     public TimeStampedAngularCoordinates getOrientation() {
161         return orientation;
162     }
163 
164     /** Get the attitude rotation.
165      * @return attitude satellite rotation from reference frame.
166      * @see #getOrientation()
167      * @see #getSpin()
168      */
169     public Rotation getRotation() {
170         return orientation.getRotation();
171     }
172 
173     /** Get the satellite spin.
174      * <p>The spin vector is defined in <strong>satellite</strong> frame.</p>
175      * @return spin satellite spin (axis and velocity).
176      * @see #getOrientation()
177      * @see #getRotation()
178      */
179     public Vector3D getSpin() {
180         return orientation.getRotationRate();
181     }
182 
183     /** Get the satellite rotation acceleration.
184      * <p>The rotation acceleration. vector is defined in <strong>satellite</strong> frame.</p>
185      * @return rotation acceleration
186      * @see #getOrientation()
187      * @see #getRotation()
188      */
189     public Vector3D getRotationAcceleration() {
190         return orientation.getRotationAcceleration();
191     }
192 
193 }