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
18 package org.orekit.files.ccsds.ndm.odm.omm;
19
20 import org.orekit.files.ccsds.section.CommentsContainer;
21
22 /** Container for TLE data.
23 * <p>
24 * Beware that the Orekit getters and setters all rely on SI units. The parsers
25 * and writers take care of converting these SI units into CCSDS mandatory units.
26 * The {@link org.orekit.utils.units.Unit Unit} class provides useful
27 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
28 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
29 * already use CCSDS units instead of the API SI units. The general-purpose
30 * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
31 * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
32 * (with an 's') also provide some predefined units. These predefined units and the
33 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
34 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
35 * what the parsers and writers use for the conversions.
36 * </p>
37 * @author sports
38 * @since 6.1
39 */
40 public class OmmTle extends CommentsContainer {
41
42 /** Constant for EPHEMERIS_TYPE SGP.
43 * @since 12.0
44 */
45 public static final int EPHEMERIS_TYPE_SGP = 0;
46
47 /** Constant for EPHEMERIS_TYPE SGP4.
48 * @since 12.0
49 */
50 public static final int EPHEMERIS_TYPE_SGP4 = 2;
51
52 /** Constant for EPHEMERIS_TYPE PPT3.
53 * @since 12.0
54 */
55 public static final int EPHEMERIS_TYPE_PPT3 = 3;
56
57 /** Constant for EPHEMERIS_TYPE SGP4-XP.
58 * @since 12.0
59 */
60 public static final int EPHEMERIS_TYPE_SGP4_XP = 4;
61
62 /** Constant for EPHEMERIS_TYPE Special Perturbations.
63 * @since 12.0
64 */
65 public static final int EPHEMERIS_TYPE_SPECIAL_PERTURBATIONS = 6;
66
67 /** Ephemeris Type, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. Some sources suggest the coding for
68 * the EPHEMERIS_TYPE keyword: 0 = SGP, 2 = SGP4, 3 = PPT3, 4 = SGP4-XP, 6 = Special Perturbations. Default value = 0.
69 */
70 private int ephemerisType;
71
72 /** Classification Type, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. Some sources suggest the
73 * following coding for the CLASSIFICATION_TYPE keyword: U = unclassified, S = secret. Default value = U.
74 */
75 private char classificationType;
76
77 /** NORAD Catalog Number ("Satellite Number"), an integer of up to nine digits. */
78 private int noradID;
79
80 /** Element set number for this satellite, only required if MEAN_ELEMENT_THEORY = SGP/SGP4.
81 * Normally incremented sequentially, but may be out of sync if it is generated from a backup source.
82 * Used to distinguish different TLEs, and therefore only meaningful if TLE based data is being exchanged. */
83 private int elementSetNo;
84
85 /** Revolution Number, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. */
86 private int revAtEpoch;
87
88 /** SGP/SGP4 drag-like coefficient (in units 1/[Earth radii]), only required if MEAN_ELEMENT_THEORY = SGP/SGP4. */
89 private double bStar;
90
91 /** SGP4-XP drag-like coefficient (in m²/kg), only required if MEAN_ELEMENT_THEORY = SGP4-XP.
92 * @since 12.0
93 */
94 private double bTerm;
95
96 /** First Time Derivative of the Mean Motion, only required if MEAN_ELEMENT_THEORY = SGP. */
97 private double meanMotionDot;
98
99 /** Second Time Derivative of Mean Motion, only required if MEAN_ELEMENT_THEORY = SGP. */
100 private double meanMotionDotDot;
101
102 /** SGP4-XP solar radiation pressure-like coefficient Aγ/m (in m²/kg), only required if MEAN_ELEMENT_THEORY = SGP4-XP.
103 * @since 12.0
104 */
105 private double agOm;
106
107 /** Create an empty data set.
108 */
109 public OmmTle() {
110 ephemerisType = EPHEMERIS_TYPE_SGP;
111 classificationType = 'U';
112 noradID = -1;
113 elementSetNo = -1;
114 revAtEpoch = -1;
115 bStar = Double.NaN;
116 bTerm = Double.NaN;
117 meanMotionDot = Double.NaN;
118 meanMotionDotDot = Double.NaN;
119 agOm = Double.NaN;
120 }
121
122 /** {@inheritDoc} */
123 @Override
124 public void validate(final double version) {
125 super.validate(version);
126
127 checkNotNegative(noradID, OmmTleKey.NORAD_CAT_ID.name());
128 checkNotNegative(elementSetNo, OmmTleKey.ELEMENT_SET_NO.name());
129 checkNotNegative(revAtEpoch, OmmTleKey.REV_AT_EPOCH.name());
130
131 if (ephemerisType == EPHEMERIS_TYPE_SGP4) {
132 checkNotNaN(bStar, OmmTleKey.BSTAR.name());
133 } else if (ephemerisType == EPHEMERIS_TYPE_SGP4_XP) {
134 checkNotNaN(bTerm, OmmTleKey.BTERM.name());
135 }
136
137 if (ephemerisType == EPHEMERIS_TYPE_SGP || ephemerisType == EPHEMERIS_TYPE_PPT3) {
138 checkNotNaN(meanMotionDot, OmmTleKey.MEAN_MOTION_DOT.name());
139 }
140
141 if (ephemerisType == EPHEMERIS_TYPE_SGP || ephemerisType == EPHEMERIS_TYPE_PPT3) {
142 checkNotNaN(meanMotionDotDot, OmmTleKey.MEAN_MOTION_DDOT.name());
143 } else if (ephemerisType == EPHEMERIS_TYPE_SGP4_XP) {
144 checkNotNaN(agOm, OmmTleKey.AGOM.name());
145 }
146
147 }
148
149 /** Get the ephemeris type.
150 * @return the ephemerisType
151 */
152 public int getEphemerisType() {
153 return ephemerisType;
154 }
155
156 /** Set the ephemeris type.
157 * @param ephemerisType the ephemeris type to be set
158 */
159 public void setEphemerisType(final int ephemerisType) {
160 refuseFurtherComments();
161 this.ephemerisType = ephemerisType;
162 }
163
164 /** Get the classification type.
165 * @return the classificationType
166 */
167 public char getClassificationType() {
168 return classificationType;
169 }
170
171 /** Set the classification type.
172 * @param classificationType the classification type to be set
173 */
174 public void setClassificationType(final char classificationType) {
175 refuseFurtherComments();
176 this.classificationType = classificationType;
177 }
178
179 /** Get the NORAD Catalog Number ("Satellite Number").
180 * @return the NORAD Catalog Number
181 */
182 public int getNoradID() {
183 return noradID;
184 }
185
186 /** Set the NORAD Catalog Number ("Satellite Number").
187 * @param noradID the element set number to be set
188 */
189 public void setNoradID(final int noradID) {
190 refuseFurtherComments();
191 this.noradID = noradID;
192 }
193
194 /** Get the element set number for this satellite.
195 * @return the element set number for this satellite
196 */
197 public int getElementSetNumber() {
198 return elementSetNo;
199 }
200
201 /** Set the element set number for this satellite.
202 * @param elementSetNo the element set number to be set
203 */
204 public void setElementSetNo(final int elementSetNo) {
205 refuseFurtherComments();
206 this.elementSetNo = elementSetNo;
207 }
208
209 /** Get the revolution rumber.
210 * @return the revolution rumber
211 */
212 public int getRevAtEpoch() {
213 return revAtEpoch;
214 }
215
216 /** Set the revolution rumber.
217 * @param revAtEpoch the Revolution Number to be set
218 */
219 public void setRevAtEpoch(final int revAtEpoch) {
220 refuseFurtherComments();
221 this.revAtEpoch = revAtEpoch;
222 }
223
224 /** Get the SGP/SGP4 drag-like coefficient.
225 * @return the SGP/SGP4 drag-like coefficient
226 */
227 public double getBStar() {
228 return bStar;
229 }
230
231 /** Set the SGP/SGP4 drag-like coefficient.
232 * @param bstar the SGP/SGP4 drag-like coefficient to be set
233 */
234 public void setBStar(final double bstar) {
235 refuseFurtherComments();
236 this.bStar = bstar;
237 }
238
239 /** Get the SGP4-XP drag-like coefficient.
240 * @return the SGP4-XP drag-like coefficient
241 * @since 12.0
242 */
243 public double getBTerm() {
244 return bTerm;
245 }
246
247 /** Set the SGP4-XP drag-like coefficient.
248 * @param bterm the SGP4-XP drag-like coefficient to be set
249 * @since 12.0
250 */
251 public void setBTerm(final double bterm) {
252 refuseFurtherComments();
253 this.bTerm = bterm;
254 }
255
256 /** Get the first time derivative of the mean motion.
257 * @return the first time derivative of the mean motion
258 */
259 public double getMeanMotionDot() {
260 return meanMotionDot;
261 }
262
263 /** Set the first time derivative of the mean motion.
264 * @param meanMotionDot the first time derivative of the mean motion to be set
265 */
266 public void setMeanMotionDot(final double meanMotionDot) {
267 refuseFurtherComments();
268 this.meanMotionDot = meanMotionDot;
269 }
270
271 /** Get the second time derivative of the mean motion.
272 * @return the second time derivative of the mean motion
273 */
274 public double getMeanMotionDotDot() {
275 return meanMotionDotDot;
276 }
277
278 /** Set the second time derivative of the mean motion.
279 * @param meanMotionDotDot the second time derivative of the mean motion to be set
280 */
281 public void setMeanMotionDotDot(final double meanMotionDotDot) {
282 refuseFurtherComments();
283 this.meanMotionDotDot = meanMotionDotDot;
284 }
285
286 /** Get the SGP4-XP solar radiation pressure-like coefficient Aγ/m.
287 * @return the SGP4-XP solar radiation pressure-like coefficient Aγ/m
288 * @since 12.0
289 */
290 public double getAGoM() {
291 return agOm;
292 }
293
294 /** Set the SGP4-XP solar radiation pressure-like coefficient Aγ/m.
295 * @param agom the SGP4-XP solar radiation pressure-like coefficient Aγ/m to be set
296 * @since 12.0
297 */
298 public void setAGoM(final double agom) {
299 refuseFurtherComments();
300 this.agOm = agom;
301 }
302
303 }