AbstractAnalyticalGradientConverter.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.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.ParameterDriversProvider;
  34. import org.orekit.utils.TimeStampedFieldAngularCoordinates;
  35. import org.orekit.utils.TimeStampedFieldPVCoordinates;

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

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

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

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

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

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

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

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

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

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

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

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

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

  87.     }

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

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

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

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

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

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

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

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

  129.         return gStates.get(nbParams);
  130.     }

  131.     /**
  132.      * Get the converted analytical orbit propagator.
  133.      * @param state state as returned by {@link #getState()}
  134.      * @param parameters model parameters
  135.      * @return the converted analytical orbit propagator
  136.      */
  137.     public abstract FieldAbstractAnalyticalPropagator<Gradient> getPropagator(FieldSpacecraftState<Gradient> state,
  138.                                                                               Gradient[] parameters);

  139. }