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<T>
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<T>
290 * @return flow rate (kg/s)
291 */
292 public abstract <T extends CalculusFieldElement<T>> T getFlowRate(T[] parameters);
293 }