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  package org.orekit.files.ccsds.ndm;
18  
19  import org.hipparchus.complex.Quaternion;
20  import org.orekit.files.ccsds.definitions.FrameFacade;
21  import org.orekit.files.ccsds.ndm.cdm.AdditionalParameters;
22  import org.orekit.files.ccsds.ndm.odm.ocm.OrbitPhysicalProperties;
23  import org.orekit.files.ccsds.section.CommentsContainer;
24  import org.orekit.time.AbsoluteDate;
25  
26  /** Container for common physical properties for both {@link OrbitPhysicalProperties} and {@link AdditionalParameters}.
27   * <p>
28   * Beware that the Orekit getters and setters all rely on SI units. The parsers
29   * and writers take care of converting these SI units into CCSDS mandatory units.
30   * The {@link org.orekit.utils.units.Unit Unit} class provides useful
31   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
32   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
33   * already use CCSDS units instead of the API SI units. The general-purpose
34   * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
35   * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
36   * (with an 's') also provide some predefined units. These predefined units and the
37   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
38   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
39   * what the parsers and writers use for the conversions.
40   * </p>
41   * @author Maxime Journot
42   * @since 11.3
43   */
44  public class CommonPhysicalProperties extends CommentsContainer {
45  
46      /** Optimally Enclosing Box parent reference frame. */
47      private FrameFacade oebParentFrame;
48  
49      /** Optimally Enclosing Box parent reference frame epoch. */
50      private AbsoluteDate oebParentFrameEpoch;
51  
52      /** Quaternion defining Optimally Enclosing Box. */
53      private final double[] oebQ;
54  
55      /** Maximum physical dimension of Optimally Enclosing Box. */
56      private double oebMax;
57  
58      /** Intermediate physical dimension of Optimally Enclosing Box. */
59      private double oebIntermediate;
60  
61      /** Minimum physical dimension of Optimally Enclosing Box. */
62      private double oebMin;
63  
64      /** Cross-sectional area of Optimally Enclosing Box when viewed along the maximum OEB direction. */
65      private double oebAreaAlongMax;
66  
67      /** Cross-sectional area of Optimally Enclosing Box when viewed along the intermediate OEB direction. */
68      private double oebAreaAlongIntermediate;
69  
70      /** Cross-sectional area of Optimally Enclosing Box when viewed along the minimum OEB direction. */
71      private double oebAreaAlongMin;
72  
73          /** Typical (50th percentile) radar cross-section. */
74      private double rcs;
75  
76      /** Minimum radar cross-section. */
77      private double minRcs;
78  
79      /** Maximum radar cross-section. */
80      private double maxRcs;
81  
82      /** Typical (50th percentile) visual magnitude. */
83      private double vmAbsolute;
84  
85      /** Minimum apparent visual magnitude. */
86      private double vmApparentMin;
87  
88      /** Typical (50th percentile) apparent visual magnitude. */
89      private double vmApparent;
90  
91      /** Maximum apparent visual magnitude. */
92      private double vmApparentMax;
93  
94      /** Typical (50th percentile) coefficient of reflectivity. */
95      private double reflectance;
96  
97      /** Simple constructor.
98       */
99      public CommonPhysicalProperties() {
100 
101         // 502.0-B-3 (page 6-23) says the default is RSW_ROTATING, but also says,
102         // "This keyword shall be provided if OEB_Q1,2,3,4 are specified".
103         // Which means it must be specified in the file any time it would be used,
104         // which leaves the default without any effect.
105         oebParentFrame           = new FrameFacade(null, null, null, null, null);
106         // 502.0-B-3 (page 6-23) says the default is EPOCH_TZERO from the OCM metadata.
107         oebParentFrameEpoch      = null;
108         // 502.0-B-3 (page 6-23) says these four values are optional.
109         oebQ                     = new double[] {Double.NaN, Double.NaN, Double.NaN, Double.NaN};
110         oebMax                   = Double.NaN;
111         oebIntermediate          = Double.NaN;
112         oebMin                   = Double.NaN;
113         oebAreaAlongMax          = Double.NaN;
114         oebAreaAlongIntermediate = Double.NaN;
115         oebAreaAlongMin          = Double.NaN;
116         rcs                      = Double.NaN;
117         minRcs                   = Double.NaN;
118         maxRcs                   = Double.NaN;
119         vmAbsolute               = Double.NaN;
120         vmApparentMin            = Double.NaN;
121         vmApparent               = Double.NaN;
122         vmApparentMax            = Double.NaN;
123         reflectance              = Double.NaN;
124     }
125 
126     /** {@inheritDoc} */
127     @Override
128     public void validate(final double version) {
129         super.validate(version);
130     }
131 
132     /** Get the Optimally Enclosing Box parent reference frame.
133      * @return Optimally Enclosing Box parent reference frame
134      */
135     public FrameFacade getOebParentFrame() {
136         return oebParentFrame;
137     }
138 
139     /** Set the Optimally Enclosing Box parent reference frame.
140      * @param oebParentFrame Optimally Enclosing Box parent reference frame
141      */
142     public void setOebParentFrame(final FrameFacade oebParentFrame) {
143         refuseFurtherComments();
144         this.oebParentFrame = oebParentFrame;
145     }
146 
147     /** Get the Optimally Enclosing Box parent reference frame epoch.
148      * @return Optimally Enclosing Box parent reference frame epoch
149      */
150     public AbsoluteDate getOebParentFrameEpoch() {
151         return oebParentFrameEpoch;
152     }
153 
154     /** Set the Optimally Enclosing Box parent reference frame epoch.
155      * @param oebParentFrameEpoch Optimally Enclosing Box parent reference frame epoch
156      */
157     public void setOebParentFrameEpoch(final AbsoluteDate oebParentFrameEpoch) {
158         refuseFurtherComments();
159         this.oebParentFrameEpoch = oebParentFrameEpoch;
160     }
161 
162     /** Get the quaternion defining Optimally Enclosing Box.
163      * @return quaternion defining Optimally Enclosing Box
164      */
165     public Quaternion getOebQ() {
166         return new Quaternion(oebQ[0], oebQ[1], oebQ[2], oebQ[3]);
167     }
168 
169     /** set the component of quaternion defining Optimally Enclosing Box.
170      * @param i index of the component
171      * @param qI component of quaternion defining Optimally Enclosing Box
172      */
173     public void setOebQ(final int i, final double qI) {
174         refuseFurtherComments();
175         oebQ[i] = qI;
176     }
177 
178     /** Get the maximum physical dimension of the OEB.
179      * @return maximum physical dimension of the OEB.
180      */
181     public double getOebMax() {
182         return oebMax;
183     }
184 
185     /** Set the maximum physical dimension of the OEB.
186      * @param oebMax maximum physical dimension of the OEB.
187      */
188     public void setOebMax(final double oebMax) {
189         refuseFurtherComments();
190         this.oebMax = oebMax;
191     }
192 
193     /** Get the intermediate physical dimension of the OEB.
194      * @return intermediate physical dimension of the OEB.
195      */
196     public double getOebIntermediate() {
197         return oebIntermediate;
198     }
199 
200     /** Set the intermediate physical dimension of the OEB.
201      * @param oebIntermediate intermediate physical dimension of the OEB.
202      */
203     public void setOebIntermediate(final double oebIntermediate) {
204         refuseFurtherComments();
205         this.oebIntermediate = oebIntermediate;
206     }
207 
208     /** Get the minimum physical dimension of the OEB.
209      * @return dimensions the minimum physical dimension of the OEB.
210      */
211     public double getOebMin() {
212         return oebMin;
213     }
214 
215     /** Set the minimum physical dimension of the OEB.
216      * @param oebMin the minimum physical dimension of the OEB.
217      */
218     public void setOebMin(final double oebMin) {
219         refuseFurtherComments();
220         this.oebMin = oebMin;
221     }
222 
223     /** Get the cross-sectional area of Optimally Enclosing Box when viewed along the maximum OEB direction.
224      * @return cross-sectional area of Optimally Enclosing Box when viewed along the maximum OEB direction.
225      */
226     public double getOebAreaAlongMax() {
227         return oebAreaAlongMax;
228     }
229 
230     /** Set the cross-sectional area of Optimally Enclosing Box when viewed along the maximum OEB direction.
231      * @param oebAreaAlongMax cross-sectional area of Optimally Enclosing Box when viewed along the maximum OEB direction.
232      */
233     public void setOebAreaAlongMax(final double oebAreaAlongMax) {
234         refuseFurtherComments();
235         this.oebAreaAlongMax = oebAreaAlongMax;
236     }
237 
238     /** Get the cross-sectional area of Optimally Enclosing Box when viewed along the intermediate OEB direction.
239      * @return cross-sectional area of Optimally Enclosing Box when viewed along the intermediate OEB direction.
240      */
241     public double getOebAreaAlongIntermediate() {
242         return oebAreaAlongIntermediate;
243     }
244 
245     /** Set the cross-sectional area of Optimally Enclosing Box when viewed along the intermediate OEB direction.
246      * @param oebAreaAlongIntermediate cross-sectional area of Optimally Enclosing Box when viewed along the intermediate OEB direction.
247      */
248     public void setOebAreaAlongIntermediate(final double oebAreaAlongIntermediate) {
249         refuseFurtherComments();
250         this.oebAreaAlongIntermediate = oebAreaAlongIntermediate;
251     }
252 
253     /** Get the cross-sectional area of Optimally Enclosing Box when viewed along the minimum OEB direction.
254      * @return cross-sectional area of Optimally Enclosing Box when viewed along the minimum OEB direction.
255      */
256     public double getOebAreaAlongMin() {
257         return oebAreaAlongMin;
258     }
259 
260     /** Set the cross-sectional area of Optimally Enclosing Box when viewed along the minimum OEB direction.
261      * @param oebAreaAlongMin cross-sectional area of Optimally Enclosing Box when viewed along the minimum OEB direction.
262      */
263     public void setOebAreaAlongMin(final double oebAreaAlongMin) {
264         refuseFurtherComments();
265         this.oebAreaAlongMin = oebAreaAlongMin;
266     }
267 
268 
269     /** Get the typical (50th percentile) radar cross-section.
270      * @return typical (50th percentile) radar cross-section
271      */
272     public double getRcs() {
273         return rcs;
274     }
275 
276     /** Set the typical (50th percentile) radar cross-section.
277      * @param rcs typical (50th percentile) radar cross-section
278      */
279     public void setRcs(final double rcs) {
280         refuseFurtherComments();
281         this.rcs = rcs;
282     }
283 
284     /** Get the minimum radar cross-section.
285      * @return minimum radar cross-section
286      */
287     public double getMinRcs() {
288         return minRcs;
289     }
290 
291     /** Set the minimum radar cross-section.
292      * @param minRcs minimum radar cross-section
293      */
294     public void setMinRcs(final double minRcs) {
295         refuseFurtherComments();
296         this.minRcs = minRcs;
297     }
298 
299     /** Get the maximum radar cross-section.
300      * @return maximum radar cross-section
301      */
302     public double getMaxRcs() {
303         return maxRcs;
304     }
305 
306     /** Set the maximum radar cross-section.
307      * @param maxRcs maximum radar cross-section
308      */
309     public void setMaxRcs(final double maxRcs) {
310         refuseFurtherComments();
311         this.maxRcs = maxRcs;
312     }
313 
314     /** Get the typical (50th percentile) visual magnitude.
315      * @return typical (50th percentile) visual magnitude
316      */
317     public double getVmAbsolute() {
318         return vmAbsolute;
319     }
320 
321     /** Set the typical (50th percentile) visual magnitude.
322      * @param vmAbsolute typical (50th percentile) visual magnitude
323      */
324     public void setVmAbsolute(final double vmAbsolute) {
325         refuseFurtherComments();
326         this.vmAbsolute = vmAbsolute;
327     }
328 
329     /** Get the minimum apparent visual magnitude.
330      * @return minimum apparent visual magnitude
331      */
332     public double getVmApparentMin() {
333         return vmApparentMin;
334     }
335 
336     /** Set the minimum apparent visual magnitude.
337      * @param vmApparentMin minimum apparent visual magnitude
338      */
339     public void setVmApparentMin(final double vmApparentMin) {
340         refuseFurtherComments();
341         this.vmApparentMin = vmApparentMin;
342     }
343 
344     /** Get the typical (50th percentile) apparent visual magnitude.
345      * @return typical (50th percentile) apparent visual magnitude
346      */
347     public double getVmApparent() {
348         return vmApparent;
349     }
350 
351     /** Set the typical (50th percentile) apparent visual magnitude.
352      * @param vmApparent typical (50th percentile) apparent visual magnitude
353      */
354     public void setVmApparent(final double vmApparent) {
355         refuseFurtherComments();
356         this.vmApparent = vmApparent;
357     }
358 
359     /** Get the maximum apparent visual magnitude.
360      * @return maximum apparent visual magnitude
361      */
362     public double getVmApparentMax() {
363         return vmApparentMax;
364     }
365 
366     /** Set the maximum apparent visual magnitude.
367      * @param vmApparentMax maximum apparent visual magnitude
368      */
369     public void setVmApparentMax(final double vmApparentMax) {
370         refuseFurtherComments();
371         this.vmApparentMax = vmApparentMax;
372     }
373 
374     /** Get the typical (50th percentile) coefficient of reflectance.
375      * @return typical (50th percentile) coefficient of reflectance
376      */
377     public double getReflectance() {
378         return reflectance;
379     }
380 
381     /** Set the typical (50th percentile) coefficient of reflectance.
382      * @param reflectance typical (50th percentile) coefficient of reflectance
383      */
384     public void setReflectance(final double reflectance) {
385         refuseFurtherComments();
386         this.reflectance = reflectance;
387     }
388 }