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