OmmTle.java

  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.odm.omm;

  18. import org.orekit.files.ccsds.section.CommentsContainer;

  19. /** Container for TLE data.
  20.  * <p>
  21.  * Beware that the Orekit getters and setters all rely on SI units. The parsers
  22.  * and writers take care of converting these SI units into CCSDS mandatory units.
  23.  * The {@link org.orekit.utils.units.Unit Unit} class provides useful
  24.  * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
  25.  * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
  26.  * already use CCSDS units instead of the API SI units. The general-purpose
  27.  * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
  28.  * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
  29.  * (with an 's') also provide some predefined units. These predefined units and the
  30.  * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
  31.  * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
  32.  * what the parsers and writers use for the conversions.
  33.  * </p>
  34.  * @author sports
  35.  * @since 6.1
  36.  */
  37. public class OmmTle extends CommentsContainer {

  38.     /** Constant for EPHEMERIS_TYPE SGP.
  39.      * @since 12.0
  40.      */
  41.     public static final int EPHEMERIS_TYPE_SGP = 0;

  42.     /** Constant for EPHEMERIS_TYPE SGP4.
  43.      * @since 12.0
  44.      */
  45.     public static final int EPHEMERIS_TYPE_SGP4 = 2;

  46.     /** Constant for EPHEMERIS_TYPE PPT3.
  47.      * @since 12.0
  48.      */
  49.     public static final int EPHEMERIS_TYPE_PPT3 = 3;

  50.     /** Constant for EPHEMERIS_TYPE SGP4-XP.
  51.      * @since 12.0
  52.      */
  53.     public static final int EPHEMERIS_TYPE_SGP4_XP = 4;

  54.     /** Constant for EPHEMERIS_TYPE Special Perturbations.
  55.      * @since 12.0
  56.      */
  57.     public static final int EPHEMERIS_TYPE_SPECIAL_PERTURBATIONS = 6;

  58.     /** Ephemeris Type, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. Some sources suggest the coding for
  59.      * the EPHEMERIS_TYPE keyword: 0 = SGP, 2 = SGP4, 3 = PPT3, 4 = SGP4-XP, 6 = Special Perturbations. Default value = 0.
  60.      */
  61.     private int ephemerisType;

  62.     /** Classification Type, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. Some sources suggest the
  63.      *  following coding for the CLASSIFICATION_TYPE keyword: U = unclassified, S = secret. Default value = U.
  64.      */
  65.     private char classificationType;

  66.     /** NORAD Catalog Number ("Satellite Number"), an integer of up to nine digits. */
  67.     private int noradID;

  68.     /** Element set number for this satellite, only required if MEAN_ELEMENT_THEORY = SGP/SGP4.
  69.      * Normally incremented sequentially, but may be out of sync if it is generated from a backup source.
  70.      * Used to distinguish different TLEs, and therefore only meaningful if TLE based data is being exchanged. */
  71.     private int elementSetNo;

  72.     /** Revolution Number, only required if MEAN_ELEMENT_THEORY = SGP/SGP4. */
  73.     private int revAtEpoch;

  74.     /** SGP/SGP4 drag-like coefficient (in units 1/[Earth radii]), only required if MEAN_ELEMENT_THEORY = SGP/SGP4. */
  75.     private double bStar;

  76.     /** SGP4-XP drag-like coefficient (in m²/kg), only required if MEAN_ELEMENT_THEORY = SGP4-XP.
  77.      * @since 12.0
  78.      */
  79.     private double bTerm;

  80.     /** First Time Derivative of the Mean Motion, only required if MEAN_ELEMENT_THEORY = SGP. */
  81.     private double meanMotionDot;

  82.     /** Second Time Derivative of Mean Motion, only required if MEAN_ELEMENT_THEORY = SGP. */
  83.     private double meanMotionDotDot;

  84.     /** SGP4-XP solar radiation pressure-like coefficient Aγ/m (in m²/kg), only required if MEAN_ELEMENT_THEORY = SGP4-XP.
  85.      * @since 12.0
  86.      */
  87.     private double agOm;

  88.     /** Create an empty data set.
  89.      */
  90.     public OmmTle() {
  91.         ephemerisType      = EPHEMERIS_TYPE_SGP;
  92.         classificationType = 'U';
  93.         noradID            = -1;
  94.         elementSetNo       = -1;
  95.         revAtEpoch         = -1;
  96.         bStar              =  Double.NaN;
  97.         bTerm              =  Double.NaN;
  98.         meanMotionDot      =  Double.NaN;
  99.         meanMotionDotDot   =  Double.NaN;
  100.         agOm               =  Double.NaN;
  101.     }

  102.     /** {@inheritDoc} */
  103.     @Override
  104.     public void validate(final double version) {
  105.         super.validate(version);

  106.         checkNotNegative(noradID,      OmmTleKey.NORAD_CAT_ID.name());
  107.         checkNotNegative(elementSetNo, OmmTleKey.ELEMENT_SET_NO.name());
  108.         checkNotNegative(revAtEpoch,   OmmTleKey.REV_AT_EPOCH.name());

  109.         if (ephemerisType == EPHEMERIS_TYPE_SGP4) {
  110.             checkNotNaN(bStar, OmmTleKey.BSTAR.name());
  111.         } else if (ephemerisType == EPHEMERIS_TYPE_SGP4_XP) {
  112.             checkNotNaN(bTerm, OmmTleKey.BTERM.name());
  113.         }

  114.         if (ephemerisType == EPHEMERIS_TYPE_SGP  || ephemerisType == EPHEMERIS_TYPE_PPT3) {
  115.             checkNotNaN(meanMotionDot, OmmTleKey.MEAN_MOTION_DOT.name());
  116.         }

  117.         if (ephemerisType == EPHEMERIS_TYPE_SGP  || ephemerisType == EPHEMERIS_TYPE_PPT3) {
  118.             checkNotNaN(meanMotionDotDot, OmmTleKey.MEAN_MOTION_DDOT.name());
  119.         } else if (ephemerisType == EPHEMERIS_TYPE_SGP4_XP) {
  120.             checkNotNaN(agOm, OmmTleKey.AGOM.name());
  121.         }

  122.     }

  123.     /** Get the ephemeris type.
  124.      * @return the ephemerisType
  125.      */
  126.     public int getEphemerisType() {
  127.         return ephemerisType;
  128.     }

  129.     /** Set the ephemeris type.
  130.      * @param ephemerisType the ephemeris type to be set
  131.      */
  132.     public void setEphemerisType(final int ephemerisType) {
  133.         refuseFurtherComments();
  134.         this.ephemerisType = ephemerisType;
  135.     }

  136.     /** Get the classification type.
  137.      * @return the classificationType
  138.      */
  139.     public char getClassificationType() {
  140.         return classificationType;
  141.     }

  142.     /** Set the classification type.
  143.      * @param classificationType the classification type to be set
  144.      */
  145.     public void setClassificationType(final char classificationType) {
  146.         refuseFurtherComments();
  147.         this.classificationType = classificationType;
  148.     }

  149.     /** Get the NORAD Catalog Number ("Satellite Number").
  150.      * @return the NORAD Catalog Number
  151.      */
  152.     public int getNoradID() {
  153.         return noradID;
  154.     }

  155.     /** Set the NORAD Catalog Number ("Satellite Number").
  156.      * @param noradID the element set number to be set
  157.      */
  158.     public void setNoradID(final int noradID) {
  159.         refuseFurtherComments();
  160.         this.noradID = noradID;
  161.     }

  162.     /** Get the element set number for this satellite.
  163.      * @return the element set number for this satellite
  164.      */
  165.     public int getElementSetNumber() {
  166.         return elementSetNo;
  167.     }

  168.     /** Set the element set number for this satellite.
  169.      * @param elementSetNo the element set number to be set
  170.      */
  171.     public void setElementSetNo(final int elementSetNo) {
  172.         refuseFurtherComments();
  173.         this.elementSetNo = elementSetNo;
  174.     }

  175.     /** Get the revolution rumber.
  176.      * @return the revolution rumber
  177.      */
  178.     public int getRevAtEpoch() {
  179.         return revAtEpoch;
  180.     }

  181.     /** Set the revolution rumber.
  182.      * @param revAtEpoch the Revolution Number to be set
  183.      */
  184.     public void setRevAtEpoch(final int revAtEpoch) {
  185.         refuseFurtherComments();
  186.         this.revAtEpoch = revAtEpoch;
  187.     }

  188.     /** Get the SGP/SGP4 drag-like coefficient.
  189.      * @return the SGP/SGP4 drag-like coefficient
  190.      */
  191.     public double getBStar() {
  192.         return bStar;
  193.     }

  194.     /** Set the SGP/SGP4 drag-like coefficient.
  195.      * @param bstar the SGP/SGP4 drag-like coefficient to be set
  196.      */
  197.     public void setBStar(final double bstar) {
  198.         refuseFurtherComments();
  199.         this.bStar = bstar;
  200.     }

  201.     /** Get the SGP4-XP drag-like coefficient.
  202.      * @return the SGP4-XP drag-like coefficient
  203.      * @since 12.0
  204.      */
  205.     public double getBTerm() {
  206.         return bTerm;
  207.     }

  208.     /** Set the SGP4-XP drag-like coefficient.
  209.      * @param bterm the SGP4-XP drag-like coefficient to be set
  210.      * @since 12.0
  211.      */
  212.     public void setBTerm(final double bterm) {
  213.         refuseFurtherComments();
  214.         this.bTerm = bterm;
  215.     }

  216.     /** Get the first time derivative of the mean motion.
  217.      * @return the first time derivative of the mean motion
  218.      */
  219.     public double getMeanMotionDot() {
  220.         return meanMotionDot;
  221.     }

  222.     /** Set the first time derivative of the mean motion.
  223.      * @param meanMotionDot the first time derivative of the mean motion to be set
  224.      */
  225.     public void setMeanMotionDot(final double meanMotionDot) {
  226.         refuseFurtherComments();
  227.         this.meanMotionDot = meanMotionDot;
  228.     }

  229.     /** Get the second time derivative of the mean motion.
  230.      * @return the second time derivative of the mean motion
  231.      */
  232.     public double getMeanMotionDotDot() {
  233.         return meanMotionDotDot;
  234.     }

  235.     /** Set the second time derivative of the mean motion.
  236.      * @param meanMotionDotDot the second time derivative of the mean motion to be set
  237.      */
  238.     public void setMeanMotionDotDot(final double meanMotionDotDot) {
  239.         refuseFurtherComments();
  240.         this.meanMotionDotDot = meanMotionDotDot;
  241.     }

  242.     /** Get the SGP4-XP solar radiation pressure-like coefficient Aγ/m.
  243.      * @return the SGP4-XP solar radiation pressure-like coefficient Aγ/m
  244.      * @since 12.0
  245.      */
  246.     public double getAGoM() {
  247.         return agOm;
  248.     }

  249.     /** Set the SGP4-XP solar radiation pressure-like coefficient Aγ/m.
  250.      * @param agom the SGP4-XP solar radiation pressure-like coefficient Aγ/m to be set
  251.      * @since 12.0
  252.      */
  253.     public void setAGoM(final double agom) {
  254.         refuseFurtherComments();
  255.         this.agOm = agom;
  256.     }

  257. }