1   /* Copyright 2002-2016 CS Systèmes d'Information
2    * Licensed to CS Systèmes d'Information (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;
19  
20  import java.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.commons.math3.linear.MatrixUtils;
29  import org.apache.commons.math3.linear.RealMatrix;
30  import org.orekit.errors.OrekitException;
31  import org.orekit.errors.OrekitMessages;
32  import org.orekit.files.general.SatelliteInformation;
33  import org.orekit.frames.Frame;
34  import org.orekit.frames.LOFType;
35  import org.orekit.orbits.PositionAngle;
36  import org.orekit.time.AbsoluteDate;
37  
38  /** This class gathers the general state data present in both OPM and OMM files.
39   * <p>
40   * This class does not appear in the CCSDS standard, it is only a design
41   * feature of Orekit to reduce code duplication.
42   * </p>
43   * @author sports
44   * @since 6.1
45   */
46  public abstract class OGMFile extends ODMFile {
47  
48      /** Epoch of state vector and optional Keplerian elements. */
49      private AbsoluteDate epoch;
50  
51      /** Orbit semi-major axis (m). */
52      private double a;
53  
54      /** Orbit eccentricity. */
55      private double e;
56  
57      /** Orbit inclination (rad). */
58      private double i;
59  
60      /** Orbit right ascension of ascending node (rad). */
61      private double raan;
62  
63      /** Orbit argument of pericenter (rad). */
64      private double pa;
65  
66      /** Orbit anomaly (rad). */
67      private double anomaly;
68  
69      /** Orbit anomaly type (mean or true). */
70      private PositionAngle anomalyType;
71  
72      /** Spacecraft mass. */
73      private double mass;
74  
75      /** Solar radiation pressure area (m^2). */
76      private double solarRadArea;
77  
78      /** Solar radiation pressure coefficient. */
79      private double solarRadCoeff;
80  
81      /** Drag area (m^2). */
82      private double dragArea;
83  
84      /** Drag coefficient. */
85      private double dragCoeff;
86  
87      /** Coordinate system for covariance matrix, for Local Orbital Frames. */
88      private LOFType covRefLofType;
89  
90      /** Coordinate system for covariance matrix, for absolute frames.
91       * If not given it is set equal to refFrame. */
92      private Frame covRefFrame;
93  
94      /** Position/Velocity covariance matrix. */
95      private RealMatrix covarianceMatrix;
96  
97      /** Map of user defined parameter keywords and corresponding values. */
98      private Map<String, String> userDefinedParameters;
99  
100     /** Tests whether the OPM contains Keplerian elements data. */
101     private boolean hasKeplerianElements;
102 
103     /** Epoch comments. The list contains a string for each line of comment. */
104     private List<String> epochComment;
105 
106     /** Keplerian elements comments. The list contains a string for each line of comment. */
107     private List<String> keplerianElementsComment;
108 
109     /** Spacecraft data comments. The list contains a string for each line of comment. */
110     private List<String> spacecraftComment;
111 
112     /** Covariance matrix data comments. The list contains a string for each line of comment. */
113     private List<String> covarianceComment;
114 
115     /** Create a new OPM file object. */
116     OGMFile() {
117         mass                     = Double.NaN;
118         userDefinedParameters    = new HashMap<String, String>();
119         epochComment             = Collections.emptyList();
120         keplerianElementsComment = Collections.emptyList();
121         spacecraftComment        = Collections.emptyList();
122         covarianceComment        = Collections.emptyList();
123     };
124 
125     /** Get epoch of state vector, Keplerian elements and covariance matrix data.
126      * @return epoch the epoch
127      */
128     public AbsoluteDate getEpoch() {
129         return epoch;
130     }
131 
132     /** Set epoch of state vector, Keplerian elements and covariance matrix data.
133      * @param epoch the epoch to be set
134      */
135     void setEpoch(final AbsoluteDate epoch) {
136         this.epoch = epoch;
137     }
138 
139     /** Get the orbit semi-major axis.
140      * @return the orbit semi-major axis
141      */
142     public double getA() {
143         return a;
144     }
145 
146     /** Set the orbit semi-major axis.
147      * @param a the semi-major axis to be set
148      */
149     void setA(final double a) {
150         this.a = a;
151     }
152 
153     /** Get the orbit eccentricity.
154      * @return the orbit eccentricity
155      */
156     public double getE() {
157         return e;
158     }
159 
160     /** Set the orbit eccentricity.
161      * @param e the eccentricity to be set
162      */
163     void setE(final double e) {
164         this.e = e;
165     }
166 
167     /** Get the orbit inclination.
168      * @return the orbit inclination
169      */
170     public double getI() {
171         return i;
172     }
173 
174     /**Set the orbit inclination.
175      * @param i the inclination to be set
176      */
177     void setI(final double i) {
178         this.i = i;
179     }
180 
181     /** Get the orbit right ascension of ascending node.
182      * @return the orbit right ascension of ascending node
183      */
184     public double getRaan() {
185         return raan;
186     }
187 
188     /** Set the orbit right ascension of ascending node.
189      * @param raan the right ascension of ascending node to be set
190      */
191     void setRaan(final double raan) {
192         this.raan = raan;
193     }
194 
195     /** Get the orbit argument of pericenter.
196      * @return the orbit argument of pericenter
197      */
198     public double getPa() {
199         return pa;
200     }
201 
202     /** Set the orbit argument of pericenter.
203      * @param pa the argument of pericenter to be set
204      */
205     void setPa(final double pa) {
206         this.pa = pa;
207     }
208 
209     /** Get the orbit anomaly.
210      * @return the orbit anomaly
211      */
212     public double getAnomaly() {
213         return anomaly;
214     }
215 
216     /** Set the orbit anomaly.
217      * @param anomaly the anomaly to be set
218      */
219     void setAnomaly(final double anomaly) {
220         this.anomaly = anomaly;
221     }
222 
223     /** Get the type of anomaly (true or mean).
224      * @return the type of anomaly
225      */
226     public PositionAngle getAnomalyType() {
227         return anomalyType;
228     }
229 
230     /** Set the type of anomaly (true or mean).
231      * @param anomalyType the type of anomaly to be set
232      */
233     void setAnomalyType(final String anomalyType) {
234         this.anomalyType = PositionAngle.valueOf(anomalyType);
235     }
236 
237     /** Get the spacecraft mass.
238      * @return the spacecraft mass
239      * @exception OrekitException if mass is unknown
240      */
241     public double getMass() throws OrekitException {
242         if (Double.isNaN(mass)) {
243             throw new OrekitException(OrekitMessages.CCSDS_UNKNOWN_SPACECRAFT_MASS);
244         }
245         return mass;
246     }
247 
248     /** Set the spacecraft mass.
249      * @param mass the spacecraft mass to be set
250      */
251     void setMass(final double mass) {
252         this.mass = mass;
253     }
254 
255     /** Get the solar radiation pressure area.
256      * @return the solar radiation pressure area
257      */
258     public double getSolarRadArea() {
259         return solarRadArea;
260     }
261 
262     /** Set the solar radiation pressure area.
263      * @param solarRadArea the area to be set
264      */
265     void setSolarRadArea(final double solarRadArea) {
266         this.solarRadArea = solarRadArea;
267     }
268 
269     /** Get the solar radiation pressure coefficient.
270      * @return the solar radiation pressure coefficient
271      */
272     public double getSolarRadCoeff() {
273         return solarRadCoeff;
274     }
275 
276     /** Get the solar radiation pressure coefficient.
277      * @param solarRadCoeff the coefficient to be set
278      */
279     void setSolarRadCoeff(final double solarRadCoeff) {
280         this.solarRadCoeff = solarRadCoeff;
281     }
282 
283     /** Get the drag area.
284      * @return the drag area
285      */
286     public double getDragArea() {
287         return dragArea;
288     }
289 
290     /** Set the drag area.
291      * @param dragArea the area to be set
292      */
293     void setDragArea(final double dragArea) {
294         this.dragArea = dragArea;
295     }
296 
297     /** Get the drag coefficient.
298      * @return the drag coefficient
299      */
300     public double getDragCoeff() {
301         return dragCoeff;
302     }
303 
304     /** Set the drag coefficient.
305      * @param dragCoeff the coefficient to be set
306      */
307     void setDragCoeff(final double dragCoeff) {
308         this.dragCoeff = dragCoeff;
309     }
310 
311     /** Get coordinate system for covariance matrix, for Local Orbital Frames.
312      * <p>
313      * The value returned is null if the covariance matrix is given in an
314      * absolute frame rather than a Local Orbital Frame. In this case, the
315      * method {@link #getCovRefFrame()} must be used instead.
316      * </p>
317      * @return the coordinate system for covariance matrix, or null if the
318      * covariance matrix is given in an absolute frame rather than a Local
319      * Orbital Frame
320      */
321     public LOFType getCovRefLofType() {
322         return covRefLofType;
323     }
324 
325     /** Set coordinate system for covariance matrix, for Local Orbital Frames.
326      * @param covRefLofType the coordinate system to be set
327      */
328     void setCovRefLofType(final LOFType covRefLofType) {
329         this.covRefLofType = covRefLofType;
330         this.covRefFrame   = null;
331     }
332 
333     /** Get coordinate system for covariance matrix, for absolute frames.
334      * <p>
335      * The value returned is null if the covariance matrix is given in a
336      * Local Orbital Frame rather than an absolute frame. In this case, the
337      * method {@link #getCovRefLofType()} must be used instead.
338      * </p>
339      * @return the coordinate system for covariance matrix
340      */
341     public Frame getCovRefFrame() {
342         return covRefFrame;
343     }
344 
345     /** Set coordinate system for covariance matrix.
346      * @param covRefFrame the coordinate system to be set
347      */
348     void setCovRefFrame(final Frame covRefFrame) {
349         this.covRefLofType = null;
350         this.covRefFrame   = covRefFrame;
351     }
352 
353     /** Get the Position/Velocity covariance matrix.
354      * @return the Position/Velocity covariance matrix
355      */
356     public RealMatrix getCovarianceMatrix() {
357         return covarianceMatrix;
358     }
359 
360     /** Set an entry in the Position/Velocity covariance matrix.
361      * <p>
362      * Both m(j, k) and m(k, j) are set.
363      * </p>
364      * @param j row index (must be between 0 and 5 (inclusive)
365      * @param k column index (must be between 0 and 5 (inclusive)
366      * @param entry value of the matrix entry
367      */
368     void setCovarianceMatrixEntry(final int j, final int k, final double entry) {
369         covarianceMatrix.setEntry(j, k, entry);
370         covarianceMatrix.setEntry(k, j, entry);
371     }
372 
373     /** Get the map of user defined parameter keywords and their corresponding values.
374      * @return the map of user defined parameter keywords and their corresponding values.
375      */
376     public Map<String, String> getUserDefinedParameters() {
377         return userDefinedParameters;
378     }
379 
380     /** Add a pair keyword-value in the map of user defined parameter keywords and their corresponding values.
381      * @param keyword the user defined parameter keyword to be set. Starts with USER_DEFINED_
382      * @param value the user defined parameter value to be set
383      */
384     void setUserDefinedParameters(final String keyword,
385                                          final String value) {
386         userDefinedParameters.put(keyword, value);
387     }
388 
389     /** Check whether the OPM contains Keplerian elements data.
390      * @return true if OPM contains Keplerian elements data.
391      */
392     public boolean hasKeplerianElements() {
393         return hasKeplerianElements;
394     }
395 
396     /** Set boolean testing whether the OPM contains Keplerian elements data.
397      * @param hasKeplerianElements the boolean to be set.
398      */
399     void setHasKeplerianElements(final boolean hasKeplerianElements) {
400         this.hasKeplerianElements = hasKeplerianElements;
401     }
402 
403     /** Check whether the OPM contains covariance matrix data.
404      * @return true if OPM contains covariance matrix data.
405      */
406     public boolean hasCovarianceMatrix() {
407         return covarianceMatrix != null;
408     }
409 
410     /** Create a covariance matrix, initialized to zero.
411      */
412     void createCovarianceMatrix() {
413         covarianceMatrix = MatrixUtils.createRealMatrix(6, 6);
414     }
415 
416     /** Get the comment for epoch.
417      * @return comment for epoch
418      */
419     public List<String> getEpochComment() {
420         return Collections.unmodifiableList(epochComment);
421     }
422 
423     /** Set the comment for epoch.
424      * @param comment comment to set
425      */
426     void setEpochComment(final List<String> comment) {
427         epochComment = new ArrayList<String>(comment);
428     }
429 
430     /** Get the comment for Keplerian elements.
431      * @return comment for Keplerian elements
432      */
433     public List<String> getKeplerianElementsComment() {
434         return Collections.unmodifiableList(keplerianElementsComment);
435     }
436 
437     /** Set the comment for Keplerian elements.
438      * @param comment comment to set
439      */
440     void setKeplerianElementsComment(final List<String> comment) {
441         keplerianElementsComment = new ArrayList<String>(comment);
442     }
443 
444     /** Get the comment for spacecraft.
445      * @return comment for spacecraft
446      */
447     public List<String> getSpacecraftComment() {
448         return Collections.unmodifiableList(spacecraftComment);
449     }
450 
451     /** Set the comment for spacecraft.
452      * @param comment comment to set
453      */
454     void setSpacecraftComment(final List<String> comment) {
455         spacecraftComment = new ArrayList<String>(comment);
456     }
457 
458     /** Get the comment for covariance.
459      * @return comment for covariance
460      */
461     public List<String> getCovarianceComment() {
462         return Collections.unmodifiableList(covarianceComment);
463     }
464 
465     /** Set the comment for covariance.
466      * @param comment comment to set
467      */
468     void setCovarianceComment(final List<String> comment) {
469         covarianceComment = new ArrayList<String>(comment);
470     }
471 
472     /** Get the meta data.
473      * @return meta data
474      */
475     public abstract ODMMetaData getMetaData();
476 
477     /** {@inheritDoc} */
478     @Override
479     public Collection<SatelliteInformation> getSatellites() {
480         return Arrays.asList(new SatelliteInformation(getMetaData().getObjectID()));
481     }
482 
483     /** {@inheritDoc} */
484     @Override
485     public int getSatelliteCount() {
486         return 1;
487     }
488 
489     /** {@inheritDoc} */
490     @Override
491     public SatelliteInformation getSatellite(final String satId) {
492         if (getMetaData().getObjectID().equals(satId)) {
493             return new SatelliteInformation(satId);
494         }
495         return null;
496     }
497 
498 }