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.FieldVector3D;
23 import org.hipparchus.geometry.euclidean.threed.Rotation;
24 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.orekit.frames.FieldTransform;
27 import org.orekit.frames.Frame;
28 import org.orekit.time.FieldAbsoluteDate;
29 import org.orekit.time.FieldTimeShiftable;
30 import org.orekit.time.FieldTimeStamped;
31 import org.orekit.utils.FieldAngularCoordinates;
32 import org.orekit.utils.TimeStampedFieldAngularCoordinates;
33
34
35 /** This class handles attitude definition at a given date.
36
37 * <p>This class represents the rotation between a reference frame and
38 * the satellite frame, as well as the spin of the satellite (axis and
39 * rotation rate).</p>
40 * <p>
41 * The state can be slightly shifted to close dates. This shift is based on
42 * a linear extrapolation for attitude taking the spin rate into account.
43 * It is <em>not</em> intended as a replacement for proper attitude propagation
44 * but should be sufficient for either small time shifts or coarse accuracy.
45 * </p>
46 * <p>The instance <code>Attitude</code> is guaranteed to be immutable.</p>
47 * @see org.orekit.orbits.Orbit
48 * @see AttitudeProvider
49 * @author Véronique Pommier-Maurussane
50 * @param <T> type of the field elements
51 */
52
53 public class FieldAttitude<T extends CalculusFieldElement<T>>
54 implements FieldTimeStamped<T>, FieldTimeShiftable<FieldAttitude<T>, T> {
55
56
57 /** Reference frame. */
58 private final Frame referenceFrame;
59
60 /** Attitude and spin. */
61 private final TimeStampedFieldAngularCoordinates<T> orientation;
62
63 /** Creates a new instance.
64 * @param referenceFrame reference frame from which attitude is defined
65 * @param orientation complete orientation between reference frame and satellite frame,
66 * including rotation rate
67 */
68 public FieldAttitude(final Frame referenceFrame, final TimeStampedFieldAngularCoordinates<T> orientation) {
69 this.referenceFrame = referenceFrame;
70 this.orientation = orientation;
71 }
72
73 /** Creates a new instance.
74 * @param date date at which attitude is defined
75 * @param referenceFrame reference frame from which attitude is defined
76 * @param orientation complete orientation between reference frame and satellite frame,
77 * including rotation rate
78 */
79 public FieldAttitude(final FieldAbsoluteDate<T> date, final Frame referenceFrame,
80 final FieldAngularCoordinates<T> orientation) {
81 this(referenceFrame,
82 new TimeStampedFieldAngularCoordinates<>(date,
83 orientation.getRotation(),
84 orientation.getRotationRate(),
85 orientation.getRotationAcceleration()));
86 }
87
88 /** Creates a new instance.
89 * @param date date at which attitude is defined
90 * @param referenceFrame reference frame from which attitude is defined
91 * @param attitude rotation between reference frame and satellite frame
92 * @param spin satellite spin (axis and velocity, in <strong>satellite</strong> frame)
93 * @param acceleration satellite rotation acceleration (in <strong>satellite</strong> frame)
94 */
95 public FieldAttitude(final FieldAbsoluteDate<T> date, final Frame referenceFrame,
96 final FieldRotation<T> attitude, final FieldVector3D<T> spin, final FieldVector3D<T> acceleration) {
97 this(referenceFrame, new TimeStampedFieldAngularCoordinates<>(date, attitude, spin, acceleration));
98 }
99
100 /** Creates a new instance.
101 * @param date date at which attitude is defined
102 * @param referenceFrame reference frame from which attitude is defined
103 * @param attitude rotation between reference frame and satellite frame
104 * @param spin satellite spin (axis and velocity, in <strong>satellite</strong> frame)
105 * @param acceleration satellite rotation acceleration (in <strong>satellite</strong> frame)
106 * @param field field used by default
107 */
108 public FieldAttitude(final FieldAbsoluteDate<T> date, final Frame referenceFrame,
109 final Rotation attitude, final Vector3D spin, final Vector3D acceleration, final Field<T> field) {
110 this(referenceFrame, new TimeStampedFieldAngularCoordinates<>(date,
111 new FieldRotation<>(field, attitude),
112 new FieldVector3D<>(field, spin),
113 new FieldVector3D<>(field, acceleration)));
114 }
115
116 /** Builds an instance for a regular {@link Attitude}.
117 * @param field fields to which the elements belong
118 * @param attitude attitude to convert
119 */
120 public FieldAttitude(final Field<T> field, final Attitude attitude) {
121 this(attitude.getReferenceFrame(), new TimeStampedFieldAngularCoordinates<>(field, attitude.getOrientation()));
122 }
123
124 /** Get a time-shifted attitude.
125 * <p>
126 * The state can be slightly shifted to close dates. This shift is based on
127 * a linear extrapolation for attitude taking the spin rate into account.
128 * It is <em>not</em> intended as a replacement for proper attitude propagation
129 * but should be sufficient for either small time shifts or coarse accuracy.
130 * </p>
131 * @param dt time shift in seconds
132 * @return a new attitude, shifted with respect to the instance (which is immutable)
133 */
134 public FieldAttitude<T> shiftedBy(final double dt) {
135 return new FieldAttitude<>(referenceFrame, orientation.shiftedBy(dt));
136 }
137
138 /** Get a time-shifted attitude.
139 * <p>
140 * The state can be slightly shifted to close dates. This shift is based on
141 * a linear extrapolation for attitude taking the spin rate into account.
142 * It is <em>not</em> intended as a replacement for proper attitude propagation
143 * but should be sufficient for either small time shifts or coarse accuracy.
144 * </p>
145 * @param dt time shift in seconds
146 * @return a new attitude, shifted with respect to the instance (which is immutable)
147 */
148 public FieldAttitude<T> shiftedBy(final T dt) {
149 return new FieldAttitude<>(referenceFrame, orientation.shiftedBy(dt));
150 }
151
152 /** Get a similar attitude with a specific reference frame.
153 * <p>
154 * If the instance reference frame is already the specified one, the instance
155 * itself is returned without any object creation. Otherwise, a new instance
156 * will be created with the specified reference frame. In this case, the
157 * required intermediate rotation and spin between the specified and the
158 * original reference frame will be inserted.
159 * </p>
160 * @param newReferenceFrame desired reference frame for attitude
161 * @return an attitude that has the same orientation and motion as the instance,
162 * but guaranteed to have the specified reference frame
163 */
164 public FieldAttitude<T> withReferenceFrame(final Frame newReferenceFrame) {
165
166 if (newReferenceFrame == referenceFrame) {
167 // simple case, the instance is already compliant
168 return this;
169 }
170
171 // we have to take an intermediate rotation into account
172 final FieldTransform<T> t = newReferenceFrame.getTransformTo(referenceFrame, orientation.getDate());
173 return new FieldAttitude<>(orientation.getDate(), newReferenceFrame,
174 orientation.getRotation().compose(t.getRotation(), RotationConvention.VECTOR_OPERATOR),
175 orientation.getRotationRate().add(orientation.getRotation().applyTo(t.getRotationRate())),
176 orientation.getRotationAcceleration().add(orientation.getRotation().applyTo(t.getRotationAcceleration())));
177
178 }
179
180 /** Get the date of attitude parameters.
181 * @return date of the attitude parameters
182 */
183 public FieldAbsoluteDate<T> getDate() {
184 return orientation.getDate();
185 }
186
187 /** Get the reference frame.
188 * @return referenceFrame reference frame from which attitude is defined.
189 */
190 public Frame getReferenceFrame() {
191 return referenceFrame;
192 }
193
194 /** Get the complete orientation including spin.
195 * @return complete orientation including spin
196 * @see #getRotation()
197 * @see #getSpin()
198 */
199 public TimeStampedFieldAngularCoordinates<T> getOrientation() {
200 return orientation;
201 }
202
203 /** Get the attitude rotation.
204 * @return attitude satellite rotation from reference frame.
205 * @see #getOrientation()
206 * @see #getSpin()
207 */
208 public FieldRotation<T> getRotation() {
209 return orientation.getRotation();
210 }
211
212 /** Get the satellite spin.
213 * <p>The spin vector is defined in <strong>satellite</strong> frame.</p>
214 * @return spin satellite spin (axis and velocity).
215 * @see #getOrientation()
216 * @see #getRotation()
217 */
218 public FieldVector3D<T> getSpin() {
219 return orientation.getRotationRate();
220 }
221
222 /** Get the satellite rotation acceleration.
223 * <p>The rotation acceleration. vector is defined in <strong>satellite</strong> frame.</p>
224 * @return rotation acceleration
225 * @see #getOrientation()
226 * @see #getRotation()
227 */
228 public FieldVector3D<T> getRotationAcceleration() {
229 return orientation.getRotationAcceleration();
230 }
231
232 /**
233 * Converts to an Attitude instance.
234 * @return Attitude with same properties
235 */
236 public Attitude toAttitude() {
237 return new Attitude(orientation.getDate().toAbsoluteDate(), referenceFrame, orientation.toAngularCoordinates());
238 }
239
240 }