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