ClockCorrectionsProvider.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;

  18. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  19. import org.orekit.propagation.AdditionalDataProvider;
  20. import org.orekit.propagation.SpacecraftState;
  21. import org.orekit.propagation.analytical.gnss.data.GNSSClockElements;
  22. import org.orekit.time.AbsoluteDate;
  23. import org.orekit.utils.Constants;
  24. import org.orekit.utils.PVCoordinates;

  25. /** Provider for clock corrections as additional states.
  26.  * <p>
  27.  * The value of this additional state is a three elements array containing
  28.  * </p>
  29.  * <ul>
  30.  *   <li>at index 0, the polynomial satellite clock model
  31.  *       Δtₛₐₜ = {@link GNSSClockElements#getAf0() a₀} +
  32.  *               {@link GNSSClockElements#getAf1() a₁} (t - {@link GNSSClockElements#getToc() toc}) +
  33.  *               {@link GNSSClockElements#getAf1() a₂} (t - {@link GNSSClockElements#getToc() toc})²
  34.  *   </li>
  35.  *   <li>at index 1 the relativistic clock correction due to eccentricity</li>
  36.  *   <li>at index 2 the estimated group delay differential {@link GNSSClockElements#getTGD() TGD} for L1-L2 correction</li>
  37.  * </ul>
  38.  * <p>
  39.  * Since Orekit 10.3 the relativistic clock correction can be used as an
  40.  * {@link org.orekit.estimation.measurements.EstimationModifier} in orbit determination applications
  41.  * to take into consideration this effect in measurement modeling.
  42.  * </p>
  43.  *
  44.  * @author Luc Maisonobe
  45.  * @since 9.3
  46.  */
  47. public class ClockCorrectionsProvider implements AdditionalDataProvider<double[]> {

  48.     /** Name of the additional state for satellite clock corrections.
  49.      * @since 9.3
  50.      */
  51.     public static final String CLOCK_CORRECTIONS = "";

  52.     /** The GPS clock elements. */
  53.     private final GNSSClockElements gnssClk;

  54.     /** Clock reference epoch. */
  55.     private final AbsoluteDate clockRef;

  56.     /** Duration of the GNSS cycle in seconds. */
  57.     private final double cycleDuration;

  58.     /** Simple constructor.
  59.      * @param gnssClk GNSS clock elements
  60.      * @param cycleDuration duration of the GNSS cycle in seconds
  61.      */
  62.     public ClockCorrectionsProvider(final GNSSClockElements gnssClk,
  63.                                     final double cycleDuration) {
  64.         this.gnssClk       = gnssClk;
  65.         this.clockRef      = gnssClk.getDate();
  66.         this.cycleDuration = cycleDuration;
  67.     }

  68.     /** {@inheritDoc} */
  69.     @Override
  70.     public String getName() {
  71.         return CLOCK_CORRECTIONS;
  72.     }

  73.     /**
  74.      * Get the duration from clock Reference epoch.
  75.      * <p>This takes the GNSS week roll-over into account.</p>
  76.      *
  77.      * @param date the considered date
  78.      * @return the duration from clock Reference epoch (s)
  79.      */
  80.     private double getDT(final AbsoluteDate date) {
  81.         // Time from ephemeris reference epoch
  82.         double dt = date.durationFrom(clockRef);
  83.         // Adjusts the time to take roll over week into account
  84.         while (dt > 0.5 * cycleDuration) {
  85.             dt -= cycleDuration;
  86.         }
  87.         while (dt < -0.5 * cycleDuration) {
  88.             dt += cycleDuration;
  89.         }
  90.         // Returns the time from ephemeris reference epoch
  91.         return dt;
  92.     }

  93.     /** {@inheritDoc} */
  94.     @Override
  95.     public double[] getAdditionalData(final SpacecraftState state) {

  96.         // polynomial clock model
  97.         final double  dt    = getDT(state.getDate());
  98.         final double  dtSat = gnssClk.getAf0() + dt * (gnssClk.getAf1() + dt * gnssClk.getAf2());

  99.         // relativistic effect due to eccentricity
  100.         final PVCoordinates pv    = state.getPVCoordinates();
  101.         final double        dtRel = -2 * Vector3D.dotProduct(pv.getPosition(), pv.getVelocity()) /
  102.                         (Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT);

  103.         // estimated group delay differential
  104.         final double tg = gnssClk.getTGD();

  105.         return new double[] {
  106.             dtSat, dtRel, tg
  107.         };
  108.     }

  109. }