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.messages.ssr;
18  
19  import org.junit.jupiter.api.Assertions;
20  import org.junit.jupiter.api.Test;
21  import org.orekit.data.DataContext;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.errors.OrekitMessages;
24  import org.orekit.gnss.SatelliteSystem;
25  import org.orekit.gnss.metric.messages.ssr.igm.SsrIgm02;
26  import org.orekit.gnss.metric.messages.ssr.igm.SsrIgm02Data;
27  import org.orekit.gnss.metric.parser.ByteArrayEncodedMessage;
28  import org.orekit.gnss.metric.parser.EncodedMessage;
29  import org.orekit.gnss.metric.parser.IgsSsrMessagesParser;
30  
31  import java.util.ArrayList;
32  
33  public class SsrIgm02Test {
34  
35      private double eps = 1.0e-13;
36  
37      @Test
38      public void testPerfectValueGlonass() {
39  
40          final String m = "010000100100" +                     // RTCM Message number: 1060
41                           "001" +                              // IGS SSR version
42                           "00101010" +                         // IGS Message number: 42 (Glonass)
43                           "01111110011000111111" +             // Epoch Time 1s
44                           "0000" +                             // SSR Update Interval
45                           "0" +                                // Multiple Message Indicator
46                           "0111" +                             // IOD SSR
47                           "0000111101101111" +                 // SSR Provider ID
48                           "0001" +                             // SSR Solution ID
49                           "000001" +                           // No. of Satellites
50                           "001100" +                           // Satellite ID
51                           "0011101011111101111111" +           // Delta Clock C0
52                           "001110101111110111111" +            // Delta Clock C1
53                           "001110101111110111111100011000000"; // Delta Clock C2
54  
55          final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
56          message.start();
57  
58          ArrayList<Integer> messages = new ArrayList<>();
59          messages.add(42);
60  
61          final SsrIgm02 igm02 = (SsrIgm02) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
62                                 parse(message, false);
63  
64          // Verify size
65          Assertions.assertEquals(1,                            igm02.getData().size());
66          Assertions.assertEquals(SatelliteSystem.GLONASS,      igm02.getSatelliteSystem());
67  
68          // Verify header
69          Assertions.assertEquals(42,                           igm02.getTypeCode());
70          Assertions.assertEquals(517695.0,                     igm02.getHeader().getSsrEpoch1s(), eps);
71          Assertions.assertEquals(1.0,                          igm02.getHeader().getSsrUpdateInterval(), eps);
72          Assertions.assertEquals(0,                            igm02.getHeader().getSsrMultipleMessageIndicator());
73          Assertions.assertEquals(7,                            igm02.getHeader().getIodSsr());
74          Assertions.assertEquals(3951,                         igm02.getHeader().getSsrProviderId());
75          Assertions.assertEquals(1,                            igm02.getHeader().getSsrSolutionId());
76          Assertions.assertEquals(1,                            igm02.getHeader().getNumberOfSatellites());
77  
78          // Verify data for satellite G12
79          final SsrIgm02Data r12 = igm02.getSsrIgm02Data().get("R12").get(0);
80          Assertions.assertEquals(12,                           r12.getSatelliteID());
81          Assertions.assertEquals(96.6527,                      r12.getClockCorrection().getDeltaClockC0(), eps);
82          Assertions.assertEquals(0.483263,                     r12.getClockCorrection().getDeltaClockC1(), eps);
83          Assertions.assertEquals(0.61857734,                   r12.getClockCorrection().getDeltaClockC2(), eps);
84  
85      }
86  
87      @Test
88      public void testPerfectValueGalileo() {
89  
90          final String m = "010000100100" +                     // RTCM Message number: 1060
91                           "001" +                              // IGS SSR version
92                           "00111110" +                         // IGS Message number: 62 (Galileo)
93                           "01111110011000111111" +             // Epoch Time 1s
94                           "1000" +                             // SSR Update Interval
95                           "0" +                                // Multiple Message Indicator
96                           "0111" +                             // IOD SSR
97                           "0000111101101111" +                 // SSR Provider ID
98                           "0001" +                             // SSR Solution ID
99                           "000001" +                           // No. of Satellites
100                          "000001" +                           // Satellite ID
101                          "0011101011111101111111" +           // Delta Clock C0
102                          "001110101111110111111" +            // Delta Clock C1
103                          "001110101111110111111100011000000"; // Delta Clock C2
104 
105         final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
106         message.start();
107 
108         ArrayList<Integer> messages = new ArrayList<>();
109         messages.add(62);
110 
111         final SsrIgm02 igm02 = (SsrIgm02) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
112                                parse(message, false);
113 
114         // Verify size
115         Assertions.assertEquals(1,                            igm02.getData().size());
116         Assertions.assertEquals(SatelliteSystem.GALILEO,      igm02.getSatelliteSystem());
117 
118         // Verify header
119         Assertions.assertEquals(62,                           igm02.getTypeCode());
120         Assertions.assertEquals(517695.0,                     igm02.getHeader().getSsrEpoch1s(), eps);
121         Assertions.assertEquals(240.0,                        igm02.getHeader().getSsrUpdateInterval(), eps);
122         Assertions.assertEquals(0,                            igm02.getHeader().getSsrMultipleMessageIndicator());
123         Assertions.assertEquals(7,                            igm02.getHeader().getIodSsr());
124         Assertions.assertEquals(3951,                         igm02.getHeader().getSsrProviderId());
125         Assertions.assertEquals(1,                            igm02.getHeader().getSsrSolutionId());
126         Assertions.assertEquals(1,                            igm02.getHeader().getNumberOfSatellites());
127 
128         // Verify data for satellite E01
129         final SsrIgm02Data e01 = igm02.getSsrIgm02Data().get("E01").get(0);
130         Assertions.assertEquals(1,                            e01.getSatelliteID());
131         Assertions.assertEquals(96.6527,                      e01.getClockCorrection().getDeltaClockC0(), eps);
132         Assertions.assertEquals(0.483263,                     e01.getClockCorrection().getDeltaClockC1(), eps);
133         Assertions.assertEquals(0.61857734,                   e01.getClockCorrection().getDeltaClockC2(), eps);
134 
135     }
136 
137     @Test
138     public void testNullMessage() {
139 
140        final String m = "010000100100" +                     // RTCM Message number: 1060
141                         "001" +                              // IGS SSR version
142                         "00101010" +                         // IGS Message number: 42 (Glonass)
143                         "01111110011000111111" +             // Epoch Time 1s
144                         "0101" +                             // SSR Update Interval
145                         "0" +                                // Multiple Message Indicator
146                         "0111" +                             // IOD SSR
147                         "0000111101101111" +                 // SSR Provider ID
148                         "0001" +                             // SSR Solution ID
149                         "000001" +                           // No. of Satellites
150                         "001100" +                           // Satellite ID
151                         "0011101011111101111111" +           // Delta Clock C0
152                         "001110101111110111111" +            // Delta Clock C1
153                         "001110101111110111111100011000000"; // Delta Clock C2
154 
155        final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
156        message.start();
157 
158        ArrayList<Integer> messages = new ArrayList<>();
159        messages.add(9999999);
160 
161        final SsrIgm02 igm02 = (SsrIgm02) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
162                               parse(message, false);
163 
164        Assertions.assertNull(igm02);
165     }
166 
167     @Test
168     public void testEmptyMessage() {
169         try {
170             final byte[] array = new byte[0];
171             final EncodedMessage emptyMessage = new ByteArrayEncodedMessage(array);
172             new IgsSsrMessagesParser(new ArrayList<>(), DataContext.getDefault().getTimeScales()).
173                 parse(emptyMessage, false);
174             Assertions.fail("an exception should have been thrown");
175         } catch (OrekitException oe) {
176             Assertions.assertEquals(OrekitMessages.END_OF_ENCODED_MESSAGE, oe.getSpecifier());
177         }
178 
179     }
180 
181     private byte[] byteArrayFromBinary(String radix2Value) {
182         final byte[] array = new byte[radix2Value.length() / 8];
183         for (int i = 0; i < array.length; ++i) {
184             for (int j = 0; j < 8; ++j) {
185                 if (radix2Value.charAt(8 * i + j) != '0') {
186                     array[i] |= 0x1 << (7 - j);
187                 }
188             }
189         }
190         return array;
191     }
192 
193 }