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.definitions;
18  
19  import org.orekit.errors.OrekitException;
20  import org.orekit.errors.OrekitMessages;
21  
22  /** Frames used in CCSDS Attitude Data Messages for the spacecraft body.
23   * @author Luc Maisonobe
24   * @since 11.0
25   */
26  public class SpacecraftBodyFrame {
27  
28      /** Equipment on which the frame is located. */
29      public enum BaseEquipment {
30  
31          /** Accelerometer. */
32          ACC,
33  
34          /** Actuator: could denote reaction wheels, solar arrays, thrusters, etc.. */
35          ACTUATOR,
36  
37          /** Autonomous Star Tracker. */
38          AST,
39  
40          /** Coarse Sun Sensor. */
41          CSS,
42  
43          /** Digital Sun Sensor. */
44          DSS,
45  
46          /** Earth Sensor Assembly. */
47          ESA,
48  
49          /** Gyro reference frame (this name is used in SANA registry https://sanaregistry.org/r/spacecraft_body_reference_frames/). */
50          GYRO_FRAME,
51  
52          /** Gyro reference frame (this name was used in ADM V1.0 (CCSDS 504.0-B-1). */
53          GYRO,
54  
55          /** Inertial Measurement Unit. */
56          IMU_FRAME,
57  
58          /** Instrument. */
59          INSTRUMENT,
60  
61          /** Magnetic Torque Assembly. */
62          MTA,
63  
64          /** Reaction Wheel. */
65          RW,
66  
67          /** Solar Array. */
68          SA,
69  
70          /** Spacecraft Body. */
71          SC_BODY,
72  
73          /** Sensor. */
74          SENSOR,
75  
76          /** Star Tracker. */
77          STARTRACKER,
78  
79          /** Three Axis Magnetometer. */
80          TAM;
81  
82      }
83  
84      /** Equipment on which the frame is located. */
85      private final BaseEquipment baseEquipment;
86  
87      /** Frame label. */
88      private final String label;
89  
90      /** Simple constructor.
91       * @param baseEquipment equipment on which the frame is located
92       * @param label frame label
93       */
94      public SpacecraftBodyFrame(final BaseEquipment baseEquipment, final String label) {
95          this.baseEquipment = baseEquipment;
96          this.label         = label;
97      }
98  
99      /** Get the quipment on which the frame is located.
100      * @return equipment on which the frame is located
101      */
102     public BaseEquipment getBaseEquipment() {
103         return baseEquipment;
104     }
105 
106     /** Get the frame label.
107      * @return frame label
108      */
109     public String getLabel() {
110         return label;
111     }
112 
113     /** {@inheritDoc}
114      * <p>
115      * The CCSDS composite name combines the {@link #getBaseEquipment() base equipment}
116      * and the {@link #getLabel()}
117      * </p>
118      * @return CCSDS composite name
119      */
120     @Override
121     public String toString() {
122         // the names should normally have a form similar to SC_BODY_i
123         // however sometimes is is only SC_BODYi or even SC_BODY when parsed
124         // in the first case, we put the missing '_' back
125         // in the second case, we just keep the base equipment name
126         return getLabel().length() > 0 ?
127                getBaseEquipment().name() + "_" + getLabel() :
128                getBaseEquipment().name();
129     }
130 
131     /** Build an instance from a normalized descriptor.
132      * <p>
133      * Normalized strings have '_' characters replaced by spaces,
134      * and multiple spaces collapsed as one space only.
135      * </p>
136      * @param descriptor normalized descriptor
137      * @return parsed body frame
138      */
139     public static SpacecraftBodyFrame parse(final String descriptor) {
140         for (final BaseEquipment equipment : BaseEquipment.values()) {
141             if (descriptor.startsWith(equipment.name())) {
142                 // the names should normally have a form similar to SC_BODY_i
143                 // however sometimes is is only SC_BODYi or even SC_BODY
144                 // so we try to parse these common cases
145                 int index = equipment.name().length();
146                 if (index < descriptor.length() && descriptor.charAt(index) == '_') {
147                     ++index;
148                 }
149                 return new SpacecraftBodyFrame(equipment, descriptor.substring(index));
150             }
151         }
152         throw new OrekitException(OrekitMessages.CCSDS_INVALID_FRAME, descriptor);
153     }
154 
155 }