GNSSOrbitalElements.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.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.propagation.analytical.gnss.GNSSPropagator;
  23. import org.orekit.time.AbsoluteDate;
  24. import org.orekit.time.GNSSDate;
  25. import org.orekit.time.TimeScales;
  26. import org.orekit.time.TimeStamped;
  27. import org.orekit.utils.ParameterDriver;

  28. /** This class provides the minimal set of orbital elements needed by the {@link GNSSPropagator}.
  29.  * <p>
  30.  * The parameters are split in two groups: Keplerian orbital parameters and non-Keplerian
  31.  * evolution parameters. All parameters can be updated as they are all instances of
  32.  * {@link ParameterDriver}. Only the non-Keplerian parameters are returned in the
  33.  * {@link #getParametersDrivers()} method, the Keplerian orbital parameters must
  34.  * be accessed independently. These groups ensure proper separate computation of
  35.  * state transition matrix and Jacobian matrix by {@link GNSSPropagator}.
  36.  * </p>
  37.  * @param <O> type of the orbital elements
  38.  * @since 13.0
  39.  * @author Pascal Parraud
  40.  * @author Luc Maisonobe
  41. */
  42. public abstract class GNSSOrbitalElements<O extends GNSSOrbitalElements<O>>
  43.     extends GNSSOrbitalElementsDriversProvider
  44.     implements TimeStamped {

  45.     /** Name for semi major axis parameter. */
  46.     public static final String SEMI_MAJOR_AXIS = "GnssSemiMajorAxis";

  47.     /** Name for eccentricity parameter. */
  48.     public static final String ECCENTRICITY = "GnssEccentricity";

  49.     /** Name for inclination at reference time parameter. */
  50.     public static final String INCLINATION = "GnssInclination";

  51.     /** Name for argument of perigee parameter. */
  52.     public static final String ARGUMENT_OF_PERIGEE = "GnssPerigeeArgument";

  53.     /** Name for longitude of ascending node at weekly epoch parameter. */
  54.     public static final String NODE_LONGITUDE = "GnssNodeLongitude";

  55.     /** Name for mean anomaly at reference time parameter. */
  56.     public static final String MEAN_ANOMALY = "GnssMeanAnomaly";

  57.     /** Earth's universal gravitational parameter. */
  58.     private final double mu;

  59.     /** Reference epoch. */
  60.     private AbsoluteDate date;

  61.     /** Semi-Major Axis (m). */
  62.     private final ParameterDriver smaDriver;

  63.     /** Eccentricity. */
  64.     private final ParameterDriver eccDriver;

  65.     /** Inclination angle at reference time (rad). */
  66.     private final ParameterDriver i0Driver;

  67.     /** Argument of perigee (rad). */
  68.     private final ParameterDriver aopDriver;

  69.     /** Longitude of ascending node of orbit plane at weekly epoch (rad). */
  70.     private final ParameterDriver om0Driver;

  71.     /** Mean anomaly at reference time (rad). */
  72.     private final ParameterDriver anomDriver;

  73.     /**
  74.      * Constructor.
  75.      * @param mu              Earth's universal gravitational parameter
  76.      * @param angularVelocity mean angular velocity of the Earth for the GNSS model
  77.      * @param weeksInCycle    number of weeks in the GNSS cycle
  78.      * @param timeScales      known time scales
  79.      * @param system          satellite system to consider for interpreting week number
  80.      *                        (may be different from real system, for example in Rinex nav, weeks
  81.      *                        are always according to GPS)
  82.      */
  83.     protected GNSSOrbitalElements(final double mu, final double angularVelocity, final int weeksInCycle,
  84.                                   final TimeScales timeScales, final SatelliteSystem system) {

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

  86.         // immutable field
  87.         this.mu         = mu;

  88.         // fields controlled by parameter drivers for Keplerian orbital elements
  89.         this.smaDriver  = createDriver(SEMI_MAJOR_AXIS);
  90.         this.eccDriver  = createDriver(ECCENTRICITY);
  91.         this.i0Driver   = createDriver(INCLINATION);
  92.         this.aopDriver  = createDriver(ARGUMENT_OF_PERIGEE);
  93.         this.om0Driver  = createDriver(NODE_LONGITUDE);
  94.         this.anomDriver = createDriver(MEAN_ANOMALY);

  95.     }

  96.     /** Constructor from field instance.
  97.      * @param <T> type of the field elements
  98.      * @param <A> type of the orbital elements (non-field version)
  99.      * @param original regular field instance
  100.      */
  101.     protected <T extends CalculusFieldElement<T>,
  102.                A extends GNSSOrbitalElements<A>> GNSSOrbitalElements(final FieldGnssOrbitalElements<T, A> original) {
  103.         this(original.getMu().getReal(), original.getAngularVelocity(), original.getWeeksInCycle(),
  104.              original.getTimeScales(), original.getSystem());

  105.         // non-Keperian parameters
  106.         setPRN(original.getPRN());
  107.         setWeek(original.getWeek());
  108.         setTime(original.getTime());
  109.         setIDot(original.getIDot());
  110.         setOmegaDot(original.getOmegaDot());
  111.         setCuc(original.getCuc());
  112.         setCus(original.getCus());
  113.         setCrc(original.getCrc());
  114.         setCrs(original.getCrs());
  115.         setCic(original.getCic());
  116.         setCis(original.getCis());

  117.         // Keplerian orbital elements
  118.         setSma(original.getSma().getReal());
  119.         setE(original.getE().getReal());
  120.         setI0(original.getI0().getReal());
  121.         setPa(original.getPa().getReal());
  122.         setOmega0(original.getOmega0().getReal());
  123.         setM0(original.getM0().getReal());

  124.         // copy selection settings
  125.         copySelectionSettings(original);

  126.     }

  127.     /** Create a field version of the instance.
  128.      * @param <T> type of the field elements
  129.      * @param <F> type of the orbital elements (field version)
  130.      * @param field field to which elements belong
  131.      * @return field version of the instance
  132.      */
  133.     public abstract <T extends CalculusFieldElement<T>, F extends FieldGnssOrbitalElements<T, O>>
  134.         F toField(Field<T> field);

  135.     /** {@inheritDoc} */
  136.     protected void setGnssDate(final GNSSDate gnssDate) {
  137.         this.date = gnssDate.getDate();
  138.     }

  139.     /** {@inheritDoc} */
  140.     @Override
  141.     public AbsoluteDate getDate() {
  142.         return date;
  143.     }

  144.     /** Get the Earth's universal gravitational parameter.
  145.      * @return the Earth's universal gravitational parameter
  146.      */
  147.     public double getMu() {
  148.         return mu;
  149.     }

  150.     /** Get semi-major axis.
  151.      * @return driver for the semi-major axis (m)
  152.      */
  153.     public ParameterDriver getSmaDriver() {
  154.         return smaDriver;
  155.     }

  156.     /** Get semi-major axis.
  157.      * @return semi-major axis (m)
  158.      */
  159.     public double getSma() {
  160.         return getSmaDriver().getValue();
  161.     }

  162.     /** Set semi-major axis.
  163.      * @param sma demi-major axis (m)
  164.      */
  165.     public void setSma(final double sma) {
  166.         getSmaDriver().setValue(sma);
  167.     }

  168.     /** Getter for the change rate in semi-major axis.
  169.      * <p>
  170.      * This value is non-zero only in civilian navigation messages
  171.      * </p>
  172.      * @return the change rate in semi-major axis
  173.      * @since 13.0
  174.      */
  175.     public double getADot() {
  176.         return 0;
  177.     }

  178.     /** Get the computed mean motion n₀.
  179.      * @return the computed mean motion n₀ (rad/s)
  180.      * @since 13.0
  181.      */
  182.     public double getMeanMotion0() {
  183.         final double absA = FastMath.abs(getSma());
  184.         return FastMath.sqrt(getMu() / absA) / absA;
  185.     }

  186.     /** Getter for the delta of satellite mean motion.
  187.      * <p>
  188.      * This value is non-zero only in navigation messages
  189.      * </p>
  190.      * @return delta of satellite mean motion
  191.      * @since 13.0
  192.      */
  193.     public double getDeltaN0() {
  194.         return 0;
  195.     }

  196.     /** Getter for change rate in Δn₀.
  197.      * <p>
  198.      * This value is non-zero only in civilian navigation messages
  199.      * </p>
  200.      * @return change rate in Δn₀
  201.      * @since 13.0
  202.      */
  203.     public double getDeltaN0Dot() {
  204.         return 0;
  205.     }

  206.     /** Get the driver for the eccentricity.
  207.      * @return driver for the eccentricity
  208.      */
  209.     public ParameterDriver getEDriver() {
  210.         return eccDriver;
  211.     }

  212.     /** Get eccentricity.
  213.      * @return eccentricity
  214.      */
  215.     public double getE() {
  216.         return getEDriver().getValue();
  217.     }

  218.     /** Set eccentricity.
  219.      * @param e eccentricity
  220.      */
  221.     public void setE(final double e) {
  222.         getEDriver().setValue(e);
  223.     }

  224.     /** Get the driver for the inclination angle at reference time.
  225.      * @return driver for the inclination angle at reference time (rad)
  226.      */
  227.     public ParameterDriver getI0Driver() {
  228.         return i0Driver;
  229.     }

  230.     /** Get the inclination angle at reference time.
  231.      * @return inclination angle at reference time (rad)
  232.      */
  233.     public double getI0() {
  234.         return getI0Driver().getValue();
  235.     }

  236.     /** Set inclination angle at reference time.
  237.      * @param i0 inclination angle at reference time (rad)
  238.      */
  239.     public void setI0(final double i0) {
  240.         getI0Driver().setValue(i0);
  241.     }

  242.     /** Get the driver for the longitude of ascending node of orbit plane at weekly epoch.
  243.      * @return driver for the longitude of ascending node of orbit plane at weekly epoch (rad)
  244.      */
  245.     public ParameterDriver getOmega0Driver() {
  246.         return om0Driver;
  247.     }

  248.     /** Get longitude of ascending node of orbit plane at weekly epoch.
  249.      * @return longitude of ascending node of orbit plane at weekly epoch (rad)
  250.      */
  251.     public double getOmega0() {
  252.         return getOmega0Driver().getValue();
  253.     }

  254.     /** Set longitude of ascending node of orbit plane at weekly epoch.
  255.      * @param om0 longitude of ascending node of orbit plane at weekly epoch (rad)
  256.      */
  257.     public void setOmega0(final double om0) {
  258.         getOmega0Driver().setValue(om0);
  259.     }

  260.     /** Get the driver for the argument of perigee.
  261.      * @return driver for the argument of perigee (rad)
  262.      */
  263.     public ParameterDriver getPaDriver() {
  264.         return aopDriver;
  265.     }

  266.     /** Get argument of perigee.
  267.      * @return argument of perigee (rad)
  268.      */
  269.     public double getPa() {
  270.         return getPaDriver().getValue();
  271.     }

  272.     /** Set argument of perigee.
  273.      * @param aop argument of perigee (rad)
  274.      */
  275.     public void setPa(final double aop) {
  276.         getPaDriver().setValue(aop);
  277.     }

  278.     /** Get the driver for the mean anomaly at reference time.
  279.      * @return driver for the mean anomaly at reference time (rad)
  280.      */
  281.     public ParameterDriver getM0Driver() {
  282.         return anomDriver;
  283.     }

  284.     /** Get mean anomaly at reference time.
  285.      * @return mean anomaly at reference time (rad)
  286.      */
  287.     public double getM0() {
  288.         return getM0Driver().getValue();
  289.     }

  290.     /** Set mean anomaly at reference time.
  291.      * @param anom mean anomaly at reference time (rad)
  292.      */
  293.     public void setM0(final double anom) {
  294.         getM0Driver().setValue(anom);
  295.     }

  296. }