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
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 protected AbstractConstantThrustPropulsionModel(final double thrust, final double isp, final Vector3D direction,
71 final Control3DVectorCostType control3DVectorCostType,
72 final String name) {
73 this.name = name;
74 this.initialThrustVector = direction.normalize().scalarMultiply(thrust);
75 this.control3DVectorCostType = control3DVectorCostType;
76 this.initialFlowRate = -control3DVectorCostType.evaluate(initialThrustVector) / ThrustPropulsionModel.getExhaustVelocity(isp);
77 }
78
79 /** Constructor with default control cost type.
80 * @param thrust initial thrust value (N)
81 * @param isp initial isp value (s)
82 * @param direction initial thrust direction in S/C frame
83 * @param name name of the maneuver
84 */
85 protected AbstractConstantThrustPropulsionModel(final double thrust, final double isp, final Vector3D direction,
86 final String name) {
87 this(thrust, isp, direction, DEFAULT_CONTROL_3D_VECTOR_COST_TYPE, name);
88 }
89
90 /** Get the initial thrust vector.
91 * @return the initial thrust vector
92 */
93 protected Vector3D getInitialThrustVector() {
94 return initialThrustVector;
95 }
96
97 /** Get the initial flow rate.
98 * @return the initial flow rate
99 */
100 protected double getInitialFlowRate() {
101 return initialFlowRate;
102 }
103
104 /** {@inheritDoc} */
105 @Override
106 public String getName() {
107 return name;
108 }
109
110 /** {@inheritDoc} */
111 @Override
112 public Control3DVectorCostType getControl3DVectorCostType() {
113 return control3DVectorCostType;
114 }
115
116 /** Get the specific impulse.
117 * @return specific impulse (s), will throw exception if
118 * used on PDriver having several driven values, because
119 * in this case a date is needed.
120 */
121 public double getIsp() {
122 final double flowRate = getFlowRate();
123 return -control3DVectorCostType.evaluate(getThrustVector()) / (Constants.G0_STANDARD_GRAVITY * flowRate);
124 }
125
126 /** Get the specific impulse at given date.
127 * @param date date at which the Isp wants to be known
128 * @return specific impulse (s).
129 */
130 public double getIsp(final AbsoluteDate date) {
131 final double flowRate = getFlowRate(date);
132 return -control3DVectorCostType.evaluate(getThrustVector(date)) / (Constants.G0_STANDARD_GRAVITY * flowRate);
133 }
134
135 /** Get the thrust direction in S/C frame.
136 * @param date date at which the direction wants to be known
137 * @return the thrust direction in S/C frame
138 */
139 public Vector3D getDirection(final AbsoluteDate date) {
140 return getThrustVector(date).normalize();
141 }
142
143 /** Get the thrust direction in S/C frame.
144 * @return the thrust direction in S/C frame, will throw exception if
145 * used on PDriver having several driven values, because
146 * in this case a date is needed.
147 */
148 public Vector3D getDirection() {
149 return getThrustVector().normalize();
150 }
151
152 /** Get the thrust magnitude (N).
153 * @return the thrust value (N), will throw
154 * an exception if called of a driver having several
155 * values driven
156 */
157 public double getThrustMagnitude() {
158 return getThrustVector().getNorm();
159 }
160
161 /** Get the thrust magnitude (N) at given date.
162 * @param date date at which the thrust vector wants to be known,
163 * often the date parameter will not be important and can be whatever
164 * if the thrust parameter driver as only value estimated over the all
165 * orbit determination interval
166 * @return the thrust value (N)
167 */
168 public double getThrustMagnitude(final AbsoluteDate date) {
169 return getThrustVector(date).getNorm();
170 }
171
172 /** {@inheritDoc}
173 * Here the thrust vector do not depend on current S/C state.
174 */
175 @Override
176 public Vector3D getThrustVector(final SpacecraftState s) {
177 // Call the abstract function that do not depend on current S/C state
178 return getThrustVector(s.getDate());
179 }
180
181 /** {@inheritDoc}
182 * Here the flow rate do not depend on current S/C state
183 */
184 @Override
185 public double getFlowRate(final SpacecraftState s) {
186 // Call the abstract function that do not depend on current S/C state
187 return getFlowRate(s.getDate());
188 }
189
190 /** {@inheritDoc}
191 * Here the thrust vector do not depend on current S/C state.
192 */
193 @Override
194 public Vector3D getThrustVector(final SpacecraftState s, final double[] parameters) {
195 // Call the abstract function that do not depend on current S/C state
196 return getThrustVector(parameters);
197 }
198
199 /** {@inheritDoc}
200 * Here the flow rate do not depend on current S/C state
201 */
202 public double getFlowRate(final SpacecraftState s, final double[] parameters) {
203 // Call the abstract function that do not depend on current S/C state
204 return getFlowRate(parameters);
205 }
206
207 /** {@inheritDoc}
208 * Here the thrust vector do not depend on current S/C state.
209 */
210 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(final FieldSpacecraftState<T> s,
211 final T[] parameters) {
212 // Call the abstract function that do not depend on current S/C state
213 return getThrustVector(parameters);
214 }
215
216 /** {@inheritDoc}
217 * Here the flow rate do not depend on current S/C state
218 */
219 public <T extends CalculusFieldElement<T>> T getFlowRate(final FieldSpacecraftState<T> s, final T[] parameters) {
220 // Call the abstract function that do not depend on current S/C state
221 return getFlowRate(parameters);
222 }
223
224 /** Get the thrust vector in spacecraft frame (N).
225 * Here it does not depend on current S/C state.
226 * @return thrust vector in spacecraft frame (N),
227 * will throw an exception if used on driver
228 * containing several value spans
229 */
230 public abstract Vector3D getThrustVector();
231
232 /** Get the thrust vector in spacecraft frame (N).
233 * Here it does not depend on current S/C state.
234 * @param date date at which the thrust vector wants to be known,
235 * often the date parameter will not be important and can be whatever
236 * if the thrust parameter driver as only value estimated over the all
237 * orbit determination interval
238 * @return thrust vector in spacecraft frame (N)
239 */
240 public abstract Vector3D getThrustVector(AbsoluteDate date);
241
242 /** Get the flow rate (kg/s).
243 * Here it does not depend on current S/C.
244 * @return flow rate (kg/s)
245 * will throw an exception if used on driver
246 * containing several value spans
247 */
248 public abstract double getFlowRate();
249
250 /** Get the flow rate (kg/s).
251 * Here it does not depend on current S/C.
252 * @param date date at which the thrust vector wants to be known,
253 * often the date parameter will not be important and can be whatever
254 * if the thrust parameter driver as only value estimated over the all
255 * orbit determination interval
256 * @return flow rate (kg/s)
257 */
258 public abstract double getFlowRate(AbsoluteDate date);
259
260 /** Get the thrust vector in spacecraft frame (N).
261 * Here it does not depend on current S/C state.
262 * @param parameters propulsion model parameters
263 * @return thrust vector in spacecraft frame (N)
264 */
265 public abstract Vector3D getThrustVector(double[] parameters);
266
267 /** Get the flow rate (kg/s).
268 * Here it does not depend on current S/C state.
269 * @param parameters propulsion model parameters
270 * @return flow rate (kg/s)
271 */
272 public abstract double getFlowRate(double[] parameters);
273
274 /** Get the thrust vector in spacecraft frame (N).
275 * Here it does not depend on current S/C state.
276 * @param parameters propulsion model parameters
277 * @param <T> extends CalculusFieldElement<T>
278 * @return thrust vector in spacecraft frame (N)
279 */
280 public abstract <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(T[] parameters);
281
282 /** Get the flow rate (kg/s).
283 * Here it does not depend on current S/C state.
284 * @param parameters propulsion model parameters
285 * @param <T> extends CalculusFieldElement<T>
286 * @return flow rate (kg/s)
287 */
288 public abstract <T extends CalculusFieldElement<T>> T getFlowRate(T[] parameters);
289 }