SubFrame4D.java

  1. /* Copyright 2022-2025 Thales Alenia Space
  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.gnss.rflink.gps;

  18. import org.hipparchus.util.FastMath;
  19. import org.orekit.gnss.metric.parser.Units;
  20. import org.orekit.utils.units.Unit;

  21. /**
  22.  * Container for sub-frames 4, page 18.
  23.  * <p>
  24.  * Table 40-1, sheet 8 in
  25.  * <a href="https://navcen.uscg.gov/sites/default/files/pdf/gps/IS-GPS-200N.pdf">NAVSTAR
  26.  * GPS Space Segment/Navigation User Segment Interface</a>, IS-GPS-200N, 22 Aug 2022
  27.  * </p>
  28.  * @author Luc Maisonobe
  29.  * @since 12.0
  30.  */
  31. public class SubFrame4D extends SubFrame45 {

  32.     /** Seconds per semi-circle. */
  33.     private static final Unit S_PER_SC = Unit.SECOND.divide("s/sc", Units.SEMI_CIRCLE);

  34.     /** Seconds per semi-circle². */
  35.     private static final Unit S_PER_SC2 = S_PER_SC.divide("s/sc²", Units.SEMI_CIRCLE);

  36.     /** Seconds per semi-circle³. */
  37.     private static final Unit S_PER_SC3 = S_PER_SC2.divide("s/sc³", Units.SEMI_CIRCLE);

  38.     /** Index of α₀ field. */
  39.     private static final int ALPHA0 = 9;

  40.     /** Index of α₁ field. */
  41.     private static final int ALPHA1 = 10;

  42.     /** Index of α₂ field. */
  43.     private static final int ALPHA2 = 11;

  44.     /** Index of α₃ field. */
  45.     private static final int ALPHA3 = 12;

  46.     /** Index of β₀ field. */
  47.     private static final int BETA0 = 13;

  48.     /** Index of β₁ field. */
  49.     private static final int BETA1 = 14;

  50.     /** Index of β₂ field. */
  51.     private static final int BETA2 = 15;

  52.     /** Index of β₃ field. */
  53.     private static final int BETA3 = 16;

  54.     /** Index of A₁ field. */
  55.     private static final int A1 = 17;

  56.     /** Index of A0 field. */
  57.     private static final int A0 = 18;

  58.     /** Index of TOT field. */
  59.     private static final int TOT = 19;

  60.     /** Index of Week Number T field. */
  61.     private static final int WEEK_NUMBER_T = 20;

  62.     /** Index of ΔtLS field. */
  63.     private static final int DELTA_T_LS = 21;

  64.     /** Index of Week Number LSF field. */
  65.     private static final int WEEK_NUMBER_LSF = 22;

  66.     /** Index of DN field. */
  67.     private static final int DN = 23;

  68.     /** Index of ΔtLSF field. */
  69.     private static final int DELTA_T_LSF = 24;

  70.     /** Index of reserved field in word 10. */
  71.     private static final int RESERVED_10 = 25;

  72.     /** Simple constructor.
  73.      * @param words raw words
  74.      */
  75.     SubFrame4D(final int[] words) {

  76.         // create raw container
  77.         super(words, RESERVED_10 + 1);

  78.         // populate container
  79.         setField(ALPHA0,           3, 14,  8, words);
  80.         setField(ALPHA1,           3,  6,  8, words);
  81.         setField(ALPHA2,           4, 22,  8, words);
  82.         setField(ALPHA3,           4, 14,  8, words);
  83.         setField(BETA0,            4,  6,  8, words);
  84.         setField(BETA1,            5, 22,  8, words);
  85.         setField(BETA2,            5, 14,  8, words);
  86.         setField(BETA3,            5,  6,  8, words);
  87.         setField(A1,               6,  6, 24, words);
  88.         setField(A0,               7,  6, 24, 8, 22, 8, words);
  89.         setField(TOT,              8, 14,  8, words);
  90.         setField(WEEK_NUMBER_T,    8,  6,  8, words);
  91.         setField(DELTA_T_LS,       9, 22,  8, words);
  92.         setField(WEEK_NUMBER_LSF,  9, 14,  8, words);
  93.         setField(DN,               9,  6,  8, words);
  94.         setField(DELTA_T_LSF,     10, 22,  8, words);
  95.         setField(RESERVED_10,     10,  8, 14, words);

  96.     }

  97.     /** Get α₀ field.
  98.      * @return α₀ field (second).
  99.      */
  100.     public double getAlpha0() {
  101.         return FastMath.scalb((double) getField(ALPHA0), -30);
  102.     }

  103.     /** Get α₁ field.
  104.      * @return α₁ field (second/rad).
  105.      */
  106.     public double getAlpha1() {
  107.         return S_PER_SC.toSI(FastMath.scalb((double) getField(ALPHA1), -27));
  108.     }

  109.     /** Get α₂ field.
  110.      * @return α₂ field (second/rad²).
  111.      */
  112.     public double getAlpha2() {
  113.         return S_PER_SC2.toSI(FastMath.scalb((double) getField(ALPHA2), -24));
  114.     }

  115.     /** Get α₃ field.
  116.      * @return α₃ field (second/rad³)
  117.      */
  118.     public double getAlpha3() {
  119.         return S_PER_SC3.toSI(FastMath.scalb((double) getField(ALPHA3), -24));
  120.     }

  121.     /** Get β₀ field.
  122.      * @return β₀ field (second)
  123.      */
  124.     public double getBeta0() {
  125.         return FastMath.scalb((double) getField(BETA0), 11);
  126.     }

  127.     /** Get β₁ field.
  128.      * @return β₁ field (second/rad)
  129.      */
  130.     public double getBeta1() {
  131.         return S_PER_SC.toSI(FastMath.scalb((double) getField(BETA1), 14));
  132.     }

  133.     /** Get β₂ field.
  134.      * @return β₂ field (second/rad²)
  135.      */
  136.     public double getBeta2() {
  137.         return S_PER_SC2.toSI(FastMath.scalb((double) getField(BETA2), 16));
  138.     }

  139.     /** Get β₃ field.
  140.      * @return β₃ field (second/rad³)
  141.      */
  142.     public double getBeta3() {
  143.         return S_PER_SC3.toSI(FastMath.scalb((double) getField(BETA3), 16));
  144.     }

  145.     /** Get A₁ field.
  146.      * @return A₁ field (second/second).
  147.      */
  148.     public double getA1() {
  149.         return FastMath.scalb((double) getField(A1), -50);
  150.     }

  151.     /** Get A0 field.
  152.      * @return A0 field (seconds).
  153.      */
  154.     public double getA0() {
  155.         return FastMath.scalb((double) getField(A0), -30);
  156.     }

  157.     /** Get TOT field.
  158.      * @return TOT field. */
  159.     public int getTot() {
  160.         return getField(TOT) << 12;
  161.     }

  162.     /** Get Week Number T field.
  163.      * @return Week Number T field. */
  164.     public int getWeekNumberT() {
  165.         return getField(WEEK_NUMBER_T);
  166.     }

  167.     /** Get ΔtLS field.
  168.      * @return ΔtLS field. */
  169.     public int getDeltaTLs() {
  170.         return getField(DELTA_T_LS);
  171.     }

  172.     /** Get Week Number LSF field.
  173.      * @return Week Number LSF field. */
  174.     public int getWeekNumberLsf() {
  175.         return getField(WEEK_NUMBER_LSF);
  176.     }

  177.     /** Get DN field.
  178.      * @return DN field. */
  179.     public int getDn() {
  180.         return getField(DN);
  181.     }

  182.     /** Get ΔtLSF field.
  183.      * @return ΔtLSF field. */
  184.     public int getDeltaTLsf() {
  185.         return getField(DELTA_T_LSF);
  186.     }

  187.     /** Get reserved field in word 10.
  188.      * @return reserved field in word 10. */
  189.     public int getReserved10() {
  190.         return getField(RESERVED_10);
  191.     }

  192. }