AbstractGradientConverter.java

  1. /* Copyright 2002-2022 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.propagation.integration;

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

  20. import org.hipparchus.analysis.differentiation.Gradient;
  21. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  22. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  23. import org.orekit.attitudes.FieldAttitude;
  24. import org.orekit.orbits.FieldCartesianOrbit;
  25. import org.orekit.orbits.FieldOrbit;
  26. import org.orekit.propagation.FieldSpacecraftState;
  27. import org.orekit.utils.FieldAngularCoordinates;
  28. import org.orekit.utils.FieldPVCoordinates;
  29. import org.orekit.utils.ParameterDriver;
  30. import org.orekit.utils.ParametersDriversProvider;
  31. import org.orekit.utils.TimeStampedFieldAngularCoordinates;
  32. import org.orekit.utils.TimeStampedFieldPVCoordinates;

  33. /** Converter for states and parameters arrays.
  34.  *  @author Luc Maisonobe
  35.  *  @author Bryan Cazabonne
  36.  *  @since 10.2
  37.  */
  38. public abstract class AbstractGradientConverter {

  39.     /** Dimension of the state. */
  40.     private final int freeStateParameters;

  41.     /** States with various number of additional parameters. */
  42.     private final List<FieldSpacecraftState<Gradient>> gStates;

  43.     /** Simple constructor.
  44.      * @param freeStateParameters number of free parameters
  45.      */
  46.     protected AbstractGradientConverter(final int freeStateParameters) {
  47.         this.freeStateParameters = freeStateParameters;
  48.         this.gStates             = new ArrayList<>();
  49.     }

  50.     /** Get the number of free state parameters.
  51.      * @return number of free state parameters
  52.      */
  53.     public int getFreeStateParameters() {
  54.         return freeStateParameters;
  55.     }

  56.     /** Initialize first state with 0 parameters.
  57.      * @param zeroParametersState state with zero parameters
  58.      * @since 11.2
  59.      */
  60.     protected void initStates(final FieldSpacecraftState<Gradient> zeroParametersState) {
  61.         gStates.clear();
  62.         gStates.add(zeroParametersState);
  63.     }

  64.     /** Add zero derivatives.
  65.      * @param original original scalar
  66.      * @param freeParameters total number of free parameters in the gradient
  67.      * @return extended scalar
  68.      */
  69.     protected Gradient extend(final Gradient original, final int freeParameters) {
  70.         final double[] originalDerivatives = original.getGradient();
  71.         final double[] extendedDerivatives = new double[freeParameters];
  72.         System.arraycopy(originalDerivatives, 0, extendedDerivatives, 0, originalDerivatives.length);
  73.         return new Gradient(original.getValue(), extendedDerivatives);
  74.     }

  75.     /** Add zero derivatives.
  76.      * @param original original vector
  77.      * @param freeParameters total number of free parameters in the gradient
  78.      * @return extended vector
  79.      */
  80.     protected FieldVector3D<Gradient> extend(final FieldVector3D<Gradient> original, final int freeParameters) {
  81.         return new FieldVector3D<>(extend(original.getX(), freeParameters),
  82.                                    extend(original.getY(), freeParameters),
  83.                                    extend(original.getZ(), freeParameters));
  84.     }

  85.     /** Add zero derivatives.
  86.      * @param original original rotation
  87.      * @param freeParameters total number of free parameters in the gradient
  88.      * @return extended rotation
  89.      */
  90.     protected FieldRotation<Gradient> extend(final FieldRotation<Gradient> original, final int freeParameters) {
  91.         return new FieldRotation<>(extend(original.getQ0(), freeParameters),
  92.                                    extend(original.getQ1(), freeParameters),
  93.                                    extend(original.getQ2(), freeParameters),
  94.                                    extend(original.getQ3(), freeParameters),
  95.                                    false);
  96.     }
  97.     /**
  98.      * Get the state with the number of parameters consistent with parametric model.
  99.      * @param parametricModel parametric model
  100.      * @return state with the number of parameters consistent with parametric model
  101.      */
  102.     public FieldSpacecraftState<Gradient> getState(final ParametersDriversProvider parametricModel) {

  103.         // count the required number of parameters
  104.         int nbParams = 0;
  105.         for (final ParameterDriver driver : parametricModel.getParametersDrivers()) {
  106.             if (driver.isSelected()) {
  107.                 ++nbParams;
  108.             }
  109.         }

  110.         // fill in intermediate slots
  111.         while (gStates.size() < nbParams + 1) {
  112.             gStates.add(null);
  113.         }

  114.         if (gStates.get(nbParams) == null) {
  115.             // it is the first time we need this number of parameters
  116.             // we need to create the state
  117.             final int freeParameters = freeStateParameters + nbParams;
  118.             final FieldSpacecraftState<Gradient> s0 = gStates.get(0);

  119.             // orbit
  120.             final FieldPVCoordinates<Gradient> pv0 = s0.getPVCoordinates();
  121.             final FieldOrbit<Gradient> gOrbit =
  122.                             new FieldCartesianOrbit<>(new TimeStampedFieldPVCoordinates<>(s0.getDate().toAbsoluteDate(),
  123.                                                                                           extend(pv0.getPosition(),     freeParameters),
  124.                                                                                           extend(pv0.getVelocity(),     freeParameters),
  125.                                                                                           extend(pv0.getAcceleration(), freeParameters)),
  126.                                                       s0.getFrame(), extend(s0.getMu(), freeParameters));

  127.             // attitude
  128.             final FieldAngularCoordinates<Gradient> ac0 = s0.getAttitude().getOrientation();
  129.             final FieldAttitude<Gradient> gAttitude =
  130.                             new FieldAttitude<>(s0.getAttitude().getReferenceFrame(),
  131.                                                 new TimeStampedFieldAngularCoordinates<>(gOrbit.getDate(),
  132.                                                                                          extend(ac0.getRotation(), freeParameters),
  133.                                                                                          extend(ac0.getRotationRate(), freeParameters),
  134.                                                                                          extend(ac0.getRotationAcceleration(), freeParameters)));

  135.             // mass
  136.             final Gradient gM = extend(s0.getMass(), freeParameters);

  137.             gStates.set(nbParams, new FieldSpacecraftState<>(gOrbit, gAttitude, gM));

  138.         }

  139.         return gStates.get(nbParams);

  140.     }

  141.     /** Get the parametric model parameters.
  142.      * @param state state as returned by {@link #getState(ParametersDriversProvider) getState(parametricModel)}
  143.      * @param parametricModel parametric model associated with the parameters
  144.      * @return parametric model parameters
  145.      */
  146.     public Gradient[] getParameters(final FieldSpacecraftState<Gradient> state,
  147.                                     final ParametersDriversProvider parametricModel) {
  148.         final int freeParameters = state.getMass().getFreeParameters();
  149.         final List<ParameterDriver> drivers = parametricModel.getParametersDrivers();
  150.         final Gradient[] parameters = new Gradient[drivers.size()];
  151.         int index = freeStateParameters;
  152.         int i = 0;
  153.         for (ParameterDriver driver : drivers) {
  154.             parameters[i++] = driver.isSelected() ?
  155.                               Gradient.variable(freeParameters, index++, driver.getValue()) :
  156.                               Gradient.constant(freeParameters, driver.getValue());
  157.         }
  158.         return parameters;
  159.     }

  160. }