CR3BPMultipleShooter.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.propagation.numerical.cr3bp;

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

  20. import org.orekit.errors.OrekitException;
  21. import org.orekit.errors.OrekitMessages;
  22. import org.orekit.propagation.SpacecraftState;
  23. import org.orekit.propagation.numerical.NumericalPropagator;
  24. import org.orekit.utils.AbsolutePVCoordinates;
  25. import org.orekit.utils.AbstractMultipleShooting;

  26. /**
  27.  * Multiple shooting method applicable for orbits, either propagation in CR3BP, or in an ephemeris model.
  28.  * @see "TRAJECTORY DESIGN AND ORBIT MAINTENANCE STRATEGIES IN MULTI-BODY DYNAMICAL REGIMES by Thomas A. Pavlak, Purdue University"
  29.  * @author William Desprats
  30.  * @author Alberto Fossà
  31.  */
  32. public class CR3BPMultipleShooter extends AbstractMultipleShooting {

  33.     /** Name of the derivatives. */
  34.     private static final String STM = "stmEquations";

  35.     /** Derivatives linked to the Propagators.
  36.      * @since 11.1
  37.      */
  38.     private final List<STMEquations> stmEquations;

  39.     /** True if orbit is closed. */
  40.     private boolean isClosedOrbit;

  41.     /** Simple Constructor.
  42.      * <p> Standard constructor for multiple shooting which can be used with the CR3BP model. </p>
  43.      * @param initialGuessList initial patch points to be corrected
  44.      * @param propagatorList list of propagators associated to each patch point
  45.      * @param stmEquations list of additional derivatives providers linked to propagatorList
  46.      * @param tolerance convergence tolerance on the constraint vector
  47.      * @param maxIter maximum number of iterations
  48.      */
  49.     public CR3BPMultipleShooter(final List<SpacecraftState> initialGuessList,
  50.                                 final List<NumericalPropagator> propagatorList,
  51.                                 final List<STMEquations> stmEquations,
  52.                                 final double tolerance, final int maxIter) {
  53.         super(initialGuessList, propagatorList, tolerance, maxIter, true, STM);
  54.         this.stmEquations = stmEquations;
  55.     }

  56.     /** {@inheritDoc} */
  57.     protected SpacecraftState getAugmentedInitialState(final int i) {
  58.         return stmEquations.get(i).setInitialPhi(getPatchPoint(i));
  59.     }

  60.     /** {@inheritDoc} */
  61.     @Override
  62.     public void setEpochFreedom(final int patchIndex, final boolean isFree) {
  63.         throw new OrekitException(OrekitMessages.FUNCTION_NOT_IMPLEMENTED);
  64.     }

  65.     /** {@inheritDoc} */
  66.     @Override
  67.     public void setScaleLength(final double scaleLength) {
  68.         throw new OrekitException(OrekitMessages.FUNCTION_NOT_IMPLEMENTED);
  69.     }

  70.     /** {@inheritDoc} */
  71.     @Override
  72.     public void setScaleTime(final double scaleTime) {
  73.         throw new OrekitException(OrekitMessages.FUNCTION_NOT_IMPLEMENTED);
  74.     }

  75.     /** Set the constraint of a closed orbit or not.
  76.      *  @param isClosed true if orbit should be closed
  77.      */
  78.     public void setClosedOrbitConstraint(final boolean isClosed) {
  79.         this.isClosedOrbit = isClosed;
  80.     }

  81.     /** {@inheritDoc} */
  82.     @Override
  83.     protected double[][] computeAdditionalJacobianMatrix(final List<SpacecraftState> propagatedSP) {

  84.         final Map<Integer, Double> mapConstraints = getConstraintsMap();
  85.         final boolean[] freeCompsMap              = getFreeCompsMap();

  86.         // Number of additional constraints
  87.         final int nRows = mapConstraints.size() + (isClosedOrbit ? 6 : 0);
  88.         final int nCols = getNumberOfFreeComponents();

  89.         final double[][] M = new double[nRows][nCols];

  90.         int j = 0;
  91.         if (isClosedOrbit) {
  92.             // The Jacobian matrix has the following form:
  93.             //
  94.             //      [-1  0              0  ...  1  0             ]
  95.             //      [ 0 -1  0           0  ...     1  0          ]
  96.             // F =  [    0 -1  0        0  ...        1  0       ]
  97.             //      [       0 -1  0     0  ...           1  0    ]
  98.             //      [          0 -1  0  0  ...              1  0 ]
  99.             //      [          0  0 -1  0  ...              0  1 ]

  100.             int index = 0;
  101.             for (int i = 0; i < 6; i++) {
  102.                 if (freeCompsMap[i]) {
  103.                     M[i][index] = -1.0;
  104.                     index++;
  105.                 }
  106.             }
  107.             index = nCols - 6;
  108.             for (int i = 0; i < 6; i++) {
  109.                 if (freeCompsMap[nCols - 6 + i]) {
  110.                     M[i][index] = 1.0;
  111.                     index++;
  112.                 }
  113.             }
  114.             j = 6;
  115.         }

  116.         for (int k : mapConstraints.keySet()) {
  117.             M[j][k] = 1.0;
  118.             j++;
  119.         }

  120.         return M;
  121.     }

  122.     /** {@inheritDoc} */
  123.     @Override
  124.     protected double[] computeAdditionalConstraints(final List<SpacecraftState> propagatedSP) {

  125.         // The additional constraint vector has the following form :

  126.         //           [ xni - x1i ]----
  127.         //           [ yni - x1i ]    |
  128.         // Fadd(X) = [ zni - x1i ] vector's component
  129.         //           [vxni - vx1i] for a closed orbit
  130.         //           [vyni - vy1i]    |
  131.         //           [vzni - vz1i]----
  132.         //           [ y1i - y1d ]---- other constraints (component of
  133.         //           [    ...    ]    | a patch point equals to a
  134.         //           [vz2i - vz2d]----  desired value)

  135.         final Map<Integer, Double> mapConstraints           = getConstraintsMap();
  136.         final List<SpacecraftState> patchedSpacecraftStates = getPatchedSpacecraftState();

  137.         final double[] fxAdditional = new double[mapConstraints.size() + (isClosedOrbit ? 6 : 0)];
  138.         int i = 0;

  139.         if (isClosedOrbit) {

  140.             final AbsolutePVCoordinates apv1i = patchedSpacecraftStates.get(0).getAbsPVA();
  141.             final AbsolutePVCoordinates apvni = patchedSpacecraftStates.get(patchedSpacecraftStates.size() - 1).getAbsPVA();

  142.             fxAdditional[0] = apvni.getPosition().getX() - apv1i.getPosition().getX();
  143.             fxAdditional[1] = apvni.getPosition().getY() - apv1i.getPosition().getY();
  144.             fxAdditional[2] = apvni.getPosition().getZ() - apv1i.getPosition().getZ();
  145.             fxAdditional[3] = apvni.getVelocity().getX() - apv1i.getVelocity().getX();
  146.             fxAdditional[4] = apvni.getVelocity().getY() - apv1i.getVelocity().getY();
  147.             fxAdditional[5] = apvni.getVelocity().getZ() - apv1i.getVelocity().getZ();

  148.             i = 6;
  149.         }

  150.         // Update additional constraints
  151.         updateAdditionalConstraints(i, fxAdditional);
  152.         return fxAdditional;
  153.     }

  154.     /** {@inheritDoc} */
  155.     @Override
  156.     protected int getNumberOfConstraints() {
  157.         return super.getNumberOfConstraints() + (isClosedOrbit ? 6 : 0);
  158.     }

  159. }