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  
19  import org.hipparchus.util.FastMath;
20  import org.orekit.gnss.metric.parser.Units;
21  
22  /**
23   * Container for sub-frames 3.
24   * <p>
25   * Table 20-1, sheet 3 and table 40-1, sheet 3 in
26   * <a href="https://navcen.uscg.gov/sites/default/files/pdf/gps/IS-GPS-200N.pdf">NAVSTAR
27   * GPS Space Segment/Navigation User Segment Interface</a>, IS-GPS-200N, 22 Aug 2022
28   * </p>
29   * @author Luc Maisonobe
30   * @since 12.0
31   */
32  public class SubFrame3 extends SubFrame {
33  
34      /** Index of Cic field. */
35      private static final int CIC = 7;
36  
37      /** Index of Ω₀ field. */
38      private static final int UPPERCASE_OMEGA_0 = 8;
39  
40      /** Index of Cis field. */
41      private static final int CIS = 9;
42  
43      /** Index of i₀ field. */
44      private static final int I0 = 10;
45  
46      /** Index of Crc field. */
47      private static final int CRC = 11;
48  
49      /** Index of ω field. */
50      private static final int LOWERCASE_OMEGA = 12;
51  
52      /** Index of dot(Ω) field. */
53      private static final int OMEGA_DOT = 13;
54  
55      /** Index of IODE field. */
56      private static final int IODE = 14;
57  
58      /** Index of dot(i) field. */
59      private static final int I_DOT = 15;
60  
61      /** Simple constructor.
62       * @param words raw words
63       */
64      SubFrame3(final int[] words) {
65  
66          // create raw container
67          super(words, I_DOT + 1);
68  
69          // populate container
70          setField(CIC,                   3, 14, 16, words);
71          setField(UPPERCASE_OMEGA_0,     3,  6,  8, 4,  6, 24, words);
72          setField(CIS,                   5, 14, 16, words);
73          setField(I0,                    5,  6,  8, 6,  6, 24, words);
74          setField(CRC,                   7, 14, 16, words);
75          setField(LOWERCASE_OMEGA,       7,  6,  8, 8,  6, 24, words);
76          setField(OMEGA_DOT,             9,  6, 24, words);
77          setField(IODE,                 10, 22,  8, words);
78          setField(I_DOT,                10,  8, 14, words);
79  
80      }
81  
82      /** Get Cic.
83       * @return Cic (rad)
84       */
85      public double getCic() {
86          return FastMath.scalb((double) getField(CIC), -29);
87      }
88  
89      /** Get Ω₀.
90       * @return Ω₀ (rad)
91       */
92      public double getUppercaseOmega0() {
93          return Units.SEMI_CIRCLE.toSI(FastMath.scalb((double) getField(UPPERCASE_OMEGA_0), -31));
94      }
95  
96      /** Get Cis.
97       * @return Cis (rad)
98       */
99      public double getCis() {
100         return FastMath.scalb((double) getField(CIS), -29);
101     }
102 
103     /** Get i₀.
104      * @return i₀ (rad)
105      */
106     public double getI0() {
107         return Units.SEMI_CIRCLE.toSI(FastMath.scalb((double) getField(I0), -31));
108     }
109 
110     /** Get Crc.
111      * @return Crc (rad)
112      */
113     public double getCrc() {
114         return FastMath.scalb((double) getField(CRC), -5);
115     }
116 
117     /** Get ω.
118      * @return ω(rad)
119      */
120     public double getLowercaseOmega() {
121         return Units.SEMI_CIRCLE.toSI(FastMath.scalb((double) getField(LOWERCASE_OMEGA), -31));
122     }
123 
124     /** Get dot(Ω).
125      * @return dot(Ω) (rad/s)
126      */
127     public double getOmegaDot() {
128         return Units.SEMI_CIRCLE.toSI(FastMath.scalb((double) getField(OMEGA_DOT), -43));
129     }
130 
131     /** Get Issue Of Data (ephemeris).
132      * @return Issue Of Data (ephemeris)
133      */
134     public int getIODE() {
135         return getField(IODE);
136     }
137 
138     /** Get dot(i).
139      * @return dot(i) (rad/s)
140      */
141     public double getIDot() {
142         return Units.SEMI_CIRCLE.toSI(FastMath.scalb((double) getField(I_DOT), -43));
143     }
144 
145 }