FieldGnssOrbitalElements.java

  1. /* Copyright 2022-2025 Luc Maisonobe
  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.analytical.gnss.data;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.Field;
  20. import org.hipparchus.util.FastMath;
  21. import org.orekit.gnss.SatelliteSystem;
  22. import org.orekit.time.FieldAbsoluteDate;
  23. import org.orekit.time.FieldTimeStamped;
  24. import org.orekit.time.GNSSDate;
  25. import org.orekit.time.TimeScales;

  26. import java.util.function.Function;

  27. /** This class provides the minimal set of orbital elements needed by the {@link
  28.  * org.orekit.propagation.analytical.gnss.FieldGnssPropagator}.
  29.  * @param <T> type of the field elements
  30.  * @param <O> type of the orbital elements (non-field version)
  31.  * @since 13.0
  32.  * @author Luc Maisonobe
  33. */
  34. public abstract class FieldGnssOrbitalElements<T extends CalculusFieldElement<T>, O extends GNSSOrbitalElements<O>>
  35.     extends GNSSOrbitalElementsDriversProvider
  36.     implements FieldTimeStamped<T> {

  37.     /** Earth's universal gravitational parameter. */
  38.     private final T mu;

  39.     /** Reference epoch. */
  40.     private FieldAbsoluteDate<T> date;

  41.     /** Semi-Major Axis (m). */
  42.     private T sma;

  43.     /** Eccentricity. */
  44.     private T ecc;

  45.     /** Inclination angle at reference time (rad). */
  46.     private T i0;

  47.     /** Argument of perigee (rad). */
  48.     private T aop;

  49.     /** Longitude of ascending node of orbit plane at weekly epoch (rad). */
  50.     private T om0;

  51.     /** Mean anomaly at reference time (rad). */
  52.     private T anom;

  53.     /** Simple constructor.
  54.      * @param mu              Earth's universal gravitational parameter
  55.      * @param angularVelocity mean angular velocity of the Earth for the GNSS model
  56.      * @param weeksInCycle    number of weeks in the GNSS cycle
  57.      * @param timeScales      known time scales
  58.      * @param system          satellite system to consider for interpreting week number
  59.      *                        (may be different from real system, for example in Rinex nav, weeks
  60.      *                        are always according to GPS)
  61.      */
  62.     protected FieldGnssOrbitalElements(final T mu, final double angularVelocity, final int weeksInCycle,
  63.                                        final TimeScales timeScales, final SatelliteSystem system) {

  64.         super(angularVelocity, weeksInCycle, timeScales, system);

  65.         // immutable field
  66.         this.mu   = mu;

  67.         // Keplerian orbital elements
  68.         this.sma  = mu.newInstance(Double.NaN);
  69.         this.ecc  = mu.newInstance(Double.NaN);
  70.         this.i0   = mu.newInstance(Double.NaN);
  71.         this.aop  = mu.newInstance(Double.NaN);
  72.         this.om0  = mu.newInstance(Double.NaN);
  73.         this.anom = mu.newInstance(Double.NaN);

  74.     }

  75.     /** Constructor from non-field instance.
  76.      * @param field    field to which elements belong
  77.      * @param original regular non-field instance
  78.      */
  79.     protected FieldGnssOrbitalElements(final Field<T> field, final O original) {

  80.         super(original.getAngularVelocity(), original.getWeeksInCycle(),
  81.               original.getTimeScales(), original.getSystem());
  82.         mu = field.getZero().newInstance(original.getMu());

  83.         // non-Keplerian parameters
  84.         setPRN(original.getPRN());
  85.         setWeek(original.getWeek());
  86.         setTime(original.getTime());
  87.         setIDot(original.getIDot());
  88.         setOmegaDot(original.getOmegaDot());
  89.         setCuc(original.getCuc());
  90.         setCus(original.getCus());
  91.         setCrc(original.getCrc());
  92.         setCrs(original.getCrs());
  93.         setCic(original.getCic());
  94.         setCis(original.getCis());

  95.         // Keplerian orbital elements
  96.         setGnssDate(new GNSSDate(original.getWeek(), original.getTime(), original.getSystem(), original.getTimeScales()));
  97.         setSma(field.getZero().newInstance(original.getSma()));
  98.         setE(field.getZero().newInstance(original.getE()));
  99.         setI0(field.getZero().newInstance(original.getI0()));
  100.         setPa(field.getZero().newInstance(original.getPa()));
  101.         setOmega0(field.getZero().newInstance(original.getOmega0()));
  102.         setM0(field.getZero().newInstance(original.getM0()));

  103.         // copy selection settings
  104.         copySelectionSettings(original);

  105.     }

  106.     /** Constructor from different field instance.
  107.      * @param <V> type of the old field elements
  108.      * @param original regular non-field instance
  109.      * @param converter for field elements
  110.      */
  111.     protected <V extends CalculusFieldElement<V>> FieldGnssOrbitalElements(final Function<V, T> converter,
  112.                                                                            final FieldGnssOrbitalElements<V, O> original) {
  113.         super(original.getAngularVelocity(), original.getWeeksInCycle(),
  114.               original.getTimeScales(), original.getSystem());
  115.         mu = converter.apply(original.getMu());

  116.         // non-Keplerian parameters
  117.         setPRN(original.getPRN());
  118.         setWeek(original.getWeek());
  119.         setTime(original.getTime());
  120.         setIDot(original.getIDot());
  121.         setOmegaDot(original.getOmegaDot());
  122.         setCuc(original.getCuc());
  123.         setCus(original.getCus());
  124.         setCrc(original.getCrc());
  125.         setCrs(original.getCrs());
  126.         setCic(original.getCic());
  127.         setCis(original.getCis());

  128.         // Keplerian orbital elements
  129.         setGnssDate(new GNSSDate(original.getWeek(), original.getTime(), original.getSystem(), original.getTimeScales()));
  130.         setSma(converter.apply(original.getSma()));
  131.         setE(converter.apply(original.getE()));
  132.         setI0(converter.apply(original.getI0()));
  133.         setPa(converter.apply(original.getPa()));
  134.         setOmega0(converter.apply(original.getOmega0()));
  135.         setM0(converter.apply(original.getM0()));

  136.         // copy selection settings
  137.         copySelectionSettings(original);

  138.     }

  139.     /** Create a non-field version of the instance.
  140.      * @return non-field version of the instance
  141.      */
  142.     public abstract O toNonField();

  143.     /**
  144.      * Create another field version of the instance.
  145.      *
  146.      * @param <U>       type of the new field elements
  147.      * @param <G>       type of the orbital elements (field version)
  148.      * @param converter for field elements
  149.      * @return field version of the instance
  150.      */
  151.     public abstract <U extends CalculusFieldElement<U>, G extends FieldGnssOrbitalElements<U, O>>
  152.         G changeField(Function<T, U> converter);

  153.     /** {@inheritDoc} */
  154.     protected void setGnssDate(final GNSSDate gnssDate) {
  155.         this.date = new FieldAbsoluteDate<>(mu.getField(), gnssDate.getDate());
  156.     }

  157.     /** Get date.
  158.      * @return date
  159.      */
  160.     public FieldAbsoluteDate<T> getDate() {
  161.         return date;
  162.     }

  163.     /** Get the Earth's universal gravitational parameter.
  164.      * @return the Earth's universal gravitational parameter
  165.      */
  166.     public T getMu() {
  167.         return mu;
  168.     }

  169.     /** Get semi-major axis.
  170.      * @return semi-major axis (m)
  171.      */
  172.     public T getSma() {
  173.         return sma;
  174.     }

  175.     /** Set semi-major axis.
  176.      * @param sma demi-major axis (m)
  177.      */
  178.     public void setSma(final T sma) {
  179.         this.sma = sma;
  180.     }

  181.     /** Getter for the change rate in semi-major axis.
  182.      * <p>
  183.      * This value is non-zero only in civilian navigation messages
  184.      * </p>
  185.      * @return the change rate in semi-major axis
  186.      * @since 13.0
  187.      */
  188.     public T getADot() {
  189.         return mu.getField().getZero();
  190.     }

  191.     /** Get the computed mean motion n₀.
  192.      * @return the computed mean motion n₀ (rad/s)
  193.      * @since 13.0
  194.      */
  195.     public T getMeanMotion0() {
  196.         final T invA = FastMath.abs(getSma()).reciprocal();
  197.         return FastMath.sqrt(getMu().multiply(invA)).multiply(invA);
  198.     }

  199.     /** Getter for the delta of satellite mean motion.
  200.      * <p>
  201.      * This value is non-zero only in navigation messages
  202.      * </p>
  203.      * @return delta of satellite mean motion
  204.      * @since 13.0
  205.      */
  206.     public T getDeltaN0() {
  207.         return mu.getField().getZero();
  208.     }

  209.     /** Getter for change rate in Δn₀.
  210.      * <p>
  211.      * This value is non-zero only in civilian navigation messages
  212.      * </p>
  213.      * @return change rate in Δn₀
  214.      * @since 13.0
  215.      */
  216.     public T getDeltaN0Dot() {
  217.         return mu.getField().getZero();
  218.     }

  219.     /** Get eccentricity.
  220.      * @return eccentricity
  221.      */
  222.     public T getE() {
  223.         return ecc;
  224.     }

  225.     /** Set eccentricity.
  226.      * @param e eccentricity
  227.      */
  228.     public void setE(final T e) {
  229.         this.ecc = e;
  230.     }

  231.     /** Get the inclination angle at reference time.
  232.      * @return inclination angle at reference time (rad)
  233.      */
  234.     public T getI0() {
  235.         return i0;
  236.     }

  237.     /** Set inclination angle at reference time.
  238.      * @param i0 inclination angle at reference time (rad)
  239.      */
  240.     public void setI0(final T i0) {
  241.         this.i0 = i0;
  242.     }

  243.     /** Get longitude of ascending node of orbit plane at weekly epoch.
  244.      * @return longitude of ascending node of orbit plane at weekly epoch (rad)
  245.      */
  246.     public T getOmega0() {
  247.         return om0;
  248.     }

  249.     /** Set longitude of ascending node of orbit plane at weekly epoch.
  250.      * @param omega0 longitude of ascending node of orbit plane at weekly epoch (rad)
  251.      */
  252.     public void setOmega0(final T omega0) {
  253.         this.om0 = omega0;
  254.     }

  255.     /** Get argument of perigee.
  256.      * @return argument of perigee (rad)
  257.      */
  258.     public T getPa() {
  259.         return aop;
  260.     }

  261.     /** Set argument of perigee.
  262.      * @param pa argument of perigee (rad)
  263.      */
  264.     public void setPa(final T pa) {
  265.         this.aop = pa;
  266.     }

  267.     /** Get mean anomaly at reference time.
  268.      * @return mean anomaly at reference time (rad)
  269.      */
  270.     public T getM0() {
  271.         return anom;
  272.     }

  273.     /** Set mean anomaly at reference time.
  274.      * @param m0 mean anomaly at reference time (rad)
  275.      */
  276.     public void setM0(final T m0) {
  277.         this.anom = m0;
  278.     }

  279. }