ParametricAcceleration.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.forces.empirical;

  18. import java.util.List;
  19. import java.util.stream.Stream;

  20. import org.hipparchus.CalculusFieldElement;
  21. import org.hipparchus.Field;
  22. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  23. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  24. import org.hipparchus.geometry.euclidean.threed.Rotation;
  25. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  26. import org.orekit.attitudes.AttitudeProvider;
  27. import org.orekit.forces.ForceModel;
  28. import org.orekit.propagation.FieldSpacecraftState;
  29. import org.orekit.propagation.SpacecraftState;
  30. import org.orekit.propagation.events.EventDetector;
  31. import org.orekit.propagation.events.FieldEventDetector;
  32. import org.orekit.time.AbsoluteDate;
  33. import org.orekit.time.FieldAbsoluteDate;
  34. import org.orekit.utils.ParameterDriver;

  35. /** This class implements a parametric acceleration.
  36.  * <p>Parametric accelerations are intended to model lesser-known
  37.  * forces, estimating a few defining parameters from a parametric
  38.  * function using orbit determination. Typical parametric functions
  39.  * are polynomial (often limited to a constant term) and harmonic
  40.  * (often with either orbital period or half orbital period).</p>
  41.  * <p>An important operational example is the infamous GPS Y-bias,
  42.  * which is thought to be related to a radiator thermal radiation.
  43.  * Other examples could be to model leaks that produce roughly constant
  44.  * trust in some spacecraft-related direction.</p>
  45.  * <p>The acceleration direction is considered constant in either:
  46.  * </p>
  47.  * <ul>
  48.  *   <li>inertial frame</li>
  49.  *   <li>spacecraft frame</li>
  50.  *   <li>a dedicated attitude frame overriding spacecraft attitude
  51.  *   (this could for example be used to model solar arrays orientation
  52.  *   if the force is related to solar arrays)</li>
  53.  * </ul>
  54.  * <p>
  55.  * If the direction of the acceleration is unknown, then three instances
  56.  * of this class should be used, one along the X axis, one along the Y
  57.  * axis and one along the Z axis and their parameters estimated as usual.
  58.  * </p>
  59.  * @since 10.3
  60.  * @author Luc Maisonobe
  61.  * @author Bryan Cazabonne
  62.  * @author Melina Vanel
  63.  */
  64. public class ParametricAcceleration implements ForceModel {

  65.     /** Direction of the acceleration in defining frame. */
  66.     private final Vector3D direction;

  67.     /** Flag for inertial acceleration direction. */
  68.     private final boolean isInertial;

  69.     /** The attitude to override, if set. */
  70.     private final AttitudeProvider attitudeOverride;

  71.     /** Acceleration model. */
  72.     private final AccelerationModel accelerationModel;

  73.     /** Simple constructor.
  74.      * @param direction acceleration direction in overridden spacecraft frame
  75.      * @param isInertial if true, direction is defined in the same inertial
  76.      * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
  77.      * otherwise direction is defined in spacecraft frame (i.e. using the
  78.      * propagation {@link
  79.      * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
  80.      * attitude law})
  81.      * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
  82.      * direction
  83.      */
  84.     public ParametricAcceleration(final Vector3D direction,
  85.                                   final boolean isInertial,
  86.                                   final AccelerationModel accelerationModel) {
  87.         this(direction, isInertial, null, accelerationModel);
  88.     }

  89.     /** Simple constructor.
  90.      * @param direction acceleration direction in overridden spacecraft frame
  91.      * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
  92.      * otherwise direction is defined in spacecraft frame (i.e. using the
  93.      * propagation {@link
  94.      * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
  95.      * attitude law})
  96.      * @param attitudeOverride provider for attitude used to compute acceleration
  97.      * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
  98.      * direction
  99.      */
  100.     public ParametricAcceleration(final Vector3D direction,
  101.                                   final AttitudeProvider attitudeOverride,
  102.                                   final AccelerationModel accelerationModel) {
  103.         this(direction, false, attitudeOverride, accelerationModel);
  104.     }

  105.     /** Simple constructor.
  106.      * @param direction acceleration direction in overridden spacecraft frame
  107.      * @param isInertial if true, direction is defined in the same inertial
  108.      * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
  109.      * otherwise direction is defined in spacecraft frame (i.e. using the
  110.      * propagation {@link
  111.      * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
  112.      * attitude law})
  113.      * @param attitudeOverride provider for attitude used to compute acceleration
  114.      * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
  115.      * direction
  116.      */
  117.     private ParametricAcceleration(final Vector3D direction,
  118.                                    final boolean isInertial,
  119.                                    final AttitudeProvider attitudeOverride,
  120.                                    final AccelerationModel accelerationModel) {
  121.         this.direction         = direction;
  122.         this.isInertial        = isInertial;
  123.         this.attitudeOverride  = attitudeOverride;
  124.         this.accelerationModel = accelerationModel;
  125.     }

  126.     /** {@inheritDoc} */
  127.     @Override
  128.     public boolean dependsOnPositionOnly() {
  129.         return isInertial;
  130.     }

  131.     /** {@inheritDoc} */
  132.     @Override
  133.     public List<ParameterDriver> getParametersDrivers() {
  134.         return accelerationModel.getParametersDrivers();
  135.     }

  136.     /** {@inheritDoc} */
  137.     @Override
  138.     public void init(final SpacecraftState initialState, final AbsoluteDate target) {
  139.         accelerationModel.init(initialState, target);
  140.     }

  141.     /** {@inheritDoc} */
  142.     @Override
  143.     public Vector3D acceleration(final SpacecraftState state,
  144.                                  final double[] parameters) {

  145.         // Date
  146.         final AbsoluteDate date = state.getDate();

  147.         final Vector3D inertialDirection;
  148.         if (isInertial) {
  149.             // the acceleration direction is already defined in the inertial frame
  150.             inertialDirection = direction;
  151.         } else {
  152.             final Rotation rotation;
  153.             if (attitudeOverride == null) {
  154.                 // the acceleration direction is defined in spacecraft frame as set by the propagator
  155.                 rotation = state.getAttitude().getRotation();
  156.             } else {
  157.                 // the acceleration direction is defined in a dedicated frame
  158.                 rotation = attitudeOverride.getAttitudeRotation(state.getOrbit(), date, state.getFrame());
  159.             }
  160.             inertialDirection = rotation.applyInverseTo(direction);
  161.         }

  162.         // Call the acceleration model to compute the acceleration
  163.         return new Vector3D(accelerationModel.signedAmplitude(state, parameters), inertialDirection);

  164.     }

  165.     /** {@inheritDoc} */
  166.     @Override
  167.     public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> state,
  168.                                                                          final T[] parameters) {

  169.         // Date
  170.         final FieldAbsoluteDate<T> date = state.getDate();

  171.         final FieldVector3D<T> inertialDirection;
  172.         if (isInertial) {
  173.             // the acceleration direction is already defined in the inertial frame
  174.             inertialDirection = new FieldVector3D<>(date.getField(), direction);
  175.         } else {
  176.             final FieldRotation<T> rotation;
  177.             if (attitudeOverride == null) {
  178.                 // the acceleration direction is defined in spacecraft frame as set by the propagator
  179.                 rotation = state.getAttitude().getRotation();
  180.             } else {
  181.                 // the acceleration direction is defined in a dedicated frame
  182.                 rotation = attitudeOverride.getAttitudeRotation(state.getOrbit(), date, state.getFrame());
  183.             }
  184.             inertialDirection = rotation.applyInverseTo(direction);
  185.         }

  186.         // Call the acceleration model to compute the acceleration
  187.         return new FieldVector3D<>(accelerationModel.signedAmplitude(state, parameters), inertialDirection);

  188.     }


  189.     /** {@inheritDoc} */
  190.     @Override
  191.     public Stream<EventDetector> getEventDetectors() {
  192.         return Stream.empty();
  193.     }

  194.     /** {@inheritDoc} */
  195.     @Override
  196.     public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(final Field<T> field) {
  197.         return Stream.empty();
  198.     }

  199. }