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 }