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.SsrIgm05;
26  import org.orekit.gnss.metric.messages.ssr.igm.SsrIgm05Data;
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 SsrIgm05Test {
34  
35      private double eps = 1.0e-13;
36  
37      @Test
38      public void testPerfectValueBeidou() {
39  
40          final String m = "010000100100" +                     // RTCM Message number: 1060
41                           "001" +                              // IGS SSR version
42                           "01101001" +                         // IGS Message number: 105 (Beidou)
43                           "01111110011000111111" +             // Epoch Time 1s
44                           "0100" +                             // 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: 1
50                           "000001" +                           // Satellite ID
51                           "00010" +                            // No. of Biases Processed
52                           "00001" +                            // GNSS Signal and Tracking Mode Identifier
53                           "00111010111111"+                    // Code Bias
54                           "00010" +                            // GNSS Signal and Tracking Mode Identifier
55                           "001110101110100";                   // Code Bias
56  
57          final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
58          message.start();
59  
60          ArrayList<Integer> messages = new ArrayList<>();
61          messages.add(105);
62  
63          final SsrIgm05 igm05 = (SsrIgm05) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
64                                 parse(message, false);
65  
66          // Verify size
67          Assertions.assertEquals(1,                            igm05.getData().size());
68          Assertions.assertEquals(SatelliteSystem.BEIDOU,       igm05.getSatelliteSystem());
69  
70          // Verify header
71          Assertions.assertEquals(105,                          igm05.getTypeCode());
72          Assertions.assertEquals(517695.0,                     igm05.getHeader().getSsrEpoch1s(), eps);
73          Assertions.assertEquals(15.0,                         igm05.getHeader().getSsrUpdateInterval(), eps);
74          Assertions.assertEquals(0,                            igm05.getHeader().getSsrMultipleMessageIndicator());
75          Assertions.assertEquals(7,                            igm05.getHeader().getIodSsr());
76          Assertions.assertEquals(3951,                         igm05.getHeader().getSsrProviderId());
77          Assertions.assertEquals(1,                            igm05.getHeader().getSsrSolutionId());
78          Assertions.assertEquals(1,                            igm05.getHeader().getNumberOfSatellites());
79  
80          // Verify data for satellite C01
81          final SsrIgm05Data c01 = igm05.getSsrIgm05Data().get("C01").get(0);
82          Assertions.assertEquals(1,                          c01.getSatelliteID());
83          Assertions.assertEquals(2,                          c01.getNumberOfBiasesProcessed());
84          Assertions.assertEquals(2,                          c01.getCodeBiases().size());
85          Assertions.assertEquals(37.75,                      c01.getCodeBias(1).getCodeBias(), eps);
86          Assertions.assertEquals(1,                          c01.getCodeBias(1).getSignalID());
87          Assertions.assertEquals(37.70,                      c01.getCodeBias(2).getCodeBias(), eps);
88          Assertions.assertEquals(2,                          c01.getCodeBias(2).getSignalID());
89  
90      }
91  
92      @Test
93      public void testPerfectValueGalileo() {
94  
95          final String m = "010000100100" +                     // RTCM Message number: 1060
96                           "001" +                              // IGS SSR version
97                           "01000001" +                         // IGS Message number: 65 (Galileo)
98                           "01111110011000111111" +             // Epoch Time 1s
99                           "1011" +                             // SSR Update Interval
100                          "0" +                                // Multiple Message Indicator
101                          "0111" +                             // IOD SSR
102                          "0000111101101111" +                 // SSR Provider ID
103                          "0001" +                             // SSR Solution ID
104                          "000001" +                           // No. of Satellites: 1
105                          "001100" +                           // Satellite ID
106                          "00010" +                            // No. of Biases Processed
107                          "00001" +                            // GNSS Signal and Tracking Mode Identifier
108                          "00111010111111"+                    // Code Bias
109                          "00010" +                            // GNSS Signal and Tracking Mode Identifier
110                          "001110101110100";                   // Code Bias
111 
112         final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
113         message.start();
114 
115         ArrayList<Integer> messages = new ArrayList<>();
116         messages.add(65);
117 
118         final SsrIgm05 igm05 = (SsrIgm05) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
119                                parse(message, false);
120 
121         // Verify size
122         Assertions.assertEquals(1,                            igm05.getData().size());
123         Assertions.assertEquals(SatelliteSystem.GALILEO,      igm05.getSatelliteSystem());
124 
125         // Verify header
126         Assertions.assertEquals(65,                           igm05.getTypeCode());
127         Assertions.assertEquals(517695.0,                     igm05.getHeader().getSsrEpoch1s(), eps);
128         Assertions.assertEquals(900.0,                        igm05.getHeader().getSsrUpdateInterval(), eps);
129         Assertions.assertEquals(0,                            igm05.getHeader().getSsrMultipleMessageIndicator());
130         Assertions.assertEquals(7,                            igm05.getHeader().getIodSsr());
131         Assertions.assertEquals(3951,                         igm05.getHeader().getSsrProviderId());
132         Assertions.assertEquals(1,                            igm05.getHeader().getSsrSolutionId());
133         Assertions.assertEquals(1,                            igm05.getHeader().getNumberOfSatellites());
134 
135         // Verify data for satellite E12
136         final SsrIgm05Data e12 = igm05.getSsrIgm05Data().get("E12").get(0);
137         Assertions.assertEquals(12,                         e12.getSatelliteID());
138         Assertions.assertEquals(2,                          e12.getNumberOfBiasesProcessed());
139         Assertions.assertEquals(2,                          e12.getCodeBiases().size());
140         Assertions.assertEquals(37.75,                      e12.getCodeBias(1).getCodeBias(), eps);
141         Assertions.assertEquals(1,                          e12.getCodeBias(1).getSignalID());
142         Assertions.assertEquals(37.70,                      e12.getCodeBias(2).getCodeBias(), eps);
143         Assertions.assertEquals(2,                          e12.getCodeBias(2).getSignalID());
144 
145     }
146 
147     @Test
148     public void testNullMessage() {
149 
150         final String m = "010000100100" +                     // RTCM Message number: 1060
151                         "001" +                              // IGS SSR version
152                         "01101001" +                         // IGS Message number: 105 (Beidou)
153                         "01111110011000111111" +             // Epoch Time 1s
154                         "0101" +                             // SSR Update Interval
155                         "0" +                                // Multiple Message Indicator
156                         "0111" +                             // IOD SSR
157                         "0000111101101111" +                 // SSR Provider ID
158                         "0001" +                             // SSR Solution ID
159                         "000010" +                           // No. of Satellites: 1
160                         "000001" +                           // Satellite ID
161                         "00010" +                            // No. of Biases Processed
162                         "00001" +                            // GNSS Signal and Tracking Mode Identifier
163                         "00111010111111"+                    // Code Bias
164                         "00010" +                            // GNSS Signal and Tracking Mode Identifier
165                         "00111010111010";                    // Code Bias
166 
167 
168        final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
169        message.start();
170 
171        ArrayList<Integer> messages = new ArrayList<>();
172        messages.add(9999999);
173 
174        final SsrIgm05 igm05 = (SsrIgm05) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
175                               parse(message, false);
176 
177        Assertions.assertNull(igm05);
178     }
179 
180     @Test
181     public void testEmptyMessage() {
182         try {
183             final byte[] array = new byte[0];
184             final EncodedMessage emptyMessage = new ByteArrayEncodedMessage(array);
185             new IgsSsrMessagesParser(new ArrayList<>(), DataContext.getDefault().getTimeScales()).
186                 parse(emptyMessage, false);
187             Assertions.fail("an exception should have been thrown");
188         } catch (OrekitException oe) {
189             Assertions.assertEquals(OrekitMessages.END_OF_ENCODED_MESSAGE, oe.getSpecifier());
190         }
191 
192     }
193 
194     private byte[] byteArrayFromBinary(String radix2Value) {
195         final byte[] array = new byte[radix2Value.length() / 8];
196         for (int i = 0; i < array.length; ++i) {
197             for (int j = 0; j < 8; ++j) {
198                 if (radix2Value.charAt(8 * i + j) != '0') {
199                     array[i] |= 0x1 << (7 - j);
200                 }
201             }
202         }
203         return array;
204     }
205 
206 }