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 }