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;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.Vector3D;
21 import org.orekit.attitudes.AttitudeProvider;
22 import org.orekit.forces.maneuvers.propulsion.AbstractConstantThrustPropulsionModel;
23 import org.orekit.forces.maneuvers.propulsion.BasicConstantThrustPropulsionModel;
24 import org.orekit.forces.maneuvers.trigger.DateBasedManeuverTriggers;
25 import org.orekit.propagation.FieldSpacecraftState;
26 import org.orekit.propagation.SpacecraftState;
27 import org.orekit.time.AbsoluteDate;
28
29 /** This class implements a simple maneuver with constant thrust.
30 * <p>The maneuver is defined by a direction in satellite frame.
31 * The current attitude of the spacecraft, defined by the current
32 * spacecraft state, will be used to compute the thrust direction in
33 * inertial frame. A typical case for tangential maneuvers is to use a
34 * {@link org.orekit.attitudes.LofOffset LOF aligned} attitude provider
35 * for state propagation and a velocity increment along the +X satellite axis.</p>
36 * @author Fabien Maussion
37 * @author Véronique Pommier-Maurussane
38 * @author Luc Maisonobe
39 * @author Maxime Journot
40 */
41 public class ConstantThrustManeuver extends Maneuver {
42
43 /** Simple constructor for a constant direction and constant thrust.
44 * <p>
45 * It uses the propulsion model {@link BasicConstantThrustPropulsionModel} and
46 * the maneuver triggers {@link DateBasedManeuverTriggers}
47 * </p><p>
48 * Calling this constructor is equivalent to call {@link
49 * #ConstantThrustManeuver(AbsoluteDate, double, double, double, Vector3D, String)
50 * ConstantThrustManeuver(date, duration, thrust, isp, direction, "")},
51 * hence not using any prefix for the parameters drivers names.
52 * </p>
53 * @param date maneuver date
54 * @param duration the duration of the thrust (s) (if negative,
55 * the date is considered to be the stop date)
56 * @param thrust the thrust force (N)
57 * @param isp engine specific impulse (s)
58 * @param direction the acceleration direction in satellite frame.
59 */
60 public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
61 final double thrust, final double isp,
62 final Vector3D direction) {
63 this(date, duration, thrust, isp, direction, "");
64 }
65
66 /** Simple constructor for a constant direction and constant thrust.
67 * <p>
68 * It uses the propulsion model {@link BasicConstantThrustPropulsionModel} and
69 * the maneuver triggers {@link DateBasedManeuverTriggers}
70 * </p><p>
71 * Calling this constructor is equivalent to call {@link
72 * #ConstantThrustManeuver(AbsoluteDate, double, double, double, Vector3D, String)
73 * ConstantThrustManeuver(date, duration, thrust, isp, direction, "")},
74 * hence not using any prefix for the parameters drivers names.
75 * </p>
76 * @param date maneuver date
77 * @param duration the duration of the thrust (s) (if negative,
78 * the date is considered to be the stop date)
79 * @param thrust the thrust force (N)
80 * @param isp engine specific impulse (s)
81 * @param attitudeOverride the attitude provider to use for the maneuver, or
82 * null if the attitude from the propagator should be used
83 * @param direction the acceleration direction in satellite frame.
84 * @param name name of the maneuver, used as a prefix for the {@link #getParametersDrivers() parameters drivers}
85 * @since 12.0
86 */
87 public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
88 final double thrust, final double isp,
89 final AttitudeProvider attitudeOverride,
90 final Vector3D direction,
91 final String name) {
92 this(date, duration, thrust, isp, attitudeOverride, direction, Control3DVectorCostType.TWO_NORM, name);
93 }
94
95 /** Simple constructor for a constant direction and constant thrust.
96 * <p>
97 * It uses the propulsion model {@link BasicConstantThrustPropulsionModel} and
98 * the maneuver triggers {@link DateBasedManeuverTriggers}
99 * </p><p>
100 * Calling this constructor is equivalent to call {@link
101 * #ConstantThrustManeuver(AbsoluteDate, double, double, double, Vector3D, String)
102 * ConstantThrustManeuver(date, duration, thrust, isp, direction, "")},
103 * hence not using any prefix for the parameters drivers names.
104 * </p>
105 * @param date maneuver date
106 * @param duration the duration of the thrust (s) (if negative,
107 * the date is considered to be the stop date)
108 * @param thrust the thrust force (N)
109 * @param isp engine specific impulse (s)
110 * @param attitudeOverride the attitude provider to use for the maneuver, or
111 * null if the attitude from the propagator should be used
112 * @param direction the acceleration direction in satellite frame.
113 * @since 9.2
114 */
115 public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
116 final double thrust, final double isp,
117 final AttitudeProvider attitudeOverride, final Vector3D direction) {
118 this(date, duration, thrust, isp, attitudeOverride, direction, "");
119 }
120
121 /** Simple constructor for a constant direction and constant thrust.
122 * <p>
123 * It uses the propulsion model {@link BasicConstantThrustPropulsionModel} and
124 * the maneuver triggers {@link DateBasedManeuverTriggers}
125 * </p><p>
126 * The name of the maneuver is used to distinguish the parameter drivers.
127 * A typical use case is to use something like "1A-" or "2B-" as a prefix corresponding to the
128 * name of the thruster to use, so separate parameters can be adjusted
129 * for the different thrusters involved during an orbit determination
130 * where maneuvers parameters are estimated.
131 * </p>
132 * @param date maneuver date
133 * @param duration the duration of the thrust (s) (if negative,
134 * the date is considered to be the stop date)
135 * @param thrust the thrust force (N)
136 * @param isp engine specific impulse (s)
137 * @param direction the acceleration direction in satellite frame
138 * @param name name of the maneuver, used as a prefix for the {@link #getParametersDrivers() parameters drivers}
139 * @since 9.0
140 */
141 public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
142 final double thrust, final double isp,
143 final Vector3D direction,
144 final String name) {
145 this(date, duration, thrust, isp, null, direction, name);
146 }
147
148 /** Simple constructor for a constant direction and constant thrust.
149 * <p>
150 * It uses the propulsion model {@link BasicConstantThrustPropulsionModel} and
151 * the maneuver triggers {@link DateBasedManeuverTriggers}
152 * </p><p>
153 * The name of the maneuver is used to distinguish the parameter drivers.
154 * A typical use case is to use something like "1A-" or "2B-" as a prefix corresponding to the
155 * name of the thruster to use, so separate parameters can be adjusted
156 * for the different thrusters involved during an orbit determination
157 * where maneuvers parameters are estimated.
158 * </p>
159 * @param date maneuver date
160 * @param duration the duration of the thrust (s) (if negative,
161 * the date is considered to be the stop date)
162 * @param thrust the thrust force (N)
163 * @param isp engine specific impulse (s)
164 * @param attitudeOverride the attitude provider to use for the maneuver, or
165 * null if the attitude from the propagator should be used
166 * @param direction the acceleration direction in satellite frame
167 * @param control3DVectorCostType control vector's cost type
168 * @param name name of the maneuver, used as a prefix for the {@link #getParametersDrivers() parameters drivers}
169 * @since 12.0
170 */
171 public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
172 final double thrust, final double isp, final AttitudeProvider attitudeOverride,
173 final Vector3D direction, final Control3DVectorCostType control3DVectorCostType,
174 final String name) {
175 this(date, duration, attitudeOverride,
176 new BasicConstantThrustPropulsionModel(thrust, isp, direction, control3DVectorCostType, name));
177 }
178
179 /** Simple constructor for a constant direction and constant thrust.
180 * <p>
181 * It uses an {@link AbstractConstantThrustPropulsionModel} and
182 * the maneuver triggers {@link DateBasedManeuverTriggers}
183 * </p><p>
184 * The names of the maneuver (and thus its parameter drivers) are extracted
185 * from the propulsion model.
186 * </p>
187 * @param date maneuver date
188 * @param duration the duration of the thrust (s) (if negative,
189 * the date is considered to be the stop date)
190 * @param attitudeOverride the attitude provider to use for the maneuver, or
191 * null if the attitude from the propagator should be used
192 * @param constantThrustPropulsionModel user-defined constant thrust propulsion model
193 */
194 public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
195 final AttitudeProvider attitudeOverride,
196 final AbstractConstantThrustPropulsionModel constantThrustPropulsionModel) {
197 this(attitudeOverride,
198 new DateBasedManeuverTriggers(constantThrustPropulsionModel.getName(), date, duration),
199 constantThrustPropulsionModel);
200 }
201
202 /** Simple constructor for a constant direction and constant thrust.
203 * <p>
204 * It uses an {@link AbstractConstantThrustPropulsionModel} and
205 * the maneuver triggers {@link DateBasedManeuverTriggers}
206 * </p><p>
207 * The names of the maneuver (and thus its parameter drivers) are extracted
208 * from the propulsion model or the maneuver triggers.
209 * Propulsion model name is evaluated first, if it isn't empty, it becomes the name of the maneuver.
210 * In that case the name in the maneuver triggers should be the same or empty, otherwise this could be
211 * misleading when retrieving estimated parameters by their names.
212 * </p>
213 * @param attitudeOverride the attitude provider to use for the maneuver, or
214 * null if the attitude from the propagator should be used
215 * @param dateBasedManeuverTriggers user-defined maneuver triggers object based on a start and end date
216 * @param constantThrustPropulsionModel user-defined constant thrust propulsion model
217 */
218 public ConstantThrustManeuver(final AttitudeProvider attitudeOverride,
219 final DateBasedManeuverTriggers dateBasedManeuverTriggers,
220 final AbstractConstantThrustPropulsionModel constantThrustPropulsionModel) {
221 super(attitudeOverride, dateBasedManeuverTriggers, constantThrustPropulsionModel);
222 }
223
224 /** Get the thrust vector (N) in S/C frame.
225 * @param date date at which the thrust vector wants to be known,
226 * often the date parameter will not be important and can be whatever
227 * if the thrust parameter driver as only value estimated over the all
228 * orbit determination interval
229 * @return thrust vector (N) in S/C frame.
230 */
231 public Vector3D getThrustVector(final AbsoluteDate date) {
232 return ((AbstractConstantThrustPropulsionModel) getPropulsionModel()).getThrustVector(date);
233 }
234
235 /** Get the thrust vector (N) in S/C frame.
236 * @return thrust vector (N) in S/C frame.
237 */
238 public Vector3D getThrustVector() {
239 return ((AbstractConstantThrustPropulsionModel) getPropulsionModel()).getThrustVector();
240 }
241
242 /** Get the thrust magnitude.
243 * @param date date at which the thrust vector wants to be known,
244 * often the date parameter will not be important and can be whatever
245 * if the thrust parameter driver as only value estimated over the all
246 * orbit determination interval
247 * @return thrust force (N).
248 */
249 public double getThrustMagnitude(final AbsoluteDate date) {
250 return getThrustVector(date).getNorm();
251 }
252
253 /** Get the thrust magnitude.
254 * @return thrust force (N).
255 */
256 public double getThrustMagnitude() {
257 return getThrustVector().getNorm();
258 }
259
260 /** Get the specific impulse at given date.
261 * @param date date at which the thrust vector wants to be known,
262 * often the date parameter will not be important and can be whatever
263 * if the thrust parameter driver as only value estimated over the all
264 * orbit determination interval
265 * @return specific impulse (s).
266 */
267 public double getIsp(final AbsoluteDate date) {
268 return ((AbstractConstantThrustPropulsionModel) getPropulsionModel()).getIsp(date);
269 }
270
271 /** Get the specific impulse.
272 * @return specific impulse (s).
273 */
274 public double getIsp() {
275 return ((AbstractConstantThrustPropulsionModel) getPropulsionModel()).getIsp();
276 }
277
278 /** Get the flow rate at given date.
279 * @param date at which the Thrust wants to be known
280 * @return flow rate (negative, kg/s).
281 */
282 public double getFlowRate(final AbsoluteDate date) {
283 return ((AbstractConstantThrustPropulsionModel) getPropulsionModel()).getFlowRate(date);
284 }
285
286 /** Get the flow rate.
287 * @return flow rate (negative, kg/s).
288 */
289 public double getFlowRate() {
290 return ((AbstractConstantThrustPropulsionModel) getPropulsionModel()).getFlowRate();
291 }
292
293 /** Get the direction.
294 * @param date at which the Thrust wants to be known
295 * @return the direction
296 * @since 9.2
297 */
298 public Vector3D getDirection(final AbsoluteDate date) {
299 return getThrustVector(date).normalize();
300 }
301
302 /** Get the direction.
303 * @return the direction
304 * @since 9.2
305 */
306 public Vector3D getDirection() {
307 return getThrustVector().normalize();
308 }
309
310 /** Get the start date.
311 * @return the start date
312 * @since 9.2
313 */
314 public AbsoluteDate getStartDate() {
315 return ((DateBasedManeuverTriggers) getManeuverTriggers()).getStartDate();
316 }
317
318 /** Get the end date.
319 * @return the end date
320 * @since 9.2
321 */
322 public AbsoluteDate getEndDate() {
323 return ((DateBasedManeuverTriggers) getManeuverTriggers()).getEndDate();
324 }
325
326 /** Get the duration of the maneuver (s).
327 * duration = endDate - startDate
328 * @return the duration of the maneuver (s)
329 * @since 9.2
330 */
331 public double getDuration() {
332 return ((DateBasedManeuverTriggers) getManeuverTriggers()).getDuration();
333 }
334
335 /** Check if maneuvering is on.
336 * @param s current state
337 * @return true if maneuver is on at this state
338 * @since 10.1
339 */
340 public boolean isFiring(final SpacecraftState s) {
341 return isFiring(s.getDate());
342 }
343
344 /** Check if maneuvering is on.
345 * @param s current state
346 * @param <T> type of the field elements
347 * @return true if maneuver is on at this state
348 * @since 10.1
349 */
350 public <T extends CalculusFieldElement<T>> boolean isFiring(final FieldSpacecraftState<T> s) {
351 return isFiring(s.getDate().toAbsoluteDate());
352 }
353
354 /** Check if maneuvering is on.
355 * @param date current date
356 * @return true if maneuver is on at this date
357 * @since 10.1
358 */
359 public boolean isFiring(final AbsoluteDate date) {
360 return getManeuverTriggers().isFiring(date, new double[] {});
361 }
362 }