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.SsrIgm03;
26  import org.orekit.gnss.metric.messages.ssr.igm.SsrIgm03Data;
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 SsrIgm03Test {
34  
35      private double eps = 1.0e-13;
36  
37      @Test
38      public void testPerfectValueGalileo() {
39  
40          final String m = "010000100100" +                     // RTCM Message number: 1060
41                           "001" +                              // IGS SSR version
42                           "00111111" +                         // IGS Message number: 63 (Galileo)
43                           "01111110011000111111" +             // Epoch Time 1s
44                           "0001" +                             // SSR Update Interval
45                           "0" +                                // Multiple Message Indicator
46                           "0111" +                             // IOD SSR
47                           "0000111101101111" +                 // SSR Provider ID
48                           "0001" +                             // SSR Solution ID
49                           "0" +                                // Global/Regional CRS Indicator
50                           "000001" +                           // No. of Satellites
51                           "001100" +                           // Satellite ID
52                           "10000100" +                         // GNSS IOD
53                           "0000101011111101111111" +           // Delta Radial
54                           "01001010111111011111" +             // Delta Along-Track
55                           "01001010111111011111" +             // Delta Cross-Track
56                           "000010101111110111111" +            // Dot Delta Radial
57                           "0100101011111101111" +              // Dot Delta Along-Track
58                           "0100101011111101111" +              // Dot Delta Cross-Track
59                           "0011101011111101111111" +           // Delta Clock C0
60                           "001110101111110111111" +            // Delta Clock C1
61                           "0011101011111101111111000110000";   // Delta Clock C2
62  
63          final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
64          message.start();
65  
66          ArrayList<Integer> messages = new ArrayList<>();
67          messages.add(63);
68  
69          final SsrIgm03 igm03 = (SsrIgm03) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
70                                 parse(message, false);
71  
72          // Verify size
73          Assertions.assertEquals(1,                            igm03.getData().size());
74          Assertions.assertEquals(SatelliteSystem.GALILEO,      igm03.getSatelliteSystem());
75  
76          // Verify header
77          Assertions.assertEquals(63,                           igm03.getTypeCode());
78          Assertions.assertEquals(517695.0,                     igm03.getHeader().getSsrEpoch1s(), eps);
79          Assertions.assertEquals(2.0,                          igm03.getHeader().getSsrUpdateInterval(), eps);
80          Assertions.assertEquals(0,                            igm03.getHeader().getSsrMultipleMessageIndicator());
81          Assertions.assertEquals(7,                            igm03.getHeader().getIodSsr());
82          Assertions.assertEquals(3951,                         igm03.getHeader().getSsrProviderId());
83          Assertions.assertEquals(1,                            igm03.getHeader().getSsrSolutionId());
84          Assertions.assertEquals(0,                            igm03.getHeader().getCrsIndicator());
85          Assertions.assertEquals(1,                            igm03.getHeader().getNumberOfSatellites());
86  
87          // Verify data for satellite E12
88          final SsrIgm03Data e12 = igm03.getSsrIgm03Data().get("E12").get(0);
89          Assertions.assertEquals(12,                           e12.getSatelliteID());
90          Assertions.assertEquals(132,                          e12.getGnssIod());
91          Assertions.assertEquals(18.0095,                      e12.getOrbitCorrection().getDeltaOrbitRadial(),        eps);
92          Assertions.assertEquals(122.8668,                     e12.getOrbitCorrection().getDeltaOrbitAlongTrack(),    eps);
93          Assertions.assertEquals(122.8668,                     e12.getOrbitCorrection().getDeltaOrbitCrossTrack(),    eps);
94          Assertions.assertEquals(0.090047,                     e12.getOrbitCorrection().getDotOrbitDeltaRadial(),     eps);
95          Assertions.assertEquals(0.614332,                     e12.getOrbitCorrection().getDotOrbitDeltaAlongTrack(), eps);
96          Assertions.assertEquals(0.614332,                     e12.getOrbitCorrection().getDotOrbitDeltaCrossTrack(), eps);
97          Assertions.assertEquals(96.6527,                      e12.getClockCorrection().getDeltaClockC0(),            eps);
98          Assertions.assertEquals(0.483263,                     e12.getClockCorrection().getDeltaClockC1(),            eps);
99          Assertions.assertEquals(0.61857734,                   e12.getClockCorrection().getDeltaClockC2(),            eps);
100 
101     }
102 
103     @Test
104     public void testPerfectValueGPS() {
105 
106         final String m = "010000100100" +                     // RTCM Message number: 1060
107                          "001" +                              // IGS SSR version
108                          "00010111" +                         // IGS Message number: 23 (GPS)
109                          "01111110011000111111" +             // Epoch Time 1s
110                          "1001" +                             // SSR Update Interval
111                          "0" +                                // Multiple Message Indicator
112                          "0111" +                             // IOD SSR
113                          "0000111101101111" +                 // SSR Provider ID
114                          "0001" +                             // SSR Solution ID
115                          "0" +                                // Global/Regional CRS Indicator
116                          "000001" +                           // No. of Satellites
117                          "000001" +                           // Satellite ID
118                          "10000100" +                         // GNSS IOD
119                          "0000101011111101111111" +           // Delta Radial
120                          "01001010111111011111" +             // Delta Along-Track
121                          "01001010111111011111" +             // Delta Cross-Track
122                          "000010101111110111111" +            // Dot Delta Radial
123                          "0100101011111101111" +              // Dot Delta Along-Track
124                          "0100101011111101111" +              // Dot Delta Cross-Track
125                          "0011101011111101111111" +           // Delta Clock C0
126                          "001110101111110111111" +            // Delta Clock C1
127                          "0011101011111101111111000110000";   // Delta Clock C2
128 
129         final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
130         message.start();
131 
132         ArrayList<Integer> messages = new ArrayList<>();
133         messages.add(23);
134 
135         final SsrIgm03 igm03 = (SsrIgm03) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
136                                parse(message, false);
137 
138         // Verify size
139         Assertions.assertEquals(1,                            igm03.getData().size());
140         Assertions.assertEquals(SatelliteSystem.GPS,          igm03.getSatelliteSystem());
141 
142         // Verify header
143         Assertions.assertEquals(23,                           igm03.getTypeCode());
144         Assertions.assertEquals(517695.0,                     igm03.getHeader().getSsrEpoch1s(), eps);
145         Assertions.assertEquals(300.0,                        igm03.getHeader().getSsrUpdateInterval(), eps);
146         Assertions.assertEquals(0,                            igm03.getHeader().getSsrMultipleMessageIndicator());
147         Assertions.assertEquals(7,                            igm03.getHeader().getIodSsr());
148         Assertions.assertEquals(3951,                         igm03.getHeader().getSsrProviderId());
149         Assertions.assertEquals(1,                            igm03.getHeader().getSsrSolutionId());
150         Assertions.assertEquals(0,                            igm03.getHeader().getCrsIndicator());
151         Assertions.assertEquals(1,                            igm03.getHeader().getNumberOfSatellites());
152 
153         // Verify data for satellite G01
154         final SsrIgm03Data g01 = igm03.getSsrIgm03Data().get("G01").get(0);
155         Assertions.assertEquals(1,                            g01.getSatelliteID());
156         Assertions.assertEquals(132,                          g01.getGnssIod());
157         Assertions.assertEquals(18.0095,                      g01.getOrbitCorrection().getDeltaOrbitRadial(),         eps);
158         Assertions.assertEquals(122.8668,                     g01.getOrbitCorrection().getDeltaOrbitAlongTrack(),    eps);
159         Assertions.assertEquals(122.8668,                     g01.getOrbitCorrection().getDeltaOrbitCrossTrack(),    eps);
160         Assertions.assertEquals(0.090047,                     g01.getOrbitCorrection().getDotOrbitDeltaRadial(),     eps);
161         Assertions.assertEquals(0.614332,                     g01.getOrbitCorrection().getDotOrbitDeltaAlongTrack(), eps);
162         Assertions.assertEquals(0.614332,                     g01.getOrbitCorrection().getDotOrbitDeltaCrossTrack(), eps);
163         Assertions.assertEquals(96.6527,                      g01.getClockCorrection().getDeltaClockC0(),            eps);
164         Assertions.assertEquals(0.483263,                     g01.getClockCorrection().getDeltaClockC1(),            eps);
165         Assertions.assertEquals(0.61857734,                   g01.getClockCorrection().getDeltaClockC2(),            eps);
166 
167     }
168 
169     @Test
170     public void testNullMessage() {
171 
172         final String m = "010000100100" +                     // RTCM Message number: 1060
173                         "001" +                              // IGS SSR version
174                         "00111111" +                         // IGS Message number: 63 (Galileo)
175                         "01111110011000111111" +             // Epoch Time 1s
176                         "0101" +                             // SSR Update Interval
177                         "0" +                                // Multiple Message Indicator
178                         "0111" +                             // IOD SSR
179                         "0000111101101111" +                 // SSR Provider ID
180                         "0001" +                             // SSR Solution ID
181                         "0" +                                // Global/Regional CRS Indicator
182                         "000001" +                           // No. of Satellites
183                         "001100" +                           // Satellite ID
184                         "10000100" +                         // GNSS IOD
185                         "0000101011111101111111" +           // Delta Radial
186                         "01001010111111011111" +             // Delta Along-Track
187                         "01001010111111011111" +             // Delta Cross-Track
188                         "000010101111110111111" +            // Dot Delta Radial
189                         "0100101011111101111" +              // Dot Delta Along-Track
190                         "0100101011111101111" +              // Dot Delta Cross-Track
191                         "0011101011111101111111" +           // Delta Clock C0
192                         "001110101111110111111" +            // Delta Clock C1
193                         "0011101011111101111111000110000";   // Delta Clock C2
194 
195        final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
196        message.start();
197 
198        ArrayList<Integer> messages = new ArrayList<>();
199        messages.add(9999999);
200 
201        final SsrIgm03 igm03 = (SsrIgm03) new IgsSsrMessagesParser(messages, DataContext.getDefault().getTimeScales()).
202                               parse(message, false);
203 
204        Assertions.assertNull(igm03);
205     }
206 
207     @Test
208     public void testEmptyMessage() {
209         try {
210             final byte[] array = new byte[0];
211             final EncodedMessage emptyMessage = new ByteArrayEncodedMessage(array);
212             new IgsSsrMessagesParser(new ArrayList<>(), DataContext.getDefault().getTimeScales()).
213                 parse(emptyMessage, false);
214             Assertions.fail("an exception should have been thrown");
215         } catch (OrekitException oe) {
216             Assertions.assertEquals(OrekitMessages.END_OF_ENCODED_MESSAGE, oe.getSpecifier());
217         }
218 
219     }
220 
221     private byte[] byteArrayFromBinary(String radix2Value) {
222         final byte[] array = new byte[radix2Value.length() / 8];
223         for (int i = 0; i < array.length; ++i) {
224             for (int j = 0; j < 8; ++j) {
225                 if (radix2Value.charAt(8 * i + j) != '0') {
226                     array[i] |= 0x1 << (7 - j);
227                 }
228             }
229         }
230         return array;
231     }
232 
233 }