1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements;
18
19 import java.util.Arrays;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import org.hipparchus.Field;
24 import org.hipparchus.analysis.differentiation.DSFactory;
25 import org.hipparchus.analysis.differentiation.DerivativeStructure;
26 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
27 import org.orekit.frames.FieldTransform;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.utils.Constants;
32 import org.orekit.utils.ParameterDriver;
33 import org.orekit.utils.TimeStampedFieldPVCoordinates;
34 import org.orekit.utils.TimeStampedPVCoordinates;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 public class Range extends AbstractMeasurement<Range> {
79
80
81 private final GroundStation station;
82
83
84 private final boolean twoway;
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 @Deprecated
101 public Range(final GroundStation station, final AbsoluteDate date,
102 final double range, final double sigma, final double baseWeight) {
103 this(station, true, date, range, sigma, baseWeight, new ObservableSatellite(0));
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 @Deprecated
122 public Range(final GroundStation station, final AbsoluteDate date, final double range,
123 final double sigma, final double baseWeight, final boolean twoWay) {
124 this(station, twoWay, date, range, sigma, baseWeight, new ObservableSatellite(0));
125 }
126
127
128
129
130
131
132
133
134
135
136
137 @Deprecated
138 public Range(final GroundStation station, final AbsoluteDate date,
139 final double range, final double sigma, final double baseWeight,
140 final int propagatorIndex) {
141 this(station, true, date, range, sigma, baseWeight, new ObservableSatellite(0));
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155
156 @Deprecated
157 public Range(final GroundStation station, final boolean twoWay, final AbsoluteDate date,
158 final double range, final double sigma, final double baseWeight,
159 final int propagatorIndex) {
160 this(station, twoWay, date, range, sigma, baseWeight, new ObservableSatellite(propagatorIndex));
161 }
162
163
164
165
166
167
168
169
170
171
172
173 public Range(final GroundStation station, final boolean twoWay, final AbsoluteDate date,
174 final double range, final double sigma, final double baseWeight,
175 final ObservableSatellite satellite) {
176 super(date, range, sigma, baseWeight, Arrays.asList(satellite));
177 addParameterDriver(station.getClockOffsetDriver());
178 addParameterDriver(station.getEastOffsetDriver());
179 addParameterDriver(station.getNorthOffsetDriver());
180 addParameterDriver(station.getZenithOffsetDriver());
181 addParameterDriver(station.getPrimeMeridianOffsetDriver());
182 addParameterDriver(station.getPrimeMeridianDriftDriver());
183 addParameterDriver(station.getPolarOffsetXDriver());
184 addParameterDriver(station.getPolarDriftXDriver());
185 addParameterDriver(station.getPolarOffsetYDriver());
186 addParameterDriver(station.getPolarDriftYDriver());
187 if (!twoWay) {
188
189 addParameterDriver(satellite.getClockOffsetDriver());
190 }
191 this.station = station;
192 this.twoway = twoWay;
193 }
194
195
196
197
198 public GroundStation getStation() {
199 return station;
200 }
201
202
203
204
205 public boolean isTwoWay() {
206 return twoway;
207 }
208
209
210 @Override
211 protected EstimatedMeasurement<Range> theoreticalEvaluation(final int iteration,
212 final int evaluation,
213 final SpacecraftState[] states) {
214
215 final ObservableSatellite satellite = getSatellites().get(0);
216 final SpacecraftState state = states[satellite.getPropagatorIndex()];
217
218
219
220
221
222
223
224
225
226 int nbParams = 6;
227 final Map<String, Integer> indices = new HashMap<>();
228 for (ParameterDriver driver : getParametersDrivers()) {
229 if (driver.isSelected()) {
230 indices.put(driver.getName(), nbParams++);
231 }
232 }
233 final DSFactory factory = new DSFactory(nbParams, 1);
234 final Field<DerivativeStructure> field = factory.getDerivativeField();
235 final FieldVector3D<DerivativeStructure> zero = FieldVector3D.getZero(field);
236
237
238 final TimeStampedFieldPVCoordinates<DerivativeStructure> pvaDS = getCoordinates(state, 0, factory);
239
240
241
242 final FieldTransform<DerivativeStructure> offsetToInertialDownlink =
243 station.getOffsetToInertial(state.getFrame(), getDate(), factory, indices);
244 final FieldAbsoluteDate<DerivativeStructure> downlinkDateDS = offsetToInertialDownlink.getFieldDate();
245
246
247 final TimeStampedFieldPVCoordinates<DerivativeStructure> stationDownlink =
248 offsetToInertialDownlink.transformPVCoordinates(new TimeStampedFieldPVCoordinates<>(downlinkDateDS,
249 zero, zero, zero));
250
251
252
253
254
255
256 final DerivativeStructure tauD = signalTimeOfFlight(pvaDS, stationDownlink.getPosition(), downlinkDateDS);
257
258
259 final DerivativeStructure delta = downlinkDateDS.durationFrom(state.getDate());
260 final DerivativeStructure deltaMTauD = tauD.negate().add(delta);
261 final SpacecraftState transitState = state.shiftedBy(deltaMTauD.getValue());
262 final TimeStampedFieldPVCoordinates<DerivativeStructure> transitStateDS = pvaDS.shiftedBy(deltaMTauD);
263
264
265 final EstimatedMeasurement<Range> estimated;
266 final DerivativeStructure range;
267
268 if (twoway) {
269
270
271 final TimeStampedFieldPVCoordinates<DerivativeStructure> stationAtTransitDate =
272 stationDownlink.shiftedBy(tauD.negate());
273
274 final DerivativeStructure tauU =
275 signalTimeOfFlight(stationAtTransitDate, transitStateDS.getPosition(), transitStateDS.getDate());
276 final TimeStampedFieldPVCoordinates<DerivativeStructure> stationUplink =
277 stationDownlink.shiftedBy(-tauD.getValue() - tauU.getValue());
278
279
280 estimated = new EstimatedMeasurement<Range>(this, iteration, evaluation,
281 new SpacecraftState[] {
282 transitState
283 }, new TimeStampedPVCoordinates[] {
284 stationUplink.toTimeStampedPVCoordinates(),
285 transitStateDS.toTimeStampedPVCoordinates(),
286 stationDownlink.toTimeStampedPVCoordinates()
287 });
288
289
290 final double cOver2 = 0.5 * Constants.SPEED_OF_LIGHT;
291 final DerivativeStructure tau = tauD.add(tauU);
292 range = tau.multiply(cOver2);
293
294 } else {
295
296 estimated = new EstimatedMeasurement<Range>(this, iteration, evaluation,
297 new SpacecraftState[] {
298 transitState
299 }, new TimeStampedPVCoordinates[] {
300 transitStateDS.toTimeStampedPVCoordinates(),
301 stationDownlink.toTimeStampedPVCoordinates()
302 });
303
304
305 final DerivativeStructure dtg = station.getClockOffsetDriver().getValue(factory, indices);
306 final DerivativeStructure dts = satellite.getClockOffsetDriver().getValue(factory, indices);
307
308
309 range = tauD.add(dtg).subtract(dts).multiply(Constants.SPEED_OF_LIGHT);
310
311 }
312
313 estimated.setEstimatedValue(range.getValue());
314
315
316 final double[] derivatives = range.getAllDerivatives();
317 estimated.setStateDerivatives(0, Arrays.copyOfRange(derivatives, 1, 7));
318
319
320
321 for (final ParameterDriver driver : getParametersDrivers()) {
322 final Integer index = indices.get(driver.getName());
323 if (index != null) {
324 estimated.setParameterDerivatives(driver, derivatives[index + 1]);
325 }
326 }
327
328 return estimated;
329
330 }
331
332 }