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.AngularCoordinates;
  28. import org.orekit.utils.FieldPVCoordinates;
  29. import org.orekit.utils.PVCoordinates;

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

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

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

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

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

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

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

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

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

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

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

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

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

  163.     /**
  164.      * Get the transform from an inertial frame defining position-velocity and the local orbital frame.
  165.      *
  166.      * @param date current date
  167.      * @param pv position-velocity of the spacecraft in some inertial frame
  168.      * @param <T> type of the fields elements
  169.      *
  170.      * @return transform from the frame where position-velocity are defined to local orbital frame
  171.      *
  172.      * @since 9.0
  173.      */
  174.     default <T extends CalculusFieldElement<T>> FieldTransform<T> transformFromInertial(final FieldAbsoluteDate<T> date,
  175.                                                                                         final FieldPVCoordinates<T> pv) {
  176.         if (isQuasiInertial()) {
  177.             final Field<T> field = date.getField();
  178.             return new FieldTransform<>(date, pv.getPosition().negate(), rotationFromInertial(field, date, pv));
  179.         }

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

  182.         // compute the rotation part of the transform
  183.         final FieldRotation<T> r        = rotationFromInertial(date.getField(), date, pv);
  184.         final FieldVector3D<T> p        = pv.getPosition();
  185.         final FieldVector3D<T> momentum = pv.getMomentum();
  186.         final FieldTransform<T> rotation = new FieldTransform<>(date, r,
  187.                                                                 new FieldVector3D<>(p.getNormSq().reciprocal(),
  188.                                                                                     r.applyTo(momentum)));

  189.         return new FieldTransform<>(date, translation, rotation);
  190.     }

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

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

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

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

  230.         // Output composed rotation
  231.         return fromLOFToInertial.compose(inertialToThis, RotationConvention.FRAME_TRANSFORM);
  232.     }

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

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

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

  249.         // Output composed rotation
  250.         return new Transform(date, fromLOFToInertial, inertialToThis);
  251.     }

  252.     /**
  253.      * Get the transform from an inertial frame defining position-velocity and the local orbital frame.
  254.      *
  255.      * @param date current date
  256.      * @param pv position-velocity of the spacecraft in some inertial frame
  257.      *
  258.      * @return transform from the frame where position-velocity are defined to local orbital frame
  259.      */
  260.     default Transform transformFromInertial(final AbsoluteDate date, final PVCoordinates pv) {
  261.         if (isQuasiInertial()) {
  262.             return new Transform(date, pv.getPosition().negate(), rotationFromInertial(date, pv));
  263.         }

  264.         // compute the rotation part of the transform
  265.         final Rotation  r        = rotationFromInertial(date, pv);
  266.         final Vector3D  p        = pv.getPosition();
  267.         final Vector3D  momentum = pv.getMomentum();
  268.         final AngularCoordinates angularCoordinates = new AngularCoordinates(r, new Vector3D(1.0 / p.getNormSq(), r.applyTo(momentum)));

  269.         return new Transform(date, pv.negate(), angularCoordinates);
  270.     }

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

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

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

  294. }