1   /* Copyright 2002-2024 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 org.hipparchus.CalculusFieldElement;
21  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.orekit.forces.maneuvers.Control3DVectorCostType;
24  import org.orekit.propagation.FieldSpacecraftState;
25  import org.orekit.propagation.SpacecraftState;
26  import org.orekit.time.AbsoluteDate;
27  import org.orekit.utils.Constants;
28  
29  /** This abstract class simply serve as a container for a constant thrust maneuver.
30   * It re-writes all spacecraft dependent methods from {@link ThrustPropulsionModel}
31   * and removes their dependencies to current spacecraft state.
32   * Indeed since the thrust is constant (i.e. not variable during the maneuver), most of the
33   * calculated parameters (thrust vector, flow rate etc.) do not depend on current spacecraft state.
34   * @author Maxime Journot
35   * @since 10.2
36   */
37  public abstract class AbstractConstantThrustPropulsionModel implements ThrustPropulsionModel {
38  
39      /** Default control vector cost type. */
40      static final Control3DVectorCostType DEFAULT_CONTROL_3D_VECTOR_COST_TYPE = Control3DVectorCostType.TWO_NORM;
41  
42      /** Initial thrust vector (N) in S/C frame, when building the object. */
43      private final Vector3D initialThrustVector;
44  
45      /** Initial flow rate (kg/s), when building the object. */
46      private final double initialFlowRate;
47  
48      /** Type of norm linking thrust vector to mass flow rate. */
49      private final Control3DVectorCostType control3DVectorCostType;
50  
51      /** User-defined name of the maneuver.
52       * This String attribute is empty by default.
53       * It is added as a prefix to the parameter drivers of the maneuver.
54       * The purpose is to differentiate between drivers in the case where several maneuvers
55       * were added to a propagator force model.
56       * Additionally, the user can retrieve the whole maneuver by looping on the force models of a propagator,
57       * scanning for its name.
58       * @since 9.2
59       */
60      private final String name;
61  
62      /** Generic constructor.
63       * @param thrust initial thrust value (N)
64       * @param isp initial isp value (s)
65       * @param direction initial thrust direction in S/C frame
66       * @param control3DVectorCostType control cost type
67       * @param name name of the maneuver
68       * @since 12.0
69       */
70      public AbstractConstantThrustPropulsionModel(final double thrust,
71                                                   final double isp,
72                                                   final Vector3D direction,
73                                                   final Control3DVectorCostType control3DVectorCostType,
74                                                   final String name) {
75          this.name = name;
76          this.initialThrustVector = direction.normalize().scalarMultiply(thrust);
77          this.control3DVectorCostType = control3DVectorCostType;
78          this.initialFlowRate = -control3DVectorCostType.evaluate(initialThrustVector) / (Constants.G0_STANDARD_GRAVITY * isp);
79      }
80  
81      /** Constructor with default control cost type.
82       * @param thrust initial thrust value (N)
83       * @param isp initial isp value (s)
84       * @param direction initial thrust direction in S/C frame
85       * @param name name of the maneuver
86       */
87      public AbstractConstantThrustPropulsionModel(final double thrust,
88                                                   final double isp,
89                                                   final Vector3D direction,
90                                                   final String name) {
91          this(thrust, isp, direction, DEFAULT_CONTROL_3D_VECTOR_COST_TYPE, name);
92      }
93  
94      /** Get the initial thrust vector.
95       * @return the initial thrust vector
96       */
97      protected Vector3D getInitialThrustVector() {
98          return initialThrustVector;
99      }
100 
101     /** Get the initial flow rate.
102      * @return the initial flow rate
103      */
104     protected double getInitialFlowRate() {
105         return initialFlowRate;
106     }
107 
108     /** {@inheritDoc} */
109     @Override
110     public String getName() {
111         return name;
112     }
113 
114     /** {@inheritDoc} */
115     @Override
116     public Control3DVectorCostType getControl3DVectorCostType() {
117         return control3DVectorCostType;
118     }
119 
120     /** Get the specific impulse.
121      * @return specific impulse (s), will throw exception if
122      * used on PDriver having several driven values, because
123      * in this case a date is needed.
124      */
125     public double getIsp() {
126         final double flowRate = getFlowRate();
127         return -control3DVectorCostType.evaluate(getThrustVector()) / (Constants.G0_STANDARD_GRAVITY * flowRate);
128     }
129 
130     /** Get the specific impulse at given date.
131      * @param date date at which the Isp wants to be known
132      * @return specific impulse (s).
133      */
134     public double getIsp(final AbsoluteDate date) {
135         final double flowRate = getFlowRate(date);
136         return -control3DVectorCostType.evaluate(getThrustVector(date)) / (Constants.G0_STANDARD_GRAVITY * flowRate);
137     }
138 
139     /** Get the thrust direction in S/C frame.
140      * @param date date at which the direction wants to be known
141      * @return the thrust direction in S/C frame
142      */
143     public Vector3D getDirection(final AbsoluteDate date) {
144         return getThrustVector(date).normalize();
145     }
146 
147     /** Get the thrust direction in S/C frame.
148      * @return the thrust direction in S/C frame,  will throw exception if
149      * used on PDriver having several driven values, because
150      * in this case a date is needed.
151      */
152     public Vector3D getDirection() {
153         return getThrustVector().normalize();
154     }
155 
156     /** Get the thrust magnitude (N).
157      * @return the thrust value (N), will throw
158      * an exception if called of a driver having several
159      * values driven
160      */
161     public double getThrustMagnitude() {
162         return getThrustVector().getNorm();
163     }
164 
165     /** Get the thrust magnitude (N) at given date.
166      * @param date date at which the thrust vector wants to be known,
167      * often the date parameter will not be important and can be whatever
168      * if the thrust parameter driver as only value estimated over the all
169      * orbit determination interval
170      * @return the thrust value (N)
171      */
172     public double getThrustMagnitude(final AbsoluteDate date) {
173         return getThrustVector(date).getNorm();
174     }
175 
176     /** {@inheritDoc}
177      * Here the thrust vector do not depend on current S/C state.
178      */
179     @Override
180     public Vector3D getThrustVector(final SpacecraftState s) {
181         // Call the abstract function that do not depend on current S/C state
182         return getThrustVector(s.getDate());
183     }
184 
185     /** {@inheritDoc}
186      * Here the flow rate do not depend on current S/C state
187      */
188     @Override
189     public double getFlowRate(final SpacecraftState s) {
190         // Call the abstract function that do not depend on current S/C state
191         return getFlowRate(s.getDate());
192     }
193 
194     /** {@inheritDoc}
195      * Here the thrust vector do not depend on current S/C state.
196      */
197     @Override
198     public Vector3D getThrustVector(final SpacecraftState s, final double[] parameters) {
199         // Call the abstract function that do not depend on current S/C state
200         return getThrustVector(parameters);
201     }
202 
203     /** {@inheritDoc}
204      * Here the flow rate do not depend on current S/C state
205      */
206     public double getFlowRate(final SpacecraftState s, final double[] parameters) {
207         // Call the abstract function that do not depend on current S/C state
208         return getFlowRate(parameters);
209     }
210 
211     /** {@inheritDoc}
212      * Here the thrust vector do not depend on current S/C state.
213      */
214     public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(final FieldSpacecraftState<T> s,
215                                                                             final T[] parameters) {
216         // Call the abstract function that do not depend on current S/C state
217         return getThrustVector(parameters);
218     }
219 
220     /** {@inheritDoc}
221      * Here the flow rate do not depend on current S/C state
222      */
223     public <T extends CalculusFieldElement<T>> T getFlowRate(final FieldSpacecraftState<T> s, final T[] parameters) {
224         // Call the abstract function that do not depend on current S/C state
225         return getFlowRate(parameters);
226     }
227 
228     /** Get the thrust vector in spacecraft frame (N).
229      * Here it does not depend on current S/C state.
230      * @return thrust vector in spacecraft frame (N),
231      * will throw an exception if used on driver
232      * containing several value spans
233      */
234     public abstract Vector3D getThrustVector();
235 
236     /** Get the thrust vector in spacecraft frame (N).
237      * Here it does not depend on current S/C state.
238      * @param date date at which the thrust vector wants to be known,
239      * often the date parameter will not be important and can be whatever
240      * if the thrust parameter driver as only value estimated over the all
241      * orbit determination interval
242      * @return thrust vector in spacecraft frame (N)
243      */
244     public abstract Vector3D getThrustVector(AbsoluteDate date);
245 
246     /** Get the flow rate (kg/s).
247      * Here it does not depend on current S/C.
248      * @return flow rate (kg/s)
249      * will throw an exception if used on driver
250      * containing several value spans
251      */
252     public abstract double getFlowRate();
253 
254     /** Get the flow rate (kg/s).
255      * Here it does not depend on current S/C.
256      * @param date date at which the thrust vector wants to be known,
257      * often the date parameter will not be important and can be whatever
258      * if the thrust parameter driver as only value estimated over the all
259      * orbit determination interval
260      * @return flow rate (kg/s)
261      */
262     public abstract double getFlowRate(AbsoluteDate date);
263 
264     /** Get the thrust vector in spacecraft frame (N).
265      * Here it does not depend on current S/C state.
266      * @param parameters propulsion model parameters
267      * @return thrust vector in spacecraft frame (N)
268      */
269     public abstract Vector3D getThrustVector(double[] parameters);
270 
271     /** Get the flow rate (kg/s).
272      * Here it does not depend on current S/C state.
273      * @param parameters propulsion model parameters
274      * @return flow rate (kg/s)
275      */
276     public abstract double getFlowRate(double[] parameters);
277 
278     /** Get the thrust vector in spacecraft frame (N).
279      * Here it does not depend on current S/C state.
280      * @param parameters propulsion model parameters
281      * @param <T> extends CalculusFieldElement&lt;T&gt;
282      * @return thrust vector in spacecraft frame (N)
283      */
284     public abstract <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(T[] parameters);
285 
286     /** Get the flow rate (kg/s).
287      * Here it does not depend on current S/C state.
288      * @param parameters propulsion model parameters
289      * @param <T> extends CalculusFieldElement&lt;T&gt;
290      * @return flow rate (kg/s)
291      */
292     public abstract <T extends CalculusFieldElement<T>> T getFlowRate(T[] parameters);
293 }