1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements.gnss;
18
19 import org.hipparchus.analysis.differentiation.Gradient;
20 import org.hipparchus.analysis.differentiation.GradientField;
21 import org.orekit.estimation.measurements.AbstractMeasurement;
22 import org.orekit.estimation.measurements.ObservableSatellite;
23 import org.orekit.estimation.measurements.ObservedMeasurement;
24 import org.orekit.estimation.measurements.QuadraticClockModel;
25 import org.orekit.estimation.measurements.QuadraticFieldClockModel;
26 import org.orekit.frames.Frame;
27 import org.orekit.propagation.SpacecraftState;
28 import org.orekit.time.AbsoluteDate;
29 import org.orekit.time.ClockOffset;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.time.FieldClockOffset;
32 import org.orekit.utils.FieldPVCoordinatesProvider;
33 import org.orekit.utils.PVCoordinatesProvider;
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 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Map;
42
43
44
45
46
47
48 public abstract class AbstractOnBoardMeasurement<T extends ObservedMeasurement<T>> extends AbstractMeasurement<T> {
49
50
51
52
53
54
55
56
57 public AbstractOnBoardMeasurement(final AbsoluteDate date, final double observed,
58 final double sigma, final double baseWeight,
59 final List<ObservableSatellite> satellites) {
60
61 super(date, observed, sigma, baseWeight, satellites);
62
63
64 satellites.forEach(s -> {
65 addParameterDriver(s.getClockOffsetDriver());
66 addParameterDriver(s.getClockDriftDriver());
67 addParameterDriver(s.getClockAccelerationDriver());
68 });
69
70 }
71
72
73
74
75 protected abstract QuadraticClockModel getRemoteClock();
76
77
78
79
80
81 protected abstract PVCoordinatesProvider getRemotePV(SpacecraftState[] states);
82
83
84
85
86
87
88 protected abstract FieldPVCoordinatesProvider<Gradient> getRemotePV(SpacecraftState[] states,
89 int freeParameters);
90
91
92
93
94
95
96
97 protected QuadraticFieldClockModel<Gradient> getRemoteClock(final int freeParameters,
98 final Map<String, Integer> indices) {
99 return getRemoteClock().toGradientModel(freeParameters, indices, getDate());
100 }
101
102
103
104
105
106
107
108
109 protected OnBoardCommonParametersWithoutDerivatives computeCommonParametersWithout(final SpacecraftState[] states,
110 final boolean clockOffsetAlreadyApplied) {
111
112
113 final Frame frame = states[0].getFrame();
114 final TimeStampedPVCoordinates pvaLocal = states[0].getPVCoordinates(frame);
115 final ClockOffset localClock = getSatellites().
116 get(0).
117 getQuadraticClockModel().
118 getOffset(getDate());
119 final double localClockOffset = localClock.getOffset();
120 final double localClockRate = localClock.getRate();
121 final PVCoordinatesProvider remotePV = getRemotePV(states);
122
123
124 final AbsoluteDate arrivalDate = clockOffsetAlreadyApplied ? getDate() : getDate().shiftedBy(-localClockOffset);
125
126
127 final double deltaT = arrivalDate.durationFrom(states[0]);
128 final TimeStampedPVCoordinates pvaDownlink = pvaLocal.shiftedBy(deltaT);
129 final double tauD = signalTimeOfFlightAdjustableEmitter(remotePV, arrivalDate, pvaDownlink.getPosition(),
130 arrivalDate, frame);
131
132
133 final AbsoluteDate emissionDate = arrivalDate.shiftedBy(-tauD);
134 final ClockOffset remoteClock = getRemoteClock().getOffset(emissionDate);
135 final double remoteClockOffset = remoteClock.getOffset();
136 final double remoteClockRate = remoteClock.getRate();
137 return new OnBoardCommonParametersWithoutDerivatives(states[0],
138 localClockOffset, localClockRate,
139 remoteClockOffset, remoteClockRate,
140 tauD, pvaDownlink,
141 remotePV.getPVCoordinates(emissionDate, frame));
142
143 }
144
145
146
147
148
149
150
151
152 protected OnBoardCommonParametersWithDerivatives computeCommonParametersWith(final SpacecraftState[] states,
153 final boolean clockOffsetAlreadyApplied) {
154
155 final Frame frame = states[0].getFrame();
156
157
158
159
160
161
162 int nbEstimatedParams = 6 * states.length;
163 final Map<String, Integer> parameterIndices = new HashMap<>();
164 for (ParameterDriver measurementDriver : getParametersDrivers()) {
165 if (measurementDriver.isSelected()) {
166 for (Span<String> span = measurementDriver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
167 parameterIndices.put(span.getData(), nbEstimatedParams++);
168 }
169 }
170 }
171 final FieldAbsoluteDate<Gradient> gDate = new FieldAbsoluteDate<>(GradientField.getField(nbEstimatedParams),
172 getDate());
173
174
175 final TimeStampedFieldPVCoordinates<Gradient> pvaLocal = getCoordinates(states[0], 0, nbEstimatedParams);
176 final QuadraticFieldClockModel<Gradient> localClock = getSatellites().get(0).getQuadraticClockModel().
177 toGradientModel(nbEstimatedParams, parameterIndices, getDate());
178 final FieldClockOffset<Gradient> localClockOffset = localClock.getOffset(gDate);
179 final FieldPVCoordinatesProvider<Gradient> remotePV = getRemotePV(states, nbEstimatedParams);
180
181
182 final FieldAbsoluteDate<Gradient> arrivalDate = clockOffsetAlreadyApplied ?
183 gDate : gDate.shiftedBy(localClockOffset.getOffset().negate());
184
185
186 final Gradient deltaT = arrivalDate.durationFrom(states[0].getDate());
187 final TimeStampedFieldPVCoordinates<Gradient> pvaDownlink = pvaLocal.shiftedBy(deltaT);
188 final Gradient tauD = signalTimeOfFlightAdjustableEmitter(remotePV, arrivalDate,
189 pvaDownlink.getPosition(), arrivalDate,
190 frame);
191
192
193 final FieldAbsoluteDate<Gradient> emissionDate = arrivalDate.shiftedBy(tauD.negate());
194 final QuadraticFieldClockModel<Gradient> remoteClock = getRemoteClock(nbEstimatedParams, parameterIndices);
195 final FieldClockOffset<Gradient> remoteClockOffset = remoteClock.getOffset(emissionDate);
196 return new OnBoardCommonParametersWithDerivatives(states[0], parameterIndices,
197 localClockOffset.getOffset(), localClockOffset.getRate(),
198 remoteClockOffset.getOffset(), remoteClockOffset.getRate(),
199 tauD, pvaDownlink,
200 remotePV.getPVCoordinates(emissionDate, frame));
201
202 }
203
204 }