DSSTPropagatorBuilder.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.conversion;

  18. import org.orekit.attitudes.Attitude;
  19. import org.orekit.attitudes.AttitudeProvider;
  20. import org.orekit.attitudes.FrameAlignedProvider;
  21. import org.orekit.estimation.leastsquares.DSSTBatchLSModel;
  22. import org.orekit.estimation.leastsquares.ModelObserver;
  23. import org.orekit.estimation.measurements.ObservedMeasurement;
  24. import org.orekit.orbits.EquinoctialOrbit;
  25. import org.orekit.orbits.Orbit;
  26. import org.orekit.orbits.OrbitType;
  27. import org.orekit.orbits.PositionAngleType;
  28. import org.orekit.propagation.PropagationType;
  29. import org.orekit.propagation.Propagator;
  30. import org.orekit.propagation.SpacecraftState;
  31. import org.orekit.propagation.integration.AdditionalDerivativesProvider;
  32. import org.orekit.propagation.semianalytical.dsst.DSSTPropagator;
  33. import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
  34. import org.orekit.propagation.semianalytical.dsst.forces.DSSTNewtonianAttraction;
  35. import org.orekit.utils.ParameterDriver;
  36. import org.orekit.utils.ParameterDriversList;

  37. import java.util.ArrayList;
  38. import java.util.Collections;
  39. import java.util.List;

  40. /** Builder for DSST propagator.
  41.  * @author Bryan Cazabonne
  42.  * @since 10.0
  43.  */
  44. public class DSSTPropagatorBuilder extends AbstractIntegratedPropagatorBuilder<DSSTPropagator> {

  45.     /** Force models used during the extrapolation of the orbit. */
  46.     private final List<DSSTForceModel> forceModels;

  47.     /** Type of the elements used to define the orbital state.*/
  48.     private PropagationType stateType;

  49.     /** Build a new instance.
  50.      * <p>
  51.      * The reference orbit is used as a model to {@link
  52.      * #createInitialOrbit() create initial orbit}. It defines the
  53.      * inertial frame, the central attraction coefficient, and is also used together
  54.      * with the {@code positionScale} to convert from the {@link
  55.      * ParameterDriver#setNormalizedValue(double) normalized} parameters used by the
  56.      * callers of this builder to the real orbital parameters.
  57.      * The default attitude provider is aligned with the orbit's inertial frame.
  58.      * </p>
  59.      *
  60.      * @param referenceOrbit reference orbit from which real orbits will be built
  61.      * @param builder first order integrator builder
  62.      * @param positionScale scaling factor used for orbital parameters normalization
  63.      * (typically set to the expected standard deviation of the position)
  64.      * @param propagationType type of the orbit used for the propagation (mean or osculating)
  65.      * @param stateType type of the elements used to define the orbital state (mean or osculating)
  66.      * @see #DSSTPropagatorBuilder(Orbit, ODEIntegratorBuilder, double, PropagationType,
  67.      * PropagationType, AttitudeProvider)
  68.      */
  69.     public DSSTPropagatorBuilder(final Orbit referenceOrbit,
  70.                                  final ODEIntegratorBuilder builder,
  71.                                  final double positionScale,
  72.                                  final PropagationType propagationType,
  73.                                  final PropagationType stateType) {
  74.         this(referenceOrbit, builder, positionScale, propagationType, stateType,
  75.              FrameAlignedProvider.of(referenceOrbit.getFrame()));
  76.     }

  77.     /** Build a new instance.
  78.      * <p>
  79.      * The reference orbit is used as a model to {@link
  80.      * #createInitialOrbit() create initial orbit}. It defines the
  81.      * inertial frame, the central attraction coefficient, and is also used together
  82.      * with the {@code positionScale} to convert from the {@link
  83.      * ParameterDriver#setNormalizedValue(double) normalized} parameters used by the
  84.      * callers of this builder to the real orbital parameters.
  85.      * </p>
  86.      * @param referenceOrbit reference orbit from which real orbits will be built
  87.      * @param builder first order integrator builder
  88.      * @param positionScale scaling factor used for orbital parameters normalization
  89.      * (typically set to the expected standard deviation of the position)
  90.      * @param propagationType type of the orbit used for the propagation (mean or osculating)
  91.      * @param stateType type of the elements used to define the orbital state (mean or osculating)
  92.      * @param attitudeProvider attitude law.
  93.      * @since 10.1
  94.      */
  95.     public DSSTPropagatorBuilder(final Orbit referenceOrbit,
  96.                                  final ODEIntegratorBuilder builder,
  97.                                  final double positionScale,
  98.                                  final PropagationType propagationType,
  99.                                  final PropagationType stateType,
  100.                                  final AttitudeProvider attitudeProvider) {
  101.         super(referenceOrbit, builder, PositionAngleType.MEAN, positionScale, propagationType, attitudeProvider, Propagator.DEFAULT_MASS);
  102.         this.forceModels       = new ArrayList<>();
  103.         this.stateType         = stateType;
  104.     }

  105.     /** Copy constructor.
  106.      * @param builder builder to copy from
  107.      */
  108.     private DSSTPropagatorBuilder(final DSSTPropagatorBuilder builder) {
  109.         this(builder.createInitialOrbit(), builder.getIntegratorBuilder(),
  110.              builder.getPositionScale(), builder.getPropagationType(),
  111.              builder.getStateType(), builder.getAttitudeProvider());
  112.     }

  113.     /** {@inheritDoc}. */
  114.     @Override
  115.     public DSSTPropagatorBuilder clone() {
  116.         // Call to super clone() method to avoid warning
  117.         final DSSTPropagatorBuilder clonedBuilder = (DSSTPropagatorBuilder) super.clone();

  118.         // Use copy constructor to unlink orbital drivers
  119.         final DSSTPropagatorBuilder copyBuilder = new DSSTPropagatorBuilder(clonedBuilder);

  120.         // Update mass and force models
  121.         copyBuilder.setMass(getMass());
  122.         for (DSSTForceModel model : forceModels) {
  123.             copyBuilder.addForceModel(model);
  124.         }
  125.         return copyBuilder;

  126.     }

  127.     /** Get the type of the elements used to define the orbital state (mean or osculating).
  128.      * @return the type of the elements used to define the orbital state
  129.      */
  130.     public PropagationType getStateType() {
  131.         return stateType;
  132.     }

  133.     /** Get the list of all force models.
  134.      * @return the list of all force models
  135.      */
  136.     public List<DSSTForceModel> getAllForceModels()
  137.     {
  138.         return Collections.unmodifiableList(forceModels);
  139.     }

  140.     /** Add a force model to the global perturbation model.
  141.      * <p>If this method is not called at all, the integrated orbit will follow
  142.      * a Keplerian evolution only.</p>
  143.      * @param model perturbing {@link DSSTForceModel} to add
  144.      */
  145.     public void addForceModel(final DSSTForceModel model) {
  146.         if (model instanceof DSSTNewtonianAttraction) {
  147.             // we want to add the central attraction force model
  148.             if (hasNewtonianAttraction()) {
  149.                 // there is already a central attraction model, replace it
  150.                 forceModels.set(forceModels.size() - 1, model);
  151.             } else {
  152.                 // there are no central attraction model yet, add it at the end of the list
  153.                 forceModels.add(model);
  154.             }
  155.         } else {
  156.             // we want to add a perturbing force model
  157.             if (hasNewtonianAttraction()) {
  158.                 // insert the new force model before Newtonian attraction,
  159.                 // which should always be the last one in the list
  160.                 forceModels.add(forceModels.size() - 1, model);
  161.             } else {
  162.                 // we only have perturbing force models up to now, just append at the end of the list
  163.                 forceModels.add(model);
  164.             }
  165.         }

  166.         addSupportedParameters(model.getParametersDrivers());
  167.     }

  168.     /** Reset the orbit in the propagator builder.
  169.      * @param newOrbit newOrbit New orbit to set in the propagator builder
  170.      * @param orbitType orbit type (MEAN or OSCULATING)
  171.      */
  172.     public void resetOrbit(final Orbit newOrbit, final PropagationType orbitType) {
  173.         this.stateType = orbitType;
  174.         super.resetOrbit(newOrbit);
  175.     }

  176.     /** {@inheritDoc} */
  177.     public DSSTPropagator buildPropagator(final double[] normalizedParameters) {

  178.         setParameters(normalizedParameters);
  179.         final EquinoctialOrbit orbit    = (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(createInitialOrbit());
  180.         final Attitude         attitude = getAttitudeProvider().getAttitude(orbit, orbit.getDate(), getFrame());
  181.         final SpacecraftState  state    = new SpacecraftState(orbit, attitude).withMass(getMass());

  182.         final DSSTPropagator propagator = new DSSTPropagator(
  183.                 getIntegratorBuilder().buildIntegrator(orbit, OrbitType.EQUINOCTIAL, PositionAngleType.MEAN),
  184.                 getPropagationType(), getAttitudeProvider());

  185.         // Configure force models
  186.         if (!hasNewtonianAttraction()) {
  187.             // There are no central attraction model yet, add it at the end of the list
  188.             addForceModel(new DSSTNewtonianAttraction(orbit.getMu()));
  189.         }
  190.         for (DSSTForceModel model : forceModels) {
  191.             propagator.addForceModel(model);
  192.         }

  193.         propagator.setInitialState(state, stateType);

  194.         // Add additional derivatives providers to the propagator
  195.         for (AdditionalDerivativesProvider provider: getAdditionalDerivativesProviders()) {
  196.             propagator.addAdditionalDerivativesProvider(provider);
  197.         }

  198.         return propagator;

  199.     }

  200.     /** {@inheritDoc} */
  201.     @Override
  202.     public DSSTBatchLSModel buildLeastSquaresModel(final PropagatorBuilder[] builders,
  203.                                                    final List<ObservedMeasurement<?>> measurements,
  204.                                                    final ParameterDriversList estimatedMeasurementsParameters,
  205.                                                    final ModelObserver observer) {
  206.         return new DSSTBatchLSModel(builders,
  207.                                     measurements,
  208.                                     estimatedMeasurementsParameters,
  209.                                     observer,
  210.                                     getPropagationType());
  211.     }

  212.     /** Check if Newtonian attraction force model is available.
  213.      * <p>
  214.      * Newtonian attraction is always the last force model in the list.
  215.      * </p>
  216.      * @return true if Newtonian attraction force model is available
  217.      */
  218.     private boolean hasNewtonianAttraction() {
  219.         final int last = forceModels.size() - 1;
  220.         return last >= 0 && forceModels.get(last) instanceof DSSTNewtonianAttraction;
  221.     }

  222. }