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