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 org.hipparchus.util.FastMath;
20  import org.junit.jupiter.api.Assertions;
21  import org.junit.jupiter.api.BeforeEach;
22  import org.junit.jupiter.api.Test;
23  import org.orekit.Utils;
24  import org.orekit.data.DataContext;
25  import org.orekit.gnss.SatelliteSystem;
26  import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1044;
27  import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1044Data;
28  import org.orekit.gnss.metric.parser.ByteArrayEncodedMessage;
29  import org.orekit.gnss.metric.parser.EncodedMessage;
30  import org.orekit.gnss.metric.parser.RtcmMessagesParser;
31  import org.orekit.propagation.analytical.gnss.GNSSPropagator;
32  import org.orekit.propagation.analytical.gnss.GNSSPropagatorBuilder;
33  import org.orekit.propagation.analytical.gnss.data.QZSSLegacyNavigationMessage;
34  import org.orekit.time.GNSSDate;
35  
36  import java.util.ArrayList;
37  
38  public class Rtcm1044Test {
39  
40      private final double eps = 9.0e-10;
41  
42      @BeforeEach
43      public void setUp() {
44          Utils.setDataRoot("gnss");
45      }
46  
47      @Test
48      public void testParseMessage() {
49  
50          final String m = "010000010100" +                     // Message number: 1044
51                          "1100" +                             // Satellite ID
52                          "0000111101101111" +                 // toc
53                          "01111111" +                         // af2
54                          "0000101011111101" +                 // af1
55                          "0100101011111101111111" +           // af0
56                          "10000100" +                         // IODE
57                          "0000000000000000" +                 // Crs
58                          "0111111011001111" +                 // DELTA n
59                          "00000110110011111011100110011011" + // M0
60                          "0000000000000000" +                 // Cuc
61                          "00010011111101111000111000011001" + // ecc
62                          "0000000000000000" +                 // Cus
63                          "10100001000011000111111111111111" + // A^(1/2)
64                          "1000100011100011" +                 // toe
65                          "0000000000000000" +                 // Cic
66                          "00011100011100000111111000111111" + // OMEGA0
67                          "0000000000000000" +                 // Cis
68                          "00101000001111100011110011110000" + // i0
69                          "0000000000000000" +                 // Crc
70                          "00001100001111100011110011110000" + // Argument of perigee
71                          "111111111011111111110100" +         // OMEGADOT
72                          "01011101111101" +                   // IDOT
73                          "10" +                               // QZSS CODE ON L2
74                          "0110111001" +                       // Week number
75                          "0001" +                             // SV Accuracy
76                          "000000" +                           // SV Health
77                          "00000011" +                         // tGD
78                          "1010110111" +                       // IODC
79                          "0" +                                // Fit Interval
80                          "000";                               // Reserved
81  
82  
83          final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
84          message.start();
85  
86          ArrayList<Integer> messages = new ArrayList<>();
87          messages.add(1044);
88  
89          final Rtcm1044              rtcm1044      = (Rtcm1044) new RtcmMessagesParser(messages, DataContext.getDefault().getTimeScales()).
90                                                      parse(message, false);
91          final Rtcm1044Data          ephemerisData = rtcm1044.getEphemerisData();
92          final QZSSLegacyNavigationMessage qzssMessage   = ephemerisData.getQzssNavigationMessage();
93  
94          // Verify propagator initialization
95          final GNSSPropagator propagator = new GNSSPropagatorBuilder(qzssMessage).build();
96          Assertions.assertNotNull(propagator);
97          Assertions.assertEquals(0.0, qzssMessage.getDate().
98                              durationFrom(new GNSSDate(qzssMessage.getWeek(), qzssMessage.getTime(), SatelliteSystem.QZSS).getDate()), eps);
99  
100         // Verify message number
101         Assertions.assertEquals(1044,                   rtcm1044.getTypeCode());
102         Assertions.assertEquals(1,                      rtcm1044.getData().size());
103 
104         // Verify navigation message
105         Assertions.assertEquals(204,                    qzssMessage.getPRN());
106         Assertions.assertEquals(441,                    qzssMessage.getWeek());
107         Assertions.assertEquals(2.1475894557210572E-9,  qzssMessage.getIDot(),               eps);
108         Assertions.assertEquals(132,                    qzssMessage.getIODE(),               eps);
109         Assertions.assertEquals(3.524958E-15,           qzssMessage.getAf2(),                eps);
110         Assertions.assertEquals(3.1980107E-10,          qzssMessage.getAf1(),                eps);
111         Assertions.assertEquals(5.721445195376873E-4,   qzssMessage.getAf0(),                eps);
112         Assertions.assertEquals(695,                    qzssMessage.getIODC());
113         Assertions.assertEquals(0.0,                    qzssMessage.getCrs(),                eps);
114         Assertions.assertEquals(1.4586338170358127E-4,  qzssMessage.getMeanMotion0(),        eps);
115         Assertions.assertEquals(1.4587496546628753E-4,  qzssMessage.getMeanMotion0() + qzssMessage.getDeltaN0(), eps);
116         Assertions.assertEquals(0.1671775426328288,     qzssMessage.getM0(),                 eps);
117         Assertions.assertEquals(0.0,                    qzssMessage.getCuc(),                eps);
118         Assertions.assertEquals(0.0389980711042881,     qzssMessage.getE(),                  eps);
119         Assertions.assertEquals(0.0,                    qzssMessage.getCus(),                eps);
120         Assertions.assertEquals(5153.562498092651,      FastMath.sqrt(qzssMessage.getSma()), eps);
121         Assertions.assertEquals(560688.0,               qzssMessage.getTime(),               eps);
122         Assertions.assertEquals(0.0,                    qzssMessage.getCic(),                eps);
123         Assertions.assertEquals(0.0,                    qzssMessage.getCis(),                eps);
124         Assertions.assertEquals(0.987714701321906,      qzssMessage.getI0(),                 eps);
125         Assertions.assertEquals(0.0,                    qzssMessage.getCrc(),                eps);
126         Assertions.assertEquals(0.30049130834913723,    qzssMessage.getPa(),                 eps);
127         Assertions.assertEquals(-5.855958209879004E-9,  qzssMessage.getOmegaDot(),           eps);
128         Assertions.assertEquals(0.6980085385373721,     qzssMessage.getOmega0(),             eps);
129         Assertions.assertEquals(1.3969839E-9,           qzssMessage.getTGD(),                eps);
130 
131         // Verify other data
132         Assertions.assertEquals(204,                    ephemerisData.getSatelliteID());
133         Assertions.assertEquals(63216.0,                ephemerisData.getQzssToc(), eps);
134         Assertions.assertEquals(2,                      ephemerisData.getQzssCodeOnL2());
135         Assertions.assertEquals(0,                      ephemerisData.getQzssFitInterval());
136         Assertions.assertEquals(ephemerisData.getAccuracyProvider().getAccuracy(), qzssMessage.getSvAccuracy(), eps);
137 
138     }
139 
140     @Test
141     public void testNullMessage() {
142 
143         final String m = "010000010100" +                     // Message number: 1044
144                         "1100" +                             // Satellite ID
145                         "0000111101101111" +                 // toc
146                         "01111111" +                         // af2
147                         "0000101011111101" +                 // af1
148                         "0100101011111101111111" +           // af0
149                         "10000100" +                         // IODE
150                         "0000000000000000" +                 // Crs
151                         "0111111011001111" +                 // DELTA n
152                         "00000110110011111011100110011011" + // M0
153                         "0000000000000000" +                 // Cuc
154                         "00010011111101111000111000011001" + // ecc
155                         "0000000000000000" +                 // Cus
156                         "10100001000011000111111111111111" + // A^(1/2)
157                         "1000100011100011" +                 // toe
158                         "0000000000000000" +                 // Cic
159                         "00011100011100000111111000111111" + // OMEGA0
160                         "0000000000000000" +                 // Cis
161                         "00101000001111100011110011110000" + // i0
162                         "0000000000000000" +                 // Crc
163                         "00001100001111100011110011110000" + // Argument of perigee
164                         "111111111011111111110100" +         // OMEGADOT
165                         "01011101111101" +                   // IDOT
166                         "10" +                               // QZSS CODE ON L2
167                         "0110111001" +                       // Week number
168                         "0001" +                             // SV Accuracy
169                         "000000" +                           // SV Health
170                         "00000011" +                         // tGD
171                         "1010110111" +                       // IODC
172                         "0" +                                // Fit Interval
173                         "000";                               // Reserved
174 
175        final EncodedMessage message = new ByteArrayEncodedMessage(byteArrayFromBinary(m));
176        message.start();
177 
178        ArrayList<Integer> messages = new ArrayList<>();
179        messages.add(9999999);
180 
181        final Rtcm1044 rtcm1044 = (Rtcm1044) new RtcmMessagesParser(messages, DataContext.getDefault().getTimeScales()).
182                                  parse(message, false);
183 
184        Assertions.assertNull(rtcm1044);
185     }
186 
187 
188     private byte[] byteArrayFromBinary(String radix2Value) {
189         final byte[] array = new byte[radix2Value.length() / 8];
190         for (int i = 0; i < array.length; ++i) {
191             for (int j = 0; j < 8; ++j) {
192                 if (radix2Value.charAt(8 * i + j) != '0') {
193                     array[i] |= 0x1 << (7 - j);
194                 }
195             }
196         }
197         return array;
198     }
199 
200 }