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.CalculusFieldElement;
23 import org.hipparchus.util.FastMath;
24 import org.hipparchus.util.FieldSinCos;
25 import org.hipparchus.util.SinCos;
26 import org.orekit.bodies.FieldGeodeticPoint;
27 import org.orekit.bodies.GeodeticPoint;
28 import org.orekit.time.AbsoluteDate;
29 import org.orekit.time.FieldAbsoluteDate;
30 import org.orekit.time.TimeScale;
31 import org.orekit.utils.FieldTrackingCoordinates;
32 import org.orekit.utils.ParameterDriver;
33 import org.orekit.utils.TrackingCoordinates;
34
35
36
37
38
39
40 public abstract class AbstractVienna implements TroposphericModel, TroposphereMappingFunction {
41
42
43
44
45 private static final double C = 0.0032;
46
47
48 private final ViennaAProvider aProvider;
49
50
51 private final AzimuthalGradientProvider gProvider;
52
53
54 private final TroposphericModel zenithDelayProvider;
55
56
57 private final TimeScale utc;
58
59
60
61
62
63
64
65 protected AbstractVienna(final ViennaAProvider aProvider,
66 final AzimuthalGradientProvider gProvider,
67 final TroposphericModel zenithDelayProvider,
68 final TimeScale utc) {
69 this.aProvider = aProvider;
70 this.gProvider = gProvider;
71 this.zenithDelayProvider = zenithDelayProvider;
72 this.utc = utc;
73 }
74
75
76 @Override
77 public TroposphericDelay pathDelay(final TrackingCoordinates trackingCoordinates,
78 final GeodeticPoint point,
79 final double[] parameters, final AbsoluteDate date) {
80
81 final TroposphericDelay delays =
82 zenithDelayProvider.pathDelay(trackingCoordinates, point, parameters, date);
83
84
85 final double[] mappingFunction = mappingFactors(trackingCoordinates, point, date);
86
87
88 final AzimuthalGradientCoefficients agc = gProvider.getGradientCoefficients(point, date);
89 final double gh;
90 final double gw;
91 if (agc != null) {
92
93
94 final double sinE = FastMath.sin(trackingCoordinates.getElevation());
95 final double tanE = FastMath.tan(trackingCoordinates.getElevation());
96 final double mfh = 1.0 / (sinE * tanE + C);
97
98 final SinCos sc = FastMath.sinCos(trackingCoordinates.getAzimuth());
99 gh = mfh * (agc.getGnh() * sc.cos() + agc.getGeh() * sc.sin());
100 gw = mfh * (agc.getGnw() * sc.cos() + agc.getGew() * sc.sin());
101
102 } else {
103 gh = 0;
104 gw = 0;
105 }
106
107
108 return new TroposphericDelay(delays.getZh(),
109 delays.getZw(),
110 delays.getZh() * mappingFunction[0] + gh,
111 delays.getZw() * mappingFunction[1] + gw);
112
113 }
114
115
116 @Override
117 public <T extends CalculusFieldElement<T>> FieldTroposphericDelay<T> pathDelay(final FieldTrackingCoordinates<T> trackingCoordinates,
118 final FieldGeodeticPoint<T> point,
119 final T[] parameters, final FieldAbsoluteDate<T> date) {
120
121 final FieldTroposphericDelay<T> delays =
122 zenithDelayProvider.pathDelay(trackingCoordinates, point, parameters, date);
123
124
125 final T[] mappingFunction = mappingFactors(trackingCoordinates, point, date);
126
127
128 final FieldAzimuthalGradientCoefficients<T> agc = gProvider.getGradientCoefficients(point, date);
129 final T gh;
130 final T gw;
131 if (agc != null) {
132
133
134 final T sinE = FastMath.sin(trackingCoordinates.getElevation());
135 final T tanE = FastMath.tan(trackingCoordinates.getElevation());
136 final T mfh = sinE.multiply(tanE).add(C).reciprocal();
137
138 final FieldSinCos<T> sc = FastMath.sinCos(trackingCoordinates.getAzimuth());
139 gh = mfh.multiply(agc.getGnh().multiply(sc.cos()).add(agc.getGeh().multiply(sc.sin())));
140 gw = mfh.multiply(agc.getGnw().multiply(sc.cos()).add(agc.getGew().multiply(sc.sin())));
141
142 } else {
143 gh = date.getField().getZero();
144 gw = date.getField().getZero();
145 }
146
147
148 return new FieldTroposphericDelay<>(delays.getZh(),
149 delays.getZw(),
150 delays.getZh().multiply(mappingFunction[0]).add(gh),
151 delays.getZw().multiply(mappingFunction[1]).add(gw));
152
153 }
154
155
156 @Override
157 public List<ParameterDriver> getParametersDrivers() {
158 return Collections.emptyList();
159 }
160
161
162
163
164 protected ViennaAProvider getAProvider() {
165 return aProvider;
166 }
167
168
169
170
171
172 protected double getDayOfYear(final AbsoluteDate date) {
173 return date.getDayOfYear(utc);
174 }
175
176
177
178
179
180
181
182 protected <T extends CalculusFieldElement<T>> T getDayOfYear(final FieldAbsoluteDate<T> date) {
183 return date.getDayOfYear(utc);
184 }
185
186 }