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
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.attitudes.Attitude;
24 import org.orekit.attitudes.FieldAttitude;
25 import org.orekit.propagation.FieldSpacecraftState;
26 import org.orekit.propagation.SpacecraftState;
27 import org.orekit.utils.Constants;
28
29 /** Interface for a thrust-based propulsion model.
30 * @author Maxime Journot
31 * @since 10.2
32 */
33 public interface ThrustPropulsionModel extends PropulsionModel {
34
35 /** Get the specific impulse (s).
36 * @param s current spacecraft state
37 * @return specific impulse (s).
38 */
39 default double getIsp(SpacecraftState s) {
40 final double thrust = getThrust(s);
41 final double flowRate = getFlowRate(s);
42 return -thrust / (Constants.G0_STANDARD_GRAVITY * flowRate);
43 }
44
45 /** Get the thrust direction in spacecraft frame.
46 * @param s current spacecraft state
47 * @return thrust direction in spacecraft frame
48 */
49 default Vector3D getDirection(SpacecraftState s) {
50 return getThrustVector(s).normalize();
51 }
52
53 /** Get the thrust norm (N).
54 * @param s current spacecraft state
55 * @return thrust norm (N)
56 */
57 default double getThrust(SpacecraftState s) {
58 return getThrustVector(s).getNorm();
59 }
60
61 /** Get the thrust vector in spacecraft frame (N).
62 * @param s current spacecraft state
63 * @return thrust vector in spacecraft frame (N)
64 */
65 Vector3D getThrustVector(SpacecraftState s);
66
67 /** Get the flow rate (kg/s).
68 * @param s current spacecraft state
69 * @return flow rate (kg/s)
70 */
71 double getFlowRate(SpacecraftState s);
72
73 /** Get the thrust vector in spacecraft frame (N).
74 * @param s current spacecraft state
75 * @param parameters propulsion model parameters
76 * @return thrust vector in spacecraft frame (N)
77 */
78 Vector3D getThrustVector(SpacecraftState s, double[] parameters);
79
80 /** Get the flow rate (kg/s).
81 * @param s current spacecraft state
82 * @param parameters propulsion model parameters
83 * @return flow rate (kg/s)
84 */
85 double getFlowRate(SpacecraftState s, double[] parameters);
86
87 /** Get the thrust vector in spacecraft frame (N).
88 * @param s current spacecraft state
89 * @param parameters propulsion model parameters
90 * @param <T> extends CalculusFieldElement<T>
91 * @return thrust vector in spacecraft frame (N)
92 */
93 <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(FieldSpacecraftState<T> s, T[] parameters);
94
95 /** Get the flow rate (kg/s).
96 * @param s current spacecraft state
97 * @param parameters propulsion model parameters
98 * @param <T> extends CalculusFieldElement<T>
99 * @return flow rate (kg/s)
100 */
101 <T extends CalculusFieldElement<T>> T getFlowRate(FieldSpacecraftState<T> s, T[] parameters);
102
103 /** {@inheritDoc}
104 * Acceleration is computed here using the thrust vector in S/C frame.
105 */
106 @Override
107 default Vector3D getAcceleration(SpacecraftState s,
108 final Attitude maneuverAttitude,
109 double[] parameters) {
110
111 final Vector3D thrustVector = getThrustVector(s, parameters);
112 final double thrust = thrustVector.getNorm();
113 final Vector3D direction = thrustVector.normalize();
114
115 // Compute thrust acceleration in inertial frame
116 // It seems under-efficient to rotate direction and apply thrust
117 // instead of just rotating the whole thrust vector itself.
118 // However it has to be done that way to avoid numerical discrepancies with legacy tests.
119 return new Vector3D(thrust / s.getMass(),
120 maneuverAttitude.getRotation().applyInverseTo(direction));
121 }
122
123 /** {@inheritDoc}
124 * Acceleration is computed here using the thrust vector in S/C frame.
125 */
126 @Override
127 default <T extends CalculusFieldElement<T>> FieldVector3D<T> getAcceleration(FieldSpacecraftState<T> s,
128 final FieldAttitude<T> maneuverAttitude,
129 T[] parameters) {
130 // Extract thrust & direction from thrust vector
131 final FieldVector3D<T> thrustVector = getThrustVector(s, parameters);
132 final T thrust = thrustVector.getNorm();
133 final FieldVector3D<T> direction = thrustVector.normalize();
134
135 // Compute thrust acceleration in inertial frame
136 // It seems under-efficient to rotate direction and apply thrust
137 // instead of just rotating the whole thrust vector itself.
138 // However it has to be done that way to avoid numerical discrepancies with legacy tests.
139 return new FieldVector3D<>(s.getMass().reciprocal().multiply(thrust),
140 maneuverAttitude.getRotation().applyInverseTo(direction));
141 }
142
143 /** {@inheritDoc}
144 * Mass derivatives are directly extracted here from the flow rate value.
145 */
146 @Override
147 default double getMassDerivatives(SpacecraftState s, double[] parameters) {
148 return getFlowRate(s, parameters);
149 }
150
151 /** {@inheritDoc}
152 * Mass derivatives are directly extracted here from the flow rate value.
153 */
154 @Override
155 default <T extends CalculusFieldElement<T>> T getMassDerivatives(FieldSpacecraftState<T> s, T[] parameters) {
156 return getFlowRate(s, parameters);
157 }
158
159 }