RateElementsType.java

  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.acm;

  18. import java.util.List;
  19. import java.util.stream.Collectors;
  20. import java.util.stream.Stream;

  21. import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
  22. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  23. import org.hipparchus.geometry.euclidean.threed.Rotation;
  24. import org.hipparchus.geometry.euclidean.threed.RotationConvention;
  25. import org.hipparchus.geometry.euclidean.threed.RotationOrder;
  26. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  27. import org.orekit.errors.OrekitException;
  28. import org.orekit.errors.OrekitMessages;
  29. import org.orekit.time.AbsoluteDate;
  30. import org.orekit.utils.TimeStampedAngularCoordinates;
  31. import org.orekit.utils.units.Unit;

  32. /** Attitude rate element set type used in CCSDS {@link Acm Attitude Comprehensive Messages}.
  33.  * @author Luc Maisonobe
  34.  * @since 12.0
  35.  */
  36. public enum RateElementsType {

  37.     // CHECKSTYLE: stop MultipleStringLiterals check

  38.     /** Angular velocity. */
  39.     ANGVEL("Angular velocity",
  40.            "°/s", "°/s", "°/s") {
  41.         /** {@inheritDoc} */
  42.         @Override
  43.         public TimeStampedAngularCoordinates toAngular(final AbsoluteDate date,
  44.                                                        final RotationOrder order,
  45.                                                        final Rotation rotation,
  46.                                                        final int first,
  47.                                                        final double[] elements) {
  48.             return new TimeStampedAngularCoordinates(date,
  49.                                                      rotation,
  50.                                                      new Vector3D(elements[first], elements[first + 1], elements[first + 2]),
  51.                                                      Vector3D.ZERO);
  52.         }
  53.     },

  54.     /** Quaternion derivatives. */
  55.     Q_DOT("Quaternion derivatives",
  56.           "s⁻¹", "s⁻¹", "s⁻¹", "s⁻¹") {
  57.         /** {@inheritDoc} */
  58.         @Override
  59.         public TimeStampedAngularCoordinates toAngular(final AbsoluteDate date,
  60.                                                        final RotationOrder order,
  61.                                                        final Rotation rotation,
  62.                                                        final int first,
  63.                                                        final double[] elements) {
  64.             final UnivariateDerivative1 q0 = new UnivariateDerivative1(rotation.getQ0(), elements[first + 3]);
  65.             final UnivariateDerivative1 q1 = new UnivariateDerivative1(rotation.getQ1(), elements[first]);
  66.             final UnivariateDerivative1 q2 = new UnivariateDerivative1(rotation.getQ2(), elements[first + 1]);
  67.             final UnivariateDerivative1 q3 = new UnivariateDerivative1(rotation.getQ3(), elements[first + 2]);
  68.             return new TimeStampedAngularCoordinates(date, new FieldRotation<>(q0, q1, q2, q3, false));
  69.         }
  70.     },

  71.     /** Euler rates. */
  72.     EULER_RATE("Euler rates",
  73.                "°/s", "°/s", "°/s") {
  74.         /** {@inheritDoc} */
  75.         @Override
  76.         public TimeStampedAngularCoordinates toAngular(final AbsoluteDate date,
  77.                                                        final RotationOrder order,
  78.                                                        final Rotation rotation,
  79.                                                        final int first,
  80.                                                        final double[] elements) {
  81.             final double[] euler0 = rotation.getAngles(order, RotationConvention.FRAME_TRANSFORM);
  82.             final UnivariateDerivative1 alpha0 = new UnivariateDerivative1(euler0[0], elements[first]);
  83.             final UnivariateDerivative1 alpha1 = new UnivariateDerivative1(euler0[1], elements[first + 1]);
  84.             final UnivariateDerivative1 alpha2 = new UnivariateDerivative1(euler0[2], elements[first + 2]);
  85.             return new TimeStampedAngularCoordinates(date, new FieldRotation<>(order, RotationConvention.FRAME_TRANSFORM,
  86.                                                                                alpha0, alpha1, alpha2));
  87.         }
  88.     },

  89.     /** Correction to gyro rates. */
  90.     GYRO_BIAS("Gyro rate corrections",
  91.               "°/s", "°/s", "°/s") {
  92.         /** {@inheritDoc} */
  93.         @Override
  94.         public TimeStampedAngularCoordinates toAngular(final AbsoluteDate date,
  95.                                                        final RotationOrder order,
  96.                                                        final Rotation rotation,
  97.                                                        final int first,
  98.                                                        final double[] elements) {
  99.             throw new OrekitException(OrekitMessages.CCSDS_UNSUPPORTED_ELEMENT_SET_TYPE, name(), toString());
  100.         }
  101.     },

  102.     /** No rates. */
  103.     NONE("no rates") {
  104.         /** {@inheritDoc} */
  105.         @Override
  106.         public TimeStampedAngularCoordinates toAngular(final AbsoluteDate date,
  107.                                                        final RotationOrder order,
  108.                                                        final Rotation rotation,
  109.                                                        final int first,
  110.                                                        final double[] elements) {
  111.             return new TimeStampedAngularCoordinates(date, rotation, Vector3D.ZERO, Vector3D.ZERO);
  112.         }
  113.     };

  114.     // CHECKSTYLE: resume MultipleStringLiterals check

  115.     /** Description. */
  116.     private final String description;

  117.     /** Elements units. */
  118.     private final List<Unit> units;

  119.     /** Simple constructor.
  120.      * @param description description
  121.      * @param unitsSpecifications elements units specifications
  122.      */
  123.     RateElementsType(final String description, final String... unitsSpecifications) {
  124.         this.description = description;
  125.         this.units       = Stream.of(unitsSpecifications).
  126.                            map(Unit::parse).
  127.                            collect(Collectors.toList());
  128.     }

  129.     /** Get the elements units.
  130.      * @return elements units
  131.      */
  132.     public List<Unit> getUnits() {
  133.         return units;
  134.     }

  135.     /** Convert to angyla coordinates.
  136.      * @param date date
  137.      * @param order rotation order for Euler angles
  138.      * @param rotation rotation
  139.      * @param first index of the first element to consider
  140.      * @param elements elements values in SI units
  141.      * @return rotation
  142.      */
  143.     public abstract TimeStampedAngularCoordinates toAngular(AbsoluteDate date,
  144.                                                             RotationOrder order,
  145.                                                             Rotation rotation,
  146.                                                             int first,
  147.                                                             double[] elements);

  148.     /** {@inheritDoc} */
  149.     @Override
  150.     public String toString() {
  151.         return description;
  152.     }

  153. }