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