1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements.gnss;
18
19 import java.io.IOException;
20 import java.security.NoSuchAlgorithmException;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.junit.jupiter.api.Assertions;
25 import org.junit.jupiter.api.BeforeEach;
26 import org.junit.jupiter.api.Test;
27 import org.orekit.Utils;
28 import org.orekit.data.DataSource;
29 import org.orekit.errors.OrekitException;
30 import org.orekit.errors.OrekitMessages;
31 import org.orekit.files.rinex.observation.ObservationData;
32 import org.orekit.files.rinex.observation.ObservationDataSet;
33 import org.orekit.files.rinex.observation.RinexObservationParser;
34 import org.orekit.gnss.GnssSignal;
35 import org.orekit.gnss.MeasurementType;
36 import org.orekit.gnss.PredefinedObservationType;
37 import org.orekit.gnss.SatInSystem;
38 import org.orekit.gnss.SatelliteSystem;
39 import org.orekit.utils.Constants;
40
41 public class MeasurementCombinationFactoryTest {
42
43
44 private static final double eps = 1.0e-4;
45
46
47 private ObservationData obs1;
48
49
50 private SatelliteSystem system;
51
52
53 private ObservationDataSet dataSetRinex2;
54
55
56 private ObservationDataSet dataSetRinex3;
57
58 @BeforeEach
59 public void setUp() throws NoSuchAlgorithmException, IOException {
60 Utils.setDataRoot("gnss");
61 RinexObservationParser parser = new RinexObservationParser();
62
63
64 obs1 = new ObservationData(PredefinedObservationType.L1, 2.25E7, 0, 0);
65
66
67 final String name2 = "rinex/truncate-sbch0440.16o";
68 List<ObservationDataSet> parsed2 = parser.parse(new DataSource(name2,
69 () -> Utils.class.getClassLoader().getResourceAsStream(name2))).
70 getObservationDataSets();
71 dataSetRinex2 = parsed2.get(0);
72
73
74 final String name3 = "rinex/aaaa0000.00o";
75 List<ObservationDataSet> parsed3 = parser.parse(new DataSource(name3,
76 () -> Utils.class.getClassLoader().getResourceAsStream(name3))).
77 getObservationDataSets();
78 dataSetRinex3 = parsed3.get(1);
79
80
81 system = dataSetRinex2.getSatellite().getSystem();
82 }
83
84 @Test
85 public void testEmptyDataSetGeometryFree() {
86 doTestEmptyDataSet(MeasurementCombinationFactory.getGeometryFreeCombination(system));
87 }
88
89 @Test
90 public void testEmptyDataSetIonoFree() {
91 doTestEmptyDataSet(MeasurementCombinationFactory.getIonosphereFreeCombination(system));
92 }
93
94 @Test
95 public void testEmptyDataSetWideLane() {
96 doTestEmptyDataSet(MeasurementCombinationFactory.getWideLaneCombination(system));
97 }
98
99 @Test
100 public void testEmptyDataSetNarrowLane() {
101 doTestEmptyDataSet(MeasurementCombinationFactory.getNarrowLaneCombination(system));
102 }
103
104 @Test
105 public void testEmptyDataSetMelbourneWubbena() {
106 doTestEmptyDataSet(MeasurementCombinationFactory.getMelbourneWubbenaCombination(system));
107 }
108
109 @Test
110 public void testEmptyDataSetPhaseMinusCode() {
111 doTestEmptyDataSet(MeasurementCombinationFactory.getPhaseMinusCodeCombination(system));
112 }
113
114 @Test
115 public void testEmptyDataSetGRAPHIC() {
116 doTestEmptyDataSet(MeasurementCombinationFactory.getGRAPHICCombination(system));
117 }
118
119
120
121
122 private void doTestEmptyDataSet(final MeasurementCombination combination) {
123
124 final ObservationDataSet emptyDataSet = new ObservationDataSet(new SatInSystem(dataSetRinex2.getSatellite().getSystem(),
125 dataSetRinex2.getSatellite().getPRN()),
126 dataSetRinex2.getDate(), 0,
127 dataSetRinex2.getRcvrClkOffset(),
128 new ArrayList<>());
129
130 final CombinedObservationDataSet combinedData = combination.combine(emptyDataSet);
131 Assertions.assertEquals(0, combinedData.getObservationData().size());
132 }
133
134 @Test
135 public void testExceptionsGeometryFree() {
136 doTestExceptionsDualFrequency(MeasurementCombinationFactory.getGeometryFreeCombination(system));
137 }
138
139 @Test
140 public void testExceptionsIonoFree() {
141 doTestExceptionsDualFrequency(MeasurementCombinationFactory.getIonosphereFreeCombination(system));
142 }
143
144 @Test
145 public void testExceptionsWideLane() {
146 doTestExceptionsDualFrequency(MeasurementCombinationFactory.getWideLaneCombination(system));
147 }
148
149 @Test
150 public void testExceptionsNarrowLane() {
151 doTestExceptionsDualFrequency(MeasurementCombinationFactory.getNarrowLaneCombination(system));
152 }
153
154 @Test
155 public void testExceptionsPhaseMinusCode() {
156 doTestExceptionsSingleFrequency(MeasurementCombinationFactory.getPhaseMinusCodeCombination(system));
157 }
158
159 @Test
160 public void testExceptionsGRAPHIC() {
161 doTestExceptionsSingleFrequency(MeasurementCombinationFactory.getGRAPHICCombination(system));
162 }
163
164 private void doTestExceptionsSingleFrequency(final AbstractSingleFrequencyCombination combination) {
165
166 try {
167 final ObservationData observation = new ObservationData(PredefinedObservationType.L5, 12345678.0, 0, 0);
168 combination.combine(obs1, observation);
169 Assertions.fail("an exception should have been thrown");
170 } catch (OrekitException oe) {
171 Assertions.assertEquals(OrekitMessages.INCOMPATIBLE_FREQUENCIES_FOR_COMBINATION_OF_MEASUREMENTS, oe.getSpecifier());
172 }
173
174
175 try {
176 final ObservationData observation = new ObservationData(PredefinedObservationType.L1, 12345678.0, 0, 0);
177 combination.combine(obs1, observation);
178 Assertions.fail("an exception should have been thrown");
179 } catch (OrekitException oe) {
180 Assertions.assertEquals(OrekitMessages.INVALID_MEASUREMENT_TYPES_FOR_COMBINATION_OF_MEASUREMENTS, oe.getSpecifier());
181 }
182 }
183
184
185
186
187 private void doTestExceptionsDualFrequency(final AbstractDualFrequencyCombination combination) {
188
189 try {
190 final ObservationData observation = new ObservationData(PredefinedObservationType.L1, 12345678.0, 0, 0);
191 combination.combine(obs1, observation);
192 Assertions.fail("an exception should have been thrown");
193 } catch (OrekitException oe) {
194 Assertions.assertEquals(OrekitMessages.INCOMPATIBLE_FREQUENCIES_FOR_COMBINATION_OF_MEASUREMENTS, oe.getSpecifier());
195 }
196
197
198 try {
199 final ObservationData observation = new ObservationData(PredefinedObservationType.D2, 12345678.0, 0, 0);
200 combination.combine(obs1, observation);
201 Assertions.fail("an exception should have been thrown");
202 } catch (OrekitException oe) {
203 Assertions.assertEquals(OrekitMessages.INVALID_MEASUREMENT_TYPES_FOR_COMBINATION_OF_MEASUREMENTS, oe.getSpecifier());
204 }
205 }
206
207 @Test
208 public void testRinex2GeometryFree() {
209 doTestRinexDualFrequency(MeasurementCombinationFactory.getGeometryFreeCombination(system),
210 CombinationType.GEOMETRY_FREE, 6.953, 27534453.519,0.0, Double.NaN, 2, 2);
211 }
212
213 @Test
214 public void testRinex2IonoFree() {
215 doTestRinexDualFrequency(MeasurementCombinationFactory.getIonosphereFreeCombination(system),
216 CombinationType.IONO_FREE, 23732467.5026, 3772223175.669, 0.0, 4658 * GnssSignal.F0, 2, 2);
217 }
218
219 @Test
220 public void testRinex2WideLane() {
221 doTestRinexDualFrequency(MeasurementCombinationFactory.getWideLaneCombination(system),
222 CombinationType.WIDE_LANE, 23732453.7100, 27534453.519, 0.0, 34 * GnssSignal.F0, 2, 2);
223 }
224
225 @Test
226 public void testRinex2NarrowLane() {
227 doTestRinexDualFrequency(MeasurementCombinationFactory.getNarrowLaneCombination(system),
228 CombinationType.NARROW_LANE, 23732481.2951, 221895659.955, 0.0, 274 * GnssSignal.F0, 2, 2);
229 }
230
231 @Test
232 public void testRinex2MelbourneWubbena() {
233 doTestRinexDualFrequency(MeasurementCombinationFactory.getMelbourneWubbenaCombination(system),
234 CombinationType.MELBOURNE_WUBBENA, 0.0, 0.0, 3801972.2239, 34 * GnssSignal.F0, 1, 2);
235 }
236
237 @Test
238 public void testRinex2PhaseMinusCode() {
239 doTestRinex2SingleFrequency(MeasurementCombinationFactory.getPhaseMinusCodeCombination(system),
240 CombinationType.PHASE_MINUS_CODE, 73448118.300);
241 }
242
243 @Test
244 public void testRinex2GRAPHIC() {
245 doTestRinex2SingleFrequency(MeasurementCombinationFactory.getGRAPHICCombination(system),
246 CombinationType.GRAPHIC, 60456544.068);
247 }
248
249 private void doTestRinex2SingleFrequency(final MeasurementCombination combination, final CombinationType type,
250 final double expectedL2P2) {
251
252 final CombinedObservationDataSet combinedDataSet = combination.combine(dataSetRinex2);
253 checkCombinedDataSet(combinedDataSet, 1);
254 Assertions.assertEquals(type.getName(), combination.getName());
255
256 final List<CombinedObservationData> data = combinedDataSet.getObservationData();
257
258 Assertions.assertEquals(expectedL2P2, data.get(0).getValue(), eps);
259 Assertions.assertEquals(120 * GnssSignal.F0, data.get(0).getCombinedFrequency(), eps);
260
261 }
262
263 @Test
264 public void testRinex3GeometryFree() {
265 doTestRinexDualFrequency(MeasurementCombinationFactory.getGeometryFreeCombination(system),
266 CombinationType.GEOMETRY_FREE, 2.187, 3821708.096, 0.0, Double.NaN, 2, 3);
267 }
268
269 @Test
270 public void testRinex3IonoFree() {
271 doTestRinexDualFrequency(MeasurementCombinationFactory.getIonosphereFreeCombination(system),
272 CombinationType.IONO_FREE, 22399214.1934, 179620369.206, 0.0, 235 * GnssSignal.F0, 2, 3);
273 }
274
275 @Test
276 public void testRinex3WideLane() {
277 doTestRinexDualFrequency(MeasurementCombinationFactory.getWideLaneCombination(system),
278 CombinationType.WIDE_LANE, 22399239.8790, 3821708.096, 0.0, 5 * GnssSignal.F0, 2, 3);
279 }
280
281 @Test
282 public void testRinex3NarrowLane() {
283 doTestRinexDualFrequency(MeasurementCombinationFactory.getNarrowLaneCombination(system),
284 CombinationType.NARROW_LANE, 22399188.5078, 179620457.900, 0.0, 235 * GnssSignal.F0, 2, 3);
285 }
286
287 @Test
288 public void testRinex3MelbourneWubbena() {
289 doTestRinexDualFrequency(MeasurementCombinationFactory.getMelbourneWubbenaCombination(system),
290 CombinationType.MELBOURNE_WUBBENA, 0.0, 0.0, -18577480.4117, 5 * GnssSignal.F0, 1, 3);
291 }
292
293 @Test
294 public void testRinex3PhaseMinusCode() {
295 doTestRinex3SingleFrequency(MeasurementCombinationFactory.getPhaseMinusCodeCombination(system),
296 CombinationType.PHASE_MINUS_CODE, 95309391.697, 69321899.401,
297 69321893.420, 65500187.511);
298 }
299
300 @Test
301 public void testRinex3GRAPHIC() {
302 doTestRinex3SingleFrequency(MeasurementCombinationFactory.getGRAPHICCombination(system),
303 CombinationType.GRAPHIC, 70053877.7315, 57060139.2905,
304 57060136.2880, 55149281.1465);
305 }
306
307 private void doTestRinex3SingleFrequency(final MeasurementCombination combination, final CombinationType type,
308 final double expected1C, final double expected2W,
309 final double expected2X, final double expected5X) {
310
311 final CombinedObservationDataSet combinedDataSet = combination.combine(dataSetRinex3);
312 Assertions.assertEquals(type.getName(), combination.getName());
313
314 final List<CombinedObservationData> data = combinedDataSet.getObservationData();
315
316 Assertions.assertEquals(expected1C, data.get(0).getValue(), eps);
317 Assertions.assertEquals(154 * GnssSignal.F0, data.get(0).getCombinedFrequency(), eps);
318
319 Assertions.assertEquals(expected2W, data.get(1).getValue(), eps);
320 Assertions.assertEquals(120 * GnssSignal.F0, data.get(1).getCombinedFrequency(), eps);
321
322 Assertions.assertEquals(expected2X, data.get(2).getValue(), eps);
323 Assertions.assertEquals(120 * GnssSignal.F0, data.get(1).getCombinedFrequency(), eps);
324
325 Assertions.assertEquals(expected5X, data.get(3).getValue(), eps);
326 Assertions.assertEquals(115 * GnssSignal.F0, data.get(3).getCombinedFrequency(), eps);
327 }
328
329
330
331
332 private void doTestRinexDualFrequency(final MeasurementCombination combination, final CombinationType expectedType,
333 final double expectedRangeValue, final double expectedPhaseValue, final double expectedRangePhase,
334 final double expectedFrequency, final int expectedSize, final int rinexVersion) {
335
336
337 final CombinedObservationDataSet combinedDataSet;
338 if (rinexVersion == 2) {
339 combinedDataSet = combination.combine(dataSetRinex2);
340 checkCombinedDataSet(combinedDataSet, expectedSize);
341 } else {
342 combinedDataSet = combination.combine(dataSetRinex3);
343 Assertions.assertEquals(expectedSize, combinedDataSet.getObservationData().size());
344 }
345
346 Assertions.assertEquals(expectedType.getName(), combination.getName());
347
348
349 for (CombinedObservationData cod : combinedDataSet.getObservationData()) {
350
351 if (cod.getMeasurementType() == MeasurementType.CARRIER_PHASE) {
352
353 Assertions.assertEquals(expectedPhaseValue, cod.getValue(), eps);
354 Assertions.assertEquals(expectedFrequency, cod.getCombinedFrequency(), eps);
355 Assertions.assertEquals(expectedType, cod.getCombinationType());
356
357 } else if (cod.getMeasurementType() == MeasurementType.PSEUDO_RANGE) {
358
359 Assertions.assertEquals(expectedRangeValue, cod.getValue(), eps);
360 Assertions.assertEquals(expectedFrequency, cod.getCombinedFrequency(), eps);
361 Assertions.assertEquals(expectedType, cod.getCombinationType());
362
363 } else if (cod.getMeasurementType() == MeasurementType.COMBINED_RANGE_PHASE) {
364
365 Assertions.assertEquals(expectedRangePhase, cod.getValue(), eps);
366 Assertions.assertEquals(expectedFrequency, cod.getCombinedFrequency(), eps);
367 Assertions.assertEquals(expectedType, cod.getCombinationType());
368
369 }
370
371 }
372 }
373
374 private void checkCombinedDataSet(final CombinedObservationDataSet combinedDataSet,
375 final int expectedSize) {
376
377 Assertions.assertEquals(expectedSize, combinedDataSet.getObservationData().size());
378
379 Assertions.assertEquals(30, combinedDataSet.getPrnNumber());
380 Assertions.assertEquals(SatelliteSystem.GPS, combinedDataSet.getSatelliteSystem());
381
382 Assertions.assertEquals(0.0, combinedDataSet.getRcvrClkOffset(), eps);
383
384 Assertions.assertEquals("2016-02-13T00:49:43.000Z", combinedDataSet.getDate().toString());
385 }
386
387 @Test
388 public void testIssue746() {
389
390
391
392
393
394 final ObservationData obs1 = new ObservationData(PredefinedObservationType.L1, 1.17452520667E8, 0, 0);
395 final ObservationData obs2 = new ObservationData(PredefinedObservationType.L2, 9.1521434853E7, 0, 0);
396
397
398 final IonosphereFreeCombination ionoFree = MeasurementCombinationFactory.getIonosphereFreeCombination(SatelliteSystem.GPS);
399 final CombinedObservationData combined = ionoFree.combine(obs1, obs2);
400
401
402 final double wavelength = Constants.SPEED_OF_LIGHT / combined.getCombinedFrequency();
403 final double combineValueMeters = combined.getValue() * wavelength;
404
405
406 Assertions.assertEquals(22350475.245, combineValueMeters, 0.001);
407
408 }
409
410 }