1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.ndm.adm.apm;
18
19 import java.util.Arrays;
20
21 import org.hipparchus.geometry.euclidean.threed.RotationOrder;
22 import org.orekit.errors.OrekitException;
23 import org.orekit.errors.OrekitMessages;
24 import org.orekit.files.ccsds.ndm.adm.AttitudeEndpoints;
25 import org.orekit.files.ccsds.section.CommentsContainer;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class Euler extends CommentsContainer {
47
48
49
50
51 private static final String KEY_ANGLES_V1 = "{X|Y|Z}_ANGLE";
52
53
54
55
56 private static final String KEY_ANGLES_V2 = "ANGLE_{1|2|3}";
57
58
59
60
61 private static final String KEY_RATES_V1 = "{X|Y|Z}_RATE";
62
63
64
65
66 private static final String KEY_RATES_V2 = "ANGLE_{1|2|3}_DOT";
67
68
69 private final AttitudeEndpoints endpoints;
70
71
72 private RotationOrder eulerRotSeq;
73
74
75 private Boolean rateFrameIsA;
76
77
78 private final double[] rotationAngles;
79
80
81 private final double[] rotationRates;
82
83
84 private boolean inRotationAngles;
85
86
87
88 public Euler() {
89 this.endpoints = new AttitudeEndpoints();
90 this.rotationAngles = new double[3];
91 this.rotationRates = new double[3];
92 this.inRotationAngles = false;
93 Arrays.fill(rotationAngles, Double.NaN);
94 Arrays.fill(rotationRates, Double.NaN);
95 }
96
97
98 @Override
99 public void validate(final double version) {
100
101 super.validate(version);
102 if (version < 2.0) {
103 endpoints.checkMandatoryEntriesExceptExternalFrame(version,
104 EulerKey.EULER_FRAME_A,
105 EulerKey.EULER_FRAME_B,
106 EulerKey.EULER_DIR);
107 endpoints.checkExternalFrame(EulerKey.EULER_FRAME_A, EulerKey.EULER_FRAME_B);
108 } else {
109 endpoints.checkMandatoryEntriesExceptExternalFrame(version,
110 EulerKey.REF_FRAME_A,
111 EulerKey.REF_FRAME_B,
112 EulerKey.EULER_DIR);
113 endpoints.checkExternalFrame(EulerKey.REF_FRAME_A, EulerKey.REF_FRAME_B);
114 }
115 checkNotNull(eulerRotSeq, EulerKey.EULER_ROT_SEQ.name());
116
117 if (!hasAngles()) {
118
119 for (final double ra : rotationAngles) {
120 if (!Double.isNaN(ra)) {
121 throw new OrekitException(OrekitMessages.UNINITIALIZED_VALUE_FOR_KEY,
122 version < 2.0 ? KEY_ANGLES_V1 : KEY_ANGLES_V2);
123 }
124 }
125 }
126
127 if (!hasRates()) {
128
129 for (final double rr : rotationRates) {
130 if (!Double.isNaN(rr)) {
131 throw new OrekitException(OrekitMessages.UNINITIALIZED_VALUE_FOR_KEY,
132 version < 2.0 ? KEY_RATES_V1 : KEY_RATES_V2);
133 }
134 }
135 }
136
137 if (version < 2.0) {
138
139
140 if (!hasAngles() && !hasRates()) {
141 throw new OrekitException(OrekitMessages.UNINITIALIZED_VALUE_FOR_KEY, KEY_ANGLES_V1 + "/" + KEY_RATES_V1);
142 }
143 } else {
144
145 if (!hasAngles()) {
146 throw new OrekitException(OrekitMessages.UNINITIALIZED_VALUE_FOR_KEY, KEY_ANGLES_V2);
147 }
148 }
149
150 }
151
152
153
154
155 public AttitudeEndpoints getEndpoints() {
156 return endpoints;
157 }
158
159
160
161
162
163 public RotationOrder getEulerRotSeq() {
164 return eulerRotSeq;
165 }
166
167
168
169
170
171 public void setEulerRotSeq(final RotationOrder eulerRotSeq) {
172 refuseFurtherComments();
173 this.eulerRotSeq = eulerRotSeq;
174 }
175
176
177
178
179 public boolean rateFrameIsA() {
180 return rateFrameIsA == null ? false : rateFrameIsA;
181 }
182
183
184
185
186 public void setRateFrameIsA(final boolean rateFrameIsA) {
187 refuseFurtherComments();
188 this.rateFrameIsA = rateFrameIsA;
189 }
190
191
192
193
194
195
196
197
198
199 public boolean isSpacecraftBodyRate() {
200 return rateFrameIsA() ^ endpoints.getFrameA().asSpacecraftBodyFrame() == null;
201 }
202
203
204
205
206
207 public double[] getRotationAngles() {
208 return rotationAngles.clone();
209 }
210
211
212
213
214
215
216 public void setLabeledRotationAngle(final char axis, final double angle) {
217 if (eulerRotSeq != null) {
218 for (int i = 0; i < rotationAngles.length; ++i) {
219 if (eulerRotSeq.name().charAt(i) == axis && Double.isNaN(rotationAngles[i])) {
220 setIndexedRotationAngle(i, angle);
221 return;
222 }
223 }
224 }
225 }
226
227
228
229
230
231
232
233 public void setIndexedRotationAngle(final int axis, final double angle) {
234 refuseFurtherComments();
235 rotationAngles[axis] = angle;
236 }
237
238
239
240
241
242 public double[] getRotationRates() {
243 return rotationRates.clone();
244 }
245
246
247
248
249
250
251 public void setLabeledRotationRate(final char axis, final double rate) {
252 if (eulerRotSeq != null) {
253 for (int i = 0; i < rotationRates.length; ++i) {
254 if (eulerRotSeq.name().charAt(i) == axis && Double.isNaN(rotationRates[i])) {
255 setIndexedRotationRate(i, rate);
256 return;
257 }
258 }
259 }
260 }
261
262
263
264
265
266
267
268 public void setIndexedRotationRate(final int axis, final double rate) {
269 refuseFurtherComments();
270 rotationRates[axis] = rate;
271 }
272
273
274
275
276 boolean inRotationAngles() {
277 return inRotationAngles;
278 }
279
280
281
282
283 public void setInRotationAngles(final boolean inRotationAngles) {
284 refuseFurtherComments();
285 this.inRotationAngles = inRotationAngles;
286 }
287
288
289
290
291
292
293
294
295 public boolean hasAngles() {
296 return !Double.isNaN(rotationAngles[0] + rotationAngles[1] + rotationAngles[2]);
297 }
298
299
300
301
302 public boolean hasRates() {
303 return !Double.isNaN(rotationRates[0] + rotationRates[1] + rotationRates[2]);
304 }
305
306 }