1 /* Copyright 2022-2025 Luc Maisonobe 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; 18 19 import org.hipparchus.geometry.euclidean.threed.Rotation; 20 import org.hipparchus.geometry.euclidean.threed.RotationConvention; 21 import org.hipparchus.geometry.euclidean.threed.RotationOrder; 22 import org.hipparchus.geometry.euclidean.threed.Vector3D; 23 import org.hipparchus.util.FastMath; 24 import org.hipparchus.util.MathUtils; 25 import org.orekit.attitudes.Attitude; 26 import org.orekit.utils.TimeStampedAngularCoordinates; 27 28 /** Utility to extract spin data. 29 * <p> 30 * In CCSDS ADM, spin axis is forced to Z. It is not the instantaneous rotation 31 * rate as it also moves. 32 * </p> 33 * @author Luc Maisonobe 34 * @since 12.0 35 */ 36 class SpinFinder { 37 38 /** Spin axis. */ 39 private final Vector3D spin; 40 41 /** Right ascension of spin axis (rad). */ 42 private final double spinAlpha; 43 44 /** declination of spin axis (rad). */ 45 private final double spinDelta; 46 47 /** Spin angle. */ 48 private final double spinAngle; 49 50 /** Build from attitude rotation. 51 * @param attitude angular coordinates, using {@link Attitude Attitude} convention 52 * (i.e. from inertial frame to spacecraft frame) 53 */ 54 SpinFinder(final TimeStampedAngularCoordinates attitude) { 55 // spin axis is forced to Z (but it is not the instantaneous rotation rate as it also moves) 56 spin = attitude.getRotation().applyInverseTo(Vector3D.PLUS_K); 57 spinAlpha = spin.getAlpha(); 58 spinDelta = spin.getDelta(); 59 final Rotation alignSpin = new Rotation(RotationOrder.ZXZ, RotationConvention.FRAME_TRANSFORM, 60 MathUtils.SEMI_PI + spinAlpha, 61 MathUtils.SEMI_PI - spinDelta, 62 0.0); 63 final Rotation phasing = attitude.getRotation().applyTo(alignSpin.revert()); 64 spinAngle = FastMath.copySign(phasing.getAngle(), 65 phasing.getAxis(RotationConvention.FRAME_TRANSFORM).getZ()); 66 67 } 68 69 /** Get the spin axis in inertial frame. 70 * @return spin axis in inertial frame 71 */ 72 public Vector3D getSpin() { 73 return spin; 74 } 75 76 /** Get the declination of spin axis. 77 * @return declination of spin axis (rad) 78 */ 79 public double getSpinDelta() { 80 return spinDelta; 81 } 82 83 /** Get the right ascension of spin axis. 84 * @return right ascension of spin axis (rad) 85 */ 86 public double getSpinAlpha() { 87 return spinAlpha; 88 } 89 90 /** Get the spin angle. 91 * @return spin angle (rad) 92 */ 93 public double getSpinAngle() { 94 return spinAngle; 95 } 96 97 }