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.gnss.metric.parser;
18  
19  import java.util.Locale;
20  
21  import org.orekit.utils.units.Unit;
22  
23  /** Enum containing all intermediate level data fields that can be parsed
24   * to build an IGS SSR message.
25   * @author Bryan Cazabonne
26   * @since 11.0
27   */
28  public enum IgsSsrDataField implements DataField {
29  
30      /** IGS SSR Version. */
31      IDF001 {
32          /** {@inheritDoc} */
33          @Override
34          public int intValue(final EncodedMessage message) {
35              return DataType.U_INT_3.decode(message).intValue();
36          }
37      },
38  
39      /** IGS Message number. */
40      IDF002 {
41          /** {@inheritDoc} */
42          @Override
43          public String stringValue(final EncodedMessage message, final int n) {
44              return String.format(Locale.US, "%3s", DataType.U_INT_8.decode(message).intValue()).trim();
45          }
46      },
47  
48      /** SSR Epoch time 1s. */
49      IDF003 {
50          /** {@inheritDoc} */
51          @Override
52          public int intValue(final EncodedMessage message) {
53              return DataType.U_INT_20.decode(message).intValue();
54          }
55      },
56  
57      /** SSR Update interval. */
58      IDF004 {
59          /** {@inheritDoc} */
60          @Override
61          public int intValue(final EncodedMessage message) {
62              switch (DataType.BIT_4.decode(message).byteValue()) {
63                  case 0  : return 1;
64                  case 1  : return 2;
65                  case 2  : return 5;
66                  case 3  : return 10;
67                  case 4  : return 15;
68                  case 5  : return 30;
69                  case 6  : return 60;
70                  case 7  : return 120;
71                  case 8  : return 240;
72                  case 9  : return 300;
73                  case 10 : return 600;
74                  case 11 : return 900;
75                  case 12 : return 1800;
76                  case 13 : return 3600;
77                  case 14 : return 7200;
78                  default : return 10800;
79              }
80          }
81      },
82  
83      /** Multiple Message Indicator. */
84      IDF005 {
85          /** {@inheritDoc} */
86          @Override
87          public int intValue(final EncodedMessage message) {
88              return DataType.BIT_1.decode(message).intValue();
89          }
90      },
91  
92      /** Global/Regional CRS Indicator. */
93      IDF006 {
94          /** {@inheritDoc} */
95          @Override
96          public int intValue(final EncodedMessage message) {
97              return DataType.BIT_1.decode(message).intValue();
98          }
99      },
100 
101     /** IOD SSR. */
102     IDF007 {
103         /** {@inheritDoc} */
104         @Override
105         public int intValue(final EncodedMessage message) {
106             return DataType.U_INT_4.decode(message).intValue();
107         }
108     },
109 
110     /** SSR Provider ID. */
111     IDF008 {
112         /** {@inheritDoc} */
113         @Override
114         public int intValue(final EncodedMessage message) {
115             return DataType.U_INT_16.decode(message).intValue();
116         }
117     },
118 
119     /** SSR Solution ID. */
120     IDF009 {
121         /** {@inheritDoc} */
122         @Override
123         public int intValue(final EncodedMessage message) {
124             return DataType.U_INT_4.decode(message).intValue();
125         }
126     },
127 
128     /** Number of satellites. */
129     IDF010 {
130         /** {@inheritDoc} */
131         @Override
132         public int intValue(final EncodedMessage message) {
133             return DataType.U_INT_6.decode(message).intValue();
134         }
135     },
136 
137     /** GNSS satellite ID. */
138     IDF011 {
139         /** {@inheritDoc} */
140         @Override
141         public int intValue(final EncodedMessage message) {
142             return DataType.U_INT_6.decode(message).intValue();
143         }
144     },
145 
146     /** GNSS IOD. */
147     IDF012 {
148         /** {@inheritDoc} */
149         @Override
150         public int intValue(final EncodedMessage message) {
151             return DataType.BIT_8.decode(message).intValue();
152         }
153     },
154 
155     /** Delta Orbit Radial (m). */
156     IDF013 {
157         /** {@inheritDoc} */
158         @Override
159         public double doubleValue(final EncodedMessage message) {
160             return Units.MM.toSI(DataType.INT_22.decode(message).intValue() * 0.1);
161         }
162     },
163 
164     /** Delta Along-Track (m). */
165     IDF014 {
166         /** {@inheritDoc} */
167         @Override
168         public double doubleValue(final EncodedMessage message) {
169             return Units.MM.toSI(DataType.INT_20.decode(message).intValue() * 0.4);
170         }
171     },
172 
173     /** Delta Cross-Track (m). */
174     IDF015 {
175         /** {@inheritDoc} */
176         @Override
177         public double doubleValue(final EncodedMessage message) {
178             return Units.MM.toSI(DataType.INT_20.decode(message).intValue() * 0.4);
179         }
180     },
181 
182     /** Dot Delta Radial (m/s). */
183     IDF016 {
184         /** {@inheritDoc} */
185         @Override
186         public double doubleValue(final EncodedMessage message) {
187             return Units.MM_PER_S.toSI(DataType.INT_21.decode(message).intValue() * 0.001);
188         }
189     },
190 
191     /** Dot Delta Along-Track (m/s). */
192     IDF017 {
193         /** {@inheritDoc} */
194         @Override
195         public double doubleValue(final EncodedMessage message) {
196             return Units.MM_PER_S.toSI(DataType.INT_19.decode(message).intValue() * 0.004);
197         }
198     },
199 
200     /** Dot Delta Cross-Track (m/s). */
201     IDF018 {
202         /** {@inheritDoc} */
203         @Override
204         public double doubleValue(final EncodedMessage message) {
205             return Units.MM_PER_S.toSI(DataType.INT_19.decode(message).intValue() * 0.004);
206         }
207     },
208 
209     /** Delta Clock C0. */
210     IDF019 {
211         /** {@inheritDoc} */
212         @Override
213         public double doubleValue(final EncodedMessage message) {
214             return Units.MM.toSI(DataType.INT_22.decode(message).intValue() * 0.1);
215         }
216     },
217 
218     /** Delta Clock C1. */
219     IDF020 {
220         /** {@inheritDoc} */
221         @Override
222         public double doubleValue(final EncodedMessage message) {
223             return Units.MM_PER_S.toSI(DataType.INT_21.decode(message).intValue() * 0.001);
224         }
225     },
226 
227     /** Delta Clock C2. */
228     IDF021 {
229         /** {@inheritDoc} */
230         @Override
231         public double doubleValue(final EncodedMessage message) {
232             return Units.MM_PER_S2.toSI(DataType.INT_27.decode(message).intValue() * 0.00002);
233         }
234     },
235 
236     /** High Rate Clock Correction. */
237     IDF022 {
238         /** {@inheritDoc} */
239         @Override
240         public double doubleValue(final EncodedMessage message) {
241             return Units.MM.toSI(DataType.INT_22.decode(message).intValue() * 0.1);
242         }
243     },
244 
245     /** No. of Code Biases Processed. */
246     IDF023 {
247         /** {@inheritDoc} */
248         @Override
249         public int intValue(final EncodedMessage message) {
250             return DataType.U_INT_5.decode(message).intValue();
251         }
252     },
253 
254     /** GNSS Signal and Tracking Mode Identifier. */
255     IDF024 {
256         /** {@inheritDoc} */
257         @Override
258         public int intValue(final EncodedMessage message) {
259             return DataType.U_INT_5.decode(message).intValue();
260         }
261     },
262 
263     /** Code Bias for specified GNSS signal. */
264     IDF025 {
265         /** {@inheritDoc} */
266         @Override
267         public double doubleValue(final EncodedMessage message) {
268             return DataType.INT_14.decode(message).intValue() * 0.01;
269         }
270     },
271 
272     /** Yaw angle used for computation of phase wind-up correction. */
273     IDF026 {
274         /** {@inheritDoc} */
275         @Override
276         public double doubleValue(final EncodedMessage message) {
277             return Units.SEMI_CIRCLE.toSI(DataType.U_INT_9.decode(message).intValue() / 256.0);
278         }
279     },
280 
281     /** Yaw rate. */
282     IDF027 {
283         /** {@inheritDoc} */
284         @Override
285         public double doubleValue(final EncodedMessage message) {
286             return Units.SEMI_CIRCLE.toSI(DataType.INT_8.decode(message).intValue() / 8192.0);
287         }
288     },
289 
290     /** Phase Bias for specified GNSS signal (m). */
291     IDF028 {
292         /** {@inheritDoc} */
293         @Override
294         public double doubleValue(final EncodedMessage message) {
295             return DataType.INT_20.decode(message).intValue() * 0.0001;
296         }
297     },
298 
299     /** Signal Integer Indicator. */
300     IDF029 {
301         /** {@inheritDoc} */
302         @Override
303         public boolean booleanValue(final EncodedMessage message) {
304             return DataType.BIT_1.decode(message) > 0;
305         }
306     },
307 
308     /** Signal Wide-Lane Integer Indicator. */
309     IDF030 {
310         /** {@inheritDoc} */
311         @Override
312         public int intValue(final EncodedMessage message) {
313             return DataType.BIT_2.decode(message).intValue();
314         }
315     },
316 
317     /** Signal Discontinuity Counter. */
318     IDF031 {
319         /** {@inheritDoc} */
320         @Override
321         public int intValue(final EncodedMessage message) {
322             return DataType.U_INT_4.decode(message).intValue();
323         }
324     },
325 
326     /** Dispersive Bias Consistency Indicator. */
327     IDF032 {
328         /** {@inheritDoc} */
329         @Override
330         public boolean booleanValue(final EncodedMessage message) {
331             return DataType.BIT_1.decode(message) > 0;
332         }
333     },
334 
335     /** Melbourne-Wübbena Consistency Indicator. */
336     IDF033 {
337         /** {@inheritDoc} */
338         @Override
339         public boolean booleanValue(final EncodedMessage message) {
340             return DataType.BIT_1.decode(message) > 0;
341         }
342     },
343 
344     /** SSR URA. */
345     IDF034 {
346         /** {@inheritDoc} */
347         @Override
348         public int intValue(final EncodedMessage message) {
349             return DataType.BIT_6.decode(message).intValue();
350         }
351     },
352 
353     /** Number of Ionospheric Layers. */
354     IDF035 {
355         /** {@inheritDoc} */
356         @Override
357         public int intValue(final EncodedMessage message) {
358             // The parsed number is between 0 and 3. So, we need to add 1.
359             return DataType.U_INT_2.decode(message).intValue() + 1;
360         }
361     },
362 
363     /** Height of the Ionospheric layer (m). */
364     IDF036 {
365         /** {@inheritDoc} */
366         @Override
367         public double doubleValue(final EncodedMessage message) {
368             // 10 km resolution
369             return Unit.KILOMETRE.toSI(DataType.U_INT_8.decode(message).intValue() * 10.0);
370         }
371     },
372 
373     /** Spherical Harmonic Degree. */
374     IDF037 {
375         /** {@inheritDoc} */
376         @Override
377         public int intValue(final EncodedMessage message) {
378             // The parsed number is between 0 and 15. So, we need to add 1.
379             return DataType.U_INT_4.decode(message).intValue() + 1;
380         }
381     },
382 
383     /** Spherical Harmonic Order. */
384     IDF038 {
385         /** {@inheritDoc} */
386         @Override
387         public int intValue(final EncodedMessage message) {
388             // The parsed number is between 0 and 15. So, we need to add 1.
389             return DataType.U_INT_4.decode(message).intValue() + 1;
390         }
391     },
392 
393     /** Spherical Harmonic Coefficient C (TECU). */
394     IDF039 {
395         /** {@inheritDoc} */
396         @Override
397         public double doubleValue(final EncodedMessage message) {
398             return DataType.INT_16.decode(message).intValue() * 0.005;
399         }
400     },
401 
402     /** Spherical Harmonic Coefficient S (TECU). */
403     IDF040 {
404         /** {@inheritDoc} */
405         @Override
406         public double doubleValue(final EncodedMessage message) {
407             return DataType.INT_16.decode(message).intValue() * 0.005;
408         }
409     },
410 
411     /** VTEC Quality Indicator (TECU). */
412     IDF041 {
413         /** {@inheritDoc} */
414         @Override
415         public double doubleValue(final EncodedMessage message) {
416             return DataType.U_INT_9.decode(message).intValue() * 0.05;
417         }
418     };
419 
420 }