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;
19  
20  import org.orekit.files.ccsds.section.CommentsContainer;
21  import org.orekit.files.ccsds.section.Data;
22  import org.orekit.frames.Frame;
23  import org.orekit.orbits.KeplerianOrbit;
24  import org.orekit.orbits.PositionAngleType;
25  import org.orekit.time.AbsoluteDate;
26  
27  /** Container for Keplerian elements.
28   * <p>
29   * Beware that the Orekit getters and setters all rely on SI units. The parsers
30   * and writers take care of converting these SI units into CCSDS mandatory units.
31   * The {@link org.orekit.utils.units.Unit Unit} class provides useful
32   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
33   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
34   * already use CCSDS units instead of the API SI units. The general-purpose
35   * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
36   * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
37   * (with an 's') also provide some predefined units. These predefined units and the
38   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
39   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
40   * what the parsers and writers use for the conversions.
41   * </p>
42   * @author sports
43   * @since 6.1
44   */
45  public class KeplerianElements extends CommentsContainer implements Data {
46  
47      /** Epoch of state vector and optional Keplerian elements. */
48      private AbsoluteDate epoch;
49  
50      /** Orbit semi-major axis (m). */
51      private double a;
52  
53      /** Mean motion (the Keplerian Mean motion in rad/s).
54       * <p>
55       * Used in OMM instead of semi-major axis if MEAN_ELEMENT_THEORY = SGP/SGP4.
56       * </p>
57       */
58      private double meanMotion;
59  
60      /** Orbit eccentricity. */
61      private double e;
62  
63      /** Orbit inclination (rad). */
64      private double i;
65  
66      /** Orbit right ascension of ascending node (rad). */
67      private double raan;
68  
69      /** Orbit argument of pericenter (rad). */
70      private double pa;
71  
72      /** Orbit anomaly (rad). */
73      private double anomaly;
74  
75      /** Orbit anomaly type (mean or true). */
76      private PositionAngleType anomalyType;
77  
78      /** Gravitational coefficient. */
79      private double mu;
80  
81      /** Simple constructor.
82       */
83      public KeplerianElements() {
84          a          = Double.NaN;
85          meanMotion =  Double.NaN;
86          e          = Double.NaN;
87          i          = Double.NaN;
88          raan       = Double.NaN;
89          pa         = Double.NaN;
90          anomaly    = Double.NaN;
91          mu         = Double.NaN;
92      }
93  
94      /** {@inheritDoc}
95       * <p>
96       * We check neither semi-major axis nor mean motion here,
97       * they must be checked separately in OPM and OMM parsers
98       * </p>
99       */
100     @Override
101     public void validate(final double version) {
102         super.validate(version);
103         checkNotNull(epoch,  StateVectorKey.EPOCH.name());
104         checkNotNaN(e,       KeplerianElementsKey.ECCENTRICITY.name());
105         checkNotNaN(i,       KeplerianElementsKey.INCLINATION.name());
106         checkNotNaN(raan,    KeplerianElementsKey.RA_OF_ASC_NODE.name());
107         checkNotNaN(pa,      KeplerianElementsKey.ARG_OF_PERICENTER.name());
108         checkNotNaN(anomaly, KeplerianElementsKey.MEAN_ANOMALY.name());
109     }
110 
111     /** Get epoch of state vector, Keplerian elements and covariance matrix data.
112      * @return epoch the epoch
113      */
114     public AbsoluteDate getEpoch() {
115         return epoch;
116     }
117 
118     /** Set epoch of state vector, Keplerian elements and covariance matrix data.
119      * @param epoch the epoch to be set
120      */
121     public void setEpoch(final AbsoluteDate epoch) {
122         refuseFurtherComments();
123         this.epoch = epoch;
124     }
125 
126     /** Get the orbit semi-major axis.
127      * @return the orbit semi-major axis
128      */
129     public double getA() {
130         return a;
131     }
132 
133     /** Set the orbit semi-major axis.
134      * @param a the semi-major axis to be set
135      */
136     public void setA(final double a) {
137         refuseFurtherComments();
138         this.a = a;
139     }
140 
141     /** Get the orbit mean motion.
142      * @return the orbit mean motion
143      */
144     public double getMeanMotion() {
145         return meanMotion;
146     }
147 
148     /** Set the orbit mean motion.
149      * @param motion the mean motion to be set
150      */
151     public void setMeanMotion(final double motion) {
152         this.meanMotion = motion;
153     }
154 
155     /** Get the orbit eccentricity.
156      * @return the orbit eccentricity
157      */
158     public double getE() {
159         return e;
160     }
161 
162     /** Set the orbit eccentricity.
163      * @param e the eccentricity to be set
164      */
165     public void setE(final double e) {
166         refuseFurtherComments();
167         this.e = e;
168     }
169 
170     /** Get the orbit inclination.
171      * @return the orbit inclination
172      */
173     public double getI() {
174         return i;
175     }
176 
177     /**Set the orbit inclination.
178      * @param i the inclination to be set
179      */
180     public void setI(final double i) {
181         refuseFurtherComments();
182         this.i = i;
183     }
184 
185     /** Get the orbit right ascension of ascending node.
186      * @return the orbit right ascension of ascending node
187      */
188     public double getRaan() {
189         return raan;
190     }
191 
192     /** Set the orbit right ascension of ascending node.
193      * @param raan the right ascension of ascending node to be set
194      */
195     public void setRaan(final double raan) {
196         refuseFurtherComments();
197         this.raan = raan;
198     }
199 
200     /** Get the orbit argument of pericenter.
201      * @return the orbit argument of pericenter
202      */
203     public double getPa() {
204         return pa;
205     }
206 
207     /** Set the orbit argument of pericenter.
208      * @param pa the argument of pericenter to be set
209      */
210     public void setPa(final double pa) {
211         refuseFurtherComments();
212         this.pa = pa;
213     }
214 
215     /** Get the orbit anomaly.
216      * @return the orbit anomaly
217      */
218     public double getAnomaly() {
219         return anomaly;
220     }
221 
222     /** Set the orbit anomaly.
223      * @param anomaly the anomaly to be set
224      */
225     public void setAnomaly(final double anomaly) {
226         refuseFurtherComments();
227         this.anomaly = anomaly;
228     }
229 
230     /** Get the type of anomaly (true or mean).
231      * @return the type of anomaly
232      */
233     public PositionAngleType getAnomalyType() {
234         return anomalyType;
235     }
236 
237     /** Set the type of anomaly.
238      * @param anomalyType the type of anomaly to be set
239      */
240     public void setAnomalyType(final PositionAngleType anomalyType) {
241         refuseFurtherComments();
242         this.anomalyType = anomalyType;
243     }
244 
245     /**
246      * Set the gravitational coefficient.
247      * @param mu the coefficient to be set
248      */
249     public void setMu(final double mu) {
250         refuseFurtherComments();
251         this.mu = mu;
252     }
253 
254     /**
255      * Get the gravitational coefficient.
256      * @return gravitational coefficient
257      */
258     public double getMu() {
259         return mu;
260     }
261 
262     /** Generate a keplerian orbit.
263      * @param frame inertial frame for orbit
264      * @return generated orbit
265      */
266     public KeplerianOrbit generateKeplerianOrbit(final Frame frame) {
267         return new KeplerianOrbit(a, e, i, pa, raan, anomaly, anomalyType, frame, epoch, mu);
268     }
269 
270 }