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.Collections;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import org.hipparchus.analysis.differentiation.Gradient;
24 import org.hipparchus.analysis.differentiation.GradientField;
25 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.orekit.frames.FieldTransform;
28 import org.orekit.frames.Frame;
29 import org.orekit.frames.Transform;
30 import org.orekit.propagation.SpacecraftState;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.time.FieldAbsoluteDate;
33 import org.orekit.utils.PVCoordinates;
34 import org.orekit.utils.ParameterDriver;
35 import org.orekit.utils.TimeSpanMap.Span;
36 import org.orekit.utils.TimeStampedFieldPVCoordinates;
37 import org.orekit.utils.TimeStampedPVCoordinates;
38
39
40
41
42
43
44
45
46 public abstract class GroundReceiverMeasurement<T extends GroundReceiverMeasurement<T>> extends AbstractMeasurement<T> {
47
48
49 private final GroundStation station;
50
51
52 private final boolean twoway;
53
54
55
56
57
58
59
60
61
62
63 public GroundReceiverMeasurement(final GroundStation station, final boolean twoWay, final AbsoluteDate date,
64 final double observed, final double sigma, final double baseWeight,
65 final ObservableSatellite satellite) {
66 super(date, observed, sigma, baseWeight, Collections.singletonList(satellite));
67 addParameterDriver(station.getClockOffsetDriver());
68 addParameterDriver(station.getClockDriftDriver());
69 addParameterDriver(station.getClockAccelerationDriver());
70 addParameterDriver(station.getEastOffsetDriver());
71 addParameterDriver(station.getNorthOffsetDriver());
72 addParameterDriver(station.getZenithOffsetDriver());
73 addParameterDriver(station.getPrimeMeridianOffsetDriver());
74 addParameterDriver(station.getPrimeMeridianDriftDriver());
75 addParameterDriver(station.getPolarOffsetXDriver());
76 addParameterDriver(station.getPolarDriftXDriver());
77 addParameterDriver(station.getPolarOffsetYDriver());
78 addParameterDriver(station.getPolarDriftYDriver());
79 if (!twoWay) {
80
81 addParameterDriver(satellite.getClockOffsetDriver());
82 addParameterDriver(satellite.getClockDriftDriver());
83 addParameterDriver(satellite.getClockAccelerationDriver());
84 }
85 this.station = station;
86 this.twoway = twoWay;
87 }
88
89
90
91
92
93
94
95
96
97
98 public GroundReceiverMeasurement(final GroundStation station, final boolean twoWay, final AbsoluteDate date,
99 final double[] observed, final double[] sigma, final double[] baseWeight,
100 final ObservableSatellite satellite) {
101 super(date, observed, sigma, baseWeight, Collections.singletonList(satellite));
102 addParameterDriver(station.getClockOffsetDriver());
103 addParameterDriver(station.getClockDriftDriver());
104 addParameterDriver(station.getClockAccelerationDriver());
105 addParameterDriver(station.getEastOffsetDriver());
106 addParameterDriver(station.getNorthOffsetDriver());
107 addParameterDriver(station.getZenithOffsetDriver());
108 addParameterDriver(station.getPrimeMeridianOffsetDriver());
109 addParameterDriver(station.getPrimeMeridianDriftDriver());
110 addParameterDriver(station.getPolarOffsetXDriver());
111 addParameterDriver(station.getPolarDriftXDriver());
112 addParameterDriver(station.getPolarOffsetYDriver());
113 addParameterDriver(station.getPolarDriftYDriver());
114 if (!twoWay) {
115
116 addParameterDriver(satellite.getClockOffsetDriver());
117 addParameterDriver(satellite.getClockDriftDriver());
118 addParameterDriver(satellite.getClockAccelerationDriver());
119 }
120 this.station = station;
121 this.twoway = twoWay;
122 }
123
124
125
126
127 public GroundStation getStation() {
128 return station;
129 }
130
131
132
133
134 public boolean isTwoWay() {
135 return twoway;
136 }
137
138
139
140
141
142 protected GroundReceiverCommonParametersWithoutDerivatives computeCommonParametersWithout(final SpacecraftState state) {
143
144
145 final TimeStampedPVCoordinates pva = state.getPVCoordinates();
146
147
148 final Transform offsetToInertialDownlink =
149 getStation().getOffsetToInertial(state.getFrame(), getDate(), false);
150 final AbsoluteDate downlinkDate = offsetToInertialDownlink.getDate();
151
152
153 final TimeStampedPVCoordinates origin = new TimeStampedPVCoordinates(downlinkDate,
154 Vector3D.ZERO, Vector3D.ZERO, Vector3D.ZERO);
155 final TimeStampedPVCoordinates stationDownlink = offsetToInertialDownlink.transformPVCoordinates(origin);
156
157
158
159
160
161
162 final double tauD = signalTimeOfFlightAdjustableEmitter(pva, stationDownlink.getPosition(), downlinkDate, state.getFrame());
163
164
165 final double delta = downlinkDate.durationFrom(state.getDate());
166 final double deltaMTauD = delta - tauD;
167 final SpacecraftState transitState = state.shiftedBy(deltaMTauD);
168
169 return new GroundReceiverCommonParametersWithoutDerivatives(state,
170 offsetToInertialDownlink,
171 stationDownlink,
172 tauD,
173 transitState,
174 transitState.getPVCoordinates());
175
176 }
177
178
179
180
181
182 protected GroundReceiverCommonParametersWithDerivatives computeCommonParametersWithDerivatives(final SpacecraftState state) {
183 int nbParams = 6;
184 final Map<String, Integer> indices = new HashMap<>();
185 for (ParameterDriver driver : getParametersDrivers()) {
186 if (driver.isSelected()) {
187 for (Span<String> span = driver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
188 indices.put(span.getData(), nbParams++);
189 }
190 }
191 }
192 final FieldVector3D<Gradient> zero = FieldVector3D.getZero(GradientField.getField(nbParams));
193
194
195 final TimeStampedFieldPVCoordinates<Gradient> pva = getCoordinates(state, 0, nbParams);
196
197
198
199 final FieldTransform<Gradient> offsetToInertialDownlink =
200 getStation().getOffsetToInertial(state.getFrame(), getDate(), nbParams, indices);
201 final FieldAbsoluteDate<Gradient> downlinkDate = offsetToInertialDownlink.getFieldDate();
202
203
204 final TimeStampedFieldPVCoordinates<Gradient> stationDownlink =
205 offsetToInertialDownlink.transformPVCoordinates(new TimeStampedFieldPVCoordinates<>(downlinkDate,
206 zero, zero, zero));
207
208
209
210
211
212
213 final Gradient tauD = signalTimeOfFlightAdjustableEmitter(pva, stationDownlink.getPosition(),
214 downlinkDate, state.getFrame());
215
216
217 final Gradient delta = downlinkDate.durationFrom(state.getDate());
218 final Gradient deltaMTauD = tauD.negate().add(delta);
219 final SpacecraftState transitState = state.shiftedBy(deltaMTauD.getValue());
220 final TimeStampedFieldPVCoordinates<Gradient> transitPV = pva.shiftedBy(deltaMTauD);
221
222 return new GroundReceiverCommonParametersWithDerivatives(state,
223 indices,
224 offsetToInertialDownlink,
225 stationDownlink,
226 tauD,
227 transitState,
228 transitPV);
229
230 }
231
232
233
234
235
236
237
238 public Vector3D getGroundStationPosition(final Frame frame) {
239 return station.getBaseFrame().getPosition(getDate(), frame);
240 }
241
242
243
244
245
246
247
248 public PVCoordinates getGroundStationCoordinates(final Frame frame) {
249 return station.getBaseFrame().getPVCoordinates(getDate(), frame);
250 }
251
252 }