SphericalConstantThrustPropulsionModel.java

  1. /* Copyright 2022-2025 Romain Serra
  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.forces.maneuvers.propulsion;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  20. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  21. import org.hipparchus.util.FastMath;
  22. import org.hipparchus.util.MathUtils;
  23. import org.orekit.forces.maneuvers.Control3DVectorCostType;
  24. import org.orekit.time.AbsoluteDate;
  25. import org.orekit.utils.ParameterDriver;

  26. import java.util.Arrays;
  27. import java.util.Collections;
  28. import java.util.List;

  29. /** Constant thrust propulsion model with:
  30.  *  - Constant thrust direction in spacecraft frame
  31.  *  - Parameter drivers (for estimation) for the thrust vector in spherical coordinates.
  32.  * @author Romain Serra
  33.  * @since 13.1
  34.  * @see BasicConstantThrustPropulsionModel
  35.  */
  36. public class SphericalConstantThrustPropulsionModel extends AbstractConstantThrustPropulsionModel {

  37.     /** Parameter name for thrust magnitude. */
  38.     public static final String THRUST_MAGNITUDE = "thrust magnitude";

  39.     /** Parameter name for thrust right ascension. */
  40.     public static final String THRUST_RIGHT_ASCENSION = "thrust alpha";

  41.     /** Parameter name for thrust declination. */
  42.     public static final String THRUST_DECLINATION = "thrust declination";

  43.     /** Thrust scaling factor.
  44.      * <p>
  45.      * We use a power of 2 to avoid numeric noise introduction
  46.      * in the multiplications/divisions sequences.
  47.      * </p>
  48.      */
  49.     public static final double THRUST_SCALE = FastMath.scalb(1.0, -5);

  50.     /** Driver for thrust magnitude. */
  51.     private final ParameterDriver thrustMagnitude;

  52.     /** Driver for thrust right ascension in spacecraft frame. */
  53.     private final ParameterDriver thrustRightAscension;

  54.     /** Driver for thrust declination in spacecraft frame. */
  55.     private final ParameterDriver thrustDeclination;

  56.     /** Mass flow rate factor. */
  57.     private final double massFlowRateFactor;

  58.     /** Generic constructor.
  59.      * @param isp isp (s)
  60.      * @param thrustMagnitude thrust magnitude (N)
  61.      * @param thrustDirection thrust direction in spacecraft frame
  62.      * @param name name of the maneuver
  63.      */
  64.     public SphericalConstantThrustPropulsionModel(final double isp, final double thrustMagnitude,
  65.                                                   final Vector3D thrustDirection, final String name) {
  66.         super(isp, thrustMagnitude, thrustDirection, Control3DVectorCostType.TWO_NORM, name);
  67.         this.massFlowRateFactor = -1. / ThrustPropulsionModel.getExhaustVelocity(isp);

  68.         // Build the parameter drivers, using maneuver name as prefix
  69.         this.thrustMagnitude   = new ParameterDriver(name + THRUST_MAGNITUDE, thrustMagnitude, THRUST_SCALE,
  70.                 0.0, Double.POSITIVE_INFINITY);
  71.         this.thrustRightAscension   = new ParameterDriver(name + THRUST_RIGHT_ASCENSION, thrustDirection.getAlpha(), 1.,
  72.                 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
  73.         this.thrustDeclination   = new ParameterDriver(name + THRUST_DECLINATION, thrustDirection.getDelta(), 1.,
  74.                 -MathUtils.SEMI_PI, MathUtils.SEMI_PI);
  75.     }

  76.     /** Constructor with thrust vector.
  77.      * @param isp isp (s)
  78.      * @param thrustVector thrust vector in spacecraft frame (N)
  79.      * @param name name of the maneuver
  80.      */
  81.     public SphericalConstantThrustPropulsionModel(final double isp, final Vector3D thrustVector, final String name) {
  82.         this(isp, thrustVector.getNorm(), thrustVector.normalize(), name);
  83.     }

  84.     /** {@inheritDoc} */
  85.     @Override
  86.     public Vector3D getThrustVector() {
  87.         // Thrust vector does not depend on spacecraft state for a constant maneuver.
  88.         // thrustDriver as only 1 value estimated over the whole time period
  89.         // by construction thrustDriver has only 1 value estimated over the all period
  90.         // that is why no argument is acceptable
  91.         return new Vector3D(thrustRightAscension.getValue(), thrustDeclination.getValue()).scalarMultiply(thrustMagnitude.getValue());
  92.     }

  93.     /** {@inheritDoc} */
  94.     @Override
  95.     public Vector3D getThrustVector(final AbsoluteDate date) {
  96.         // Thrust vector does not depend on spacecraft state for a constant maneuver.
  97.         return new Vector3D(thrustRightAscension.getValue(date), thrustDeclination.getValue(date)).scalarMultiply(thrustMagnitude.getValue(date));
  98.     }

  99.     /** {@inheritDoc} */
  100.     @Override
  101.     public double getFlowRate() {
  102.         // Thrust vector does not depend on spacecraft state for a constant maneuver.
  103.         // thrustDriver has only 1 value estimated over the whole time period
  104.         // by construction thrustDriver has only 1 value estimated over the all period
  105.         // that is why no argument is acceptable
  106.         return getThrustVector().getNorm() * massFlowRateFactor;
  107.     }

  108.     /** {@inheritDoc} */
  109.     @Override
  110.     public double getFlowRate(final AbsoluteDate date) {
  111.         return getThrustVector(date).getNorm() * massFlowRateFactor;
  112.     }

  113.     /** {@inheritDoc} */
  114.     @Override
  115.     public List<ParameterDriver> getParametersDrivers() {
  116.         return Collections.unmodifiableList(Arrays.asList(thrustMagnitude, thrustRightAscension, thrustDeclination));
  117.     }

  118.     /** {@inheritDoc} */
  119.     @Override
  120.     public Vector3D getThrustVector(final double[] parameters) {
  121.         // Thrust vector does not depend on spacecraft state for a constant maneuver.
  122.         return new Vector3D(parameters[1], parameters[2]).scalarMultiply(parameters[0]);
  123.     }

  124.     /** {@inheritDoc} */
  125.     @Override
  126.     public double getFlowRate(final double[] parameters) {
  127.         return getThrustVector(parameters).getNorm() * massFlowRateFactor;
  128.     }

  129.     /** {@inheritDoc} */
  130.     @Override
  131.     public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(final T[] parameters) {
  132.         return new FieldVector3D<>(parameters[1], parameters[2]).scalarMultiply(parameters[0]);
  133.     }

  134.     /** {@inheritDoc} */
  135.     @Override
  136.     public <T extends CalculusFieldElement<T>> T getFlowRate(final T[] parameters) {
  137.         return getThrustVector(parameters).getNorm().multiply(massFlowRateFactor);
  138.     }
  139. }