1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.maneuvers.propulsion;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.Rotation;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.orekit.attitudes.Attitude;
23 import org.orekit.attitudes.AttitudeProvider;
24 import org.orekit.attitudes.FieldAttitude;
25 import org.orekit.errors.OrekitException;
26 import org.orekit.errors.OrekitMessages;
27 import org.orekit.frames.Frame;
28 import org.orekit.frames.LOF;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.utils.FieldPVCoordinatesProvider;
32 import org.orekit.utils.PVCoordinatesProvider;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class ThrustDirectionAndAttitudeProvider implements AttitudeProvider {
51
52
53 private static final String FIELD_NAME_VARIABLE_DIRECTION = "variableDirectionInFrame";
54
55
56 private static final String FIELD_NAME_DIRECTION_FRAME = "thrustDirectionFrame";
57
58
59 private static final String FIELD_NAME_LOF_TYPE = "thrustDirectionLof";
60
61
62 private enum ThrustDirectionAndAttitudeProviderType {
63
64 SATELLITE_ATTITUDE,
65
66 CUSTOM_ATTITUDE,
67
68 DIRECTION_IN_LOF,
69
70 DIRECTION_IN_FRAME
71 }
72
73
74 private final ThrustDirectionAndAttitudeProviderType type;
75
76
77
78
79 private final AttitudeProvider attitudeProvider;
80
81
82
83
84
85 private final ThrustDirectionProvider variableDirectionInFrame;
86
87
88 private final Vector3D thrusterAxisInSatelliteFrame;
89
90
91
92
93
94 private final Frame thrustDirectionFrame;
95
96
97
98
99 private final LOF thrustDirectionLof;
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 private ThrustDirectionAndAttitudeProvider(final ThrustDirectionAndAttitudeProviderType type,
116 final AttitudeProvider attitudeProvider, final ThrustDirectionProvider variableDirectionInFrame,
117 final Vector3D thrusterAxisInSatelliteFrame, final Frame frame, final LOF thrustDirectionLof) {
118 this.type = type;
119 this.attitudeProvider = attitudeProvider;
120 this.variableDirectionInFrame = variableDirectionInFrame;
121 this.thrustDirectionFrame = frame;
122 this.thrustDirectionLof = thrustDirectionLof;
123 this.thrusterAxisInSatelliteFrame = thrusterAxisInSatelliteFrame;
124 }
125
126
127
128
129
130
131
132 private static void checkParameterNotNull(final Object parameter, final String name,
133 final ThrustDirectionAndAttitudeProviderType type) {
134 if (parameter == null) {
135 throw new OrekitException(OrekitMessages.PARAMETER_NOT_SET, name,
136 "ThrustDirectionAndAttitudeProvider-" + type.toString());
137 }
138 }
139
140
141
142
143
144
145
146
147 public static ThrustDirectionAndAttitudeProvider buildFromFixedDirectionInSatelliteFrame(final Vector3D direction) {
148 final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
149 ThrustDirectionAndAttitudeProviderType.SATELLITE_ATTITUDE, null, null, direction, null, null);
150 checkParameterNotNull(direction, "thrusterAxisInSatelliteFrame", obj.type);
151 return obj;
152 }
153
154
155
156
157
158
159
160
161
162 public static ThrustDirectionAndAttitudeProvider buildFromCustomAttitude(final AttitudeProvider attitudeProvider,
163 final Vector3D direction) {
164 final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
165 ThrustDirectionAndAttitudeProviderType.CUSTOM_ATTITUDE, attitudeProvider, null, direction, null, null);
166 checkParameterNotNull(attitudeProvider, "attitudeProvider", obj.type);
167 checkParameterNotNull(direction, "direction", obj.type);
168 return obj;
169 }
170
171
172
173
174
175
176
177
178
179
180 public static ThrustDirectionAndAttitudeProvider buildFromDirectionInFrame(final Frame thrustDirectionFrame,
181 final ThrustDirectionProvider variableDirectionInFrame, final Vector3D thrusterAxisInSatelliteFrame) {
182 final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
183 ThrustDirectionAndAttitudeProviderType.DIRECTION_IN_FRAME, null, variableDirectionInFrame,
184 thrusterAxisInSatelliteFrame, thrustDirectionFrame, null);
185 checkParameterNotNull(variableDirectionInFrame, FIELD_NAME_VARIABLE_DIRECTION, obj.type);
186 checkParameterNotNull(thrustDirectionFrame, FIELD_NAME_DIRECTION_FRAME, obj.type);
187 return obj;
188 }
189
190
191
192
193
194
195
196
197
198
199 public static ThrustDirectionAndAttitudeProvider buildFromDirectionInLOF(final LOF thrustDirectionLof,
200 final ThrustDirectionProvider variableDirectionInFrame, final Vector3D thrusterAxisInSatelliteFrame) {
201 final ThrustDirectionAndAttitudeProvider obj = new ThrustDirectionAndAttitudeProvider(
202 ThrustDirectionAndAttitudeProviderType.DIRECTION_IN_LOF, null, variableDirectionInFrame,
203 thrusterAxisInSatelliteFrame, null, thrustDirectionLof);
204 checkParameterNotNull(variableDirectionInFrame, FIELD_NAME_VARIABLE_DIRECTION, obj.type);
205 checkParameterNotNull(thrustDirectionLof, FIELD_NAME_LOF_TYPE, obj.type);
206 return obj;
207 }
208
209
210
211
212
213 public Vector3D getThrusterAxisInSatelliteFrame() {
214 return thrusterAxisInSatelliteFrame;
215 }
216
217
218 @Override
219 public Attitude getAttitude(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) {
220 switch (type) {
221 case CUSTOM_ATTITUDE:
222 return attitudeProvider.getAttitude(pvProv, date, frame);
223 case DIRECTION_IN_FRAME:
224 case DIRECTION_IN_LOF:
225 return getAttitudeFromFrame(pvProv, date, frame);
226 default:
227 throw new OrekitException(OrekitMessages.INVALID_TYPE_FOR_FUNCTION,
228 "ThrustDirectionAndAttitudeProvider.getAttitude", "type", type.toString());
229 }
230 }
231
232
233 @Override
234 public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
235 final FieldAbsoluteDate<T> date, final Frame frame) {
236 throw new OrekitException(OrekitMessages.FUNCTION_NOT_IMPLEMENTED,
237 "ThrustDirectionAndAttitudeProvider with CalculusFieldElement");
238 }
239
240
241
242
243
244
245
246
247 protected Attitude getAttitudeFromFrame(final PVCoordinatesProvider pvProv, final AbsoluteDate date,
248 final Frame frame) {
249
250 final Rotation inertial2ThrusterFrame;
251 if (type.equals(ThrustDirectionAndAttitudeProviderType.DIRECTION_IN_FRAME)) {
252 inertial2ThrusterFrame = frame.getStaticTransformTo(thrustDirectionFrame, date).getRotation();
253 } else {
254 inertial2ThrusterFrame = thrustDirectionLof.rotationFromInertial(date, pvProv.getPVCoordinates(date, frame));
255 }
256
257 final Vector3D thrustDirection = variableDirectionInFrame.computeThrustDirection(pvProv, date, frame);
258 final Vector3D thrustDirectionInertial = inertial2ThrusterFrame.applyInverseTo(thrustDirection);
259
260 final Rotation attitude = new Rotation(getThrusterAxisInSatelliteFrame(), thrustDirectionInertial);
261 final Attitude att = new Attitude(date, frame, attitude.revert(), Vector3D.ZERO, Vector3D.ZERO);
262
263 return att;
264 }
265
266
267
268
269
270 public AttitudeProvider getManeuverAttitudeProvider() {
271 AttitudeProvider attitudeProviderToReturn = null;
272 if (type != ThrustDirectionAndAttitudeProviderType.SATELLITE_ATTITUDE) {
273 attitudeProviderToReturn = this;
274 }
275 return attitudeProviderToReturn;
276 }
277
278 }