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