1   /* Copyright 2002-2022 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 java.util.ArrayList;
20  
21  import org.junit.Assert;
22  import org.junit.Test;
23  import org.orekit.errors.OrekitException;
24  import org.orekit.errors.OrekitMessages;
25  import org.orekit.gnss.metric.messages.ssr.subtype.SsrIm201;
26  import org.orekit.gnss.metric.messages.ssr.subtype.SsrIm201Data;
27  import org.orekit.gnss.metric.parser.ByteArrayEncodedMessages;
28  import org.orekit.gnss.metric.parser.EncodedMessage;
29  import org.orekit.gnss.metric.parser.IgsSsrMessagesParser;
30  
31  public class SsrIm201Test {
32  
33      private double eps = 1.0e-13;
34  
35      @Test
36      public void testPerfectValue() {
37  
38          final String m = "010000100100" +                     // RTCM Message number: 1060
39                           "001" +                              // IGS SSR version
40                           "11001001" +                         // IGS Message number: 201 (VTEC)
41                           "01111110011000111111" +             // Epoch Time 1s
42                           "0101" +                             // SSR Update Interval
43                           "0" +                                // Multiple Message Indicator
44                           "0111" +                             // IOD SSR
45                           "0000111101101111" +                 // SSR Provider ID
46                           "0001" +                             // SSR Solution ID
47                           "000000001" +                        // VTEC Quality Indicator
48                           "00" +                               // Number of Ionospheric Layers: 1
49                           "01000001" +                         // Height of ionospheric layer
50                           "0010" +                             // Spherical Harmonics Degree
51                           "0001" +                             // Spherical Harmonics Order
52                           "0100101000101101"+                  // C00
53                           "0101011001101101"+                  // C10
54                           "0110101010001100"+                  // C20
55                           "0100001100101111"+                  // C30
56                           "0100101011101101"+                  // C11
57                           "0100101000111110"+                  // C21
58                           "0010100110101101"+                  // C31
59                           "0000111101101101"+                  // C22
60                           "0111101000101100"+                  // C32
61                           "0111101110101101"+                  // S11
62                           "0000101000101100"+                  // S21
63                           "0110101000101001"+                  // S31
64                           "0110101000100100"+                  // S22
65                           "001100100010110100000";             // S32
66  
67          final EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
68          message.start();
69  
70          ArrayList<Integer> messages = new ArrayList<>();
71          messages.add(201);
72  
73          final SsrIm201 im201 = (SsrIm201) new IgsSsrMessagesParser(messages).parse(message, false);
74  
75          // Ionospheric model
76          Assert.assertNotNull(im201.getIonosphericModel());
77  
78          // Verify size
79          Assert.assertEquals(1,                            im201.getData().size());
80  
81          // Verify header
82          Assert.assertEquals(201,                          im201.getTypeCode());
83          Assert.assertEquals(517695.0,                     im201.getHeader().getSsrEpoch1s(), eps);
84          Assert.assertEquals(30.0,                         im201.getHeader().getSsrUpdateInterval(), eps);
85          Assert.assertEquals(0,                            im201.getHeader().getSsrMultipleMessageIndicator());
86          Assert.assertEquals(7,                            im201.getHeader().getIodSsr());
87          Assert.assertEquals(3951,                         im201.getHeader().getSsrProviderId());
88          Assert.assertEquals(1,                            im201.getHeader().getSsrSolutionId());
89          Assert.assertEquals(0.05,                         im201.getHeader().getVtecQualityIndicator(), eps);
90          Assert.assertEquals(1,                            im201.getHeader().getNumberOfIonosphericLayers());
91  
92          // Verify data
93          final SsrIm201Data data = im201.getData().get(0);
94          final double[][] cnm = data.getCnm();
95          final double[][] snm = data.getSnm();
96          Assert.assertEquals(650000,            data.getHeightIonosphericLayer(), eps);
97          Assert.assertEquals(3,                 data.getSphericalHarmonicsDegree());
98          Assert.assertEquals(2,                 data.getSphericalHarmonicsOrder());
99          Assert.assertEquals(94.945,            cnm[0][0], eps);
100         Assert.assertEquals(110.625,           cnm[1][0], eps);
101         Assert.assertEquals(136.380,           cnm[2][0], eps);
102         Assert.assertEquals(85.995,            cnm[3][0], eps);
103         Assert.assertEquals(0.0,               cnm[0][1], eps);
104         Assert.assertEquals(95.905,            cnm[1][1], eps);
105         Assert.assertEquals(95.030,            cnm[2][1], eps);
106         Assert.assertEquals(53.345,            cnm[3][1], eps);
107         Assert.assertEquals(0.0,               cnm[0][2], eps);
108         Assert.assertEquals(0.0,               cnm[1][2], eps);
109         Assert.assertEquals(19.745,            cnm[2][2], eps);
110         Assert.assertEquals(156.380,           cnm[3][2], eps);
111         Assert.assertEquals(0.0,               snm[0][0], eps);
112         Assert.assertEquals(0.0,               snm[1][0], eps);
113         Assert.assertEquals(0.0,               snm[2][0], eps);
114         Assert.assertEquals(0.0,               snm[3][0], eps);
115         Assert.assertEquals(0.0,               snm[0][1], eps);
116         Assert.assertEquals(158.305,           snm[1][1], eps);
117         Assert.assertEquals(13.020,            snm[2][1], eps);
118         Assert.assertEquals(135.885,           snm[3][1], eps);
119         Assert.assertEquals(0.0,               snm[0][2], eps);
120         Assert.assertEquals(0.0,               snm[1][2], eps);
121         Assert.assertEquals(135.860,           snm[2][2], eps);
122         Assert.assertEquals(64.225,            snm[3][2], eps);
123 
124     }
125 
126     @Test
127     public void testPerfectValue2() {
128 
129         final String m = "010000100100" +                     // RTCM Message number: 1060
130                          "001" +                              // IGS SSR version
131                          "11001001" +                         // IGS Message number: 201 (VTEC)
132                          "01111110011000111111" +             // Epoch Time 1s
133                          "1110" +                             // SSR Update Interval
134                          "0" +                                // Multiple Message Indicator
135                          "0111" +                             // IOD SSR
136                          "0000111101101111" +                 // SSR Provider ID
137                          "0001" +                             // SSR Solution ID
138                          "000000001" +                        // VTEC Quality Indicator
139                          "00" +                               // Number of Ionospheric Layers: 1
140                          "01000001" +                         // Height of ionospheric layer
141                          "0010" +                             // Spherical Harmonics Degree
142                          "0001" +                             // Spherical Harmonics Order
143                          "0100101000101101"+                  // C00
144                          "0101011001101101"+                  // C10
145                          "0110101010001100"+                  // C20
146                          "0100001100101111"+                  // C30
147                          "0100101011101101"+                  // C11
148                          "0100101000111110"+                  // C21
149                          "0010100110101101"+                  // C31
150                          "0000111101101101"+                  // C22
151                          "0111101000101100"+                  // C32
152                          "0111101110101101"+                  // S11
153                          "0000101000101100"+                  // S21
154                          "0110101000101001"+                  // S31
155                          "0110101000100100"+                  // S22
156                          "001100100010110100000";             // S32
157 
158         final EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
159         message.start();
160 
161         ArrayList<Integer> messages = new ArrayList<>();
162         messages.add(201);
163 
164         final SsrIm201 im201 = (SsrIm201) new IgsSsrMessagesParser(messages).parse(message, false);
165 
166         // Verify size
167         Assert.assertEquals(1,                            im201.getData().size());
168 
169         // Verify header
170         Assert.assertEquals(201,                          im201.getTypeCode());
171         Assert.assertEquals(517695.0,                     im201.getHeader().getSsrEpoch1s(), eps);
172         Assert.assertEquals(7200.0,                       im201.getHeader().getSsrUpdateInterval(), eps);
173         Assert.assertEquals(0,                            im201.getHeader().getSsrMultipleMessageIndicator());
174         Assert.assertEquals(7,                            im201.getHeader().getIodSsr());
175         Assert.assertEquals(3951,                         im201.getHeader().getSsrProviderId());
176         Assert.assertEquals(1,                            im201.getHeader().getSsrSolutionId());
177         Assert.assertEquals(0.05,                         im201.getHeader().getVtecQualityIndicator(), eps);
178         Assert.assertEquals(1,                            im201.getHeader().getNumberOfIonosphericLayers());
179 
180         // Verify data
181         final SsrIm201Data data = im201.getData().get(0);
182         final double[][] cnm = data.getCnm();
183         final double[][] snm = data.getSnm();
184         Assert.assertEquals(650000,            data.getHeightIonosphericLayer(), eps);
185         Assert.assertEquals(3,                 data.getSphericalHarmonicsDegree());
186         Assert.assertEquals(2,                 data.getSphericalHarmonicsOrder());
187         Assert.assertEquals(94.945,            cnm[0][0], eps);
188         Assert.assertEquals(110.625,           cnm[1][0], eps);
189         Assert.assertEquals(136.380,           cnm[2][0], eps);
190         Assert.assertEquals(85.995,            cnm[3][0], eps);
191         Assert.assertEquals(0.0,               cnm[0][1], eps);
192         Assert.assertEquals(95.905,            cnm[1][1], eps);
193         Assert.assertEquals(95.030,            cnm[2][1], eps);
194         Assert.assertEquals(53.345,            cnm[3][1], eps);
195         Assert.assertEquals(0.0,               cnm[0][2], eps);
196         Assert.assertEquals(0.0,               cnm[1][2], eps);
197         Assert.assertEquals(19.745,            cnm[2][2], eps);
198         Assert.assertEquals(156.380,           cnm[3][2], eps);
199         Assert.assertEquals(0.0,               snm[0][0], eps);
200         Assert.assertEquals(0.0,               snm[1][0], eps);
201         Assert.assertEquals(0.0,               snm[2][0], eps);
202         Assert.assertEquals(0.0,               snm[3][0], eps);
203         Assert.assertEquals(0.0,               snm[0][1], eps);
204         Assert.assertEquals(158.305,           snm[1][1], eps);
205         Assert.assertEquals(13.020,            snm[2][1], eps);
206         Assert.assertEquals(135.885,           snm[3][1], eps);
207         Assert.assertEquals(0.0,               snm[0][2], eps);
208         Assert.assertEquals(0.0,               snm[1][2], eps);
209         Assert.assertEquals(135.860,           snm[2][2], eps);
210         Assert.assertEquals(64.225,            snm[3][2], eps);
211 
212     }
213 
214     @Test
215     public void testNullMessage() {
216 
217         final String m = "010000100100" +                     // RTCM Message number: 1060
218                         "001" +                              // IGS SSR version
219                         "11001001" +                         // IGS Message number: 201 (VTEC)
220                         "01111110011000111111" +             // Epoch Time 1s
221                         "0101" +                             // SSR Update Interval
222                         "0" +                                // Multiple Message Indicator
223                         "0111" +                             // IOD SSR
224                         "0000111101101111" +                 // SSR Provider ID
225                         "0001" +                             // SSR Solution ID
226                         "000000001" +                        // VTEC Quality Indicator
227                         "00" +                               // Number of Ionospheric Layers: 1
228                         "01000001" +                         // Height of ionospheric layer
229                         "0010" +                             // Spherical Harmonics Degree
230                         "0001" +                             // Spherical Harmonics Order
231                         "0100101000101101"+                  // C00
232                         "0101011001101101"+                  // C10
233                         "0110101010001100"+                  // C20
234                         "0100001100101111"+                  // C30
235                         "0100101011101101"+                  // C11
236                         "0100101000111110"+                  // C21
237                         "0010100110101101"+                  // C31
238                         "0000111101101101"+                  // C22
239                         "0111101000101100"+                  // C32
240                         "0111101110101101"+                  // S11
241                         "0000101000101100"+                  // S21
242                         "0110101000101001"+                  // S31
243                         "0110101000100100"+                  // S22
244                         "001100100010110100000";             // S32
245 
246 
247        final EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
248        message.start();
249 
250        ArrayList<Integer> messages = new ArrayList<>();
251        messages.add(9999999);
252 
253        final SsrIm201 im201 = (SsrIm201) new IgsSsrMessagesParser(messages).parse(message, false);
254 
255        Assert.assertNull(im201);
256     }
257 
258     @Test
259     public void testEmptyMessage() {
260         try {
261             final byte[] array = new byte[0];
262             final EncodedMessage emptyMessage = new ByteArrayEncodedMessages(array);
263             new IgsSsrMessagesParser(new ArrayList<Integer>()).parse(emptyMessage, false);
264             Assert.fail("an exception should have been thrown");
265         } catch (OrekitException oe) {
266             Assert.assertEquals(OrekitMessages.END_OF_ENCODED_MESSAGE, oe.getSpecifier());
267         }
268 
269     }
270 
271     private byte[] byteArrayFromBinary(String radix2Value) {
272         final byte[] array = new byte[radix2Value.length() / 8];
273         for (int i = 0; i < array.length; ++i) {
274             for (int j = 0; j < 8; ++j) {
275                 if (radix2Value.charAt(8 * i + j) != '0') {
276                     array[i] |= 0x1 << (7 - j);
277                 }
278             }
279         }
280         return array;
281     }
282 
283 }