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