1   /* Copyright 2002-2026 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  
18  package org.orekit.forces.maneuvers.propulsion;
19  
20  import java.util.Arrays;
21  import java.util.Collections;
22  import java.util.List;
23  
24  import org.hipparchus.CalculusFieldElement;
25  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26  import org.hipparchus.geometry.euclidean.threed.Vector3D;
27  import org.hipparchus.util.FastMath;
28  import org.orekit.forces.maneuvers.Control3DVectorCostType;
29  import org.orekit.time.AbsoluteDate;
30  import org.orekit.time.TimeInterval;
31  import org.orekit.utils.drivers.ParameterDriver;
32  
33  /** Constant thrust propulsion model with:
34   *  - Constant thrust direction in spacecraft frame
35   *  - Parameter drivers (for estimation) for the thrust norm or the flow rate.
36   * Note that both parameters CANNOT be selected at the same time since they depend on one another.
37   * @author Maxime Journot
38   * @since 10.2
39   */
40  public class BasicConstantThrustPropulsionModel extends AbstractConstantThrustPropulsionModel {
41  
42      /** Parameter name for thrust. */
43      public static final String THRUST = "thrust";
44  
45      /** Parameter name for flow rate. */
46      public static final String FLOW_RATE = "flow rate";
47  
48      /** Thrust scaling factor.
49       * <p>
50       * We use a power of 2 to avoid numeric noise introduction
51       * in the multiplications/divisions sequences.
52       * </p>
53       */
54      public static final double THRUST_SCALE = FastMath.scalb(1.0, -5);
55  
56      /** Flow rate scaling factor.
57       * <p>
58       * We use a power of 2 to avoid numeric noise introduction
59       * in the multiplications/divisions sequences.
60       * </p>
61       */
62      public static final double FLOW_RATE_SCALE = FastMath.scalb(1.0, -12);
63  
64      /** Driver for thrust parameter. */
65      private final ParameterDriver thrustDriver;
66  
67      /** Driver for flow rate parameter. */
68      private final ParameterDriver flowRateDriver;
69  
70      /** Thrust direction in spacecraft frame. */
71      private final Vector3D direction;
72  
73      /** Generic constructor.
74       * @param thrust thrust (N)
75       * @param isp isp (s)
76       * @param direction direction in spacecraft frame
77       * @param control3DVectorCostType control cost type
78       * @param name name of the maneuver
79       * @since 12.0
80       */
81      public BasicConstantThrustPropulsionModel(final double thrust,
82                                                final double isp,
83                                                final Vector3D direction,
84                                                final Control3DVectorCostType control3DVectorCostType,
85                                                final String name) {
86          super(thrust, isp, direction, control3DVectorCostType, name);
87          this.direction = direction.normalize();
88  
89          final double initialFlowRate = super.getInitialFlowRate();
90  
91          // Build the parameter drivers, using maneuver name as prefix
92          this.thrustDriver   = new ParameterDriver(name + THRUST, thrust, THRUST_SCALE,
93                                                    0.0, Double.POSITIVE_INFINITY, TimeInterval.UNLIMITED);
94          this.flowRateDriver = new ParameterDriver(name + FLOW_RATE, initialFlowRate, FLOW_RATE_SCALE,
95                                                    Double.NEGATIVE_INFINITY, 0.0, TimeInterval.UNLIMITED);
96      }
97  
98      /** Simple constructor.
99       * @param thrust thrust (N)
100      * @param isp isp (s)
101      * @param direction direction in spacecraft frame
102      * @param name name of the maneuver
103      */
104     public BasicConstantThrustPropulsionModel(final double thrust,
105                                               final double isp,
106                                               final Vector3D direction,
107                                               final String name) {
108         this(thrust, isp, direction, DEFAULT_CONTROL_3D_VECTOR_COST_TYPE, name);
109     }
110 
111     /** {@inheritDoc} */
112     @Override
113     public Vector3D getThrustVector() {
114         // Thrust vector does not depend on spacecraft state for a constant maneuver.
115         return direction.scalarMultiply(thrustDriver.getValue());
116     }
117 
118     /** {@inheritDoc} */
119     @Override
120     public Vector3D getThrustVector(final AbsoluteDate date) {
121         // Thrust vector does not depend on spacecraft state for a constant maneuver.
122         return getThrustVector();
123     }
124 
125     /** {@inheritDoc} */
126     @Override
127     public double getFlowRate() {
128         // Thrust vector does not depend on spacecraft state for a constant maneuver.
129         // thrustDriver has only 1 value estimated over the whole time period
130         // by construction thrustDriver has only 1 value estimated over the all period
131         // that is why no argument is acceptable
132         return flowRateDriver.getValue();
133     }
134 
135     /** {@inheritDoc} */
136     @Override
137     public double getFlowRate(final AbsoluteDate date) {
138         return getFlowRate();
139     }
140 
141     /** {@inheritDoc} */
142     @Override
143     public List<ParameterDriver> getParametersDrivers() {
144         return Collections.unmodifiableList(Arrays.asList(thrustDriver, flowRateDriver));
145     }
146 
147     /** {@inheritDoc} */
148     @Override
149     public Vector3D getThrustVector(final double[] parameters) {
150         // Thrust vector does not depend on spacecraft state for a constant maneuver.
151         return direction.scalarMultiply(parameters[0]);
152     }
153 
154     /** {@inheritDoc} */
155     @Override
156     public double getFlowRate(final double[] parameters) {
157         return parameters[1];
158     }
159 
160     /** {@inheritDoc} */
161     @Override
162     public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(final T[] parameters) {
163         return new FieldVector3D<>(parameters[0], direction);
164     }
165 
166     /** {@inheritDoc} */
167     @Override
168     public <T extends CalculusFieldElement<T>> T getFlowRate(final T[] parameters) {
169         return parameters[1];
170     }
171 }