1   /* Copyright 2022-2025 Luc Maisonobe
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  
18  package org.orekit.files.ccsds.ndm.adm.acm;
19  
20  import org.hipparchus.geometry.euclidean.threed.RotationOrder;
21  import org.orekit.errors.OrekitException;
22  import org.orekit.errors.OrekitMessages;
23  import org.orekit.files.ccsds.ndm.adm.AttitudeEndpoints;
24  import org.orekit.files.ccsds.section.CommentsContainer;
25  
26  /** Metadata for attitude state history.
27   * <p>
28   * Beware that the Orekit getters and setters all rely on SI units. The parsers
29   * and writers take care of converting these SI units into CCSDS mandatory units.
30   * The {@link org.orekit.utils.units.Unit Unit} class provides useful
31   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
32   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
33   * already use CCSDS units instead of the API SI units. The general-purpose
34   * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
35   * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
36   * (with an 's') also provide some predefined units. These predefined units and the
37   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
38   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
39   * what the parsers and writers use for the conversions.
40   * </p>
41   * @author Luc Maisonobe
42   * @since 12.0
43   */
44  public class AttitudeStateHistoryMetadata extends CommentsContainer {
45  
46      /** Endpoints (i.e. frames A, B and their relationship). */
47      private final AttitudeEndpoints endpoints;
48  
49      /** Attitude identification number. */
50      private String attID;
51  
52      /** Identification number of previous attitude. */
53      private String attPrevID;
54  
55      /** Basis of this attitude state time history data. */
56      private String attBasis;
57  
58      /** Identification number of the attitude determination or simulation upon which this attitude is based. */
59      private String attBasisID;
60  
61      /** Rotation order for Euler angles. */
62      private RotationOrder eulerRotSeq;
63  
64      /** Number of data states included (attitude components plus rates components). */
65      private int nbStates;
66  
67      /** Attitude element set type. */
68      private AttitudeElementsType attitudeType;
69  
70      /** Attitude rate element set type. */
71      private RateElementsType rateType;
72  
73      /** Simple constructor.
74       */
75      public AttitudeStateHistoryMetadata() {
76          endpoints = new AttitudeEndpoints();
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public void validate(final double version) {
82          super.validate(version);
83          endpoints.checkExternalFrame(AttitudeStateHistoryMetadataKey.REF_FRAME_A,
84                                       AttitudeStateHistoryMetadataKey.REF_FRAME_B);
85          checkNotNull(attitudeType, AttitudeStateHistoryMetadataKey.ATT_TYPE.name());
86          final int rateSize = rateType == null ? 0 : rateType.getUnits().size();
87          if (nbStates != attitudeType.getUnits().size() + rateSize) {
88              throw new OrekitException(OrekitMessages.CCSDS_INCONSISTENT_NUMBER_OF_ATTITUDE_STATES,
89                                        attitudeType.toString(), rateType.toString(),
90                                        attitudeType.getUnits().size() + rateSize, nbStates);
91          }
92          if (attitudeType == AttitudeElementsType.EULER_ANGLES) {
93              checkNotNull(eulerRotSeq, AttitudeStateHistoryMetadataKey.EULER_ROT_SEQ.name());
94          }
95      }
96  
97      /** Get the endpoints (i.e. frames A, B and their relationship).
98       * @return endpoints
99       */
100     public AttitudeEndpoints getEndpoints() {
101         return endpoints;
102     }
103 
104     /** Get attitude identification number.
105      * @return attitude identification number
106      */
107     public String getAttID() {
108         return attID;
109     }
110 
111     /** Set attitude identification number.
112      * @param attID attitude identification number
113      */
114     public void setAttID(final String attID) {
115         refuseFurtherComments();
116         this.attID = attID;
117     }
118 
119     /** Get identification number of previous attitude.
120      * @return identification number of previous attitude
121      */
122     public String getAttPrevID() {
123         return attPrevID;
124     }
125 
126     /** Set identification number of previous attitude.
127      * @param attPrevID identification number of previous attitude
128      */
129     public void setAttPrevID(final String attPrevID) {
130         refuseFurtherComments();
131         this.attPrevID = attPrevID;
132     }
133 
134     /** Get basis of this attitude state time history data.
135      * @return basis of this attitude state time history data
136      */
137     public String getAttBasis() {
138         return attBasis;
139     }
140 
141     /** Set basis of this attitude state time history data.
142      * @param attBasis basis of this attitude state time history data
143      */
144     public void setAttBasis(final String attBasis) {
145         refuseFurtherComments();
146         this.attBasis = attBasis;
147     }
148 
149     /** Get identification number of the orbit determination or simulation upon which this attitude is based.
150      * @return identification number of the orbit determination or simulation upon which this attitude is based
151      */
152     public String getAttBasisID() {
153         return attBasisID;
154     }
155 
156     /** Set identification number of the orbit determination or simulation upon which this attitude is based.
157      * @param attBasisID identification number of the orbit determination or simulation upon which this attitude is based
158      */
159     public void setAttBasisID(final String attBasisID) {
160         refuseFurtherComments();
161         this.attBasisID = attBasisID;
162     }
163 
164     /** Get the rotation order for Euler angles.
165      * @return rotation order for Euler angles
166      */
167     public RotationOrder getEulerRotSeq() {
168         return eulerRotSeq;
169     }
170 
171     /** Set the rotation order for Euler angles.
172      * @param eulerRotSeq rotation order for Euler angles
173      */
174     public void setEulerRotSeq(final RotationOrder eulerRotSeq) {
175         this.eulerRotSeq = eulerRotSeq;
176     }
177 
178     /** Get the number of data states included (attitude components plus rates components).
179      * @return number of data states included (attitude components plus rates components)
180      */
181     public int getNbStates() {
182         return nbStates;
183     }
184 
185     /** Set the number of data states included (attitude components plus rates components).
186      * @param nbStates number of data states included (attitude components plus rates components)
187      */
188     public void setNbStates(final int nbStates) {
189         this.nbStates = nbStates;
190     }
191 
192     /** Get attitude element set type.
193      * @return attitude element set type
194      */
195     public AttitudeElementsType getAttitudeType() {
196         return attitudeType;
197     }
198 
199     /** Set attitude element set type.
200      * @param attitudeType attitude element set type
201      */
202     public void setAttitudeType(final AttitudeElementsType attitudeType) {
203         refuseFurtherComments();
204         this.attitudeType = attitudeType;
205     }
206 
207     /** Get attitude rate element set type.
208      * @return attitude rate element set type
209      */
210     public RateElementsType getRateType() {
211         return rateType;
212     }
213 
214     /** Set attitude rate element set type.
215      * @param rateType attitude rate element set type
216      */
217     public void setRateType(final RateElementsType rateType) {
218         refuseFurtherComments();
219         this.rateType = rateType;
220     }
221 
222 }