ThrustDirectionAndAttitudeProvider.java

  1. /* Copyright 2020 Exotrail
  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.  * Exotrail 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.forces.maneuvers.propulsion;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.geometry.euclidean.threed.Rotation;
  20. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  21. import org.orekit.attitudes.Attitude;
  22. import org.orekit.attitudes.AttitudeProvider;
  23. import org.orekit.attitudes.FieldAttitude;
  24. import org.orekit.errors.OrekitException;
  25. import org.orekit.errors.OrekitMessages;
  26. import org.orekit.frames.Frame;
  27. import org.orekit.frames.LOF;
  28. import org.orekit.time.AbsoluteDate;
  29. import org.orekit.time.FieldAbsoluteDate;
  30. import org.orekit.utils.FieldPVCoordinatesProvider;
  31. import org.orekit.utils.PVCoordinatesProvider;

  32. /**
  33.  * This class is used in to both manage the attitude of the satellite and the
  34.  * direction of thrust.
  35.  *<p>
  36.  * It is used in ConfigurableLowThrustManeuver to set the spacecraft attitude
  37.  * according to the expected thrust direction.
  38.  *<p>
  39.  * The direction can be variable or fixed, defined in the spaceraft frame, a
  40.  * Local Orbital Frame or a user frame.
  41.  *<p>
  42.  * It is also possible to use an external attitude provider.
  43.  *
  44.  * @author Mikael Fillastre
  45.  * @author Andrea Fiorentino
  46.  * @since 10.2
  47.  */
  48. public class ThrustDirectionAndAttitudeProvider implements AttitudeProvider {

  49.     /** Field name for error message. */
  50.     private static final String FIELD_NAME_VARIABLE_DIRECTION = "variableDirectionInFrame";

  51.     /** Field name for error message. */
  52.     private static final String FIELD_NAME_DIRECTION_FRAME = "thrustDirectionFrame";

  53.     /** Field name for error message. */
  54.     private static final String FIELD_NAME_LOF_TYPE = "thrustDirectionLof";

  55.     /** Types, see builders for details. */
  56.     private enum ThrustDirectionAndAttitudeProviderType {
  57.         /** SATELLITE_ATTITUDE. */
  58.         SATELLITE_ATTITUDE,
  59.         /** CUSTOM_ATTITUDE. */
  60.         CUSTOM_ATTITUDE,
  61.         /** DIRECTION_IN_LOF. */
  62.         DIRECTION_IN_LOF,
  63.         /** DIRECTION_IN_FRAME. */
  64.         DIRECTION_IN_FRAME
  65.     }

  66.     /** Type. */
  67.     private final ThrustDirectionAndAttitudeProviderType type;

  68.     /**
  69.      * External attitude provider, for CUSTOM_ATTITUDE type. Set to null otherwise.
  70.      */
  71.     private final AttitudeProvider attitudeProvider;

  72.     /**
  73.      * Direction provider, for DIRECTION_IN_LOF and DIRECTION_IN_FRAME types. Set to
  74.      * null otherwise.
  75.      */
  76.     private final ThrustDirectionProvider variableDirectionInFrame;

  77.     /** Thruster axis in satellite frame. */
  78.     private final Vector3D thrusterAxisInSatelliteFrame;

  79.     /**
  80.      * Reference frame for thrust direction, for DIRECTION_IN_FRAME type. Set to
  81.      * null otherwise.
  82.      */
  83.     private final Frame thrustDirectionFrame;

  84.     /**
  85.      * Local Orbital Frame, for DIRECTION_IN_LOF local orbital frame. Set to null otherwise.
  86.      */
  87.     private final LOF thrustDirectionLof;

  88.     /**
  89.      * Internal constructor.
  90.      * @param type                         Type
  91.      * @param attitudeProvider             External attitude provider, for
  92.      *                                     CUSTOM_ATTITUDE type. Set to null
  93.      *                                     otherwise
  94.      * @param variableDirectionInFrame     Direction provider, for DIRECTION_IN_LOF
  95.      *                                     and DIRECTION_IN_FRAME types. Set to null
  96.      *                                     otherwise.
  97.      * @param thrusterAxisInSatelliteFrame Thruster axis in satellite frame
  98.      * @param frame                        Reference frame for thrust direction
  99.      * @param thrustDirectionLof           Local Orbital Frame, for DIRECTION_IN_LOF local orbital frame
  100.      *                                     (set to null otherwise)
  101.      */
  102.     private ThrustDirectionAndAttitudeProvider(final ThrustDirectionAndAttitudeProviderType type,
  103.             final AttitudeProvider attitudeProvider, final ThrustDirectionProvider variableDirectionInFrame,
  104.             final Vector3D thrusterAxisInSatelliteFrame, final Frame frame, final LOF thrustDirectionLof) {
  105.         this.type = type;
  106.         this.attitudeProvider = attitudeProvider;
  107.         this.variableDirectionInFrame = variableDirectionInFrame;
  108.         this.thrustDirectionFrame = frame;
  109.         this.thrustDirectionLof = thrustDirectionLof;
  110.         this.thrusterAxisInSatelliteFrame = thrusterAxisInSatelliteFrame;
  111.     }

  112.     /**
  113.      * Throw an error if a mandatory parameter is not set.
  114.      * @param parameter value
  115.      * @param name      name of the parameter (for user message)
  116.      * @param type      type to add details to user
  117.      */
  118.     private static void checkParameterNotNull(final Object parameter, final String name,
  119.             final ThrustDirectionAndAttitudeProviderType type) {
  120.         if (parameter == null) {
  121.             throw new OrekitException(OrekitMessages.PARAMETER_NOT_SET, name,
  122.                     "ThrustDirectionAndAttitudeProvider-" + type.toString());
  123.         }
  124.     }

  125.     /**
  126.      * Build a ThrustDirectionAndAttitudeProvider from a fixed direction in the
  127.      * satellite frame. The satellite attitude won't be managed by this object
  128.      *
  129.      * @param direction constant direction in the satellite frame
  130.      * @return a new instance
  131.      */
  132.     public static ThrustDirectionAndAttitudeProvider buildFromFixedDirectionInSatelliteFrame(final Vector3D direction) {
  133.         final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
  134.                 ThrustDirectionAndAttitudeProviderType.SATELLITE_ATTITUDE, null, null, direction, null, null);
  135.         checkParameterNotNull(direction, "thrusterAxisInSatelliteFrame", obj.type);
  136.         return obj;
  137.     }

  138.     /**
  139.      * Build a ThrustDirectionAndAttitudeProvider where the attitude is provided by
  140.      * an external. Object the direction of thrust will be constant
  141.      *
  142.      * @param attitudeProvider the object that provide the satellite attitude
  143.      * @param direction        thruster axis in satellite frame
  144.      * @return a new instance
  145.      */
  146.     public static ThrustDirectionAndAttitudeProvider buildFromCustomAttitude(final AttitudeProvider attitudeProvider,
  147.             final Vector3D direction) {
  148.         final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
  149.                 ThrustDirectionAndAttitudeProviderType.CUSTOM_ATTITUDE, attitudeProvider, null, direction, null, null);
  150.         checkParameterNotNull(attitudeProvider, "attitudeProvider", obj.type);
  151.         checkParameterNotNull(direction, "direction", obj.type);
  152.         return obj;
  153.     }

  154.     /**
  155.      * Build a ThrustDirectionAndAttitudeProvider by a variable direction in a
  156.      * custom frame.
  157.      *
  158.      * @param thrustDirectionFrame         reference frame for thrust direction
  159.      * @param variableDirectionInFrame     the object providing the thrust direction
  160.      * @param thrusterAxisInSatelliteFrame thruster axis in satellite frame
  161.      * @return a new instance
  162.      */
  163.     public static ThrustDirectionAndAttitudeProvider buildFromDirectionInFrame(final Frame thrustDirectionFrame,
  164.             final ThrustDirectionProvider variableDirectionInFrame, final Vector3D thrusterAxisInSatelliteFrame) {
  165.         final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
  166.                 ThrustDirectionAndAttitudeProviderType.DIRECTION_IN_FRAME, null, variableDirectionInFrame,
  167.                 thrusterAxisInSatelliteFrame, thrustDirectionFrame, null);
  168.         checkParameterNotNull(variableDirectionInFrame, FIELD_NAME_VARIABLE_DIRECTION, obj.type);
  169.         checkParameterNotNull(thrustDirectionFrame, FIELD_NAME_DIRECTION_FRAME, obj.type);
  170.         return obj;
  171.     }

  172.     /**
  173.      * Build a ThrustDirectionAndAttitudeProvider by a variable direction in a Local
  174.      * Orbital Frame.
  175.      *
  176.      * @param thrustDirectionLof           local orbital frame
  177.      * @param variableDirectionInFrame     the object providing the thrust direction
  178.      * @param thrusterAxisInSatelliteFrame thruster axis in satellite frame
  179.      * @return a new instance
  180.      */
  181.     public static ThrustDirectionAndAttitudeProvider buildFromDirectionInLOF(final LOF thrustDirectionLof,
  182.             final ThrustDirectionProvider variableDirectionInFrame, final Vector3D thrusterAxisInSatelliteFrame) {
  183.         final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
  184.                 ThrustDirectionAndAttitudeProviderType.DIRECTION_IN_LOF, null, variableDirectionInFrame,
  185.                 thrusterAxisInSatelliteFrame, null, thrustDirectionLof);
  186.         checkParameterNotNull(variableDirectionInFrame, FIELD_NAME_VARIABLE_DIRECTION, obj.type);
  187.         checkParameterNotNull(thrustDirectionLof, FIELD_NAME_LOF_TYPE, obj.type);
  188.         return obj;
  189.     }

  190.     /**
  191.      * Thruster axis in satellite frame.
  192.      * @return field
  193.      */
  194.     public Vector3D getThrusterAxisInSatelliteFrame() {
  195.         return thrusterAxisInSatelliteFrame;
  196.     }

  197.     /** {@inheritDoc} */
  198.     @Override
  199.     public Attitude getAttitude(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) {
  200.         switch (type) {
  201.             case CUSTOM_ATTITUDE:
  202.                 return attitudeProvider.getAttitude(pvProv, date, frame);
  203.             case DIRECTION_IN_FRAME:
  204.             case DIRECTION_IN_LOF:
  205.                 return getAttitudeFromFrame(pvProv, date, frame);
  206.             default:
  207.                 throw new OrekitException(OrekitMessages.INVALID_TYPE_FOR_FUNCTION,
  208.                         "ThrustDirectionAndAttitudeProvider.getAttitude", "type", type.toString());
  209.         }
  210.     }

  211.     /** {@inheritDoc} */
  212.     @Override
  213.     public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
  214.             final FieldAbsoluteDate<T> date, final Frame frame) {
  215.         throw new OrekitException(OrekitMessages.FUNCTION_NOT_IMPLEMENTED,
  216.                 "ThrustDirectionAndAttitudeProvider with CalculusFieldElement");
  217.     }

  218.     /**
  219.      * Compute the attitude for DIRECTION_IN_FRAME or DIRECTION_IN_LOF types.
  220.      * @param pvProv local position-velocity provider around current date
  221.      * @param date   current date
  222.      * @param frame  reference frame from which attitude is computed
  223.      * @return attitude attitude on the specified date and position-velocity state
  224.      */
  225.     protected Attitude getAttitudeFromFrame(final PVCoordinatesProvider pvProv, final AbsoluteDate date,
  226.             final Frame frame) {

  227.         final Rotation inertial2ThrusterFrame;
  228.         if (type.equals(ThrustDirectionAndAttitudeProviderType.DIRECTION_IN_FRAME)) {
  229.             inertial2ThrusterFrame = frame.getStaticTransformTo(thrustDirectionFrame, date).getRotation();
  230.         } else { // LOF
  231.             inertial2ThrusterFrame = thrustDirectionLof.rotationFromInertial(date, pvProv.getPVCoordinates(date, frame));
  232.         }

  233.         final Vector3D thrustDirection = variableDirectionInFrame.computeThrustDirection(pvProv, date, frame);
  234.         final Vector3D thrustDirectionInertial = inertial2ThrusterFrame.applyInverseTo(thrustDirection);

  235.         final Rotation attitude = new Rotation(getThrusterAxisInSatelliteFrame(), thrustDirectionInertial);
  236.         final Attitude att = new Attitude(date, frame, attitude.revert(), Vector3D.ZERO, Vector3D.ZERO);

  237.         return att;
  238.     }

  239.     /**
  240.      * Attitude provider to use.
  241.      * @return null in mode SATELLITE_ATTITUDE
  242.      */
  243.     public AttitudeProvider getManeuverAttitudeProvider() {
  244.         AttitudeProvider attitudeProviderToReturn = null;
  245.         if (type != ThrustDirectionAndAttitudeProviderType.SATELLITE_ATTITUDE) {
  246.             attitudeProviderToReturn = this;
  247.         } // else default behavior
  248.         return attitudeProviderToReturn;
  249.     }

  250. }