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