FieldAttitude.java

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

  18. import org.hipparchus.Field;
  19. import org.hipparchus.CalculusFieldElement;
  20. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  21. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  22. import org.hipparchus.geometry.euclidean.threed.Rotation;
  23. import org.hipparchus.geometry.euclidean.threed.RotationConvention;
  24. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  25. import org.orekit.frames.FieldTransform;
  26. import org.orekit.frames.Frame;
  27. import org.orekit.time.FieldAbsoluteDate;
  28. import org.orekit.time.FieldTimeShiftable;
  29. import org.orekit.time.FieldTimeStamped;
  30. import org.orekit.utils.FieldAngularCoordinates;
  31. import org.orekit.utils.TimeStampedFieldAngularCoordinates;


  32. /** This class handles attitude definition at a given date.

  33.  * <p>This class represents the rotation between a reference frame and
  34.  * the satellite frame, as well as the spin of the satellite (axis and
  35.  * rotation rate).</p>
  36.  * <p>
  37.  * The state can be slightly shifted to close dates. This shift is based on
  38.  * a linear extrapolation for attitude taking the spin rate into account.
  39.  * It is <em>not</em> intended as a replacement for proper attitude propagation
  40.  * but should be sufficient for either small time shifts or coarse accuracy.
  41.  * </p>
  42.  * <p>The instance <code>Attitude</code> is guaranteed to be immutable.</p>
  43.  * @see     org.orekit.orbits.Orbit
  44.  * @see AttitudeProvider
  45.  * @author V&eacute;ronique Pommier-Maurussane
  46.  * @param <T> type of the field elements
  47.  */

  48. public class FieldAttitude<T extends CalculusFieldElement<T>>
  49.     implements FieldTimeStamped<T>, FieldTimeShiftable<FieldAttitude<T>, T> {


  50.     /** Reference frame. */
  51.     private final Frame referenceFrame;

  52.      /** Attitude and spin.  */
  53.     private final TimeStampedFieldAngularCoordinates<T> orientation;

  54.     /** Creates a new instance.
  55.      * @param referenceFrame reference frame from which attitude is defined
  56.      * @param orientation complete orientation between reference frame and satellite frame,
  57.      * including rotation rate
  58.      */
  59.     public FieldAttitude(final Frame referenceFrame, final TimeStampedFieldAngularCoordinates<T> orientation) {
  60.         this.referenceFrame = referenceFrame;
  61.         this.orientation    = orientation;
  62.     }

  63.     /** Creates a new instance.
  64.      * @param date date at which attitude is defined
  65.      * @param referenceFrame reference frame from which attitude is defined
  66.      * @param orientation complete orientation between reference frame and satellite frame,
  67.      * including rotation rate
  68.      */
  69.     public FieldAttitude(final FieldAbsoluteDate<T> date, final Frame referenceFrame,
  70.                          final FieldAngularCoordinates<T> orientation) {
  71.         this(referenceFrame,
  72.              new TimeStampedFieldAngularCoordinates<>(date,
  73.                                                       orientation.getRotation(),
  74.                                                       orientation.getRotationRate(),
  75.                                                       orientation.getRotationAcceleration()));
  76.     }

  77.     /** Creates a new instance.
  78.      * @param date date at which attitude is defined
  79.      * @param referenceFrame reference frame from which attitude is defined
  80.      * @param attitude rotation between reference frame and satellite frame
  81.      * @param spin satellite spin (axis and velocity, in <strong>satellite</strong> frame)
  82.      * @param acceleration satellite rotation acceleration (in <strong>satellite</strong> frame)
  83.      */
  84.     public FieldAttitude(final FieldAbsoluteDate<T> date, final Frame referenceFrame,
  85.                          final FieldRotation<T> attitude, final FieldVector3D<T> spin, final FieldVector3D<T> acceleration) {
  86.         this(referenceFrame, new TimeStampedFieldAngularCoordinates<>(date, attitude, spin, acceleration));
  87.     }

  88.     /** Creates a new instance.
  89.      * @param date date at which attitude is defined
  90.      * @param referenceFrame reference frame from which attitude is defined
  91.      * @param attitude rotation between reference frame and satellite frame
  92.      * @param spin satellite spin (axis and velocity, in <strong>satellite</strong> frame)
  93.      * @param acceleration satellite rotation acceleration (in <strong>satellite</strong> frame)
  94.      * @param field field used by default
  95.      */
  96.     public FieldAttitude(final FieldAbsoluteDate<T> date, final Frame referenceFrame,
  97.                          final Rotation attitude, final Vector3D spin, final Vector3D acceleration, final Field<T> field) {
  98.         this(referenceFrame, new TimeStampedFieldAngularCoordinates<>(date,
  99.                                                                       new FieldRotation<>(field, attitude),
  100.                                                                       new FieldVector3D<>(field, spin),
  101.                                                                       new FieldVector3D<>(field, acceleration)));
  102.     }

  103.     /** Builds an instance for a regular {@link Attitude}.
  104.      * @param field fields to which the elements belong
  105.      * @param attitude attitude to convert
  106.      */
  107.     public FieldAttitude(final Field<T> field, final Attitude attitude) {
  108.         this(attitude.getReferenceFrame(), new TimeStampedFieldAngularCoordinates<>(field, attitude.getOrientation()));
  109.     }

  110.     /** Get a time-shifted attitude.
  111.      * <p>
  112.      * The state can be slightly shifted to close dates. This shift is based on
  113.      * a linear extrapolation for attitude taking the spin rate into account.
  114.      * It is <em>not</em> intended as a replacement for proper attitude propagation
  115.      * but should be sufficient for either small time shifts or coarse accuracy.
  116.      * </p>
  117.      * @param dt time shift in seconds
  118.      * @return a new attitude, shifted with respect to the instance (which is immutable)
  119.      */
  120.     public FieldAttitude<T> shiftedBy(final double dt) {
  121.         return new FieldAttitude<>(referenceFrame, orientation.shiftedBy(dt));
  122.     }

  123.     /** Get a time-shifted attitude.
  124.      * <p>
  125.      * The state can be slightly shifted to close dates. This shift is based on
  126.      * a linear extrapolation for attitude taking the spin rate into account.
  127.      * It is <em>not</em> intended as a replacement for proper attitude propagation
  128.      * but should be sufficient for either small time shifts or coarse accuracy.
  129.      * </p>
  130.      * @param dt time shift in seconds
  131.      * @return a new attitude, shifted with respect to the instance (which is immutable)
  132.      */
  133.     public FieldAttitude<T> shiftedBy(final T dt) {
  134.         return new FieldAttitude<>(referenceFrame, orientation.shiftedBy(dt));
  135.     }

  136.     /** Get a similar attitude with a specific reference frame.
  137.      * <p>
  138.      * If the instance reference frame is already the specified one, the instance
  139.      * itself is returned without any object creation. Otherwise, a new instance
  140.      * will be created with the specified reference frame. In this case, the
  141.      * required intermediate rotation and spin between the specified and the
  142.      * original reference frame will be inserted.
  143.      * </p>
  144.      * @param newReferenceFrame desired reference frame for attitude
  145.      * @return an attitude that has the same orientation and motion as the instance,
  146.      * but guaranteed to have the specified reference frame
  147.      */
  148.     public FieldAttitude<T> withReferenceFrame(final Frame newReferenceFrame) {

  149.         if (newReferenceFrame == referenceFrame) {
  150.             // simple case, the instance is already compliant
  151.             return this;
  152.         }

  153.         // we have to take an intermediate rotation into account
  154.         final FieldTransform<T> t = newReferenceFrame.getTransformTo(referenceFrame, orientation.getDate());
  155.         return new FieldAttitude<>(orientation.getDate(), newReferenceFrame,
  156.                                    orientation.getRotation().compose(t.getRotation(), RotationConvention.VECTOR_OPERATOR),
  157.                                    orientation.getRotationRate().add(orientation.getRotation().applyTo(t.getRotationRate())),
  158.                                    orientation.getRotationAcceleration().add(orientation.getRotation().applyTo(t.getRotationAcceleration())));

  159.     }

  160.     /** Get the date of attitude parameters.
  161.      * @return date of the attitude parameters
  162.      */
  163.     public FieldAbsoluteDate<T> getDate() {
  164.         return orientation.getDate();
  165.     }

  166.     /** Get the reference frame.
  167.      * @return referenceFrame reference frame from which attitude is defined.
  168.      */
  169.     public Frame getReferenceFrame() {
  170.         return referenceFrame;
  171.     }

  172.     /** Get the complete orientation including spin.
  173.      * @return complete orientation including spin
  174.      * @see #getRotation()
  175.      * @see #getSpin()
  176.      */
  177.     public TimeStampedFieldAngularCoordinates<T> getOrientation() {
  178.         return orientation;
  179.     }

  180.     /** Get the attitude rotation.
  181.      * @return attitude satellite rotation from reference frame.
  182.      * @see #getOrientation()
  183.      * @see #getSpin()
  184.      */
  185.     public FieldRotation<T> getRotation() {
  186.         return orientation.getRotation();
  187.     }

  188.     /** Get the satellite spin.
  189.      * <p>The spin vector is defined in <strong>satellite</strong> frame.</p>
  190.      * @return spin satellite spin (axis and velocity).
  191.      * @see #getOrientation()
  192.      * @see #getRotation()
  193.      */
  194.     public FieldVector3D<T> getSpin() {
  195.         return orientation.getRotationRate();
  196.     }

  197.     /** Get the satellite rotation acceleration.
  198.      * <p>The rotation acceleration. vector is defined in <strong>satellite</strong> frame.</p>
  199.      * @return rotation acceleration
  200.      * @see #getOrientation()
  201.      * @see #getRotation()
  202.      */
  203.     public FieldVector3D<T> getRotationAcceleration() {
  204.         return orientation.getRotationAcceleration();
  205.     }

  206.     /**
  207.      * Converts to an Attitude instance.
  208.      * @return Attitude with same properties
  209.      */
  210.     public Attitude toAttitude() {
  211.         return new Attitude(orientation.getDate().toAbsoluteDate(), referenceFrame, orientation.toAngularCoordinates());
  212.     }

  213. }