LOF.java

  1. /* Copyright 2002-2024 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.frames;

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

  29. /**
  30.  * Interface for local orbital frame.
  31.  *
  32.  * @author Vincent Cucchietti
  33.  */
  34. public interface LOF {

  35.     /**
  36.      * Get the rotation from input to output {@link LOF local orbital frame}.
  37.      * <p>
  38.      * This rotation does not include any time derivatives. If first time derivatives (i.e. rotation rate) is needed as well,
  39.      * the full {@link #transformFromLOFInToLOFOut(LOF, LOF, FieldAbsoluteDate, FieldPVCoordinates)} method must be called and
  40.      * the complete rotation transform must be extracted from it.
  41.      *
  42.      * @param field field to which the elements belong
  43.      * @param in input commonly used local orbital frame
  44.      * @param out output commonly used local orbital frame
  45.      * @param date date of the rotation
  46.      * @param pv position-velocity of the spacecraft in some inertial frame
  47.      * @param <T> type of the field elements
  48.      *
  49.      * @return rotation from input to output local orbital frame
  50.      *
  51.      * @since 11.3
  52.      */
  53.     static <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromLOFInToLOFOut(final Field<T> field,
  54.                                                                                           final LOF in, final LOF out,
  55.                                                                                           final FieldAbsoluteDate<T> date,
  56.                                                                                           final FieldPVCoordinates<T> pv) {
  57.         return out.rotationFromLOF(field, in, date, pv);
  58.     }

  59.     /**
  60.      * Get the transform from input to output {@link LOF local orbital frame}.
  61.      *
  62.      * @param in input commonly used local orbital frame
  63.      * @param out output commonly used local orbital frame
  64.      * @param date date of the transform
  65.      * @param pv position-velocity of the spacecraft in some inertial frame
  66.      * @param <T> type of the field elements
  67.      *
  68.      * @return rotation from input to output local orbital frame.
  69.      *
  70.      * @since 11.3
  71.      */
  72.     static <T extends CalculusFieldElement<T>> FieldTransform<T> transformFromLOFInToLOFOut(final LOF in, final LOF out,
  73.                                                                                             final FieldAbsoluteDate<T> date,
  74.                                                                                             final FieldPVCoordinates<T> pv) {
  75.         return out.transformFromLOF(in, date, pv);
  76.     }

  77.     /**
  78.      * Get the rotation from input to output {@link LOF local orbital frame}.
  79.      * <p>
  80.      * This rotation does not include any time derivatives. If first time derivatives (i.e. rotation rate) is needed as well,
  81.      * the full {@link #transformFromLOFInToLOFOut(LOF, LOF, AbsoluteDate, PVCoordinates)}   method must be called and
  82.      * the complete rotation transform must be extracted from it.
  83.      *
  84.      * @param in input commonly used local orbital frame
  85.      * @param out output commonly used local orbital frame
  86.      * @param date date of the rotation
  87.      * @param pv position-velocity of the spacecraft in some inertial frame
  88.      *
  89.      * @return rotation from input to output local orbital frame.
  90.      *
  91.      * @since 11.3
  92.      */
  93.     static Rotation rotationFromLOFInToLOFOut(final LOF in, final LOF out, final AbsoluteDate date, final PVCoordinates pv) {
  94.         return out.rotationFromLOF(in, date, pv);
  95.     }

  96.     /**
  97.      * Get the transform from input to output {@link LOF local orbital frame}.
  98.      *
  99.      * @param in input commonly used local orbital frame
  100.      * @param out output commonly used local orbital frame
  101.      * @param date date of the transform
  102.      * @param pv position-velocity of the spacecraft in some inertial frame
  103.      *
  104.      * @return rotation from input to output local orbital frame
  105.      *
  106.      * @since 11.3
  107.      */
  108.     static Transform transformFromLOFInToLOFOut(final LOF in, final LOF out, final AbsoluteDate date,
  109.                                                 final PVCoordinates pv) {
  110.         return out.transformFromLOF(in, date, pv);
  111.     }

  112.     /**
  113.      * Get the rotation from input {@link LOF local orbital frame} to the instance.
  114.      * <p>
  115.      * This rotation does not include any time derivatives. If first time derivatives (i.e. rotation rate) is needed as well,
  116.      * the full {@link #transformFromLOF(LOF, FieldAbsoluteDate, FieldPVCoordinates)}   method must be called and
  117.      * the complete rotation transform must be extracted from it.
  118.      *
  119.      * @param field field to which the elements belong
  120.      * @param fromLOF input local orbital frame
  121.      * @param date date of the rotation
  122.      * @param pv position-velocity of the spacecraft in some inertial frame
  123.      * @param <T> type of the field elements
  124.      *
  125.      * @return rotation from input local orbital frame to the instance
  126.      *
  127.      * @since 11.3
  128.      */
  129.     default <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromLOF(final Field<T> field,
  130.                                                                                  final LOF fromLOF,
  131.                                                                                  final FieldAbsoluteDate<T> date,
  132.                                                                                  final FieldPVCoordinates<T> pv) {

  133.         // First compute the rotation from the input LOF to the pivot inertial
  134.         final FieldRotation<T> fromLOFToInertial = fromLOF.rotationFromInertial(field, date, pv).revert();

  135.         // Then compute the rotation from the pivot inertial to the output LOF
  136.         final FieldRotation<T> inertialToThis = this.rotationFromInertial(field, date, pv);

  137.         // Output composed rotation
  138.         return fromLOFToInertial.compose(inertialToThis, RotationConvention.FRAME_TRANSFORM);
  139.     }

  140.     /**
  141.      * Get the rotation from input {@link LOF commonly used local orbital frame} to the instance.
  142.      *
  143.      * @param fromLOF input local orbital frame
  144.      * @param date date of the transform
  145.      * @param pv position-velocity of the spacecraft in some inertial frame
  146.      * @param <T> type of the field elements
  147.      *
  148.      * @return rotation from input local orbital frame to the instance
  149.      *
  150.      * @since 11.3
  151.      */
  152.     default <T extends CalculusFieldElement<T>> FieldTransform<T> transformFromLOF(final LOF fromLOF,
  153.                                                                                    final FieldAbsoluteDate<T> date,
  154.                                                                                    final FieldPVCoordinates<T> pv) {

  155.         // Get transform from input local orbital frame to inertial
  156.         final FieldTransform<T> fromLOFToInertial = fromLOF.transformFromInertial(date, pv).getInverse();

  157.         // Get transform from inertial to output local orbital frame
  158.         final FieldTransform<T> inertialToLOFOut = this.transformFromInertial(date, pv);

  159.         // Output composition of both transforms
  160.         return new FieldTransform<>(date, fromLOFToInertial, inertialToLOFOut);
  161.     }

  162.     /**
  163.      * Get the transform from an inertial frame defining position-velocity and the local orbital frame.
  164.      *
  165.      * @param date current date
  166.      * @param pv position-velocity of the spacecraft in some inertial frame
  167.      * @param <T> type of the fields elements
  168.      *
  169.      * @return transform from the frame where position-velocity are defined to local orbital frame
  170.      *
  171.      * @since 9.0
  172.      */
  173.     default <T extends CalculusFieldElement<T>> FieldTransform<T> transformFromInertial(final FieldAbsoluteDate<T> date,
  174.                                                                                         final FieldPVCoordinates<T> pv) {

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

  177.         // compute the rotation part of the transform
  178.         final FieldRotation<T> r        = rotationFromInertial(date.getField(), date, pv);
  179.         final FieldVector3D<T> p        = pv.getPosition();
  180.         final FieldVector3D<T> momentum = pv.getMomentum();
  181.         final FieldTransform<T> rotation = new FieldTransform<>(date, r,
  182.                                                                 new FieldVector3D<>(p.getNormSq().reciprocal(),
  183.                                                                                     r.applyTo(momentum)));

  184.         final FieldTransform<T> transform = new FieldTransform<>(date, translation, rotation);

  185.         // If LOF is considered pseudo-inertial, freeze transform
  186.         return isQuasiInertial() ? transform.freeze() : transform;

  187.     }

  188.     /**
  189.      * Get the rotation from inertial frame to local orbital frame.
  190.      * <p>
  191.      * This rotation does not include any time derivatives. If first time derivatives (i.e. rotation rate) is needed as well,
  192.      * the full {@link #transformFromInertial(FieldAbsoluteDate, FieldPVCoordinates)} method must be
  193.      * called and the complete rotation transform must be extracted from it.
  194.      * </p>
  195.      *
  196.      * @param field field to which the elements belong
  197.      * @param date date of the rotation
  198.      * @param pv position-velocity of the spacecraft in some inertial frame
  199.      * @param <T> type of the field elements
  200.      *
  201.      * @return rotation from inertial frame to local orbital frame
  202.      *
  203.      * @since 9.0
  204.      */
  205.     <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromInertial(Field<T> field, FieldAbsoluteDate<T> date,
  206.                                                                               FieldPVCoordinates<T> pv);

  207.     /**
  208.      * Get the rotation from input {@link LOF local orbital frame} to the instance.
  209.      * <p>
  210.      * This rotation does not include any time derivatives. If first time derivatives (i.e. rotation rate) is needed as well,
  211.      * the full {@link #transformFromLOF(LOF, AbsoluteDate, PVCoordinates)}  method must be called and
  212.      * the complete rotation transform must be extracted from it.
  213.      *
  214.      * @param fromLOF input local orbital frame
  215.      * @param date date of the rotation
  216.      * @param pv position-velocity of the spacecraft in some inertial frame
  217.      *
  218.      * @return rotation from input local orbital frame to the instance
  219.      *
  220.      * @since 11.3
  221.      */
  222.     default Rotation rotationFromLOF(final LOF fromLOF, final AbsoluteDate date, final PVCoordinates pv) {

  223.         // First compute the rotation from the input LOF to the pivot inertial
  224.         final Rotation fromLOFToInertial = fromLOF.rotationFromInertial(date, pv).revert();

  225.         // Then compute the rotation from the pivot inertial to the output LOF
  226.         final Rotation inertialToThis = this.rotationFromInertial(date, pv);

  227.         // Output composed rotation
  228.         return fromLOFToInertial.compose(inertialToThis, RotationConvention.FRAME_TRANSFORM);
  229.     }

  230.     /**
  231.      * Get the rotation from input {@link LOF local orbital frame} to the instance.
  232.      *
  233.      * @param fromLOF input local orbital frame
  234.      * @param date date of the transform
  235.      * @param pv position-velocity of the spacecraft in some inertial frame
  236.      *
  237.      * @return rotation from input local orbital frame to the instance
  238.      *
  239.      * @since 11.3
  240.      */
  241.     default Transform transformFromLOF(final LOF fromLOF, final AbsoluteDate date, final PVCoordinates pv) {

  242.         // First compute the rotation from the input LOF to the pivot inertial
  243.         final Transform fromLOFToInertial = fromLOF.transformFromInertial(date, pv).getInverse();

  244.         // Then compute the rotation from the pivot inertial to the output LOF
  245.         final Transform inertialToThis = this.transformFromInertial(date, pv);

  246.         // Output composed rotation
  247.         return new Transform(date, fromLOFToInertial, inertialToThis);
  248.     }

  249.     /**
  250.      * Get the transform from an inertial frame defining position-velocity and the local orbital frame.
  251.      *
  252.      * @param date current date
  253.      * @param pv position-velocity of the spacecraft in some inertial frame
  254.      *
  255.      * @return transform from the frame where position-velocity are defined to local orbital frame
  256.      */
  257.     default Transform transformFromInertial(final AbsoluteDate date, final PVCoordinates pv) {

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

  260.         // compute the rotation part of the transform
  261.         final Rotation  r        = rotationFromInertial(date, pv);
  262.         final Vector3D  p        = pv.getPosition();
  263.         final Vector3D  momentum = pv.getMomentum();
  264.         final Transform rotation = new Transform(date, r, new Vector3D(1.0 / p.getNormSq(), r.applyTo(momentum)));

  265.         final Transform transform = new Transform(date, translation, rotation);

  266.         // If LOF is considered pseudo-inertial, freeze transform
  267.         return isQuasiInertial() ? transform.freeze() : transform;

  268.     }

  269.     /**
  270.      * Get the rotation from inertial frame to local orbital frame.
  271.      * <p>
  272.      * This rotation does not include any time derivatives. If first time derivatives (i.e. rotation rate) is needed as well,
  273.      * the full {@link #transformFromInertial(AbsoluteDate, PVCoordinates) transformFromInertial} method must be called and
  274.      * the complete rotation transform must be extracted from it.
  275.      *
  276.      * @param date date of the rotation
  277.      * @param pv position-velocity of the spacecraft in some inertial frame
  278.      *
  279.      * @return rotation from inertial frame to local orbital frame
  280.      */
  281.     Rotation rotationFromInertial(AbsoluteDate date, PVCoordinates pv);

  282.     /** Get flag that indicates if current local orbital frame shall be treated as pseudo-inertial.
  283.      * @return flag that indicates if current local orbital frame shall be treated as pseudo-inertial
  284.      */
  285.     default boolean isQuasiInertial() {
  286.         return false;
  287.     }

  288.     /** Get name of the local orbital frame.
  289.      * @return name of the local orbital frame
  290.      */
  291.     String getName();

  292. }