AbstractParametricAcceleration.java

  1. /* Copyright 2002-2017 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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;

  18. import java.util.stream.Stream;

  19. import org.hipparchus.Field;
  20. import org.hipparchus.RealFieldElement;
  21. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  22. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  23. import org.orekit.attitudes.Attitude;
  24. import org.orekit.attitudes.AttitudeProvider;
  25. import org.orekit.attitudes.FieldAttitude;
  26. import org.orekit.errors.OrekitException;
  27. import org.orekit.propagation.FieldSpacecraftState;
  28. import org.orekit.propagation.SpacecraftState;
  29. import org.orekit.propagation.events.EventDetector;
  30. import org.orekit.propagation.events.FieldEventDetector;

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

  59.     /** Direction of the acceleration in defining frame. */
  60.     private final Vector3D direction;

  61.     /** Flag for inertial acceleration direction. */
  62.     private final boolean isInertial;

  63.     /** The attitude to override, if set. */
  64.     private final AttitudeProvider attitudeOverride;

  65.     /** Simple constructor.
  66.      * @param direction acceleration direction in overridden spacecraft frame
  67.      * @param isInertial if true, direction is defined in the same inertial
  68.      * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
  69.      * otherwise direction is defined in spacecraft frame (i.e. using the
  70.      * propagation {@link
  71.      * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
  72.      * attitude law})
  73.      * @param attitudeOverride provider for attitude used to compute acceleration
  74.      * direction
  75.      */
  76.     protected AbstractParametricAcceleration(final Vector3D direction,  final boolean isInertial,
  77.                                              final AttitudeProvider attitudeOverride) {
  78.         this.direction        = direction;
  79.         this.isInertial       = isInertial;
  80.         this.attitudeOverride = attitudeOverride;
  81.     }

  82.     /** Check if direction is inertial.
  83.      * @return true if direction is inertial
  84.      */
  85.     protected boolean isInertial() {
  86.         return isInertial;
  87.     }

  88.     /** Compute the signed amplitude of the acceleration.
  89.      * <p>
  90.      * The acceleration is the direction multiplied by the signed amplitude. So if
  91.      * signed amplitude is negative, the acceleratin is towards the opposite of the
  92.      * direction specified at construction.
  93.      * </p>
  94.      * @param state current state information: date, kinematics, attitude
  95.      * @param parameters values of the force model parameters
  96.      * @return norm of the acceleration
  97.      */
  98.     protected abstract double signedAmplitude(SpacecraftState state, double[] parameters);

  99.     /** Compute the signed amplitude of the acceleration.
  100.      * <p>
  101.      * The acceleration is the direction multiplied by the signed amplitude. So if
  102.      * signed amplitude is negative, the acceleratin is towards the opposite of the
  103.      * direction specified at construction.
  104.      * </p>
  105.      * @param state current state information: date, kinematics, attitude
  106.      * @param parameters values of the force model parameters
  107.      * @param <T> type of the elements
  108.      * @return norm of the acceleration
  109.      */
  110.     protected abstract <T extends RealFieldElement<T>> T signedAmplitude(FieldSpacecraftState<T> state, T[] parameters);

  111.     /** {@inheritDoc} */
  112.     @Override
  113.     public Vector3D acceleration(final SpacecraftState state, final double[] parameters)
  114.         throws OrekitException {

  115.         final Vector3D inertialDirection;
  116.         if (isInertial) {
  117.             // the acceleration direction is already defined in the inertial frame
  118.             inertialDirection = direction;
  119.         } else {
  120.             final Attitude attitude;
  121.             if (attitudeOverride == null) {
  122.                 // the acceleration direction is defined in spacecraft frame as set by the propagator
  123.                 attitude = state.getAttitude();
  124.             } else {
  125.                 // the acceleration direction is defined in a dedicated frame
  126.                 attitude = attitudeOverride.getAttitude(state.getOrbit(), state.getDate(), state.getFrame());
  127.             }
  128.             inertialDirection = attitude.getRotation().applyInverseTo(direction);
  129.         }

  130.         return new Vector3D(signedAmplitude(state, parameters), inertialDirection);

  131.     }

  132.     /** {@inheritDoc} */
  133.     @Override
  134.     public <T extends RealFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> state,
  135.                                                                          final T[] parameters)
  136.         throws OrekitException {

  137.         final FieldVector3D<T> inertialDirection;
  138.         if (isInertial) {
  139.             // the acceleration direction is already defined in the inertial frame
  140.             inertialDirection = new FieldVector3D<>(state.getDate().getField(), direction);
  141.         } else {
  142.             final FieldAttitude<T> attitude;
  143.             if (attitudeOverride == null) {
  144.                 // the acceleration direction is defined in spacecraft frame as set by the propagator
  145.                 attitude = state.getAttitude();
  146.             } else {
  147.                 // the acceleration direction is defined in a dedicated frame
  148.                 attitude = attitudeOverride.getAttitude(state.getOrbit(), state.getDate(), state.getFrame());
  149.             }
  150.             inertialDirection = attitude.getRotation().applyInverseTo(direction);
  151.         }

  152.         return new FieldVector3D<>(signedAmplitude(state, parameters), inertialDirection);

  153.     }

  154.     /** {@inheritDoc} */
  155.     @Override
  156.     public Stream<EventDetector> getEventsDetectors() {
  157.         return Stream.empty();
  158.     }

  159.     /** {@inheritDoc} */
  160.     @Override
  161.     public <T extends RealFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(final Field<T> field) {
  162.         return Stream.empty();
  163.     }

  164. }