1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements.modifiers;
18
19 import java.util.Arrays;
20 import java.util.List;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.analysis.differentiation.Gradient;
24 import org.orekit.attitudes.FrameAlignedProvider;
25 import org.orekit.estimation.measurements.EstimatedMeasurement;
26 import org.orekit.estimation.measurements.EstimatedMeasurementBase;
27 import org.orekit.estimation.measurements.EstimationModifier;
28 import org.orekit.estimation.measurements.GroundStation;
29 import org.orekit.estimation.measurements.TurnAroundRange;
30 import org.orekit.frames.TopocentricFrame;
31 import org.orekit.models.earth.ionosphere.IonosphericModel;
32 import org.orekit.propagation.FieldSpacecraftState;
33 import org.orekit.propagation.SpacecraftState;
34 import org.orekit.time.AbsoluteDate;
35 import org.orekit.utils.Differentiation;
36 import org.orekit.utils.ParameterDriver;
37 import org.orekit.utils.ParameterFunction;
38 import org.orekit.utils.TimeSpanMap.Span;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class TurnAroundRangeIonosphericDelayModifier implements EstimationModifier<TurnAroundRange> {
57
58
59 private final IonosphericModel ionoModel;
60
61
62 private final double frequency;
63
64
65
66
67
68
69 public TurnAroundRangeIonosphericDelayModifier(final IonosphericModel model,
70 final double freq) {
71 ionoModel = model;
72 frequency = freq;
73 }
74
75
76
77
78
79
80 private double rangeErrorIonosphericModel(final GroundStation station,
81 final SpacecraftState state) {
82
83 final TopocentricFrame baseFrame = station.getBaseFrame();
84
85 return ionoModel.pathDelay(state, baseFrame, frequency, ionoModel.getParameters(state.getDate()));
86 }
87
88
89
90
91
92
93
94
95 private <T extends CalculusFieldElement<T>> T rangeErrorIonosphericModel(final GroundStation station,
96 final FieldSpacecraftState<T> state,
97 final T[] parameters) {
98
99 final TopocentricFrame baseFrame = station.getBaseFrame();
100
101 return ionoModel.pathDelay(state, baseFrame, frequency, parameters);
102 }
103
104
105
106
107
108
109
110
111 private double[][] rangeErrorJacobianState(final double[] derivatives) {
112 final double[][] finiteDifferencesJacobian = new double[1][6];
113 System.arraycopy(derivatives, 0, finiteDifferencesJacobian[0], 0, 6);
114 return finiteDifferencesJacobian;
115 }
116
117
118
119
120
121
122
123
124
125 private double rangeErrorParameterDerivative(final GroundStation station,
126 final ParameterDriver driver,
127 final SpacecraftState state) {
128
129 final ParameterFunction rangeError = new ParameterFunction() {
130
131 @Override
132 public double value(final ParameterDriver parameterDriver, final AbsoluteDate date) {
133 return rangeErrorIonosphericModel(station, state);
134 }
135 };
136
137 final ParameterFunction rangeErrorDerivative =
138 Differentiation.differentiate(rangeError, 3, 10.0 * driver.getScale());
139
140 return rangeErrorDerivative.value(driver, state.getDate());
141
142 }
143
144
145
146
147
148
149
150
151 private double[] rangeErrorParameterDerivative(final double[] derivatives, final int freeStateParameters) {
152
153
154 return Arrays.copyOfRange(derivatives, freeStateParameters, derivatives.length);
155 }
156
157
158 @Override
159 public List<ParameterDriver> getParametersDrivers() {
160 return ionoModel.getParametersDrivers();
161 }
162
163 @Override
164 public void modifyWithoutDerivatives(final EstimatedMeasurementBase<TurnAroundRange> estimated) {
165
166 final TurnAroundRange measurement = estimated.getObservedMeasurement();
167 final GroundStation primaryStation = measurement.getPrimaryStation();
168 final GroundStation secondaryStation = measurement.getSecondaryStation();
169 final SpacecraftState state = estimated.getStates()[0];
170
171
172
173 final double[] newValue = estimated.getEstimatedValue();
174 final double primaryDelay = rangeErrorIonosphericModel(primaryStation, state);
175 final double secondaryDelay = rangeErrorIonosphericModel(secondaryStation, state);
176 newValue[0] = newValue[0] + primaryDelay + secondaryDelay;
177 estimated.modifyEstimatedValue(this, newValue);
178
179 }
180
181 @Override
182 public void modify(final EstimatedMeasurement<TurnAroundRange> estimated) {
183 final TurnAroundRange measurement = estimated.getObservedMeasurement();
184 final GroundStation primaryStation = measurement.getPrimaryStation();
185 final GroundStation secondaryStation = measurement.getSecondaryStation();
186 final SpacecraftState state = estimated.getStates()[0];
187
188
189 final ModifierGradientConverter converter =
190 new ModifierGradientConverter(state, 6, new FrameAlignedProvider(state.getFrame()));
191 final FieldSpacecraftState<Gradient> gState = converter.getState(ionoModel);
192 final Gradient[] gParameters = converter.getParametersAtStateDate(gState, ionoModel);
193 final Gradient primaryGDelay = rangeErrorIonosphericModel(primaryStation, gState, gParameters);
194 final Gradient secondaryGDelay = rangeErrorIonosphericModel(secondaryStation, gState, gParameters);
195 final double[] primaryDerivatives = primaryGDelay.getGradient();
196 final double[] secondaryDerivatives = secondaryGDelay.getGradient();
197
198 final double[][] primaryDjac = rangeErrorJacobianState(primaryDerivatives);
199 final double[][] secondaryDjac = rangeErrorJacobianState(secondaryDerivatives);
200 final double[][] stateDerivatives = estimated.getStateDerivatives(0);
201 for (int irow = 0; irow < stateDerivatives.length; ++irow) {
202 for (int jcol = 0; jcol < stateDerivatives[0].length; ++jcol) {
203 stateDerivatives[irow][jcol] += primaryDjac[irow][jcol] + secondaryDjac[irow][jcol];
204 }
205 }
206 estimated.setStateDerivatives(0, stateDerivatives);
207
208 int indexPrimary = 0;
209 for (final ParameterDriver driver : getParametersDrivers()) {
210 if (driver.isSelected()) {
211 for (Span<String> span = driver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
212
213 double parameterDerivative = estimated.getParameterDerivatives(driver, span.getStart())[0];
214 final double[] derivatives = rangeErrorParameterDerivative(primaryDerivatives, converter.getFreeStateParameters());
215 parameterDerivative += derivatives[indexPrimary];
216 estimated.setParameterDerivatives(driver, span.getStart(), parameterDerivative);
217 indexPrimary += 1;
218 }
219 }
220
221 }
222
223 int indexSecondary = 0;
224 for (final ParameterDriver driver : getParametersDrivers()) {
225 if (driver.isSelected()) {
226 for (Span<String> span = driver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
227
228 double parameterDerivative = estimated.getParameterDerivatives(driver, span.getStart())[0];
229 final double[] derivatives = rangeErrorParameterDerivative(secondaryDerivatives, converter.getFreeStateParameters());
230 parameterDerivative += derivatives[indexSecondary];
231 estimated.setParameterDerivatives(driver, span.getStart(), parameterDerivative);
232 indexSecondary += 1;
233 }
234 }
235
236 }
237
238
239 for (final ParameterDriver driver : Arrays.asList(primaryStation.getClockOffsetDriver(),
240 primaryStation.getEastOffsetDriver(),
241 primaryStation.getNorthOffsetDriver(),
242 primaryStation.getZenithOffsetDriver())) {
243 if (driver.isSelected()) {
244 for (Span<String> span = driver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
245
246 double parameterDerivative = estimated.getParameterDerivatives(driver, span.getStart())[0];
247 parameterDerivative += rangeErrorParameterDerivative(primaryStation, driver, state);
248 estimated.setParameterDerivatives(driver, span.getStart(), parameterDerivative);
249 }
250 }
251 }
252
253
254 for (final ParameterDriver driver : Arrays.asList(secondaryStation.getEastOffsetDriver(),
255 secondaryStation.getNorthOffsetDriver(),
256 secondaryStation.getZenithOffsetDriver())) {
257 if (driver.isSelected()) {
258 for (Span<String> span = driver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
259
260 double parameterDerivative = estimated.getParameterDerivatives(driver, span.getStart())[0];
261 parameterDerivative += rangeErrorParameterDerivative(secondaryStation, driver, state);
262 estimated.setParameterDerivatives(driver, span.getStart(), parameterDerivative);
263 }
264 }
265 }
266
267
268
269 final double[] newValue = estimated.getEstimatedValue();
270 newValue[0] = newValue[0] + primaryGDelay.getReal() + secondaryGDelay.getReal();
271 estimated.modifyEstimatedValue(this, newValue);
272 }
273
274 }