LOFType.java

  1. /* Copyright 2002-2018 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.frames;

  18. import org.hipparchus.Field;
  19. import org.hipparchus.RealFieldElement;
  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.Vector3D;
  24. import org.orekit.time.AbsoluteDate;
  25. import org.orekit.time.FieldAbsoluteDate;
  26. import org.orekit.utils.FieldPVCoordinates;
  27. import org.orekit.utils.PVCoordinates;

  28. /** Enumerate for different types of Local Orbital Frames.
  29.  * @author Luc Maisonobe
  30.  */
  31. public enum LOFType {

  32.     /** Constant for TNW frame
  33.      * (X axis aligned with velocity, Z axis aligned with orbital momentum).
  34.      * <p>
  35.      * The axes of this frame are parallel to the axes of the {@link #VNC} frame:
  36.      * <ul>
  37.      *   <li>X<sub>TNW</sub> =  X<sub>VNC</sub></li>
  38.      *   <li>Y<sub>TNW</sub> = -Z<sub>VNC</sub></li>
  39.      *   <li>Z<sub>TNW</sub> =  Y<sub>VNC</sub></li>
  40.      * </ul>
  41.      *
  42.      * @see #VNC
  43.      */
  44.     TNW {

  45.         /** {@inheritDoc} */
  46.         public Rotation rotationFromInertial(final PVCoordinates pv) {
  47.             return new Rotation(pv.getVelocity(), pv.getMomentum(),
  48.                                 Vector3D.PLUS_I, Vector3D.PLUS_K);
  49.         }

  50.         /** {@inheritDoc} */
  51.         public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
  52.                                                                                      final FieldPVCoordinates<T> pv) {
  53.             return new FieldRotation<>(pv.getVelocity(), pv.getMomentum(),
  54.                                        new FieldVector3D<>(field, Vector3D.PLUS_I),
  55.                                        new FieldVector3D<>(field, Vector3D.PLUS_K));
  56.         }

  57.     },

  58.     /** Constant for QSW frame
  59.      * (X axis aligned with position, Z axis aligned with orbital momentum).
  60.      * <p>
  61.      * This frame is also known as the {@link #LVLH} frame, both constants are equivalent.
  62.      * </p>
  63.      * <p>
  64.      * The axes of these frames are parallel to the axes of the {@link #VVLH} frame:
  65.      * <ul>
  66.      *   <li>X<sub>QSW/LVLH</sub> = -Z<sub>VVLH</sub></li>
  67.      *   <li>Y<sub>QSW/LVLH</sub> =  X<sub>VVLH</sub></li>
  68.      *   <li>Z<sub>QSW/LVLH</sub> = -Y<sub>VVLH</sub></li>
  69.      * </ul>
  70.      *
  71.      * @see #LVLH
  72.      * @see #VVLH
  73.      */
  74.     QSW {

  75.         /** {@inheritDoc} */
  76.         public Rotation rotationFromInertial(final PVCoordinates pv) {
  77.             return new Rotation(pv.getPosition(), pv.getMomentum(),
  78.                                 Vector3D.PLUS_I, Vector3D.PLUS_K);
  79.         }

  80.         /** {@inheritDoc} */
  81.         public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
  82.                                                                                      final FieldPVCoordinates<T> pv) {
  83.             return new FieldRotation<>(pv.getPosition(), pv.getMomentum(),
  84.                                        new FieldVector3D<>(field, Vector3D.PLUS_I),
  85.                                        new FieldVector3D<>(field, Vector3D.PLUS_K));
  86.         }

  87.     },

  88.     /** Constant for Local Vertical, Local Horizontal frame
  89.      * (X axis aligned with position, Z axis aligned with orbital momentum).
  90.      * <p>
  91.      * This frame is also known as the {@link #QSW} frame, both constants are equivalent.
  92.      * </p>
  93.      * <p>
  94.      * The axes of these frames are parallel to the axes of the {@link #VVLH} frame:
  95.      * <ul>
  96.      *   <li>X<sub>LVLH/QSW</sub> = -Z<sub>VVLH</sub></li>
  97.      *   <li>Y<sub>LVLH/QSW</sub> =  X<sub>VVLH</sub></li>
  98.      *   <li>Z<sub>LVLH/QSW</sub> = -Y<sub>VVLH</sub></li>
  99.      * </ul>
  100.      *
  101.      * @see #QSW
  102.      * @see #VVLH
  103.      */
  104.     LVLH {

  105.         /** {@inheritDoc} */
  106.         public Rotation rotationFromInertial(final PVCoordinates pv) {
  107.             return new Rotation(pv.getPosition(), pv.getMomentum(),
  108.                                 Vector3D.PLUS_I, Vector3D.PLUS_K);
  109.         }

  110.         /** {@inheritDoc} */
  111.         public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
  112.                                                                                      final FieldPVCoordinates<T> pv) {
  113.             return new FieldRotation<>(pv.getPosition(), pv.getMomentum(),
  114.                                        new FieldVector3D<>(field, Vector3D.PLUS_I),
  115.                                        new FieldVector3D<>(field, Vector3D.PLUS_K));
  116.         }

  117.     },

  118.     /** Constant for Vehicle Velocity, Local Horizontal frame
  119.      * (Z axis aligned with opposite of position, Y axis aligned with opposite of orbital momentum).
  120.      * <p>
  121.      * The axes of this frame are parallel to the axes of both the {@link #QSW} and {@link #LVLH} frames:
  122.      * <ul>
  123.      *   <li>X<sub>VVLH</sub> =  Y<sub>QSW/LVLH</sub></li>
  124.      *   <li>Y<sub>VVLH</sub> = -Z<sub>QSW/LVLH</sub></li>
  125.      *   <li>Z<sub>VVLH</sub> = -X<sub>QSW/LVLH</sub></li>
  126.      * </ul>
  127.      *
  128.      * @see #QSW
  129.      * @see #LVLH
  130.      */
  131.     VVLH {

  132.         /** {@inheritDoc} */
  133.         public Rotation rotationFromInertial(final PVCoordinates pv) {
  134.             return new Rotation(pv.getPosition(), pv.getMomentum(),
  135.                                 Vector3D.MINUS_K, Vector3D.MINUS_J);
  136.         }

  137.         /** {@inheritDoc} */
  138.         public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
  139.                                                                                      final FieldPVCoordinates<T> pv) {
  140.             return new FieldRotation<>(pv.getPosition(), pv.getMomentum(),
  141.                                        new FieldVector3D<>(field, Vector3D.MINUS_K),
  142.                                        new FieldVector3D<>(field, Vector3D.MINUS_J));
  143.         }

  144.     },

  145.     /** Constant for Velocity - Normal - Co-normal frame
  146.      * (X axis aligned with velocity, Y axis aligned with orbital momentum).
  147.      * <p>
  148.      * The axes of this frame are parallel to the axes of the {@link #TNW} frame:
  149.      * <ul>
  150.      *   <li>X<sub>VNC</sub> =  X<sub>TNW</sub></li>
  151.      *   <li>Y<sub>VNC</sub> =  Z<sub>TNW</sub></li>
  152.      *   <li>Z<sub>VNC</sub> = -Y<sub>TNW</sub></li>
  153.      * </ul>
  154.      *
  155.      * @see #TNW
  156.      */
  157.     VNC {

  158.         /** {@inheritDoc} */
  159.         public Rotation rotationFromInertial(final PVCoordinates pv) {
  160.             return new Rotation(pv.getVelocity(), pv.getMomentum(),
  161.                                 Vector3D.PLUS_I, Vector3D.PLUS_J);
  162.         }

  163.         @Override
  164.         public <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
  165.                                                                                      final FieldPVCoordinates<T> pv) {
  166.             return new FieldRotation<>(pv.getVelocity(), pv.getMomentum(),
  167.                                        new FieldVector3D<>(field, Vector3D.PLUS_I),
  168.                                        new FieldVector3D<>(field, Vector3D.PLUS_J));
  169.         }

  170.     };

  171.     /** Get the transform from an inertial frame defining position-velocity and the local orbital frame.
  172.      * @param date current date
  173.      * @param pv position-velocity of the spacecraft in some inertial frame
  174.      * @return transform from the frame where position-velocity are defined to local orbital frame
  175.      */
  176.     public Transform transformFromInertial(final AbsoluteDate date, final PVCoordinates pv) {

  177.         // compute the translation part of the transform
  178.         final Transform translation = new Transform(date, pv.negate());

  179.         // compute the rotation part of the transform
  180.         final Rotation r = rotationFromInertial(pv);
  181.         final Vector3D p = pv.getPosition();
  182.         final Vector3D momentum = pv.getMomentum();
  183.         final Transform rotation =
  184.                 new Transform(date, r, new Vector3D(1.0 / p.getNormSq(), r.applyTo(momentum)));

  185.         return new Transform(date, translation, rotation);

  186.     }

  187.     /** Get the transform from an inertial frame defining position-velocity and the local orbital frame.
  188.      * @param date current date
  189.      * @param pv position-velocity of the spacecraft in some inertial frame
  190.      * @param <T> type of the fiels elements
  191.      * @return transform from the frame where position-velocity are defined to local orbital frame
  192.      * @since 9.0
  193.      */
  194.     public <T extends RealFieldElement<T>> FieldTransform<T> transformFromInertial(final FieldAbsoluteDate<T> date,
  195.                                                                                    final FieldPVCoordinates<T> pv) {

  196.         // compute the translation part of the transform
  197.         final FieldTransform<T> translation = new FieldTransform<>(date, pv.negate());

  198.         // compute the rotation part of the transform
  199.         final FieldRotation<T> r = rotationFromInertial(date.getField(), pv);
  200.         final FieldVector3D<T> p = pv.getPosition();
  201.         final FieldVector3D<T> momentum = pv.getMomentum();
  202.         final FieldTransform<T> rotation =
  203.                 new FieldTransform<T>(date, r, new FieldVector3D<>(p.getNormSq().reciprocal(), r.applyTo(momentum)));

  204.         return new FieldTransform<>(date, translation, rotation);

  205.     }

  206.     /** Get the rotation from inertial frame to local orbital frame.
  207.      * <p>
  208.      * This rotation does not include any time derivatives. If first
  209.      * time derivatives (i.e. rotation rate) is needed as well, the full
  210.      * {@link #transformFromInertial(AbsoluteDate, PVCoordinates) transformFromInertial}
  211.      * method must be called and the complete rotation transform must be extracted
  212.      * from it.
  213.      * </p>
  214.      * @param pv position-velocity of the spacecraft in some inertial frame
  215.      * @return rotation from inertial frame to local orbital frame
  216.      */
  217.     public abstract Rotation rotationFromInertial(PVCoordinates pv);

  218.     /** Get the rotation from inertial frame to local orbital frame.
  219.      * <p>
  220.      * This rotation does not include any time derivatives. If first
  221.      * time derivatives (i.e. rotation rate) is needed as well, the full
  222.      * {@link #transformFromInertial(FieldAbsoluteDate, FieldPVCoordinates) transformFromInertial}
  223.      * method must be called and the complete rotation transform must be extracted
  224.      * from it.
  225.      * </p>
  226.      * @param field field to which the elements belong
  227.      * @param pv position-velocity of the spacecraft in some inertial frame
  228.      * @param <T> type of the field elements
  229.      * @return rotation from inertial frame to local orbital frame
  230.      * @since 9.0
  231.      */
  232.     public abstract <T extends RealFieldElement<T>> FieldRotation<T> rotationFromInertial(Field<T> field,
  233.                                                                                           FieldPVCoordinates<T> pv);

  234. }