/* Copyright 2002-2017 CS Systèmes d'Information * Licensed to CS Systèmes d'Information (CS) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * CS licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.orekit.files.ccsds; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.hipparchus.util.FastMath; import org.orekit.errors.OrekitException; import org.orekit.orbits.CartesianOrbit; import org.orekit.orbits.KeplerianOrbit; import org.orekit.orbits.PositionAngle; import org.orekit.propagation.SpacecraftState; import org.orekit.propagation.analytical.tle.TLE; /** * This class gathers the informations present in the Orbital Mean-Elements Message (OMM), * and contains methods to generate a {@link CartesianOrbit}, a {@link KeplerianOrbit}, * a {@link SpacecraftState} and, eventually, a {@link TLE}. * @author sports * @since 6.1 */ public class OMMFile extends OGMFile { /** Meta-data. */ private final OMMMetaData metaData; /** Mean motion (the Keplerian Mean motion in revolutions per day). To be used instead of semi-major * axis if MEAN_ELEMENT_THEORY = SGP/SGP4. */ private double meanMotion; /** Ephemeris Type, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. Some sources suggest the coding for * the EPHEMERIS_TYPE keyword: 1 = SGP, 2 = SGP4, 3 = SDP4, 4 = SGP8, 5 = SDP8. Default value = 0. */ private int ephemerisType; /** Classification Type, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. Some sources suggest the * following coding for the CLASSIFICATION_TYPE keyword: U = unclassified, S = secret. Default value = U. */ private char classificationType; /** NORAD Catalog Number ("Satellite Number"), an integer of up to nine digits. */ private Integer noradID; /** Element set number for this satellite, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. * Normally incremented sequentially, but may be out of sync if it is generated from a backup source. * Used to distinguish different TLEs, and therefore only meaningful if TLE based data is being exchanged. */ private String elementSetNo; /** Revolution Number, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. */ private int revAtEpoch; /** SGP/SGP4 drag-like coefficient (in units 1/[Earth radii]), only required if MEAN_ELEMENT_THEORY = SGP/SGP4. */ private Double bStar; /** First Time Derivative of the Mean Motion, only required if MEAN_ELEMENT_THEORY = SGP. */ private Double meanMotionDot; /** Second Time Derivative of Mean Motion, only required if MEAN_ELEMENT_THEORY = SGP. */ private Double meanMotionDotDot; /** TLE related parameters comments. The list contains a string for each line of comment. */ private List<String> dataTleRelatedParametersComment; /** Create a new OMM file object. */ OMMFile() { metaData = new OMMMetaData(this); }; /** Get the meta data. * @return meta data */ @Override public OMMMetaData getMetaData() { return metaData; } /** Get the orbit mean motion. * @return the orbit mean motion */ public double getMeanMotion() { return meanMotion; } /** Set the orbit mean motion. * @param motion the mean motion to be set */ void setMeanMotion(final double motion) { this.meanMotion = motion; } /** Get the ephemeris type. * @return the ephemerisType */ public int getEphemerisType() { return ephemerisType; } /** Set the ephemeris type. * @param ephemerisType the ephemeris type to be set */ void setEphemerisType(final int ephemerisType) { this.ephemerisType = ephemerisType; } /** Get the classification type. * @return the classificationType */ public char getClassificationType() { return classificationType; } /** Set the classification type. * @param classificationType the classification type to be set */ void setClassificationType(final char classificationType) { this.classificationType = classificationType; } /** Get the NORAD Catalog Number ("Satellite Number"). * @return the NORAD Catalog Number */ public Integer getNoradID() { return noradID; } /** Set the NORAD Catalog Number ("Satellite Number"). * @param noradID the element set number to be set */ void setNoradID(final Integer noradID) { this.noradID = noradID; } /** Get the element set number for this satellite. * @return the element set number for this satellite */ public String getElementSetNumber() { return elementSetNo; } /** Set the element set number for this satellite. * @param elementSetNo the element set number to be set */ void setElementSetNo(final String elementSetNo) { this.elementSetNo = elementSetNo; } /** Get the revolution rumber. * @return the revolution rumber */ public int getRevAtEpoch() { return revAtEpoch; } /** Set the revolution rumber. * @param revAtEpoch the Revolution Number to be set */ void setRevAtEpoch(final int revAtEpoch) { this.revAtEpoch = revAtEpoch; } /** Get the SGP/SGP4 drag-like coefficient. * @return the SGP/SGP4 drag-like coefficient */ public double getBStar() { return bStar; } /** Set the SGP/SGP4 drag-like coefficient. * @param bStar the SGP/SGP4 drag-like coefficient to be set */ void setbStar(final double bStar) { this.bStar = bStar; } /** Get the first time derivative of the mean motion. * @return the first time derivative of the mean motion */ public double getMeanMotionDot() { return meanMotionDot; } /** Set the first time derivative of the mean motion. * @param meanMotionDot the first time derivative of the mean motion to be set */ void setMeanMotionDot(final double meanMotionDot) { this.meanMotionDot = meanMotionDot; } /** Get the second time derivative of the mean motion. * @return the second time derivative of the mean motion */ public double getMeanMotionDotDot() { return meanMotionDotDot; } /** Set the second time derivative of the mean motion. * @param meanMotionDotDot the second time derivative of the mean motion to be set */ void setMeanMotionDotDot(final double meanMotionDotDot) { this.meanMotionDotDot = meanMotionDotDot; } /** Get the comment for TLE related parameters. * @return comment for TLE related parameters */ public List<String> getTLERelatedParametersComment() { return Collections.unmodifiableList(dataTleRelatedParametersComment); } /** Set the comment for TLE related parameters. * @param comment comment to set */ void setTLERelatedParametersComment(final List<String> comment) { dataTleRelatedParametersComment = new ArrayList<String>(comment); } /** Generate a {@link KeplerianOrbit} based on the OMM mean keplerian elements. * If the reference frame is not pseudo-inertial, an exception is raised. * @return the {@link KeplerianOrbit} generated from the OMM information * @exception OrekitException if the reference frame is not pseudo-inertial or if the central body * gravitational coefficient cannot be retrieved from the OMM */ public KeplerianOrbit generateKeplerianOrbit() throws OrekitException { setMuUsed(); final double a; if (Double.isNaN(getA())) { a = FastMath.cbrt(getMuUsed() / (meanMotion * meanMotion)); } else { a = getA(); } return new KeplerianOrbit(a, getE(), getI(), getPa(), getRaan(), getAnomaly(), PositionAngle.MEAN, metaData.getFrame(), getEpoch(), getMuUsed()); } /** Generate a {@link CartesianOrbit} from the {@link KeplerianOrbit}. * @return the {@link CartesianOrbit} generated from the OPM information * @throws OrekitException if the Keplerian Orbit cannot be generated */ public CartesianOrbit generateCartesianOrbit() throws OrekitException { return new CartesianOrbit(generateKeplerianOrbit()); } /** Generate spacecraft state from the {@link KeplerianOrbit} generated by generateKeplerianOrbit. * Raises an exception if OMM doesn't contain spacecraft mass information. * @return the spacecraft state of the OMM * @exception OrekitException if there is no spacecraft mass associated with the OMM */ public SpacecraftState generateSpacecraftState() throws OrekitException { return new SpacecraftState(generateKeplerianOrbit(), getMass()); } /** Generate TLE from OMM file. Launch Year, Launch Day and Launch Piece are not present in the * OMM file, they have to be set manually by the user with the AdditionalData static class. * @return the tle */ public TLE generateTLE() { return new TLE(noradID, classificationType, metaData.getLaunchYear(), metaData.getLaunchNumber(), metaData.getLaunchPiece(), ephemerisType, Integer.parseInt(elementSetNo), getEpoch(), meanMotion, meanMotionDot, meanMotionDotDot, getE(), getI(), getPa(), getRaan(), getAnomaly(), revAtEpoch, bStar); } public static class OMMMetaData extends ODMMetaData { /** Description of the Mean Element Theory. Indicates the proper method to employ * to propagate the state. */ private String meanElementTheory; /** Create a new meta-data. * @param ommFile OMM file to which these meta-data belongs */ OMMMetaData(final OMMFile ommFile) { super(ommFile); } /** Get the description of the Mean Element Theory. * @return the mean element theory */ public String getMeanElementTheory() { return meanElementTheory; } /** Set the description of the Mean Element Theory. * @param meanElementTheory the mean element theory to be set */ void setMeanElementTheory(final String meanElementTheory) { this.meanElementTheory = meanElementTheory; } } }