GNSSOrbitalElementsDriversProvider.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.util.FastMath;
  19. import org.orekit.gnss.SatelliteSystem;
  20. import org.orekit.time.AbsoluteDate;
  21. import org.orekit.time.GNSSDate;
  22. import org.orekit.time.TimeScales;
  23. import org.orekit.utils.ParameterDriver;
  24. import org.orekit.utils.ParameterDriversProvider;
  25. import org.orekit.utils.ParameterObserver;
  26. import org.orekit.utils.TimeSpanMap;

  27. import java.util.Arrays;
  28. import java.util.List;

  29. /** This class manages the non-keplerian parameter drivers for
  30.  * {@link GNSSOrbitalElements} and {@link FieldGnssOrbitalElements}.
  31.  * <p>
  32.  * In both primitive double and field classes, only the non-Keplerian parameters
  33.  * are returned in the {@link #getParametersDrivers()} method, the Keplerian orbital
  34.  * parameters must be accessed independently. These groups ensure proper separate
  35.  * computation of state transition matrix and Jacobian matrix by
  36.  * {@link org.orekit.propagation.analytical.gnss.GNSSPropagator} and
  37.  * {@link org.orekit.propagation.analytical.gnss.FieldGnssPropagator}.
  38.  * </p>
  39.  * @since 13.0
  40.  * @author Luc Maisonobe
  41.  */
  42. public abstract class GNSSOrbitalElementsDriversProvider
  43.     implements ParameterDriversProvider {

  44.     /** Name for time parameter. */
  45.     public static final String TIME = "GnssTime";

  46.     /** Name for inclination rate parameter. */
  47.     public static final String INCLINATION_RATE = "GnssInclinationRate";

  48.     /** Name for longitude rate parameter. */
  49.     public static final String LONGITUDE_RATE = "GnssLongitudeRate";

  50.     /** Name for cosine of latitude argument harmonic parameter. */
  51.     public static final String LATITUDE_COSINE = "GnssLatitudeCosine";

  52.     /** Name for sine of latitude argument harmonic parameter. */
  53.     public static final String LATITUDE_SINE = "GnssLatitudeSine";

  54.     /** Name for cosine of orbit radius harmonic parameter. */
  55.     public static final String RADIUS_COSINE = "GnssRadiusCosine";

  56.     /** Name for sine of orbit radius harmonic parameter. */
  57.     public static final String RADIUS_SINE = "GnssRadiusSine";

  58.     /** Name for cosine of inclination harmonic parameter. */
  59.     public static final String INCLINATION_COSINE = "GnssInclinationCosine";

  60.     /** Name for sine of inclination harmonic parameter. */
  61.     public static final String INCLINATION_SINE = "GnssInclinationSine";

  62.     /** Index of time in the list returned by {@link #getParametersDrivers()}. */
  63.     public static final int TIME_INDEX = 0;

  64.     /** Index of inclination rate in the list returned by {@link #getParametersDrivers()}. */
  65.     public static final int I_DOT_INDEX = TIME_INDEX + 1;

  66.     /** Index of longitude rate in the list returned by {@link #getParametersDrivers()}. */
  67.     public static final int OMEGA_DOT_INDEX = I_DOT_INDEX + 1;

  68.     /** Index of cosine on latitude argument in the list returned by {@link #getParametersDrivers()}. */
  69.     public static final int CUC_INDEX = OMEGA_DOT_INDEX + 1;

  70.     /** Index of sine on latitude argument in the list returned by {@link #getParametersDrivers()}. */
  71.     public static final int CUS_INDEX = CUC_INDEX + 1;

  72.     /** Index of cosine on radius in the list returned by {@link #getParametersDrivers()}. */
  73.     public static final int CRC_INDEX = CUS_INDEX + 1;

  74.     /** Index of sine on radius in the list returned by {@link #getParametersDrivers()}. */
  75.     public static final int CRS_INDEX = CRC_INDEX + 1;

  76.     /** Index of cosine on inclination in the list returned by {@link #getParametersDrivers()}. */
  77.     public static final int CIC_INDEX = CRS_INDEX + 1;

  78.     /** Index of sine on inclination in the list returned by {@link #getParametersDrivers()}. */
  79.     public static final int CIS_INDEX = CIC_INDEX + 1;

  80.     /** Size of parameters array. */
  81.     public static final int SIZE = CIS_INDEX + 1;

  82.     /** Mean angular velocity of the Earth for the GNSS model. */
  83.     private final double angularVelocity;

  84.     /** Duration of the GNSS cycle in weeks. */
  85.     private final int weeksInCycle;

  86.     /** Duration of the GNSS cycle in seconds. */
  87.     private final double cycleDuration;

  88.     /** Satellite system to use for interpreting week number. */
  89.     private final SatelliteSystem system;

  90.     /** Known time scales. */
  91.     private final TimeScales timeScales;

  92.     /** PRN number of the satellite. */
  93.     private int prn;

  94.     /** Reference Week of the orbit. */
  95.     private int week;

  96.     /** Reference time. */
  97.     private final ParameterDriver timeDriver;

  98.     /** Inclination rate (rad/s). */
  99.     private final ParameterDriver iDotDriver;

  100.     /** Rate of right ascension (rad/s). */
  101.     private final ParameterDriver domDriver;

  102.     /** Amplitude of the cosine harmonic correction term to the argument of latitude. */
  103.     private final ParameterDriver cucDriver;

  104.     /** Amplitude of the sine harmonic correction term to the argument of latitude. */
  105.     private final ParameterDriver cusDriver;

  106.     /** Amplitude of the cosine harmonic correction term to the orbit radius. */
  107.     private final ParameterDriver crcDriver;

  108.     /** Amplitude of the sine harmonic correction term to the orbit radius. */
  109.     private final ParameterDriver crsDriver;

  110.     /** Amplitude of the cosine harmonic correction term to the inclination. */
  111.     private final ParameterDriver cicDriver;

  112.     /** Amplitude of the sine harmonic correction term to the inclination. */
  113.     private final ParameterDriver cisDriver;

  114.     /** Constructor.
  115.      * @param angularVelocity mean angular velocity of the Earth for the GNSS model
  116.      * @param weeksInCycle    number of weeks in the GNSS cycle
  117.      * @param timeScales      known time scales
  118.      * @param system          satellite system to consider for interpreting week number
  119.      *                        (may be different from real system, for example in Rinex nav, weeks
  120.      *                        are always according to GPS)
  121.      */
  122.     protected GNSSOrbitalElementsDriversProvider(final double angularVelocity, final int weeksInCycle,
  123.                                                  final TimeScales timeScales, final SatelliteSystem system) {

  124.         // immutable fields
  125.         this.angularVelocity = angularVelocity;
  126.         this.weeksInCycle    = weeksInCycle;
  127.         this.cycleDuration   = GNSSConstants.GNSS_WEEK_IN_SECONDS * weeksInCycle;
  128.         this.system          = system;
  129.         this.timeScales      = timeScales;

  130.         this.timeDriver = createDriver(TIME);
  131.         this.iDotDriver = createDriver(INCLINATION_RATE);
  132.         this.domDriver  = createDriver(LONGITUDE_RATE);
  133.         this.cucDriver  = createDriver(LATITUDE_COSINE);
  134.         this.cusDriver  = createDriver(LATITUDE_SINE);
  135.         this.crcDriver  = createDriver(RADIUS_COSINE);
  136.         this.crsDriver  = createDriver(RADIUS_SINE);
  137.         this.cicDriver  = createDriver(INCLINATION_COSINE);
  138.         this.cisDriver  = createDriver(INCLINATION_SINE);

  139.         // automatically update date when time driver is updated
  140.         timeDriver.addObserver(new ParameterObserver() {

  141.             /** {@inheritDoc} */
  142.             @Override
  143.             public void valueChanged(final double previousValue, final ParameterDriver driver,
  144.                                      final AbsoluteDate date) {
  145.                 setGnssDate(new GNSSDate(week, driver.getValue(), system, timeScales));
  146.             }

  147.             /** {@inheritDoc} */
  148.             @Override
  149.             public void valueSpanMapChanged(final TimeSpanMap<Double> previousValueSpanMap,
  150.                                             final ParameterDriver driver) {
  151.                 // nothing to do
  152.             }
  153.         });

  154.     }

  155.     /** Copy drivers selection settings from another instance.
  156.      * @param original original instance providing selection settings
  157.      */
  158.     protected void copySelectionSettings(final GNSSOrbitalElementsDriversProvider original) {
  159.         timeDriver.setSelected(original.timeDriver.isSelected());
  160.         iDotDriver.setSelected(original.iDotDriver.isSelected());
  161.         domDriver.setSelected(original.domDriver.isSelected());
  162.         cucDriver.setSelected(original.cucDriver.isSelected());
  163.         cusDriver.setSelected(original.cusDriver.isSelected());
  164.         crcDriver.setSelected(original.crcDriver.isSelected());
  165.         crsDriver.setSelected(original.crsDriver.isSelected());
  166.         cicDriver.setSelected(original.cicDriver.isSelected());
  167.         cisDriver.setSelected(original.cisDriver.isSelected());
  168.     }

  169.     /** Set GNSS date.
  170.      * @param gnssDate GNSS date
  171.      */
  172.     protected abstract void setGnssDate(GNSSDate gnssDate);

  173.     /** Create parameter driver.
  174.      * @param name name of the driver
  175.      * @return build driver
  176.      */
  177.     protected static ParameterDriver createDriver(final String name) {
  178.         return new ParameterDriver(name, 0, FastMath.scalb(1.0, -30),
  179.                                    Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
  180.     }

  181.     /** Get satellite system.
  182.      * @return satellite system
  183.      */
  184.     public SatelliteSystem getSystem() {
  185.         return system;
  186.     }

  187.     /** Get known time scales.
  188.      * @return known time scales
  189.      */
  190.     public TimeScales getTimeScales() {
  191.         return timeScales;
  192.     }

  193.     /** {@inheritDoc}
  194.      * <p>
  195.      * Only the 9 non-Keplerian evolution parameters are listed here,
  196.      * i.e. {@link #getTimeDriver()} (at index {@link #TIME_INDEX}),
  197.      * {@link #getIDotDriver()} (at index {@link #I_DOT_INDEX}),
  198.      * {@link #getOmegaDotDriver()} (at index {@link #OMEGA_DOT_INDEX}),
  199.      * {@link #getCucDriver()} (at index {@link #CUC_INDEX}),
  200.      * {@link #getCusDriver()} (at index {@link #CUS_INDEX}),
  201.      * {@link #getCrcDriver()} (at index {@link #CRC_INDEX}),
  202.      * {@link #getCrsDriver()} (at index {@link #CRS_INDEX}),
  203.      * {@link #getCicDriver()} (at index {@link #CIC_INDEX}),
  204.      * and {@link #getCisDriver()} (at index {@link #CIS_INDEX})
  205.      * </p>
  206.      * <p>
  207.      * The Keplerian orbital parameters drivers are not included.
  208.      * </p>
  209.      */
  210.     @Override
  211.     public List<ParameterDriver> getParametersDrivers() {
  212.         // ensure the parameters are really at the advertised indices
  213.         final ParameterDriver[] array = new ParameterDriver[SIZE];
  214.         array[TIME_INDEX]      = getTimeDriver();
  215.         array[I_DOT_INDEX]     = getIDotDriver();
  216.         array[OMEGA_DOT_INDEX] = getOmegaDotDriver();
  217.         array[CUC_INDEX]       = getCucDriver();
  218.         array[CUS_INDEX]       = getCusDriver();
  219.         array[CRC_INDEX]       = getCrcDriver();
  220.         array[CRS_INDEX]       = getCrsDriver();
  221.         array[CIC_INDEX]       = getCicDriver();
  222.         array[CIS_INDEX]       = getCisDriver();
  223.         return Arrays.asList(array);
  224.     }

  225.     /** Get the mean angular velocity of the Earth of the GNSS model.
  226.      * @return mean angular velocity of the Earth of the GNSS model
  227.      */
  228.     public double getAngularVelocity() {
  229.         return angularVelocity;
  230.     }

  231.     /** Get for the duration of the GNSS cycle in weeks.
  232.      * @return the duration of the GNSS cycle in weeks
  233.      */
  234.     public int getWeeksInCycle() {
  235.         return weeksInCycle;
  236.     }

  237.     /** Get for the duration of the GNSS cycle in seconds.
  238.      * @return the duration of the GNSS cycle in seconds
  239.      */
  240.     public double getCycleDuration() {
  241.         return cycleDuration;
  242.     }

  243.     /** Get the PRN number of the satellite.
  244.      * @return PRN number of the satellite
  245.      */
  246.     public int getPRN() {
  247.         return prn;
  248.     }

  249.     /** Set the PRN number of the satellite.
  250.      * @param number the prn number ot set
  251.      */
  252.     public void setPRN(final int number) {
  253.         this.prn = number;
  254.     }

  255.     /** Get the reference week of the orbit.
  256.      * @return reference week of the orbit
  257.      */
  258.     public int getWeek() {
  259.         return week;
  260.     }

  261.     /** Set the reference week of the orbit.
  262.      * @param week the week to set
  263.      */
  264.     public void setWeek(final int week) {
  265.         this.week = week;
  266.         setGnssDate(new GNSSDate(week, timeDriver.getValue(), system, timeScales));
  267.     }

  268.     /** Get the driver for reference time of the GNSS orbit as a duration from week start.
  269.      * @return driver for the reference time of the GNSS orbit (s)
  270.      */
  271.     public ParameterDriver getTimeDriver() {
  272.         return timeDriver;
  273.     }

  274.     /** Get reference time of the GNSS orbit as a duration from week start.
  275.      * @return reference time of the GNSS orbit (s)
  276.      */
  277.     public double getTime() {
  278.         return getTimeDriver().getValue();
  279.     }

  280.     /** Set reference time of the GNSS orbit as a duration from week start.
  281.      * @param time reference time of the GNSS orbit (s)
  282.      */
  283.     public void setTime(final double time) {
  284.         getTimeDriver().setValue(time);
  285.     }

  286.     /** Get the driver for the rate of inclination angle.
  287.      * @return driver for the rate of inclination angle (rad/s)
  288.      */
  289.     public ParameterDriver getIDotDriver() {
  290.         return iDotDriver;
  291.     }

  292.     /** Get rate of inclination angle.
  293.      * @return rate of inclination angle (rad/s)
  294.      */
  295.     public double getIDot() {
  296.         return getIDotDriver().getValue();
  297.     }

  298.     /** Set the driver for the rate of inclination angle.
  299.      * @param iDot rate of inclination angle (rad/s)
  300.      */
  301.     public void setIDot(final double iDot) {
  302.         getIDotDriver().setValue(iDot);
  303.     }

  304.     /** Get the driver for the rate of right ascension.
  305.      * @return driver for the rate of right ascension (rad/s)
  306.      */
  307.     public ParameterDriver getOmegaDotDriver() {
  308.         return domDriver;
  309.     }

  310.     /** Get rate of right ascension.
  311.      * @return rate of right ascension (rad/s)
  312.      */
  313.     public double getOmegaDot() {
  314.         return getOmegaDotDriver().getValue();
  315.     }

  316.     /** Set rate of right ascension.
  317.      * @param dom rate of right ascension (rad/s)
  318.      */
  319.     public void setOmegaDot(final double dom) {
  320.         getOmegaDotDriver().setValue(dom);
  321.     }

  322.     /** Get the driver for the amplitude of the cosine harmonic correction term to the argument of latitude.
  323.      * @return driver for the amplitude of the cosine harmonic correction term to the argument of latitude (rad)
  324.      */
  325.     public ParameterDriver getCucDriver() {
  326.         return cucDriver;
  327.     }

  328.     /** Get amplitude of the cosine harmonic correction term to the argument of latitude.
  329.      * @return amplitude of the cosine harmonic correction term to the argument of latitude (rad)
  330.      */
  331.     public double getCuc() {
  332.         return getCucDriver().getValue();
  333.     }

  334.     /** Set amplitude of the cosine harmonic correction term to the argument of latitude.
  335.      * @param cuc amplitude of the cosine harmonic correction term to the argument of latitude (rad)
  336.      */
  337.     public void setCuc(final double cuc) {
  338.         getCucDriver().setValue(cuc);
  339.     }

  340.     /** Get the driver for the amplitude of the sine harmonic correction term to the argument of latitude.
  341.      * @return driver for the amplitude of the sine harmonic correction term to the argument of latitude (rad)
  342.      */
  343.     public ParameterDriver getCusDriver() {
  344.         return cusDriver;
  345.     }

  346.     /** Get amplitude of the sine harmonic correction term to the argument of latitude.
  347.      * @return amplitude of the sine harmonic correction term to the argument of latitude (rad)
  348.      */
  349.     public double getCus() {
  350.         return getCusDriver().getValue();
  351.     }

  352.     /** Set amplitude of the sine harmonic correction term to the argument of latitude.
  353.      * @param cus amplitude of the sine harmonic correction term to the argument of latitude (rad)
  354.      */
  355.     public void setCus(final double cus) {
  356.         getCusDriver().setValue(cus);
  357.     }

  358.     /** Get the driver for the amplitude of the cosine harmonic correction term to the orbit radius.
  359.      * @return driver for the amplitude of the cosine harmonic correction term to the orbit radius (m)
  360.      */
  361.     public ParameterDriver getCrcDriver() {
  362.         return crcDriver;
  363.     }

  364.     /** Get amplitude of the cosine harmonic correction term to the orbit radius.
  365.      * @return amplitude of the cosine harmonic correction term to the orbit radius (m)
  366.      */
  367.     public double getCrc() {
  368.         return getCrcDriver().getValue();
  369.     }

  370.     /** Set amplitude of the cosine harmonic correction term to the orbit radius.
  371.      * @param crc amplitude of the cosine harmonic correction term to the orbit radius (m)
  372.      */
  373.     public void setCrc(final double crc) {
  374.         getCrcDriver().setValue(crc);
  375.     }

  376.     /** Get the driver for the amplitude of the sine harmonic correction term to the orbit radius.
  377.      * @return driver for the amplitude of the sine harmonic correction term to the orbit radius (m)
  378.      */
  379.     public ParameterDriver getCrsDriver() {
  380.         return crsDriver;
  381.     }

  382.     /** Get amplitude of the sine harmonic correction term to the orbit radius.
  383.      * @return amplitude of the sine harmonic correction term to the orbit radius (m)
  384.      */
  385.     public double getCrs() {
  386.         return getCrsDriver().getValue();
  387.     }

  388.     /** Set amplitude of the sine harmonic correction term to the orbit radius.
  389.      * @param crs amplitude of the sine harmonic correction term to the orbit radius (m)
  390.      */
  391.     public void setCrs(final double crs) {
  392.         getCrsDriver().setValue(crs);
  393.     }

  394.     /** Get the driver for the amplitude of the cosine harmonic correction term to the angle of inclination.
  395.      * @return driver for the amplitude of the cosine harmonic correction term to the angle of inclination (rad)
  396.      */
  397.     public ParameterDriver getCicDriver() {
  398.         return cicDriver;
  399.     }

  400.     /** Get amplitude of the cosine harmonic correction term to the angle of inclination.
  401.      * @return amplitude of the cosine harmonic correction term to the angle of inclination (rad)
  402.      */
  403.     public double getCic() {
  404.         return getCicDriver().getValue();
  405.     }

  406.     /** Set amplitude of the cosine harmonic correction term to the angle of inclination.
  407.      * @param cic amplitude of the cosine harmonic correction term to the angle of inclination (rad)
  408.      */
  409.     public void setCic(final double cic) {
  410.         getCicDriver().setValue(cic);
  411.     }

  412.     /** Get the driver for the amplitude of the sine harmonic correction term to the angle of inclination.
  413.      * @return driver for the amplitude of the sine harmonic correction term to the angle of inclination (rad)
  414.      */
  415.     public ParameterDriver getCisDriver() {
  416.         return cisDriver;
  417.     }

  418.     /** Get amplitude of the sine harmonic correction term to the angle of inclination.
  419.      * @return amplitude of the sine harmonic correction term to the angle of inclination (rad)
  420.      */
  421.     public double getCis() {
  422.         return getCisDriver().getValue();
  423.     }

  424.     /** Set amplitude of the sine harmonic correction term to the angle of inclination.
  425.      * @param cis amplitude of the sine harmonic correction term to the angle of inclination (rad)
  426.      */
  427.     public void setCis(final double cis) {
  428.         getCisDriver().setValue(cis);
  429.     }

  430. }