TLETheory.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.propagation.conversion.osc2mean;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.Field;
  20. import org.orekit.annotation.DefaultDataContext;
  21. import org.orekit.data.DataContext;
  22. import org.orekit.frames.Frame;
  23. import org.orekit.orbits.FieldKeplerianOrbit;
  24. import org.orekit.orbits.FieldOrbit;
  25. import org.orekit.orbits.KeplerianOrbit;
  26. import org.orekit.orbits.Orbit;
  27. import org.orekit.orbits.OrbitType;
  28. import org.orekit.propagation.analytical.tle.FieldTLE;
  29. import org.orekit.propagation.analytical.tle.FieldTLEPropagator;
  30. import org.orekit.propagation.analytical.tle.TLE;
  31. import org.orekit.propagation.analytical.tle.TLEConstants;
  32. import org.orekit.propagation.analytical.tle.TLEPropagator;
  33. import org.orekit.propagation.analytical.tle.generation.TleGenerationUtil;
  34. import org.orekit.time.FieldAbsoluteDate;
  35. import org.orekit.time.TimeScale;

  36. /**
  37.  * TLE, i.e. SGP4/SDP4, theory for osculating to mean orbit conversion.
  38.  *
  39.  * @author Pascal Parraud
  40.  * @since 13.0
  41.  */
  42. public class TLETheory implements MeanTheory {

  43.     /** First line of arbitrary TLE. Should not impact conversion. */
  44.     public static final String TMP_L1 = "1 00000U 00000A   00001.00000000  .00000000  00000+0  00000+0 0    02";
  45.     /** Second line of arbitrary TLE. Should not impact conversion. */
  46.     public static final String TMP_L2 = "2 00000   0.0000   0.0000 0000000   0.0000   0.0000  0.00000000    02";

  47.     /** Theory used for converting from osculating to mean orbit. */
  48.     public static final String THEORY = "TLE";

  49.     /** Template TLE. */
  50.     private final TLE tmpTle;

  51.     /** UTC scale. */
  52.     private final TimeScale utc;

  53.     /** TEME frame. */
  54.     private final Frame teme;

  55.     /**
  56.      * Constructor with default data context and default TLE template.
  57.      */
  58.     @DefaultDataContext
  59.     public TLETheory() {
  60.         this(DataContext.getDefault());
  61.     }

  62.     /**
  63.      * Constructor with default data context.
  64.      * @param template template TLE
  65.      */
  66.     @DefaultDataContext
  67.     public TLETheory(final TLE template) {
  68.         this(template, DataContext.getDefault());
  69.     }

  70.     /**
  71.      * Constructor with default data context.
  72.      * @param <T> type of the elements
  73.      * @param template template TLE
  74.      */
  75.     @DefaultDataContext
  76.     public <T extends CalculusFieldElement<T>> TLETheory(final FieldTLE<T> template) {
  77.         this(template, DataContext.getDefault());
  78.     }

  79.     /**
  80.      * Constructor with default TLE template.
  81.      * @param dataContext data context
  82.      */
  83.     public TLETheory(final DataContext dataContext) {
  84.         this(dataContext.getTimeScales().getUTC(), dataContext.getFrames().getTEME());
  85.     }

  86.     /**
  87.      * Constructor.
  88.      * @param utc      UTC scale
  89.      * @param teme     TEME frame scale
  90.      */
  91.     public TLETheory(final TimeScale utc, final Frame teme) {
  92.         this(new TLE(TMP_L1, TMP_L2, utc), utc, teme);
  93.     }

  94.     /**
  95.      * Constructor.
  96.      * @param template template TLE
  97.      * @param dataContext data context
  98.      */
  99.     public TLETheory(final TLE template, final DataContext dataContext) {
  100.         this(template, dataContext.getTimeScales().getUTC(), dataContext.getFrames().getTEME());
  101.     }

  102.     /**
  103.      * Constructor.
  104.      * @param template template TLE
  105.      * @param utc      UTC scale
  106.      * @param teme     TEME frame scale
  107.      */
  108.     public TLETheory(final TLE template, final TimeScale utc, final Frame teme) {
  109.         this.tmpTle = template;
  110.         this.utc    = utc;
  111.         this.teme   = teme;
  112.     }

  113.     /**
  114.      * Constructor.
  115.      * @param <T> type of the elements
  116.      * @param template template TLE
  117.      * @param dataContext data context
  118.      */
  119.     public <T extends CalculusFieldElement<T>> TLETheory(final FieldTLE<T> template, final DataContext dataContext) {
  120.         this(template, dataContext.getTimeScales().getUTC(), dataContext.getFrames().getTEME());
  121.     }

  122.     /**
  123.      * Constructor.
  124.      * @param <T> type of the elements
  125.      * @param template template TLE
  126.      * @param utc      UTC scale
  127.      * @param teme     TEME frame scale
  128.      */
  129.     public <T extends CalculusFieldElement<T>> TLETheory(final FieldTLE<T> template, final TimeScale utc, final Frame teme) {
  130.         this.tmpTle = template.toTLE();
  131.         this.utc    = utc;
  132.         this.teme   = teme;
  133.     }

  134.     /** {@inheritDoc} */
  135.     @Override
  136.     public String getTheoryName() {
  137.         return THEORY;
  138.     }

  139.     /** {@inheritDoc} */
  140.     @Override
  141.     public double getReferenceRadius() {
  142.         return 1000 * TLEConstants.EARTH_RADIUS;
  143.     };

  144.     /** Pre-treatment of the osculating orbit to be converted.
  145.      * <p>The osculating orbit is transformed to TEME frame.</p>
  146.      */
  147.     @Override
  148.     public Orbit preprocessing(final Orbit osculating) {
  149.         return new KeplerianOrbit(osculating.getPVCoordinates(teme), teme, TLEPropagator.getMU());
  150.     }

  151.     /** {@inheritDoc} */
  152.     @Override
  153.     public Orbit meanToOsculating(final Orbit mean) {
  154.         // Build TLE from mean and template
  155.         final KeplerianOrbit meanKepl = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(mean);
  156.         final TLE meanTle = TleGenerationUtil.newTLE(meanKepl, tmpTle, tmpTle.getBStar(mean.getDate()), utc);
  157.         final TLEPropagator propagator = TLEPropagator.selectExtrapolator(meanTle, teme);
  158.         return propagator.getInitialState().getOrbit();
  159.     }

  160.     /** Post-treatment of the converted mean orbit.
  161.      * <p>The mean orbit returned is a Keplerian orbit in TEME frame.</p>
  162.      */
  163.     @Override
  164.     public Orbit postprocessing(final Orbit osculating, final Orbit mean) {
  165.         return OrbitType.KEPLERIAN.convertType(mean);
  166.     }

  167.     /** Pre-treatment of the osculating orbit to be converted.
  168.      * <p>The osculating orbit is transformed to TEME frame.</p>
  169.      */
  170.     @Override
  171.     public <T extends CalculusFieldElement<T>> FieldOrbit<T> preprocessing(final FieldOrbit<T> osculating) {
  172.         final T mu = osculating.getDate().getField().getZero().newInstance(TLEConstants.MU);
  173.         return new FieldKeplerianOrbit<T>(osculating.getPVCoordinates(teme), teme, mu);
  174.     }

  175.     /** {@inheritDoc} */
  176.     @Override
  177.     public <T extends CalculusFieldElement<T>> FieldOrbit<T> meanToOsculating(final FieldOrbit<T> mean) {
  178.         final FieldAbsoluteDate<T> date = mean.getDate();
  179.         final Field<T> field = date.getField();
  180.         final FieldTLE<T> fieldTmpTle = new FieldTLE<T>(field, tmpTle.getLine1(), tmpTle.getLine2(), utc);
  181.         final T bStar = field.getZero().newInstance(fieldTmpTle.getBStar());
  182.         // Build TLE from mean and template
  183.         final FieldKeplerianOrbit<T> meanKepl = (FieldKeplerianOrbit<T>) OrbitType.KEPLERIAN.convertType(mean);
  184.         final FieldTLE<T> meanTle = TleGenerationUtil.newTLE(meanKepl, fieldTmpTle, bStar, utc);
  185.         final FieldTLEPropagator<T> propagator = FieldTLEPropagator.selectExtrapolator(meanTle, teme, meanTle.getParameters(field));
  186.         return propagator.getInitialState().getOrbit();
  187.     }

  188.     /** Post-treatment of the converted mean orbit.
  189.      * <p>The mean orbit returned is a Keplerian orbit in TEME frame.</p>
  190.      */
  191.     @Override
  192.     public <T extends CalculusFieldElement<T>> FieldOrbit<T> postprocessing(final FieldOrbit<T> osculating,
  193.                                                                             final FieldOrbit<T> mean) {
  194.         return OrbitType.KEPLERIAN.convertType(mean);
  195.     }

  196. }