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.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
22
23 import org.orekit.errors.OrekitException;
24 import org.orekit.errors.OrekitMessages;
25 import org.orekit.gnss.CombinedObservationData;
26 import org.orekit.gnss.CombinedObservationDataSet;
27 import org.orekit.gnss.Frequency;
28 import org.orekit.gnss.MeasurementType;
29 import org.orekit.gnss.ObservationData;
30 import org.orekit.gnss.ObservationDataSet;
31 import org.orekit.gnss.ObservationType;
32 import org.orekit.gnss.RinexObservationHeader;
33 import org.orekit.gnss.SatelliteSystem;
34
35
36
37
38
39 public abstract class AbstractSingleFrequencyCombination implements MeasurementCombination {
40
41
42 private final CombinationType type;
43
44
45 private final SatelliteSystem system;
46
47
48
49
50
51
52 protected AbstractSingleFrequencyCombination(final CombinationType type, final SatelliteSystem system) {
53 this.type = type;
54 this.system = system;
55 }
56
57
58 @Override
59 public String getName() {
60 return type.getName();
61 }
62
63
64 @Override
65 public CombinedObservationDataSet combine(final ObservationDataSet observations) {
66
67
68 final RinexObservationHeader header = observations.getHeader();
69
70 final int version = (int) header.getRinexVersion();
71
72
73 final List<ObservationData> pseudoRanges = new ArrayList<>();
74 final List<ObservationData> phases = new ArrayList<>();
75
76
77 for (final ObservationData od : observations.getObservationData()) {
78 if (!Double.isNaN(od.getValue())) {
79 if (od.getObservationType().getMeasurementType() == MeasurementType.PSEUDO_RANGE) {
80 pseudoRanges.add(od);
81 } else if (od.getObservationType().getMeasurementType() == MeasurementType.CARRIER_PHASE) {
82 phases.add(od);
83 }
84 }
85 }
86
87
88 final List<CombinedObservationData> combined = new ArrayList<>();
89
90 for (int i = 0; i < phases.size(); i++) {
91 for (int j = 0; j < pseudoRanges.size(); j++) {
92 final boolean combine = isCombinationPossible(version, phases.get(i), pseudoRanges.get(j));
93 if (combine) {
94 combined.add(combine(phases.get(i), pseudoRanges.get(j)));
95 }
96 }
97 }
98
99 return new CombinedObservationDataSet(observations.getHeader(), observations.getSatelliteSystem(),
100 observations.getPrnNumber(), observations.getDate(),
101 observations.getRcvrClkOffset(), combined);
102 }
103
104
105
106
107
108
109
110 public CombinedObservationData combine(final ObservationData phase, final ObservationData pseudoRange) {
111
112
113 final ObservationType obsType1 = phase.getObservationType();
114 final ObservationType obsType2 = pseudoRange.getObservationType();
115
116
117 final Frequency freq1 = obsType1.getFrequency(system);
118 final Frequency freq2 = obsType2.getFrequency(system);
119
120 if (freq1 != freq2) {
121 throw new OrekitException(OrekitMessages.INCOMPATIBLE_FREQUENCIES_FOR_COMBINATION_OF_MEASUREMENTS,
122 freq1, freq2, getName());
123 }
124
125
126 final MeasurementType measType1 = obsType1.getMeasurementType();
127 final MeasurementType measType2 = obsType2.getMeasurementType();
128
129
130 if (measType1 == measType2) {
131
132 throw new OrekitException(OrekitMessages.INVALID_MEASUREMENT_TYPES_FOR_COMBINATION_OF_MEASUREMENTS,
133 measType1, measType2, getName());
134 }
135
136
137 final double f = freq1.getMHzFrequency();
138
139
140 final double combinedValue = getCombinedValue(phase.getValue(), pseudoRange.getValue());
141
142
143 return new CombinedObservationData(CombinationType.PHASE_MINUS_CODE, MeasurementType.COMBINED_RANGE_PHASE,
144 combinedValue, f, Arrays.asList(phase, pseudoRange));
145 }
146
147
148
149
150
151
152
153 protected abstract double getCombinedValue(double phase, double pseudoRange);
154
155
156
157
158
159
160
161
162 private boolean isCombinationPossible(final int version, final ObservationData phase, final ObservationData pseudoRange) {
163
164 final ObservationType obsType1 = phase.getObservationType();
165 final ObservationType obsType2 = pseudoRange.getObservationType();
166
167 if (obsType1.getFrequency(system) == obsType2.getFrequency(system)) {
168
169 switch (version) {
170 case 2 : return true;
171 case 3 : return obsType1.getSignalCode() == obsType2.getSignalCode();
172 default: return false;
173 }
174 } else {
175
176 return false;
177 }
178 }
179
180 }