PredefinedTarget.java

  1. /* Copyright 2022-2025 Luc Maisonobe
  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.CalculusFieldElement;
  19. import org.hipparchus.analysis.differentiation.FieldUnivariateDerivative2;
  20. import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
  21. import org.hipparchus.analysis.differentiation.UnivariateDerivative2Field;
  22. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  23. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  24. import org.orekit.bodies.FieldGeodeticPoint;
  25. import org.orekit.bodies.GeodeticPoint;
  26. import org.orekit.bodies.OneAxisEllipsoid;
  27. import org.orekit.frames.FieldStaticTransform;
  28. import org.orekit.frames.Frame;
  29. import org.orekit.frames.StaticTransform;
  30. import org.orekit.time.AbsoluteDate;
  31. import org.orekit.time.FieldAbsoluteDate;
  32. import org.orekit.utils.ExtendedPositionProvider;
  33. import org.orekit.utils.PVCoordinates;
  34. import org.orekit.utils.TimeStampedFieldPVCoordinates;
  35. import org.orekit.utils.TimeStampedPVCoordinates;

  36. /**
  37.  * Predefined targets for {@link AlignedAndConstrained}.
  38.  * @author Luc Maisonobe
  39.  * @since 12.2
  40.  */
  41. public enum PredefinedTarget implements TargetProvider
  42. {

  43.     /** Sun direction. */
  44.     SUN {

  45.         /** {@inheritDoc} */
  46.         @Override
  47.         public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  48.                                                                                   final OneAxisEllipsoid earth,
  49.                                                                                   final TimeStampedPVCoordinates pv,
  50.                                                                                   final Frame frame) {
  51.             return new PVCoordinates(pv, sun.getPVCoordinates(pv.getDate(), frame)).
  52.                    toUnivariateDerivative2Vector().
  53.                    normalize();
  54.         }

  55.         /** {@inheritDoc} */
  56.         @Override
  57.         public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
  58.                                            final TimeStampedPVCoordinates pv, final Frame frame) {
  59.             return sun.getPosition(pv.getDate(), frame).subtract(pv.getPosition()).normalize();
  60.         }

  61.         /** {@inheritDoc} */
  62.         @Override
  63.         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
  64.                                                                                        final OneAxisEllipsoid earth,
  65.                                                                                        final TimeStampedFieldPVCoordinates<T> pv,
  66.                                                                                        final Frame frame) {
  67.             return sun.getPosition(pv.getDate(), frame).subtract(pv.getPosition()).normalize();
  68.         }
  69.     },

  70.     /** Earth direction (assumes the frame is Earth centered). */
  71.     EARTH {

  72.         /** {@inheritDoc} */
  73.         @Override
  74.         public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  75.                                                                                   final OneAxisEllipsoid earth,
  76.                                                                                   final TimeStampedPVCoordinates pv,
  77.                                                                                   final Frame frame) {
  78.             return pv.toUnivariateDerivative2Vector().negate().normalize();
  79.         }

  80.         /** {@inheritDoc} */
  81.         @Override
  82.         public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
  83.                                            final TimeStampedPVCoordinates pv, final Frame frame) {
  84.             return pv.getPosition().negate().normalize();
  85.         }

  86.         /** {@inheritDoc} */
  87.         @Override
  88.         public <T extends CalculusFieldElement<T>> FieldVector3D<FieldUnivariateDerivative2<T>> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  89.                                                                                                                               final OneAxisEllipsoid earth,
  90.                                                                                                                               final TimeStampedFieldPVCoordinates<T> pv,
  91.                                                                                                                               final Frame frame) {
  92.             return pv.toUnivariateDerivative2Vector().negate().normalize();
  93.         }

  94.         /** {@inheritDoc} */
  95.         @Override
  96.         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
  97.                                                                                        final OneAxisEllipsoid earth,
  98.                                                                                        final TimeStampedFieldPVCoordinates<T> pv,
  99.                                                                                        final Frame frame) {
  100.             return pv.getPosition().negate().normalize();
  101.         }
  102.     },

  103.     /** Nadir. */
  104.     NADIR {

  105.         /** {@inheritDoc} */
  106.         @Override
  107.         public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  108.                                                                                   final OneAxisEllipsoid earth,
  109.                                                                                   final TimeStampedPVCoordinates pv,
  110.                                                                                   final Frame frame) {
  111.             final FieldStaticTransform<UnivariateDerivative2> inert2Earth = inert2Earth(earth, pv.getDate(), frame);
  112.             final FieldGeodeticPoint<UnivariateDerivative2> gp = toGeodeticPoint(earth, pv, inert2Earth);
  113.             return inert2Earth.getStaticInverse().transformVector(gp.getNadir());
  114.         }

  115.         /** {@inheritDoc} */
  116.         @Override
  117.         public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
  118.                                            final TimeStampedPVCoordinates pv, final Frame frame) {
  119.             final StaticTransform inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
  120.             final GeodeticPoint geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
  121.                     earth.getBodyFrame(), pv.getDate());
  122.             return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNadir());
  123.         }

  124.         /** {@inheritDoc} */
  125.         @Override
  126.         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
  127.                                                                                        final OneAxisEllipsoid earth,
  128.                                                                                        final TimeStampedFieldPVCoordinates<T> pv,
  129.                                                                                        final Frame frame) {
  130.             final FieldStaticTransform<T> inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
  131.             final FieldGeodeticPoint<T> geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
  132.                     earth.getBodyFrame(), pv.getDate());
  133.             return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNadir());
  134.         }
  135.     },

  136.     /** North direction. */
  137.     NORTH {

  138.         /** {@inheritDoc} */
  139.         @Override
  140.         public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  141.                                                                                   final OneAxisEllipsoid earth,
  142.                                                                                   final TimeStampedPVCoordinates pv,
  143.                                                                                   final Frame frame) {
  144.             final FieldStaticTransform<UnivariateDerivative2> inert2Earth = inert2Earth(earth, pv.getDate(), frame);
  145.             final FieldGeodeticPoint<UnivariateDerivative2> gp = toGeodeticPoint(earth, pv, inert2Earth);
  146.             return inert2Earth.getStaticInverse().transformVector(gp.getNorth());
  147.         }

  148.         /** {@inheritDoc} */
  149.         @Override
  150.         public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
  151.                                            final TimeStampedPVCoordinates pv, final Frame frame) {
  152.             final StaticTransform inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
  153.             final GeodeticPoint geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
  154.                     earth.getBodyFrame(), pv.getDate());
  155.             return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNorth());
  156.         }

  157.         /** {@inheritDoc} */
  158.         @Override
  159.         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
  160.                                                                                        final OneAxisEllipsoid earth,
  161.                                                                                        final TimeStampedFieldPVCoordinates<T> pv,
  162.                                                                                        final Frame frame) {
  163.             final FieldStaticTransform<T> inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
  164.             final FieldGeodeticPoint<T> geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
  165.                     earth.getBodyFrame(), pv.getDate());
  166.             return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getNorth());
  167.         }
  168.     },

  169.     /** East direction. */
  170.     EAST {

  171.         /** {@inheritDoc} */
  172.         @Override
  173.         public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  174.                                                                                   final OneAxisEllipsoid earth,
  175.                                                                                   final TimeStampedPVCoordinates pv,
  176.                                                                                   final Frame frame) {
  177.             final FieldStaticTransform<UnivariateDerivative2> inert2Earth = inert2Earth(earth, pv.getDate(), frame);
  178.             final FieldGeodeticPoint<UnivariateDerivative2> gp = toGeodeticPoint(earth, pv, inert2Earth);
  179.             return inert2Earth.getStaticInverse().transformVector(gp.getEast());
  180.         }

  181.         /** {@inheritDoc} */
  182.         @Override
  183.         public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
  184.                                            final TimeStampedPVCoordinates pv, final Frame frame) {
  185.             final StaticTransform inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
  186.             final GeodeticPoint geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
  187.                     earth.getBodyFrame(), pv.getDate());
  188.             return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getEast());
  189.         }

  190.         /** {@inheritDoc} */
  191.         @Override
  192.         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
  193.                                                                                        final OneAxisEllipsoid earth,
  194.                                                                                        final TimeStampedFieldPVCoordinates<T> pv,
  195.                                                                                        final Frame frame) {
  196.             final FieldStaticTransform<T> inert2Earth = frame.getStaticTransformTo(earth.getBodyFrame(), pv.getDate());
  197.             final FieldGeodeticPoint<T> geodeticPoint = earth.transform(inert2Earth.transformPosition(pv.getPosition()),
  198.                     earth.getBodyFrame(), pv.getDate());
  199.             return inert2Earth.getStaticInverse().transformVector(geodeticPoint.getEast());
  200.         }
  201.     },

  202.     /** Satellite velocity. */
  203.     VELOCITY {

  204.         /** {@inheritDoc} */
  205.         @Override
  206.         public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  207.                                                                                   final OneAxisEllipsoid earth,
  208.                                                                                   final TimeStampedPVCoordinates pv,
  209.                                                                                   final Frame frame) {
  210.             return pv.toUnivariateDerivative2PV().getVelocity().normalize();
  211.         }

  212.         /** {@inheritDoc} */
  213.         @Override
  214.         public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
  215.                                                 final TimeStampedPVCoordinates pv, final Frame frame) {
  216.             return pv.getVelocity().normalize();
  217.         }

  218.         /** {@inheritDoc} */
  219.         @Override
  220.         public <T extends CalculusFieldElement<T>> FieldVector3D<FieldUnivariateDerivative2<T>> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  221.                                                                                                                               final OneAxisEllipsoid earth,
  222.                                                                                                                               final TimeStampedFieldPVCoordinates<T> pv,
  223.                                                                                                                               final Frame frame) {
  224.             return pv.toUnivariateDerivative2PV().getVelocity().normalize();
  225.         }

  226.         /** {@inheritDoc} */
  227.         @Override
  228.         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
  229.                                                                                        final OneAxisEllipsoid earth,
  230.                                                                                        final TimeStampedFieldPVCoordinates<T> pv,
  231.                                                                                        final Frame frame) {
  232.             return pv.getVelocity().normalize();
  233.         }
  234.     },

  235.     /** Satellite orbital momentum. */
  236.     MOMENTUM {

  237.         /** {@inheritDoc} */
  238.         @Override
  239.         public FieldVector3D<UnivariateDerivative2> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  240.                                                                                   final OneAxisEllipsoid earth,
  241.                                                                                   final TimeStampedPVCoordinates pv,
  242.                                                                                   final Frame frame) {
  243.             return pv.toUnivariateDerivative2PV().getMomentum().normalize();
  244.         }

  245.         /** {@inheritDoc} */
  246.         @Override
  247.         public Vector3D getTargetDirection(final ExtendedPositionProvider sun, final OneAxisEllipsoid earth,
  248.                                            final TimeStampedPVCoordinates pv, final Frame frame) {
  249.             return pv.getMomentum().normalize();
  250.         }

  251.         /** {@inheritDoc} */
  252.         @Override
  253.         public <T extends CalculusFieldElement<T>> FieldVector3D<FieldUnivariateDerivative2<T>> getDerivative2TargetDirection(final ExtendedPositionProvider sun,
  254.                                                                                                                               final OneAxisEllipsoid earth,
  255.                                                                                                                               final TimeStampedFieldPVCoordinates<T> pv,
  256.                                                                                                                               final Frame frame) {
  257.             return pv.toUnivariateDerivative2PV().getMomentum().normalize();
  258.         }

  259.         /** {@inheritDoc} */
  260.         @Override
  261.         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getTargetDirection(final ExtendedPositionProvider sun,
  262.                                                                                        final OneAxisEllipsoid earth,
  263.                                                                                        final TimeStampedFieldPVCoordinates<T> pv,
  264.                                                                                        final Frame frame) {
  265.             return pv.getMomentum().normalize();
  266.         }
  267.     };

  268.     /** Get transform from inertial frame to Earth frame.
  269.      * @param earth Earth model
  270.      * @param date  date
  271.      * @param frame inertial frame
  272.      * @return geodetic point with derivatives
  273.      */
  274.     private static FieldStaticTransform<UnivariateDerivative2> inert2Earth(final OneAxisEllipsoid earth,
  275.                                                                      final AbsoluteDate date,
  276.                                                                      final Frame frame) {
  277.         final FieldAbsoluteDate<UnivariateDerivative2> dateU2 =
  278.             new FieldAbsoluteDate<>(UnivariateDerivative2Field.getInstance(), date).
  279.             shiftedBy(new UnivariateDerivative2(0.0, 1.0, 0.0));
  280.         return frame.getStaticTransformTo(earth.getBodyFrame(), dateU2);
  281.     }

  282.     /** Convert to geodetic point with derivatives.
  283.      * @param earth       Earth model
  284.      * @param pv          spacecraft position and velocity
  285.      * @param inert2Earth transform from inertial frame to Earth frame
  286.      * @return geodetic point with derivatives
  287.      */
  288.     private static FieldGeodeticPoint<UnivariateDerivative2> toGeodeticPoint(final OneAxisEllipsoid earth,
  289.                                                                              final TimeStampedPVCoordinates pv,
  290.                                                                              final FieldStaticTransform<UnivariateDerivative2> inert2Earth) {
  291.         return earth.transform(inert2Earth.transformPosition(pv.toUnivariateDerivative2Vector()),
  292.                                earth.getBodyFrame(), inert2Earth.getFieldDate());
  293.     }
  294. }