AbstractAnalyticalGradientConverter.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.analytical;

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

  20. import org.hipparchus.analysis.differentiation.Gradient;
  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.attitudes.FieldAttitude;
  25. import org.orekit.orbits.FieldCartesianOrbit;
  26. import org.orekit.orbits.FieldOrbit;
  27. import org.orekit.propagation.FieldSpacecraftState;
  28. import org.orekit.propagation.SpacecraftState;
  29. import org.orekit.propagation.integration.AbstractGradientConverter;
  30. import org.orekit.utils.FieldAngularCoordinates;
  31. import org.orekit.utils.FieldPVCoordinates;
  32. import org.orekit.utils.ParameterDriver;
  33. import org.orekit.utils.TimeStampedFieldAngularCoordinates;
  34. import org.orekit.utils.TimeStampedFieldPVCoordinates;

  35. /**
  36.  * Converter for analytical orbit propagator.
  37.  *
  38.  * @author Bryan Cazabonne
  39.  * @since 11.1
  40.  */
  41. public abstract class AbstractAnalyticalGradientConverter extends AbstractGradientConverter {

  42.     /** Attitude provider. */
  43.     private final AttitudeProvider provider;

  44.     /** States with various number of additional propagation parameters. */
  45.     private final List<FieldSpacecraftState<Gradient>> gStates;

  46.     /**
  47.      * Constructor.
  48.      * @param propagator analytical orbit propagator
  49.      * @param mu central attraction coefficient
  50.      * @param freeStateParameters number of free parameters
  51.      */
  52.     protected AbstractAnalyticalGradientConverter(final AbstractAnalyticalPropagator propagator,
  53.                                                   final double mu,
  54.                                                   final int freeStateParameters) {
  55.         super(freeStateParameters);

  56.         // Attitude provider
  57.         this.provider = propagator.getAttitudeProvider();

  58.         // Spacecraft state
  59.         final SpacecraftState state = propagator.getInitialState();

  60.         // Position always has derivatives
  61.         final Vector3D pos = state.getPVCoordinates().getPosition();
  62.         final FieldVector3D<Gradient> posG = new FieldVector3D<>(Gradient.variable(freeStateParameters, 0, pos.getX()),
  63.                                                                  Gradient.variable(freeStateParameters, 1, pos.getY()),
  64.                                                                  Gradient.variable(freeStateParameters, 2, pos.getZ()));

  65.         // Velocity may have derivatives or not
  66.         final Vector3D vel = state.getPVCoordinates().getVelocity();
  67.         final FieldVector3D<Gradient> velG = new FieldVector3D<>(Gradient.variable(freeStateParameters, 3, vel.getX()),
  68.                                                                  Gradient.variable(freeStateParameters, 4, vel.getY()),
  69.                                                                  Gradient.variable(freeStateParameters, 5, vel.getZ()));

  70.         // Acceleration never has derivatives
  71.         final Vector3D acc = state.getPVCoordinates().getAcceleration();
  72.         final FieldVector3D<Gradient> accG = new FieldVector3D<>(Gradient.constant(freeStateParameters, acc.getX()),
  73.                                                                  Gradient.constant(freeStateParameters, acc.getY()),
  74.                                                                  Gradient.constant(freeStateParameters, acc.getZ()));

  75.         // Mass never has derivatives
  76.         final Gradient gM  = Gradient.constant(freeStateParameters, state.getMass());
  77.         final Gradient gMu = Gradient.constant(freeStateParameters, mu);

  78.         final FieldOrbit<Gradient> gOrbit =
  79.                         new FieldCartesianOrbit<>(new TimeStampedFieldPVCoordinates<>(state.getDate(), posG, velG, accG),
  80.                                                   state.getFrame(), gMu);

  81.         // Attitude
  82.         final FieldAttitude<Gradient> gAttitude = provider.getAttitude(gOrbit, gOrbit.getDate(), gOrbit.getFrame());

  83.         // Initialize the list with the state having 0 force model parameters
  84.         gStates = new ArrayList<>();
  85.         gStates.add(new FieldSpacecraftState<>(gOrbit, gAttitude, gM));

  86.     }

  87.     /** Get the state with the number of parameters consistent with the propagation model.
  88.      * @return state with the number of parameters consistent with the propagation model
  89.      */
  90.     public FieldSpacecraftState<Gradient> getState() {

  91.         // Count the required number of parameters
  92.         int nbParams = 0;
  93.         for (final ParameterDriver driver : getParametersDrivers()) {
  94.             if (driver.isSelected()) {
  95.                 ++nbParams;
  96.             }
  97.         }

  98.         // Fill in intermediate slots
  99.         while (gStates.size() < nbParams + 1) {
  100.             gStates.add(null);
  101.         }

  102.         if (gStates.get(nbParams) == null) {
  103.             // It is the first time we need this number of parameters
  104.             // We need to create the state
  105.             final int freeParameters = getFreeStateParameters() + nbParams;
  106.             final FieldSpacecraftState<Gradient> s0 = gStates.get(0);

  107.             // Orbit
  108.             final FieldPVCoordinates<Gradient> pv0 = s0.getPVCoordinates();
  109.             final FieldOrbit<Gradient> gOrbit =
  110.                             new FieldCartesianOrbit<>(new TimeStampedFieldPVCoordinates<>(s0.getDate().toAbsoluteDate(),
  111.                                                                                           extend(pv0.getPosition(),     freeParameters),
  112.                                                                                           extend(pv0.getVelocity(),     freeParameters),
  113.                                                                                           extend(pv0.getAcceleration(), freeParameters)),
  114.                                                       s0.getFrame(),
  115.                                                       extend(s0.getMu(), freeParameters));

  116.             // Attitude
  117.             final FieldAngularCoordinates<Gradient> ac0 = s0.getAttitude().getOrientation();
  118.             final FieldAttitude<Gradient> gAttitude =
  119.                             new FieldAttitude<>(s0.getAttitude().getReferenceFrame(),
  120.                                                 new TimeStampedFieldAngularCoordinates<>(gOrbit.getDate(),
  121.                                                                                          extend(ac0.getRotation(), freeParameters),
  122.                                                                                          extend(ac0.getRotationRate(), freeParameters),
  123.                                                                                          extend(ac0.getRotationAcceleration(), freeParameters)));

  124.             // Mass
  125.             final Gradient gM = extend(s0.getMass(), freeParameters);

  126.             gStates.set(nbParams, new FieldSpacecraftState<>(gOrbit, gAttitude, gM));
  127.         }

  128.         return gStates.get(nbParams);

  129.     }

  130.     /** Get the model parameters.
  131.      * @param state state as returned by {@link #getState()}
  132.      * @return the model parameters
  133.      */
  134.     public Gradient[] getParameters(final FieldSpacecraftState<Gradient> state) {
  135.         final int freeParameters = state.getMass().getFreeParameters();
  136.         final List<ParameterDriver> drivers = getParametersDrivers();
  137.         final Gradient[] parameters = new Gradient[drivers.size()];
  138.         int index = getFreeStateParameters();
  139.         int i = 0;
  140.         for (ParameterDriver driver : drivers) {
  141.             parameters[i++] = driver.isSelected() ?
  142.                               Gradient.variable(freeParameters, index++, driver.getValue()) :
  143.                               Gradient.constant(freeParameters, driver.getValue());
  144.         }
  145.         return parameters;
  146.     }

  147.     /**
  148.      * Get the parameter drivers related to the analytical propagation model.
  149.      * @return a list of parameter drivers
  150.      */
  151.     public abstract List<ParameterDriver> getParametersDrivers();

  152.     /**
  153.      * Get the converted analytical orbit propagator.
  154.      * @param state state as returned by {@link #getState()}
  155.      * @param parameters model parameters as returned by {@link #getParameters(FieldSpacecraftState)}
  156.      * @return the converted analytical orbit propagator
  157.      */
  158.     public abstract FieldAbstractAnalyticalPropagator<Gradient> getPropagator(FieldSpacecraftState<Gradient> state,
  159.                                                                               Gradient[] parameters);

  160. }