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 }