1   /* Copyright 2002-2021 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&eacute;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       * @since 9.2
85       */
86      public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
87                                    final double thrust, final double isp,
88                                    final AttitudeProvider attitudeOverride, final Vector3D direction) {
89          this(date, duration, thrust, isp, attitudeOverride, direction, "");
90      }
91  
92      /** Simple constructor for a constant direction and constant thrust.
93       * <p>
94       * It uses the propulsion model {@link BasicConstantThrustPropulsionModel} and
95       * the maneuver triggers {@link DateBasedManeuverTriggers}
96       * </p><p>
97       * The name of the maneuver is used to distinguish the parameter drivers.
98       * A typical use case is to use something like "1A-" or "2B-" as a prefix corresponding to the
99       * name of the thruster to use, so separate parameters can be adjusted
100      * for the different thrusters involved during an orbit determination
101      * where maneuvers parameters are estimated.
102      * </p>
103      * @param date maneuver date
104      * @param duration the duration of the thrust (s) (if negative,
105      * the date is considered to be the stop date)
106      * @param thrust the thrust force (N)
107      * @param isp engine specific impulse (s)
108      * @param direction the acceleration direction in satellite frame
109      * @param name name of the maneuver, used as a prefix for the {@link #getParametersDrivers() parameters drivers}
110      * @since 9.0
111      */
112     public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
113                                   final double thrust, final double isp,
114                                   final Vector3D direction,
115                                   final String name) {
116         this(date, duration, thrust, isp, null, direction, name);
117     }
118 
119     /** Simple constructor for a constant direction and constant thrust.
120      * <p>
121      * It uses the propulsion model {@link BasicConstantThrustPropulsionModel} and
122      * the maneuver triggers {@link DateBasedManeuverTriggers}
123      * </p><p>
124      * The name of the maneuver is used to distinguish the parameter drivers.
125      * A typical use case is to use something like "1A-" or "2B-" as a prefix corresponding to the
126      * name of the thruster to use, so separate parameters can be adjusted
127      * for the different thrusters involved during an orbit determination
128      * where maneuvers parameters are estimated.
129      * </p>
130      * @param date maneuver date
131      * @param duration the duration of the thrust (s) (if negative,
132      * the date is considered to be the stop date)
133      * @param thrust the thrust force (N)
134      * @param isp engine specific impulse (s)
135      * @param attitudeOverride the attitude provider to use for the maneuver, or
136      * null if the attitude from the propagator should be used
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.2
140      */
141     public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
142                                   final double thrust, final double isp,
143                                   final AttitudeProvider attitudeOverride, final Vector3D direction,
144                                   final String name) {
145         this(date, duration, attitudeOverride, new BasicConstantThrustPropulsionModel(thrust, isp, direction, name));
146     }
147 
148     /** Simple constructor for a constant direction and constant thrust.
149      * <p>
150      * It uses an {@link AbstractConstantThrustPropulsionModel} and
151      * the maneuver triggers {@link DateBasedManeuverTriggers}
152      * </p><p>
153      * The names of the maneuver (and thus its parameter drivers) are extracted
154      * from the propulsion model.
155      * </p>
156      * @param date maneuver date
157      * @param duration the duration of the thrust (s) (if negative,
158      * the date is considered to be the stop date)
159      * @param attitudeOverride the attitude provider to use for the maneuver, or
160      * null if the attitude from the propagator should be used
161      * @param constantThrustPropulsionModel user-defined constant thrust propulsion model
162      */
163     public ConstantThrustManeuver(final AbsoluteDate date, final double duration,
164                                   final AttitudeProvider attitudeOverride,
165                                   final AbstractConstantThrustPropulsionModel constantThrustPropulsionModel) {
166         this(attitudeOverride, new DateBasedManeuverTriggers(date, duration), constantThrustPropulsionModel);
167     }
168 
169     /** Simple constructor for a constant direction and constant thrust.
170      * <p>
171      * It uses an {@link AbstractConstantThrustPropulsionModel} and
172      * the maneuver triggers {@link DateBasedManeuverTriggers}
173      * </p><p>
174      * The names of the maneuver (and thus its parameter drivers) are extracted
175      * from the propulsion model or the maneuver triggers.
176      * Propulsion model name is evaluated first, if it isn't empty, it becomes the name of the maneuver.
177      * In that case the name in the maneuver triggers should be the same or empty, otherwise this could be
178      * misleading when retrieving estimated parameters by their names.
179      * </p>
180      * @param attitudeOverride the attitude provider to use for the maneuver, or
181      * null if the attitude from the propagator should be used
182      * @param dateBasedManeuverTriggers user-defined maneuver triggers object based on a start and end date
183      * @param constantThrustPropulsionModel user-defined constant thrust propulsion model
184      */
185     public ConstantThrustManeuver(final AttitudeProvider attitudeOverride,
186                                   final DateBasedManeuverTriggers dateBasedManeuverTriggers,
187                                   final AbstractConstantThrustPropulsionModel constantThrustPropulsionModel) {
188         super(attitudeOverride, dateBasedManeuverTriggers, constantThrustPropulsionModel);
189     }
190 
191     /** Get the thrust vector (N) in S/C frame.
192      * @return thrust vector (N) in S/C frame.
193      */
194     public Vector3D getThrustVector() {
195         return ((AbstractConstantThrustPropulsionModel) (getPropulsionModel())).getThrustVector();
196     }
197 
198     /** Get the thrust.
199      * @return thrust force (N).
200      */
201     public double getThrust() {
202         return getThrustVector().getNorm();
203     }
204 
205     /** Get the specific impulse.
206      * @return specific impulse (s).
207      */
208     public double getISP() {
209         return ((AbstractConstantThrustPropulsionModel) (getPropulsionModel())).getIsp();
210     }
211 
212     /** Get the flow rate.
213      * @return flow rate (negative, kg/s).
214      */
215     public double getFlowRate() {
216         return ((AbstractConstantThrustPropulsionModel) (getPropulsionModel())).getFlowRate();
217     }
218 
219     /** Get the direction.
220      * @return the direction
221      * @since 9.2
222      */
223     public Vector3D getDirection() {
224         return getThrustVector().normalize();
225     }
226 
227     /** Get the start date.
228      * @return the start date
229      * @since 9.2
230      */
231     public AbsoluteDate getStartDate() {
232         return ((DateBasedManeuverTriggers) (getManeuverTriggers())).getStartDate();
233     }
234 
235     /** Get the end date.
236      * @return the end date
237      * @since 9.2
238      */
239     public AbsoluteDate getEndDate() {
240         return ((DateBasedManeuverTriggers) (getManeuverTriggers())).getEndDate();
241     }
242 
243     /** Get the duration of the maneuver (s).
244      * duration = endDate - startDate
245      * @return the duration of the maneuver (s)
246      * @since 9.2
247      */
248     public double getDuration() {
249         return ((DateBasedManeuverTriggers) (getManeuverTriggers())).getDuration();
250     }
251 
252     /** Check if maneuvering is on.
253      * @param s current state
254      * @return true if maneuver is on at this state
255      * @since 10.1
256      */
257     public boolean isFiring(final SpacecraftState s) {
258         return isFiring(s.getDate());
259     }
260 
261     /** Check if maneuvering is on.
262      * @param s current state
263      * @param <T> type of the field elements
264      * @return true if maneuver is on at this state
265      * @since 10.1
266      */
267     public <T extends CalculusFieldElement<T>> boolean isFiring(final FieldSpacecraftState<T> s) {
268         return isFiring(s.getDate().toAbsoluteDate());
269     }
270 
271     /** Check if maneuvering is on.
272      * @param date current date
273      * @return true if maneuver is on at this date
274      * @since 10.1
275      */
276     public boolean isFiring(final AbsoluteDate date) {
277         return getManeuverTriggers().isFiring(date, new double[] {});
278     }
279 }