AbstractConstantThrustPropulsionModel.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.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.orekit.forces.maneuvers.Control3DVectorCostType;
  22. import org.orekit.propagation.FieldSpacecraftState;
  23. import org.orekit.propagation.SpacecraftState;
  24. import org.orekit.time.AbsoluteDate;
  25. import org.orekit.utils.Constants;

  26. /** This abstract class simply serve as a container for a constant thrust maneuver.
  27.  * It re-writes all spacecraft dependent methods from {@link ThrustPropulsionModel}
  28.  * and removes their dependencies to current spacecraft state.
  29.  * Indeed since the thrust is constant (i.e. not variable during the maneuver), most of the
  30.  * calculated parameters (thrust vector, flow rate etc.) do not depend on current spacecraft state.
  31.  * @author Maxime Journot
  32.  * @since 10.2
  33.  */
  34. public abstract class AbstractConstantThrustPropulsionModel implements ThrustPropulsionModel {

  35.     /** Default control vector cost type. */
  36.     static final Control3DVectorCostType DEFAULT_CONTROL_3D_VECTOR_COST_TYPE = Control3DVectorCostType.TWO_NORM;

  37.     /** Initial thrust vector (N) in S/C frame, when building the object. */
  38.     private final Vector3D initialThrustVector;

  39.     /** Initial flow rate (kg/s), when building the object. */
  40.     private final double initialFlowRate;

  41.     /** Type of norm linking thrust vector to mass flow rate. */
  42.     private final Control3DVectorCostType control3DVectorCostType;

  43.     /** User-defined name of the maneuver.
  44.      * This String attribute is empty by default.
  45.      * It is added as a prefix to the parameter drivers of the maneuver.
  46.      * The purpose is to differentiate between drivers in the case where several maneuvers
  47.      * were added to a propagator force model.
  48.      * Additionally, the user can retrieve the whole maneuver by looping on the force models of a propagator,
  49.      * scanning for its name.
  50.      * @since 9.2
  51.      */
  52.     private final String name;

  53.     /** Generic constructor.
  54.      * @param thrust initial thrust value (N)
  55.      * @param isp initial isp value (s)
  56.      * @param direction initial thrust direction in S/C frame
  57.      * @param control3DVectorCostType control cost type
  58.      * @param name name of the maneuver
  59.      * @since 12.0
  60.      */
  61.     protected AbstractConstantThrustPropulsionModel(final double thrust, final double isp, final Vector3D direction,
  62.                                                     final Control3DVectorCostType control3DVectorCostType,
  63.                                                     final String name) {
  64.         this.name = name;
  65.         this.initialThrustVector = direction.normalize().scalarMultiply(thrust);
  66.         this.control3DVectorCostType = control3DVectorCostType;
  67.         this.initialFlowRate = -control3DVectorCostType.evaluate(initialThrustVector) / ThrustPropulsionModel.getExhaustVelocity(isp);
  68.     }

  69.     /** Constructor with default control cost type.
  70.      * @param thrust initial thrust value (N)
  71.      * @param isp initial isp value (s)
  72.      * @param direction initial thrust direction in S/C frame
  73.      * @param name name of the maneuver
  74.      */
  75.     protected AbstractConstantThrustPropulsionModel(final double thrust, final double isp, final Vector3D direction,
  76.                                                     final String name) {
  77.         this(thrust, isp, direction, DEFAULT_CONTROL_3D_VECTOR_COST_TYPE, name);
  78.     }

  79.     /** Get the initial thrust vector.
  80.      * @return the initial thrust vector
  81.      */
  82.     protected Vector3D getInitialThrustVector() {
  83.         return initialThrustVector;
  84.     }

  85.     /** Get the initial flow rate.
  86.      * @return the initial flow rate
  87.      */
  88.     protected double getInitialFlowRate() {
  89.         return initialFlowRate;
  90.     }

  91.     /** {@inheritDoc} */
  92.     @Override
  93.     public String getName() {
  94.         return name;
  95.     }

  96.     /** {@inheritDoc} */
  97.     @Override
  98.     public Control3DVectorCostType getControl3DVectorCostType() {
  99.         return control3DVectorCostType;
  100.     }

  101.     /** Get the specific impulse.
  102.      * @return specific impulse (s), will throw exception if
  103.      * used on PDriver having several driven values, because
  104.      * in this case a date is needed.
  105.      */
  106.     public double getIsp() {
  107.         final double flowRate = getFlowRate();
  108.         return -control3DVectorCostType.evaluate(getThrustVector()) / (Constants.G0_STANDARD_GRAVITY * flowRate);
  109.     }

  110.     /** Get the specific impulse at given date.
  111.      * @param date date at which the Isp wants to be known
  112.      * @return specific impulse (s).
  113.      */
  114.     public double getIsp(final AbsoluteDate date) {
  115.         final double flowRate = getFlowRate(date);
  116.         return -control3DVectorCostType.evaluate(getThrustVector(date)) / (Constants.G0_STANDARD_GRAVITY * flowRate);
  117.     }

  118.     /** Get the thrust direction in S/C frame.
  119.      * @param date date at which the direction wants to be known
  120.      * @return the thrust direction in S/C frame
  121.      */
  122.     public Vector3D getDirection(final AbsoluteDate date) {
  123.         return getThrustVector(date).normalize();
  124.     }

  125.     /** Get the thrust direction in S/C frame.
  126.      * @return the thrust direction in S/C frame,  will throw exception if
  127.      * used on PDriver having several driven values, because
  128.      * in this case a date is needed.
  129.      */
  130.     public Vector3D getDirection() {
  131.         return getThrustVector().normalize();
  132.     }

  133.     /** Get the thrust magnitude (N).
  134.      * @return the thrust value (N), will throw
  135.      * an exception if called of a driver having several
  136.      * values driven
  137.      */
  138.     public double getThrustMagnitude() {
  139.         return getThrustVector().getNorm();
  140.     }

  141.     /** Get the thrust magnitude (N) at given date.
  142.      * @param date date at which the thrust vector wants to be known,
  143.      * often the date parameter will not be important and can be whatever
  144.      * if the thrust parameter driver as only value estimated over the all
  145.      * orbit determination interval
  146.      * @return the thrust value (N)
  147.      */
  148.     public double getThrustMagnitude(final AbsoluteDate date) {
  149.         return getThrustVector(date).getNorm();
  150.     }

  151.     /** {@inheritDoc}
  152.      * Here the thrust vector do not depend on current S/C state.
  153.      */
  154.     @Override
  155.     public Vector3D getThrustVector(final SpacecraftState s) {
  156.         // Call the abstract function that do not depend on current S/C state
  157.         return getThrustVector(s.getDate());
  158.     }

  159.     /** {@inheritDoc}
  160.      * Here the flow rate do not depend on current S/C state
  161.      */
  162.     @Override
  163.     public double getFlowRate(final SpacecraftState s) {
  164.         // Call the abstract function that do not depend on current S/C state
  165.         return getFlowRate(s.getDate());
  166.     }

  167.     /** {@inheritDoc}
  168.      * Here the thrust vector do not depend on current S/C state.
  169.      */
  170.     @Override
  171.     public Vector3D getThrustVector(final SpacecraftState s, final double[] parameters) {
  172.         // Call the abstract function that do not depend on current S/C state
  173.         return getThrustVector(parameters);
  174.     }

  175.     /** {@inheritDoc}
  176.      * Here the flow rate do not depend on current S/C state
  177.      */
  178.     public double getFlowRate(final SpacecraftState s, final double[] parameters) {
  179.         // Call the abstract function that do not depend on current S/C state
  180.         return getFlowRate(parameters);
  181.     }

  182.     /** {@inheritDoc}
  183.      * Here the thrust vector do not depend on current S/C state.
  184.      */
  185.     public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(final FieldSpacecraftState<T> s,
  186.                                                                             final T[] parameters) {
  187.         // Call the abstract function that do not depend on current S/C state
  188.         return getThrustVector(parameters);
  189.     }

  190.     /** {@inheritDoc}
  191.      * Here the flow rate do not depend on current S/C state
  192.      */
  193.     public <T extends CalculusFieldElement<T>> T getFlowRate(final FieldSpacecraftState<T> s, final T[] parameters) {
  194.         // Call the abstract function that do not depend on current S/C state
  195.         return getFlowRate(parameters);
  196.     }

  197.     /** Get the thrust vector in spacecraft frame (N).
  198.      * Here it does not depend on current S/C state.
  199.      * @return thrust vector in spacecraft frame (N),
  200.      * will throw an exception if used on driver
  201.      * containing several value spans
  202.      */
  203.     public abstract Vector3D getThrustVector();

  204.     /** Get the thrust vector in spacecraft frame (N).
  205.      * Here it does not depend on current S/C state.
  206.      * @param date date at which the thrust vector wants to be known,
  207.      * often the date parameter will not be important and can be whatever
  208.      * if the thrust parameter driver as only value estimated over the all
  209.      * orbit determination interval
  210.      * @return thrust vector in spacecraft frame (N)
  211.      */
  212.     public abstract Vector3D getThrustVector(AbsoluteDate date);

  213.     /** Get the flow rate (kg/s).
  214.      * Here it does not depend on current S/C.
  215.      * @return flow rate (kg/s)
  216.      * will throw an exception if used on driver
  217.      * containing several value spans
  218.      */
  219.     public abstract double getFlowRate();

  220.     /** Get the flow rate (kg/s).
  221.      * Here it does not depend on current S/C.
  222.      * @param date date at which the thrust vector wants to be known,
  223.      * often the date parameter will not be important and can be whatever
  224.      * if the thrust parameter driver as only value estimated over the all
  225.      * orbit determination interval
  226.      * @return flow rate (kg/s)
  227.      */
  228.     public abstract double getFlowRate(AbsoluteDate date);

  229.     /** Get the thrust vector in spacecraft frame (N).
  230.      * Here it does not depend on current S/C state.
  231.      * @param parameters propulsion model parameters
  232.      * @return thrust vector in spacecraft frame (N)
  233.      */
  234.     public abstract Vector3D getThrustVector(double[] parameters);

  235.     /** Get the flow rate (kg/s).
  236.      * Here it does not depend on current S/C state.
  237.      * @param parameters propulsion model parameters
  238.      * @return flow rate (kg/s)
  239.      */
  240.     public abstract double getFlowRate(double[] parameters);

  241.     /** Get the thrust vector in spacecraft frame (N).
  242.      * Here it does not depend on current S/C state.
  243.      * @param parameters propulsion model parameters
  244.      * @param <T> extends CalculusFieldElement&lt;T&gt;
  245.      * @return thrust vector in spacecraft frame (N)
  246.      */
  247.     public abstract <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(T[] parameters);

  248.     /** Get the flow rate (kg/s).
  249.      * Here it does not depend on current S/C state.
  250.      * @param parameters propulsion model parameters
  251.      * @param <T> extends CalculusFieldElement&lt;T&gt;
  252.      * @return flow rate (kg/s)
  253.      */
  254.     public abstract <T extends CalculusFieldElement<T>> T getFlowRate(T[] parameters);
  255. }