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.rtcm;
18  
19  import java.util.ArrayList;
20  
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.BeforeEach;
23  import org.junit.jupiter.api.Test;
24  import org.orekit.data.DataContext;
25  import org.orekit.errors.OrekitException;
26  import org.orekit.errors.OrekitMessages;
27  import org.orekit.gnss.metric.messages.rtcm.correction.Rtcm1060;
28  import org.orekit.gnss.metric.messages.rtcm.correction.RtcmCombinedCorrectionData;
29  import org.orekit.gnss.metric.parser.ByteArrayEncodedMessage;
30  import org.orekit.gnss.metric.parser.EncodedMessage;
31  import org.orekit.gnss.metric.parser.RtcmMessagesParser;
32  
33  public class Rtcm1060Test {
34  
35      private double eps = 1.0e-13;
36  
37      private EncodedMessage message;
38  
39      private ArrayList<Integer> messages;
40  
41      @BeforeEach
42      public void setUp() {
43  
44          final String m = "010000100100" +                      // Message number: 1060
45                           "01111110011000111111" +              // GPS Epoch Time 1s
46                           "0101" +                              // SSR Update Interval
47                           "0" +                                 // Multiple Message Indicator
48                           "0" +                                 // Satellite Reference Datum
49                           "0111" +                              // IOD SSR
50                           "0000111101101111" +                  // SSR Provider ID
51                           "0001" +                              // SSR Solution ID
52                           "000001" +                            // No. of Satellites
53                           "000001" +                            // Satellite ID
54                           "10000100" +                          // IODE
55                           "0000101011111101111111" +            // Delta Radial
56                           "01001010111111011111" +              // Delta Along-Track
57                           "01001010111111011111" +              // Delta Cross-Track
58                           "000010101111110111111" +             // Dot Delta Radial
59                           "0100101011111101111" +               // Dot Delta Along-Track
60                           "0100101011111101111" +               // Dot Delta Cross-Track
61                           "0011101011111101111111" +            // Delta Clock C0
62                           "001110101111110111111" +             // Delta Clock C1
63                           "0011101011111101111111000110000000"; // Delta Clock C2
64  
65          message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
66          message.start();
67  
68          messages = new ArrayList<>();
69          messages.add(1060);
70  
71      }
72  
73      @Test
74      public void testPerfectValue() {
75          final Rtcm1060 rtcm1060 = (Rtcm1060) new RtcmMessagesParser(messages, DataContext.getDefault().getTimeScales()).
76                                    parse(message, false);
77  
78          // Verify size
79          Assertions.assertEquals(1,                            rtcm1060.getData().size());
80  
81          // Verify header
82          Assertions.assertEquals(1060,                         rtcm1060.getTypeCode());
83          Assertions.assertEquals(517695.0,                     rtcm1060.getHeader().getEpochTime1s(), eps);
84          Assertions.assertEquals(30.0,                         rtcm1060.getHeader().getSsrUpdateInterval().getUpdateInterval(), eps);
85          Assertions.assertEquals(0,                            rtcm1060.getHeader().getMultipleMessageIndicator());
86          Assertions.assertEquals(7,                            rtcm1060.getHeader().getIodSsr());
87          Assertions.assertEquals(3951,                         rtcm1060.getHeader().getSsrProviderId());
88          Assertions.assertEquals(1,                            rtcm1060.getHeader().getSsrSolutionId());
89          Assertions.assertEquals(1,                            rtcm1060.getHeader().getNumberOfSatellites());
90  
91          // Verify data for satellite G01
92          final RtcmCombinedCorrectionData g01 = rtcm1060.getDataMap().get("G01").get(0);
93          Assertions.assertEquals(1,                            g01.getSatelliteID());
94          Assertions.assertEquals(132,                          g01.getGnssIod());
95          Assertions.assertEquals(18.0095,                      g01.getOrbitCorrection().getDeltaOrbitRadial(),        eps);
96          Assertions.assertEquals(122.8668,                     g01.getOrbitCorrection().getDeltaOrbitAlongTrack(),    eps);
97          Assertions.assertEquals(122.8668,                     g01.getOrbitCorrection().getDeltaOrbitCrossTrack(),    eps);
98          Assertions.assertEquals(0.090047,                     g01.getOrbitCorrection().getDotOrbitDeltaRadial(),     eps);
99          Assertions.assertEquals(0.614332,                     g01.getOrbitCorrection().getDotOrbitDeltaAlongTrack(), eps);
100         Assertions.assertEquals(0.614332,                     g01.getOrbitCorrection().getDotOrbitDeltaCrossTrack(), eps);
101         Assertions.assertEquals(96.6527,                      g01.getClockCorrection().getDeltaClockC0(),            eps);
102         Assertions.assertEquals(0.483263,                     g01.getClockCorrection().getDeltaClockC1(),            eps);
103         Assertions.assertEquals(0.61857734,                   g01.getClockCorrection().getDeltaClockC2(),            eps);
104     }
105 
106     @Test
107     public void testEmptyMessage() {
108         try {
109             final byte[] array = new byte[0];
110             final EncodedMessage emptyMessage = new ByteArrayEncodedMessage(array);
111 
112             new RtcmMessagesParser(messages, DataContext.getDefault().getTimeScales()).parse(emptyMessage, false);
113 
114             Assertions.fail("an exception should have been thrown");
115         } catch (OrekitException oe) {
116             Assertions.assertEquals(OrekitMessages.END_OF_ENCODED_MESSAGE, oe.getSpecifier());
117         }
118 
119     }
120 
121     private byte[] byteArrayFromBinary(String radix2Value) {
122         final byte[] array = new byte[radix2Value.length() / 8];
123         for (int i = 0; i < array.length; ++i) {
124             for (int j = 0; j < 8; ++j) {
125                 if (radix2Value.charAt(8 * i + j) != '0') {
126                     array[i] |= 0x1 << (7 - j);
127                 }
128             }
129         }
130         return array;
131     }
132 
133 }