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

  18. import java.util.ArrayList;
  19. import java.util.List;

  20. import org.hipparchus.CalculusFieldElement;
  21. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  22. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  23. import org.orekit.attitudes.AttitudeProvider;
  24. import org.orekit.propagation.FieldSpacecraftState;
  25. import org.orekit.propagation.SpacecraftState;
  26. import org.orekit.time.AbsoluteDate;
  27. import org.orekit.utils.ParameterDriver;

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

  58.     /** Acceleration model. */
  59.     private final AccelerationModel accelerationModel;

  60.     /** Simple constructor.
  61.      * @param direction acceleration direction in overridden spacecraft frame
  62.      * @param isInertial if true, direction is defined in the same inertial
  63.      * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
  64.      * otherwise direction is defined in spacecraft frame (i.e. using the
  65.      * propagation {@link
  66.      * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
  67.      * attitude law})
  68.      * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
  69.      * direction
  70.      */
  71.     public ParametricAcceleration(final Vector3D direction,
  72.                                   final boolean isInertial,
  73.                                   final AccelerationModel accelerationModel) {
  74.         this(direction, isInertial, null, accelerationModel);
  75.     }

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

  92.     /** Simple constructor.
  93.      * @param direction acceleration direction in overridden spacecraft frame
  94.      * @param isInertial if true, direction is defined in the same inertial
  95.      * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
  96.      * otherwise direction is defined in spacecraft frame (i.e. using the
  97.      * propagation {@link
  98.      * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
  99.      * attitude law})
  100.      * @param attitudeOverride provider for attitude used to compute acceleration
  101.      * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
  102.      * direction
  103.      */
  104.     private ParametricAcceleration(final Vector3D direction,
  105.                                    final boolean isInertial,
  106.                                    final AttitudeProvider attitudeOverride,
  107.                                    final AccelerationModel accelerationModel) {
  108.         super(direction, isInertial, attitudeOverride);
  109.         this.accelerationModel = accelerationModel;
  110.     }

  111.     /** {@inheritDoc} */
  112.     @Override
  113.     public List<ParameterDriver> getParametersDrivers() {
  114.         final List<ParameterDriver> parameterDrivers = new ArrayList<>(accelerationModel.getParametersDrivers());
  115.         if (getAttitudeOverride() != null) {
  116.             parameterDrivers.addAll(getAttitudeOverride().getParametersDrivers());
  117.         }
  118.         return parameterDrivers;
  119.     }

  120.     /** {@inheritDoc} */
  121.     @Override
  122.     public void init(final SpacecraftState initialState, final AbsoluteDate target) {
  123.         accelerationModel.init(initialState, target);
  124.     }

  125.     /** {@inheritDoc} */
  126.     @Override
  127.     public Vector3D acceleration(final SpacecraftState state,
  128.                                  final double[] parameters) {
  129.         final Vector3D inertialDirection = getAccelerationDirection(state);

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

  132.     }

  133.     /** {@inheritDoc} */
  134.     @Override
  135.     public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> state,
  136.                                                                              final T[] parameters) {
  137.         final FieldVector3D<T> inertialDirection = getAccelerationDirection(state);

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

  140.     }

  141. }