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.files.ccsds.ndm.adm.aem;
18
19 import org.orekit.files.ccsds.definitions.Units;
20 import org.orekit.files.ccsds.ndm.adm.AttitudeType;
21 import org.orekit.files.ccsds.utils.ContextBinding;
22 import org.orekit.files.ccsds.utils.lexical.ParseToken;
23 import org.orekit.utils.units.Unit;
24
25
26 /** Keys for {@link AttitudeEntry attitude entries} in XML messages.
27 * @author Luc Maisonobe
28 * @since 11.0
29 */
30 public enum AttitudeEntryKey {
31
32 /** Quaternion state sub-section (only for ADM V1). */
33 quaternionState((token, context, container) -> true),
34
35 /** Quaternion state sub-section.
36 * @since 12.0
37 */
38 quaternionEphemeris((token, context, container) -> true),
39
40 /** Quaternion/derivative sub-section. */
41 quaternionDerivative((token, context, container) -> true),
42
43 /** Quaternion/rate sub-section (only for ADM V1). */
44 quaternionEulerRate((token, context, container) -> true),
45
46 /** Quaternion/angular velocity sub-section.
47 * @since 12.0
48 */
49 quaternionAngVel((token, context, container) -> true),
50
51 /** Euler angle sub-section. */
52 eulerAngle((token, context, container) -> true),
53
54 /** Euler angle/rate sub-section (only for ADM V1). */
55 eulerAngleRate((token, context, container) -> true),
56
57 /** Euler angle/derivative sub-section.
58 * @since 12.0
59 */
60 eulerAngleDerivative((token, context, container) -> true),
61
62 /** Euler angle/angular velocity sub-section.
63 * @since 12.0
64 */
65 eulerAngleAngVel((token, context, container) -> true),
66
67 /** Spin sub-section. */
68 spin((token, context, container) -> true),
69
70 /** Spin/nutation sub-section. */
71 spinNutation((token, context, container) -> true),
72
73 /** Spin/nutation/momentum sub-section.
74 * @since 12.0
75 */
76 spinNutationMom((token, context, container) -> true),
77
78 /** Quaternion sub-sub-section. */
79 quaternion((token, context, container) -> true),
80
81 /** Quaternion rate sub-sub-section(only for ADM V1). */
82 quaternionRate((token, context, container) -> true),
83
84 /** Quaternion rate sub-sub-section.
85 * @since 12.0
86 */
87 quaternionDot((token, context, container) -> true),
88
89 /** Rotation angles sub-sub-section (only for ADM V1). */
90 rotationAngles((token, context, container) -> true),
91
92 /** Rotation rates sub-sub-section (only for ADM V1). */
93 rotationRates((token, context, container) -> true),
94
95 /** Angular velocity sub-sub-section.
96 * @since 12.0
97 */
98 angVel((token, context, container) -> true),
99
100 /** Entry epoch. */
101 EPOCH((token, context, container) -> token.processAsDate(container::setEpoch, context)),
102
103 /** Quaternion first vectorial component. */
104 Q1((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 1 : 0,
105 Unit.ONE, context.getParsedUnitsBehavior(),
106 container::setComponent)),
107
108 /** Quaternion second vectorial component. */
109 Q2((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 2 : 1,
110 Unit.ONE, context.getParsedUnitsBehavior(),
111 container::setComponent)),
112
113 /** Quaternion third vectorial component. */
114 Q3((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 3 : 2,
115 Unit.ONE, context.getParsedUnitsBehavior(),
116 container::setComponent)),
117
118 /** Quaternion scalar component. */
119 QC((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 0 : 3,
120 Unit.ONE, context.getParsedUnitsBehavior(),
121 container::setComponent)),
122
123 /** Quaternion first vectorial component. */
124 Q1_DOT((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 5 : 4,
125 Units.ONE_PER_S, context.getParsedUnitsBehavior(),
126 container::setComponent)),
127
128 /** Quaternion second vectorial component. */
129 Q2_DOT((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 6 : 5,
130 Units.ONE_PER_S, context.getParsedUnitsBehavior(),
131 container::setComponent)),
132
133 /** Quaternion third vectorial component. */
134 Q3_DOT((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 7 : 6,
135 Units.ONE_PER_S, context.getParsedUnitsBehavior(),
136 container::setComponent)),
137
138 /** Quaternion scalar component. */
139 QC_DOT((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().isFirst() ? 4 : 7,
140 Units.ONE_PER_S, context.getParsedUnitsBehavior(),
141 container::setComponent)),
142
143 /** Angular velocity about X axis.
144 * @since 12.0
145 */
146 ANGVEL_X((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().getAttitudeType() == AttitudeType.QUATERNION_ANGVEL ? 4 : 3,
147 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
148 container::setComponent)),
149
150 /** Angular velocity about Y axis.
151 * @since 12.0
152 */
153 ANGVEL_Y((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().getAttitudeType() == AttitudeType.QUATERNION_ANGVEL ? 5 : 4,
154 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
155 container::setComponent)),
156
157 /** Angular velocity about Z axis.
158 * @since 12.0
159 */
160 ANGVEL_Z((token, context, container) -> token.processAsIndexedDouble(container.getMetadata().getAttitudeType() == AttitudeType.QUATERNION_ANGVEL ? 6 : 5,
161 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
162 container::setComponent)),
163
164 /** Rotation about first axis.
165 * @since 12.0
166 */
167 ANGLE_1((token, context, container) -> token.processAsIndexedDouble(0,
168 Unit.DEGREE, context.getParsedUnitsBehavior(),
169 container::setComponent)),
170
171 /** Rotation about second axis.
172 * @since 12.0
173 */
174 ANGLE_2((token, context, container) -> token.processAsIndexedDouble(1,
175 Unit.DEGREE, context.getParsedUnitsBehavior(),
176 container::setComponent)),
177
178 /** Rotation about third axis.
179 * @since 12.0
180 */
181 ANGLE_3((token, context, container) -> token.processAsIndexedDouble(2,
182 Unit.DEGREE, context.getParsedUnitsBehavior(),
183 container::setComponent)),
184
185 /** Rotation about first axis.
186 * @since 12.0
187 */
188 ANGLE_1_DOT((token, context, container) -> token.processAsIndexedDouble(3,
189 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
190 container::setComponent)),
191
192 /** Rotation about second axis.
193 * @since 12.0
194 */
195 ANGLE_2_DOT((token, context, container) -> token.processAsIndexedDouble(4,
196 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
197 container::setComponent)),
198
199 /** Rotation about third axis.
200 * @since 12.0
201 */
202 ANGLE_3_DOT((token, context, container) -> token.processAsIndexedDouble(5,
203 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
204 container::setComponent)),
205
206 /** Rotation about X axis (only for ADM V1). */
207 X_ANGLE((token, context, container) -> token.processAsLabeledDouble('X', Unit.DEGREE, context.getParsedUnitsBehavior(),
208 container::setLabeledAngle)),
209
210 /** Rotation about Y axis (only for ADM V1). */
211 Y_ANGLE((token, context, container) -> token.processAsLabeledDouble('Y', Unit.DEGREE, context.getParsedUnitsBehavior(),
212 container::setLabeledAngle)),
213
214 /** Rotation about Z axis (only for ADM V1). */
215 Z_ANGLE((token, context, container) -> token.processAsLabeledDouble('Z', Unit.DEGREE, context.getParsedUnitsBehavior(),
216 container::setLabeledAngle)),
217
218 /** Rotation about X axis (only for ADM V1). */
219 X_RATE((token, context, container) -> token.processAsLabeledDouble('X',
220 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
221 container::setLabeledRate)),
222
223 /** Rotation about Y axis (only for ADM V1). */
224 Y_RATE((token, context, container) -> token.processAsLabeledDouble('Y',
225 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
226 container::setLabeledRate)),
227
228 /** Rotation about Z axis (only for ADM V1). */
229 Z_RATE((token, context, container) -> token.processAsLabeledDouble('Z',
230 Units.DEG_PER_S, context.getParsedUnitsBehavior(),
231 container::setLabeledRate)),
232
233 /** Right ascension of spin axis vector. */
234 SPIN_ALPHA((token, context, container) -> token.processAsIndexedDouble(0, Unit.DEGREE, context.getParsedUnitsBehavior(),
235 container::setComponent)),
236
237 /** Declination of spin axis vector. */
238 SPIN_DELTA((token, context, container) -> token.processAsIndexedDouble(1, Unit.DEGREE, context.getParsedUnitsBehavior(),
239 container::setComponent)),
240
241 /** Phase of satellite about spin axis. */
242 SPIN_ANGLE((token, context, container) -> token.processAsIndexedDouble(2, Unit.DEGREE, context.getParsedUnitsBehavior(),
243 container::setComponent)),
244
245 /** angular velocity of satellite around spin axis. */
246 SPIN_ANGLE_VEL((token, context, container) -> token.processAsIndexedDouble(3, Units.DEG_PER_S, context.getParsedUnitsBehavior(),
247 container::setComponent)),
248
249 /** Nutation angle entry. */
250 NUTATION((token, context, container) -> token.processAsIndexedDouble(4, Unit.DEGREE, context.getParsedUnitsBehavior(),
251 container::setComponent)),
252
253 /** Nutation period entry. */
254 NUTATION_PER((token, context, container) -> token.processAsIndexedDouble(5, Unit.SECOND, context.getParsedUnitsBehavior(),
255 container::setComponent)),
256
257 /** Nutation phase entry. */
258 NUTATION_PHASE((token, context, container) -> token.processAsIndexedDouble(6, Unit.DEGREE, context.getParsedUnitsBehavior(),
259 container::setComponent)),
260
261 /** Right ascension of angular momentum vector.
262 * @since 12.0
263 */
264 MOMENTUM_ALPHA((token, context, container) -> token.processAsIndexedDouble(4, Unit.DEGREE, context.getParsedUnitsBehavior(),
265 container::setComponent)),
266
267 /** Declination of angular momentum vector.
268 * @since 12.0
269 */
270 MOMENTUM_DELTA((token, context, container) -> token.processAsIndexedDouble(5, Unit.DEGREE, context.getParsedUnitsBehavior(),
271 container::setComponent)),
272
273 /** Nutation velocity entry.
274 * @since 12.0
275 */
276 NUTATION_VEL((token, context, container) -> token.processAsIndexedDouble(6, Units.DEG_PER_S, context.getParsedUnitsBehavior(),
277 container::setComponent));
278
279 /** Processing method. */
280 private final transient TokenProcessor processor;
281
282 /** Simple constructor.
283 * @param processor processing method
284 */
285 AttitudeEntryKey(final TokenProcessor processor) {
286 this.processor = processor;
287 }
288
289 /** Process an token.
290 * @param token token to process
291 * @param context context binding
292 * @param container container to fill
293 * @return true of token was accepted
294 */
295 public boolean process(final ParseToken token, final ContextBinding context, final AttitudeEntry container) {
296 return processor.process(token, context, container);
297 }
298
299 /** Interface for processing one token. */
300 interface TokenProcessor {
301 /** Process one token.
302 * @param token token to process
303 * @param context context binding
304 * @param container container to fill
305 * @return true of token was accepted
306 */
307 boolean process(ParseToken token, ContextBinding context, AttitudeEntry container);
308 }
309
310 }