EncounterLOF.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.frames.encounter;

  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.Vector3D;
  24. import org.hipparchus.geometry.euclidean.twod.FieldVector2D;
  25. import org.hipparchus.geometry.euclidean.twod.Vector2D;
  26. import org.hipparchus.linear.Array2DRowFieldMatrix;
  27. import org.hipparchus.linear.Array2DRowRealMatrix;
  28. import org.hipparchus.linear.FieldMatrix;
  29. import org.hipparchus.linear.MatrixUtils;
  30. import org.hipparchus.linear.RealMatrix;
  31. import org.hipparchus.util.MathArrays;
  32. import org.orekit.frames.LOF;
  33. import org.orekit.time.AbsoluteDate;
  34. import org.orekit.time.FieldAbsoluteDate;
  35. import org.orekit.utils.FieldPVCoordinates;
  36. import org.orekit.utils.PVCoordinates;

  37. import java.util.Arrays;
  38. import java.util.List;
  39. import java.util.stream.Collectors;

  40. /**
  41.  * Interface for encounter local orbital frame.
  42.  * <p>
  43.  * Encounter local orbital frame are defined using two objects, one of them is placed at the origin and the other is
  44.  * expressed relatively to the origin.
  45.  *
  46.  * @author Vincent Cucchietti
  47.  * @since 12.0
  48.  */
  49. public interface EncounterLOF extends LOF {

  50.     /**
  51.      * {@inheritDoc} It is unnecessary to use this method when dealing with {@link EncounterLOF}, use
  52.      * {@link #rotationFromInertial(Field, FieldPVCoordinates)} instead.
  53.      */
  54.     @Override
  55.     default <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromInertial(Field<T> field,
  56.                                                                                       FieldAbsoluteDate<T> date,
  57.                                                                                       FieldPVCoordinates<T> pv) {
  58.         return rotationFromInertial(field, pv);
  59.     }

  60.     /**
  61.      * {@inheritDoc} It is unnecessary to use this method when dealing with {@link EncounterLOF}, use
  62.      * {@link #rotationFromInertial(PVCoordinates)} instead.
  63.      */
  64.     @Override
  65.     default Rotation rotationFromInertial(AbsoluteDate date, PVCoordinates pv) {
  66.         return rotationFromInertial(pv);
  67.     }

  68.     /**
  69.      * Get the rotation from inertial to this encounter local orbital frame.
  70.      * <p>
  71.      * <b>BEWARE: The given origin's position and velocity coordinates must be given in the frame in which this instance
  72.      * has been expressed in.</b>
  73.      *
  74.      * @param field field to which the elements belong
  75.      * @param origin position-velocity of the origin in the same inertial frame as the one this instance has been expressed
  76.      * in.
  77.      * @param <T> type of the field elements
  78.      *
  79.      * @return rotation from inertial to this encounter local orbital frame
  80.      */
  81.     default <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
  82.                                                                                       final FieldPVCoordinates<T> origin) {
  83.         return rotationFromInertial(field, origin, getFieldOther(field));
  84.     }

  85.     /**
  86.      * Get the rotation from inertial to this encounter local orbital frame.
  87.      * <p>
  88.      * <b>BEWARE: The given origin's position and velocity coordinates must be given in the frame in which this instance
  89.      * has been expressed in.</b>
  90.      *
  91.      * @param origin position-velocity of the origin in some inertial frame
  92.      *
  93.      * @return rotation from inertial to this encounter local orbital frame
  94.      */
  95.     default Rotation rotationFromInertial(final PVCoordinates origin) {
  96.         return rotationFromInertial(origin, getOther());
  97.     }

  98.     /**
  99.      * Get the rotation from inertial to this encounter local orbital frame.
  100.      * <p>
  101.      * <b>BEWARE: The given origin's position and velocity coordinates must be given in the frame in which this instance
  102.      * has been expressed in.</b>
  103.      *
  104.      * @param field field to which the elements belong
  105.      * @param origin position-velocity of the origin in the same inertial frame as other
  106.      * @param other position-velocity of the other in the same inertial frame as origin
  107.      * @param <T> type of the field elements
  108.      *
  109.      * @return rotation from inertial to this encounter local orbital frame
  110.      */
  111.     <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromInertial(Field<T> field,
  112.                                                                               FieldPVCoordinates<T> origin,
  113.                                                                               FieldPVCoordinates<T> other);

  114.     /**
  115.      * Get the rotation from inertial to this encounter local orbital frame.
  116.      * <p>
  117.      * <b>BEWARE: The given origin's position and velocity coordinates must be given in the frame in which this instance
  118.      * has been expressed in.</b>
  119.      *
  120.      * @param origin position-velocity of the origin in the same inertial frame as other
  121.      * @param other position-velocity of the other instance in the same inertial frame as origin
  122.      *
  123.      * @return rotation from inertial to this encounter local orbital frame
  124.      */
  125.     Rotation rotationFromInertial(PVCoordinates origin, PVCoordinates other);

  126.     /**
  127.      * Project given {@link RealMatrix matrix} expressed in this encounter local orbital frame onto the collision plane.
  128.      *
  129.      * @param matrix matrix to project, a 3 by 3 matrix is expected
  130.      *
  131.      * @return projected matrix onto the collision plane defined by this encounter local orbital frame
  132.      */
  133.     default RealMatrix projectOntoCollisionPlane(RealMatrix matrix) {
  134.         final RealMatrix projectionMatrix = computeProjectionMatrix();
  135.         return projectionMatrix.multiply(matrix.multiplyTransposed(projectionMatrix));
  136.     }

  137.     /**
  138.      * Get the 2x3 projection matrix that projects values expressed in this encounter local orbital frame to the collision
  139.      * plane.
  140.      *
  141.      * @return 2x3 projection matrix
  142.      */
  143.     default RealMatrix computeProjectionMatrix() {
  144.         // Remove axis normal to collision plane from the identity matrix
  145.         final RealMatrix identity = MatrixUtils.createRealIdentityMatrix(3);
  146.         final List<double[]> projectionMatrixDataList = Arrays.stream(identity.getData())
  147.                                                               .filter(values -> !Arrays.equals(values,
  148.                                                                                                getAxisNormalToCollisionPlane().toArray()))
  149.                                                               .collect(Collectors.toList());

  150.         // Map list<double[]> to double[][]
  151.         final double[][] projectionMatrixData = new double[2][3];
  152.         for (int i = 0; i < 2; i++) {
  153.             projectionMatrixData[i] = projectionMatrixDataList.get(i);
  154.         }

  155.         return new Array2DRowRealMatrix(projectionMatrixData);
  156.     }

  157.     /**
  158.      * Project given {@link RealMatrix matrix} expressed in this encounter local orbital frame onto the collision plane
  159.      * defined by this same encounter local orbital frame.
  160.      *
  161.      * @param matrix matrix to project, a 3 by 3 matrix is expected
  162.      * @param <T> type of the field elements
  163.      *
  164.      * @return projected matrix onto the collision plane defined by this encounter local orbital frame
  165.      */
  166.     default <T extends CalculusFieldElement<T>> FieldMatrix<T> projectOntoCollisionPlane(FieldMatrix<T> matrix) {
  167.         final FieldMatrix<T> projectionMatrix = computeProjectionMatrix(matrix.getField());
  168.         return projectionMatrix.multiply(matrix.multiplyTransposed(projectionMatrix));
  169.     }

  170.     /**
  171.      * Get the 2x3 projection matrix that projects values expressed in this encounter local orbital frame to the collision
  172.      * plane defined by this same encounter local orbital frame.
  173.      *
  174.      * @param field field to which the elements belong
  175.      * @param <T> type of the field elements
  176.      *
  177.      * @return 2x3 projection matrix
  178.      */
  179.     default <T extends CalculusFieldElement<T>> FieldMatrix<T> computeProjectionMatrix(Field<T> field) {
  180.         // Remove axis normal to collision plane from the identity matrix
  181.         final FieldMatrix<T> identity = MatrixUtils.createFieldIdentityMatrix(field, 3);
  182.         final List<T[]> projectionMatrixDataList = Arrays.stream(identity.getData())
  183.                                                          .filter(values -> !Arrays.equals(values,
  184.                                                                                           getAxisNormalToCollisionPlane(
  185.                                                                                                   field).toArray()))
  186.                                                          .collect(Collectors.toList());

  187.         // Map list<C[]> to C[][]
  188.         final T[][] projectionMatrixData = MathArrays.buildArray(field, 2, 3);
  189.         for (int i = 0; i < 2; i++) {
  190.             projectionMatrixData[i] = projectionMatrixDataList.get(i);
  191.         }

  192.         return new Array2DRowFieldMatrix<>(projectionMatrixData);
  193.     }

  194.     /**
  195.      * Get the axis normal to the collision plane (i, j or k) in this encounter local orbital frame.
  196.      *
  197.      * @param field field of the elements
  198.      * @param <T> type of the field elements
  199.      *
  200.      * @return axis normal to the collision plane (i, j or k) in this encounter local orbital frame
  201.      */
  202.     <T extends CalculusFieldElement<T>> FieldVector3D<T> getAxisNormalToCollisionPlane(Field<T> field);

  203.     /**
  204.      * Project given {@link Vector3D vector} expressed in this encounter local orbital frame onto the collision plane.
  205.      *
  206.      * @param vector vector to project
  207.      *
  208.      * @return projected vector onto the collision plane defined by this encounter local orbital frame
  209.      */
  210.     default Vector2D projectOntoCollisionPlane(Vector3D vector) {
  211.         final RealMatrix projectionMatrix = computeProjectionMatrix();
  212.         final RealMatrix vectorInMatrix   = new Array2DRowRealMatrix(vector.toArray());

  213.         return new Vector2D(projectionMatrix.multiply(vectorInMatrix).getColumn(0));
  214.     }

  215.     /**
  216.      * Project given {@link Vector3D vector} expressed in this encounter local orbital frame onto the collision plane.
  217.      *
  218.      * @param vector vector to project
  219.      * @param <T> type of the field elements
  220.      *
  221.      * @return projected vector onto the collision plane defined by this encounter local orbital frame
  222.      */
  223.     default <T extends CalculusFieldElement<T>> FieldVector2D<T> projectOntoCollisionPlane(
  224.             final FieldVector3D<T> vector) {
  225.         final FieldMatrix<T> projectionMatrix = computeProjectionMatrix(vector.getX().getField());
  226.         final FieldMatrix<T> vectorInMatrix   = new Array2DRowFieldMatrix<>(vector.toArray());

  227.         return new FieldVector2D<>(projectionMatrix.multiply(vectorInMatrix).getColumn(0));
  228.     }

  229.     /** Get other's position and velocity coordinates.
  230.      * @param field field of the element
  231.      * @param <T> type of the element
  232.      *
  233.      * @return other's position and velocity coordinates
  234.      */
  235.     <T extends CalculusFieldElement<T>> FieldPVCoordinates<T> getFieldOther(Field<T> field);

  236.     /**
  237.      * Get the axis normal to the collision plane (i, j or k) in this encounter local orbital frame.
  238.      *
  239.      * @return axis normal to the collision plane (i, j or k) in this encounter local orbital frame
  240.      */
  241.     Vector3D getAxisNormalToCollisionPlane();

  242.     /** Get other's position and velocity coordinates.
  243.      * @return other's position and velocity coordinates
  244.      */
  245.     PVCoordinates getOther();

  246.     /** Get flag that indicates if current local orbital frame shall be treated as pseudo-inertial.
  247.      * @return flag that indicates if current local orbital frame shall be treated as pseudo-inertial
  248.      */
  249.     @Override
  250.     default boolean isQuasiInertial() {
  251.         return true;
  252.     }

  253. }