1 /* Copyright 2002-2026 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.files.ccsds.ndm.adm.apm;
18
19 import org.orekit.errors.OrekitException;
20 import org.orekit.errors.OrekitMessages;
21 import org.orekit.files.ccsds.definitions.CcsdsFrameMapper;
22 import org.orekit.files.ccsds.ndm.adm.AttitudeEndpoints;
23 import org.orekit.files.ccsds.section.CommentsContainer;
24 import org.orekit.frames.Frame;
25
26 /**
27 * Container for Attitude Parameter Message data lines.
28 * <p>
29 * Beware that the Orekit getters and setters all rely on SI units. The parsers
30 * and writers take care of converting these SI units into CCSDS mandatory units.
31 * The {@link org.orekit.utils.units.Unit Unit} class provides useful
32 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
33 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
34 * already use CCSDS units instead of the API SI units. The general-purpose
35 * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
36 * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
37 * (with an 's') also provide some predefined units. These predefined units and the
38 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
39 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
40 * what the parsers and writers use for the conversions.
41 * </p>
42 * @author Bryan Cazabonne
43 * @since 10.2
44 */
45 public class SpinStabilized extends CommentsContainer {
46
47 /** Endpoints (i.e. frames A, B and their relationship). */
48 private final AttitudeEndpoints endpoints;
49
50 /** Right ascension of spin axis vector (rad). */
51 private double spinAlpha;
52
53 /** Declination of the spin axis vector (rad). */
54 private double spinDelta;
55
56 /** Phase of the satellite about the spin axis (rad). */
57 private double spinAngle;
58
59 /** Angular velocity of satellite around spin axis (rad/s). */
60 private double spinAngleVel;
61
62 /** Nutation angle of spin axis (rad). */
63 private double nutation;
64
65 /** Body nutation period of the spin axis (s). */
66 private double nutationPer;
67
68 /** Inertial nutation phase (rad). */
69 private double nutationPhase;
70
71 /** Right ascension of angular momentum vector (rad).
72 * @since 12.0
73 */
74 private double momentumAlpha;
75
76 /** Declination of the angular momentum vector (rad).
77 * @since 12.0
78 */
79 private double momentumDelta;
80
81 /** Angular velocity of spin vector around the angular momentum vector (rad/s).
82 * @since 12.0
83 */
84 private double nutationVel;
85
86 /**
87 * Simple constructor.
88 *
89 * @param frameMapper for creating a {@link Frame}.
90 * @since 13.1.5
91 */
92 public SpinStabilized(final CcsdsFrameMapper frameMapper) {
93 endpoints = new AttitudeEndpoints(frameMapper);
94 spinAlpha = Double.NaN;
95 spinDelta = Double.NaN;
96 spinAngle = Double.NaN;
97 spinAngleVel = Double.NaN;
98 nutation = Double.NaN;
99 nutationPer = Double.NaN;
100 nutationPhase = Double.NaN;
101 momentumAlpha = Double.NaN;
102 momentumDelta = Double.NaN;
103 nutationVel = Double.NaN;
104 }
105
106 /** {@inheritDoc} */
107 @Override
108 public void validate(final double version) {
109 super.validate(version);
110 endpoints.checkMandatoryEntriesExceptExternalFrame(version,
111 SpinStabilizedKey.SPIN_FRAME_A,
112 SpinStabilizedKey.SPIN_FRAME_B,
113 SpinStabilizedKey.SPIN_DIR);
114 endpoints.checkExternalFrame(SpinStabilizedKey.SPIN_FRAME_A, SpinStabilizedKey.SPIN_FRAME_B);
115 checkNotNaN(spinAlpha, SpinStabilizedKey.SPIN_ALPHA.name());
116 checkNotNaN(spinDelta, SpinStabilizedKey.SPIN_DELTA.name());
117 checkNotNaN(spinAngle, SpinStabilizedKey.SPIN_ANGLE.name());
118 checkNotNaN(spinAngleVel, SpinStabilizedKey.SPIN_ANGLE_VEL.name());
119 if (Double.isNaN(nutation + nutationPer + nutationPhase)) {
120 // if at least one is NaN, all must be NaN (i.e. not initialized)
121 if (!(Double.isNaN(nutation) && Double.isNaN(nutationPer) && Double.isNaN(nutationPhase))) {
122 throw new OrekitException(OrekitMessages.UNINITIALIZED_VALUE_FOR_KEY, "NUTATION*");
123 }
124 }
125 if (Double.isNaN(momentumAlpha + momentumDelta + nutationVel)) {
126 // if at least one is NaN, all must be NaN (i.e. not initialized)
127 if (!(Double.isNaN(momentumAlpha) && Double.isNaN(momentumDelta) && Double.isNaN(nutationVel))) {
128 throw new OrekitException(OrekitMessages.UNINITIALIZED_VALUE_FOR_KEY, "MOMENTUM*/NUTATION_VEL");
129 }
130 }
131 }
132
133 /** Get the endpoints (i.e. frames A, B and their relationship).
134 * @return endpoints
135 */
136 public AttitudeEndpoints getEndpoints() {
137 return endpoints;
138 }
139
140 /**
141 * Get the right ascension of spin axis vector (rad).
142 * @return the right ascension of spin axis vector
143 */
144 public double getSpinAlpha() {
145 return spinAlpha;
146 }
147
148 /**
149 * Set the right ascension of spin axis vector (rad).
150 * @param spinAlpha value to be set
151 */
152 public void setSpinAlpha(final double spinAlpha) {
153 refuseFurtherComments();
154 this.spinAlpha = spinAlpha;
155 }
156
157 /**
158 * Get the declination of the spin axis vector (rad).
159 * @return the declination of the spin axis vector (rad).
160 */
161 public double getSpinDelta() {
162 return spinDelta;
163 }
164
165 /**
166 * Set the declination of the spin axis vector (rad).
167 * @param spinDelta value to be set
168 */
169 public void setSpinDelta(final double spinDelta) {
170 refuseFurtherComments();
171 this.spinDelta = spinDelta;
172 }
173
174 /**
175 * Get the phase of the satellite about the spin axis (rad).
176 * @return the phase of the satellite about the spin axis
177 */
178 public double getSpinAngle() {
179 return spinAngle;
180 }
181
182 /**
183 * Set the phase of the satellite about the spin axis (rad).
184 * @param spinAngle value to be set
185 */
186 public void setSpinAngle(final double spinAngle) {
187 refuseFurtherComments();
188 this.spinAngle = spinAngle;
189 }
190
191 /**
192 * Get the angular velocity of satellite around spin axis (rad/s).
193 * @return the angular velocity of satellite around spin axis
194 */
195 public double getSpinAngleVel() {
196 return spinAngleVel;
197 }
198
199 /**
200 * Set the angular velocity of satellite around spin axis (rad/s).
201 * @param spinAngleVel value to be set
202 */
203 public void setSpinAngleVel(final double spinAngleVel) {
204 refuseFurtherComments();
205 this.spinAngleVel = spinAngleVel;
206 }
207
208 /**
209 * Get the nutation angle of spin axis (rad).
210 * @return the nutation angle of spin axis
211 */
212 public double getNutation() {
213 return nutation;
214 }
215
216 /**
217 * Set the nutation angle of spin axis (rad).
218 * @param nutation the nutation angle to be set
219 */
220 public void setNutation(final double nutation) {
221 refuseFurtherComments();
222 this.nutation = nutation;
223 }
224
225 /**
226 * Get the body nutation period of the spin axis (s).
227 * @return the body nutation period of the spin axis
228 */
229 public double getNutationPeriod() {
230 return nutationPer;
231 }
232
233 /**
234 * Set the body nutation period of the spin axis (s).
235 * @param period the nutation period to be set
236 */
237 public void setNutationPeriod(final double period) {
238 refuseFurtherComments();
239 this.nutationPer = period;
240 }
241
242 /**
243 * Get the inertial nutation phase (rad).
244 * @return the inertial nutation phase
245 */
246 public double getNutationPhase() {
247 return nutationPhase;
248 }
249
250 /**
251 * Set the inertial nutation phase (rad).
252 * @param nutationPhase the nutation phase to be set
253 */
254 public void setNutationPhase(final double nutationPhase) {
255 refuseFurtherComments();
256 this.nutationPhase = nutationPhase;
257 }
258
259 /**
260 * Get the right ascension of angular momentum vector (rad).
261 * @return the right ascension of angular momentum vector
262 * @since 12.0
263 */
264 public double getMomentumAlpha() {
265 return momentumAlpha;
266 }
267
268 /**
269 * Set the right ascension of angular momentum vector (rad).
270 * @param momentumAlpha value to be set
271 * @since 12.0
272 */
273 public void setMomentumAlpha(final double momentumAlpha) {
274 refuseFurtherComments();
275 this.momentumAlpha = momentumAlpha;
276 }
277
278 /**
279 * Get the declination of the angular momentum vector (rad).
280 * @return the declination of the angular momentum vector (rad).
281 * @since 12.0
282 */
283 public double getMomentumDelta() {
284 return momentumDelta;
285 }
286
287 /**
288 * Set the declination of the angular momentum vector (rad).
289 * @param momentumDelta value to be set
290 * @since 12.0
291 */
292 public void setMomentumDelta(final double momentumDelta) {
293 refuseFurtherComments();
294 this.momentumDelta = momentumDelta;
295 }
296
297 /**
298 * Get the angular velocity of spin vector around angular momentum vector.
299 * @return angular velocity of spin vector around angular momentum vector (rad/s)
300 * @since 12.0
301 */
302 public double getNutationVel() {
303 return nutationVel;
304 }
305
306 /**
307 * Set the angular velocity of spin vector around angular momentum vector.
308 * @param nutationVel angular velocity of spin vector around angular momentum vector (rad/s)
309 * @since 12.0
310 */
311 public void setNutationVel(final double nutationVel) {
312 refuseFurtherComments();
313 this.nutationVel = nutationVel;
314 }
315
316 /** Check if the logical block includes nutation.
317 * @return true if logical block includes nutation
318 * @since 12.0
319 */
320 public boolean hasNutation() {
321 return !Double.isNaN(nutation + nutationPer + nutationPhase);
322 }
323
324 /** Check if the logical block includes momentum.
325 * @return true if logical block includes momentum
326 * @since 12.0
327 */
328 public boolean hasMomentum() {
329 return !Double.isNaN(momentumAlpha + momentumDelta + nutationVel);
330 }
331
332 }