1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth.troposphere;
18
19 import java.util.Collections;
20 import java.util.List;
21
22 import org.hipparchus.Field;
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.util.FastMath;
25 import org.hipparchus.util.MathArrays;
26 import org.orekit.annotation.DefaultDataContext;
27 import org.orekit.bodies.FieldGeodeticPoint;
28 import org.orekit.bodies.GeodeticPoint;
29 import org.orekit.data.DataContext;
30 import org.orekit.time.AbsoluteDate;
31 import org.orekit.time.DateTimeComponents;
32 import org.orekit.time.FieldAbsoluteDate;
33 import org.orekit.time.TimeScale;
34 import org.orekit.utils.ParameterDriver;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class ViennaOneModel implements DiscreteTroposphericModel, MappingFunction {
52
53
54 private final double[] coefficientsA;
55
56
57 private final double[] zenithDelay;
58
59
60 private final TimeScale utc;
61
62
63
64
65
66
67
68
69
70 @DefaultDataContext
71 public ViennaOneModel(final double[] coefficientA, final double[] zenithDelay) {
72 this(coefficientA, zenithDelay,
73 DataContext.getDefault().getTimeScales().getUTC());
74 }
75
76
77
78
79
80
81
82
83
84
85 public ViennaOneModel(final double[] coefficientA,
86 final double[] zenithDelay,
87 final TimeScale utc) {
88 this.coefficientsA = coefficientA.clone();
89 this.zenithDelay = zenithDelay.clone();
90 this.utc = utc;
91 }
92
93
94 @Override
95 public double pathDelay(final double elevation, final GeodeticPoint point,
96 final double[] parameters, final AbsoluteDate date) {
97
98 final double[] delays = computeZenithDelay(point, parameters, date);
99
100 final double[] mappingFunction = mappingFactors(elevation, point, date);
101
102 return delays[0] * mappingFunction[0] + delays[1] * mappingFunction[1];
103 }
104
105
106 @Override
107 public <T extends CalculusFieldElement<T>> T pathDelay(final T elevation, final FieldGeodeticPoint<T> point,
108 final T[] parameters, final FieldAbsoluteDate<T> date) {
109
110 final T[] delays = computeZenithDelay(point, parameters, date);
111
112 final T[] mappingFunction = mappingFactors(elevation, point, date);
113
114 return delays[0].multiply(mappingFunction[0]).add(delays[1].multiply(mappingFunction[1]));
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128 public double[] computeZenithDelay(final GeodeticPoint point, final double[] parameters, final AbsoluteDate date) {
129 return zenithDelay.clone();
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144 public <T extends CalculusFieldElement<T>> T[] computeZenithDelay(final FieldGeodeticPoint<T> point, final T[] parameters,
145 final FieldAbsoluteDate<T> date) {
146 final Field<T> field = date.getField();
147 final T zero = field.getZero();
148 final T[] delays = MathArrays.buildArray(field, 2);
149 delays[0] = zero.add(zenithDelay[0]);
150 delays[1] = zero.add(zenithDelay[1]);
151 return delays;
152 }
153
154
155 @Override
156 public double[] mappingFactors(final double elevation, final GeodeticPoint point,
157 final AbsoluteDate date) {
158
159 final DateTimeComponents dtc = date.getComponents(utc);
160 final int dofyear = dtc.getDate().getDayOfYear();
161
162
163 final double bh = 0.0029;
164 final double c0h = 0.062;
165 final double c10h;
166 final double c11h;
167 final double psi;
168
169
170 final double latitude = point.getLatitude();
171
172
173 if (FastMath.sin(latitude) > 0) {
174 c10h = 0.001;
175 c11h = 0.005;
176 psi = 0;
177 } else {
178 c10h = 0.002;
179 c11h = 0.007;
180 psi = FastMath.PI;
181 }
182
183
184 double t0 = 28;
185 if (latitude < 0) {
186
187 t0 += 183;
188 }
189
190 final double coef = ((dofyear - t0) / 365) * 2 * FastMath.PI + psi;
191 final double ch = c0h + ((FastMath.cos(coef) + 1) * (c11h / 2) + c10h) * (1 - FastMath.cos(latitude));
192
193
194 final double bw = 0.00146;
195 final double cw = 0.04391;
196
197 final double[] function = new double[2];
198 function[0] = TroposphericModelUtils.mappingFunction(coefficientsA[0], bh, ch, elevation);
199 function[1] = TroposphericModelUtils.mappingFunction(coefficientsA[1], bw, cw, elevation);
200
201
202 final double correction = TroposphericModelUtils.computeHeightCorrection(elevation, point.getAltitude());
203 function[0] = function[0] + correction;
204
205 return function;
206 }
207
208
209 @Override
210 public <T extends CalculusFieldElement<T>> T[] mappingFactors(final T elevation, final FieldGeodeticPoint<T> point,
211 final FieldAbsoluteDate<T> date) {
212 final Field<T> field = date.getField();
213 final T zero = field.getZero();
214
215
216 final DateTimeComponents dtc = date.getComponents(utc);
217 final int dofyear = dtc.getDate().getDayOfYear();
218
219
220 final T bh = zero.add(0.0029);
221 final T c0h = zero.add(0.062);
222 final T c10h;
223 final T c11h;
224 final T psi;
225
226
227 final T latitude = point.getLatitude();
228
229
230 if (FastMath.sin(latitude.getReal()) > 0) {
231 c10h = zero.add(0.001);
232 c11h = zero.add(0.005);
233 psi = zero;
234 } else {
235 c10h = zero.add(0.002);
236 c11h = zero.add(0.007);
237 psi = zero.getPi();
238 }
239
240
241
242 double t0 = 28;
243 if (latitude.getReal() < 0) {
244
245 t0 += 183;
246 }
247 final T coef = psi.add(zero.getPi().multiply(2.0).multiply((dofyear - t0) / 365));
248 final T ch = c11h.divide(2.0).multiply(FastMath.cos(coef).add(1.0)).add(c10h).multiply(FastMath.cos(latitude).negate().add(1.)).add(c0h);
249
250
251 final T bw = zero.add(0.00146);
252 final T cw = zero.add(0.04391);
253
254 final T[] function = MathArrays.buildArray(field, 2);
255 function[0] = TroposphericModelUtils.mappingFunction(zero.add(coefficientsA[0]), bh, ch, elevation);
256 function[1] = TroposphericModelUtils.mappingFunction(zero.add(coefficientsA[1]), bw, cw, elevation);
257
258
259 final T correction = TroposphericModelUtils.computeHeightCorrection(elevation, point.getAltitude(), field);
260 function[0] = function[0].add(correction);
261
262 return function;
263 }
264
265
266 @Override
267 public List<ParameterDriver> getParametersDrivers() {
268 return Collections.emptyList();
269 }
270
271 }