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.rtcm;
18
19 import java.util.ArrayList;
20
21 import org.hipparchus.ode.nonstiff.ClassicalRungeKuttaIntegrator;
22 import org.junit.Assert;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.orekit.Utils;
26 import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1020;
27 import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1020Data;
28 import org.orekit.gnss.metric.parser.ByteArrayEncodedMessages;
29 import org.orekit.gnss.metric.parser.EncodedMessage;
30 import org.orekit.gnss.metric.parser.RtcmDataField;
31 import org.orekit.gnss.metric.parser.RtcmMessagesParser;
32 import org.orekit.propagation.analytical.gnss.data.GLONASSNavigationMessage;
33 import org.orekit.propagation.numerical.GLONASSNumericalPropagator;
34 import org.orekit.propagation.numerical.GLONASSNumericalPropagatorBuilder;
35 import org.orekit.time.GLONASSDate;
36
37 public class Rtcm1020Test {
38
39 private double eps = 1.0e-16;
40
41 @Before
42 public void setUp() {
43 Utils.setDataRoot("gnss");
44 }
45
46 @Test
47 public void testParseMessage() {
48
49 final String m = "001111111100" + // Message number: 1020
50 "001100" + // Satellite ID
51 "10001" + // Channel number
52 "1" + // Cn word
53 "0" + // Health availability indicator
54 "01" + // Word P1
55 "001100011011" + // tk
56 "0" + // Bn word
57 "1" + // P2 flag
58 "0011101" + // tb
59 "000000111110000011111010" + // xn first derivative
60 "000011111110000011111010010" + // xn
61 "01101" + // xn second derivative
62 "100000111110000011111010" + // yn first derivative
63 "100011111110000011111010010" + // yn
64 "11101" + // yn second derivative
65 "110000111110000011111010" + // zn first derivative
66 "101011111110000011111010010" + // zn
67 "01101" + // zn second derivative
68 "0" + // P3 flag
69 "00111100101" + // GLONASS γn (tb)
70 "11" + // Time Operation Mode
71 "0" + // ln (third string)
72 "0011101011001110101011" + // τn (tb)
73 "01110" + // Δτn
74 "01110" + // En
75 "1" + // P4 Flag
76 "1110" + // Ft
77 "10011011010" + // Nt
78 "01" + // GLONASS-M Flag
79 "1" + // Availability of additional data
80 "10011011010" + // NA
81 "00001100001111100011110011110000" + // τc
82 "00111" + // N4
83 "0011011100111101010111" + // τGPS
84 "0" + // ln (fifth string)
85 "0000000"; // Reserved
86
87 final EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
88 message.start();
89
90 ArrayList<Integer> messages = new ArrayList<>();
91 messages.add(1020);
92
93 final Rtcm1020 rtcm1020 = (Rtcm1020) new RtcmMessagesParser(messages).parse(message, false);
94 final Rtcm1020Data ephemerisData = rtcm1020.getEphemerisData();
95 final GLONASSNavigationMessage glonassMessage = ephemerisData.getGlonassNavigationMessage();
96
97 // Verify propagator initialization
98 final GLONASSNumericalPropagator propagator = new GLONASSNumericalPropagatorBuilder(new ClassicalRungeKuttaIntegrator(60.0), glonassMessage, true).build();
99 Assert.assertNotNull(propagator);
100 Assert.assertEquals(0.0, glonassMessage.getDate().
101 durationFrom(new GLONASSDate(ephemerisData.getNt(), ephemerisData.getN4(), glonassMessage.getTime()).getDate()), eps);
102
103 Assert.assertEquals(12, glonassMessage.getPRN());
104 Assert.assertEquals(10, glonassMessage.getFrequencyNumber());
105 Assert.assertFalse(ephemerisData.isHealthAvailable());
106 Assert.assertEquals(1800, ephemerisData.getP1());
107 Assert.assertEquals(22410.0, ephemerisData.getTk(), eps);
108 Assert.assertEquals(0, ephemerisData.getBN());
109 Assert.assertEquals(1, ephemerisData.getP2());
110 Assert.assertEquals(26100.0, glonassMessage.getTime(), eps);
111 Assert.assertEquals(242.42592, glonassMessage.getXDot(), 2.0e-6);
112 Assert.assertEquals(1.21071935E-5, glonassMessage.getXDotDot(), 2.0e-6);
113 Assert.assertEquals(4064977.5390625, glonassMessage.getX(), eps);
114 Assert.assertEquals(-242.42592, glonassMessage.getYDot(), 2.0e-6);
115 Assert.assertEquals(-1.21071935E-5, glonassMessage.getYDotDot(), 2.0e-6);
116 Assert.assertEquals(-4064977.5390625, glonassMessage.getY(), eps);
117 Assert.assertEquals(-4242.426, glonassMessage.getZDot(), 2.5e-4);
118 Assert.assertEquals(1.21071935E-5, glonassMessage.getZDotDot(), 2.0e-6);
119 Assert.assertEquals(-1.22569775390625E7, glonassMessage.getZ(), eps);
120 Assert.assertEquals(4, ephemerisData.getP3());
121 Assert.assertEquals(3, ephemerisData.getP());
122 Assert.assertEquals(0, ephemerisData.getLNThirdString());
123 Assert.assertEquals(14, ephemerisData.getEn());
124 Assert.assertEquals(1.30385160446367E-8, ephemerisData.getDeltaTN(), eps);
125 Assert.assertEquals(1, ephemerisData.getP4());
126 Assert.assertEquals(14, ephemerisData.getFT());
127 Assert.assertEquals(1, ephemerisData.getM());
128 Assert.assertTrue(ephemerisData.areAdditionalDataAvailable());
129 Assert.assertEquals(1242, ephemerisData.getNA());
130 Assert.assertEquals(0.095649354159832, ephemerisData.getTauC(), eps);
131 Assert.assertEquals(4.214453510940075E-4, ephemerisData.getTauGps(), eps);
132 Assert.assertEquals(0, ephemerisData.getLNFifthString());
133
134 }
135
136 @Test
137 public void testNullMessage() {
138
139 final String m = "001111111100" + // Message number: 1020
140 "001100" + // Satellite ID
141 "10001" + // Channel number
142 "1" + // Cn word
143 "0" + // Health availability indicator
144 "01" + // Word P1
145 "001100011011" + // tk
146 "0" + // Bn word
147 "1" + // P2 flag
148 "0011101" + // tb
149 "000000111110000011111010" + // xn first derivative
150 "000011111110000011111010010" + // xn
151 "01101" + // xn second derivative
152 "100000111110000011111010" + // yn first derivative
153 "100011111110000011111010010" + // yn
154 "11101" + // yn second derivative
155 "110000111110000011111010" + // zn first derivative
156 "101011111110000011111010010" + // zn
157 "01101" + // zn second derivative
158 "0" + // P3 flag
159 "00111100101" + // GLONASS γn (tb)
160 "11" + // Time Operation Mode
161 "0" + // ln (third string)
162 "0011101011001110101011" + // τn (tb)
163 "01110" + // Δτn
164 "01110" + // En
165 "1" + // P4 Flag
166 "1110" + // Ft
167 "10011011010" + // Nt
168 "01" + // GLONASS-M Flag
169 "1" + // Availability of additional data
170 "10011011010" + // NA
171 "00001100001111100011110011110000" + // τc
172 "00111" + // N4
173 "0011011100111101010111" + // τGPS
174 "0" + // ln (fifth string)
175 "0000000"; // Reserved
176
177 final EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
178 message.start();
179
180 ArrayList<Integer> messages = new ArrayList<>();
181 messages.add(9999999);
182
183 final Rtcm1020 rtcm1020 = (Rtcm1020) new RtcmMessagesParser(messages).parse(message, false);
184
185 Assert.assertNull(rtcm1020);
186 }
187
188 @Test
189 public void testAdditionalDataFields() {
190 String m = "11111111111111111";
191 EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
192 Assert.assertTrue(RtcmDataField.DF105.booleanValue(message));
193 m = "11111111111111111";
194 message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
195 Assert.assertEquals(5, RtcmDataField.DF120.intValue(message));
196 m = "00000000000000000";
197 message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
198 Assert.assertFalse(RtcmDataField.DF131.booleanValue(message));
199 }
200
201 private byte[] byteArrayFromBinary(String radix2Value) {
202 final byte[] array = new byte[radix2Value.length() / 8];
203 for (int i = 0; i < array.length; ++i) {
204 for (int j = 0; j < 8; ++j) {
205 if (radix2Value.charAt(8 * i + j) != '0') {
206 array[i] |= 0x1 << (7 - j);
207 }
208 }
209 }
210 return array;
211 }
212
213 }