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.files.rinex.observation.ObservationData;
26 import org.orekit.files.rinex.observation.ObservationDataSet;
27 import org.orekit.gnss.GnssSignal;
28 import org.orekit.gnss.MeasurementType;
29 import org.orekit.gnss.ObservationType;
30 import org.orekit.gnss.SatelliteSystem;
31 import org.orekit.utils.Constants;
32
33
34
35
36
37 public abstract class AbstractDualFrequencyCombination implements MeasurementCombination {
38
39
40 private final CombinationType type;
41
42
43 private final SatelliteSystem system;
44
45
46
47
48
49
50 protected AbstractDualFrequencyCombination(final CombinationType type, final SatelliteSystem system) {
51 this.type = type;
52 this.system = system;
53 }
54
55
56 @Override
57 public String getName() {
58 return type.getName();
59 }
60
61
62
63
64
65
66
67 public CombinedObservationData combine(final ObservationData od1, final ObservationData od2) {
68
69
70 final ObservationType obsType1 = od1.getObservationType();
71 final ObservationType obsType2 = od2.getObservationType();
72
73
74 final GnssSignal signal1 = obsType1.getSignal(system);
75 final GnssSignal signal2 = obsType2.getSignal(system);
76
77 if (signal1 == signal2) {
78 throw new OrekitException(OrekitMessages.INCOMPATIBLE_FREQUENCIES_FOR_COMBINATION_OF_MEASUREMENTS,
79 signal1.getFrequency(), signal2.getFrequency(), getName());
80 }
81
82
83 final MeasurementType measType1 = obsType1.getMeasurementType();
84 final MeasurementType measType2 = obsType2.getMeasurementType();
85
86
87 if (measType1 != measType2) {
88
89 throw new OrekitException(OrekitMessages.INVALID_MEASUREMENT_TYPES_FOR_COMBINATION_OF_MEASUREMENTS,
90 measType1, measType2, getName());
91 }
92
93
94 final double combinedFrequency = getCombinedFrequency(signal1, signal2);
95
96
97 final double combinedValue;
98 if (obsType1.getMeasurementType() == MeasurementType.CARRIER_PHASE && !Double.isNaN(combinedFrequency)) {
99
100 final double obs1Meters = od1.getValue() * signal1.getWavelength();
101 final double obs2Meters = od2.getValue() * signal2.getWavelength();
102
103
104 combinedValue = getCombinedValue(obs1Meters, signal1, obs2Meters, signal2) * combinedFrequency / Constants.SPEED_OF_LIGHT;
105 } else {
106 combinedValue = getCombinedValue(od1.getValue(), signal1, od2.getValue(), signal2);
107 }
108
109
110 return new CombinedObservationData(combinedValue, combinedFrequency, type, measType1, Arrays.asList(od1, od2));
111
112 }
113
114
115 @Override
116 public CombinedObservationDataSet combine(final ObservationDataSet observations) {
117
118
119 final List<ObservationData> pseudoRanges = new ArrayList<>();
120 final List<ObservationData> phases = new ArrayList<>();
121
122
123 for (final ObservationData od : observations.getObservationData()) {
124 if (!Double.isNaN(od.getValue())) {
125 if (od.getObservationType().getMeasurementType() == MeasurementType.PSEUDO_RANGE) {
126 pseudoRanges.add(od);
127 } else if (od.getObservationType().getMeasurementType() == MeasurementType.CARRIER_PHASE) {
128 phases.add(od);
129 }
130 }
131 }
132
133
134 final List<CombinedObservationData> combined = new ArrayList<>();
135
136 for (int i = 0; i < pseudoRanges.size() - 1; i++) {
137 for (int j = 1; j < pseudoRanges.size(); j++) {
138 final boolean combine = isCombinationPossible(pseudoRanges.get(i), pseudoRanges.get(j));
139 if (combine) {
140 combined.add(combine(pseudoRanges.get(i), pseudoRanges.get(j)));
141 }
142 }
143 }
144
145 for (int i = 0; i < phases.size() - 1; i++) {
146 for (int j = 1; j < phases.size(); j++) {
147 final boolean combine = isCombinationPossible(phases.get(i), phases.get(j));
148 if (combine) {
149 combined.add(combine(phases.get(i), phases.get(j)));
150 }
151 }
152 }
153
154 return new CombinedObservationDataSet(observations.getSatellite().getSystem(),
155 observations.getSatellite().getPRN(),
156 observations.getDate(),
157 observations.getRcvrClkOffset(), combined);
158 }
159
160
161
162
163
164
165
166
167
168
169 protected abstract double getCombinedValue(double obs1, GnssSignal s1, double obs2, GnssSignal s2);
170
171
172
173
174
175
176
177
178 protected abstract double getCombinedFrequency(GnssSignal s1, GnssSignal s2);
179
180
181
182
183
184
185
186 private boolean isCombinationPossible(final ObservationData data1, final ObservationData data2) {
187
188 final ObservationType obsType1 = data1.getObservationType();
189 final ObservationType obsType2 = data2.getObservationType();
190
191 return obsType1.getSignal(system) != obsType2.getSignal(system) &&
192 obsType1.getSignalCode() == obsType2.getSignalCode();
193 }
194
195 }