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 java.util.Arrays;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import org.hipparchus.analysis.differentiation.Gradient;
25 import org.orekit.estimation.measurements.AbstractMeasurement;
26 import org.orekit.estimation.measurements.EstimatedMeasurement;
27 import org.orekit.estimation.measurements.ObservableSatellite;
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.PVCoordinatesProvider;
33 import org.orekit.utils.ParameterDriver;
34 import org.orekit.utils.TimeStampedFieldPVCoordinates;
35 import org.orekit.utils.TimeStampedPVCoordinates;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class OneWayGNSSPhase extends AbstractMeasurement<OneWayGNSSPhase> {
57
58
59 public static final String AMBIGUITY_NAME = "ambiguity";
60
61
62 private final ParameterDriver ambiguityDriver;
63
64
65 private final PVCoordinatesProvider remote;
66
67
68 private final double dtRemote;
69
70
71 private final double wavelength;
72
73
74
75
76
77
78
79
80
81
82
83 public OneWayGNSSPhase(final PVCoordinatesProvider remote,
84 final double dtRemote,
85 final AbsoluteDate date,
86 final double phase, final double wavelength, final double sigma,
87 final double baseWeight, final ObservableSatellite local) {
88
89 super(date, phase, sigma, baseWeight, Collections.singletonList(local));
90
91
92 ambiguityDriver = new ParameterDriver(AMBIGUITY_NAME, 0.0, 1.0,
93 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
94
95
96 addParameterDriver(ambiguityDriver);
97 addParameterDriver(local.getClockOffsetDriver());
98
99
100 this.dtRemote = dtRemote;
101 this.remote = remote;
102 this.wavelength = wavelength;
103 }
104
105
106
107
108 public double getWavelength() {
109 return wavelength;
110 }
111
112
113
114
115 public ParameterDriver getAmbiguityDriver() {
116 return ambiguityDriver;
117 }
118
119
120 @Override
121 protected EstimatedMeasurement<OneWayGNSSPhase> theoreticalEvaluation(final int iteration,
122 final int evaluation,
123 final SpacecraftState[] states) {
124
125
126
127
128
129
130 int nbEstimatedParamsPhase = 6;
131 final Map<String, Integer> parameterIndicesPhase = new HashMap<>();
132 for (ParameterDriver phaseMeasurementDriver : getParametersDrivers()) {
133 if (phaseMeasurementDriver.isSelected()) {
134 parameterIndicesPhase.put(phaseMeasurementDriver.getName(), nbEstimatedParamsPhase++);
135 }
136 }
137
138
139 final SpacecraftState localState = states[0];
140 final TimeStampedFieldPVCoordinates<Gradient> pvaLocal = getCoordinates(localState, 0, nbEstimatedParamsPhase);
141 final TimeStampedPVCoordinates pvaRemote = remote.getPVCoordinates(getDate(), localState.getFrame());
142
143
144 final Gradient dtLocal = getSatellites().get(0).getClockOffsetDriver().getValue(nbEstimatedParamsPhase, parameterIndicesPhase);
145 final FieldAbsoluteDate<Gradient> arrivalDate = new FieldAbsoluteDate<>(getDate(), dtLocal.negate());
146
147 final TimeStampedFieldPVCoordinates<Gradient> s1Downlink =
148 pvaLocal.shiftedBy(arrivalDate.durationFrom(pvaLocal.getDate()));
149 final Gradient tauD = signalTimeOfFlight(new TimeStampedFieldPVCoordinates<>(pvaRemote.getDate(), dtLocal.getField().getOne(), pvaRemote),
150 s1Downlink.getPosition(), arrivalDate);
151
152
153 final double delta = getDate().durationFrom(pvaRemote.getDate());
154 final Gradient deltaMTauD = tauD.negate().add(delta);
155
156
157 final EstimatedMeasurement<OneWayGNSSPhase> estimatedPhase =
158 new EstimatedMeasurement<>(this, iteration, evaluation,
159 new SpacecraftState[] {
160 localState.shiftedBy(deltaMTauD.getValue())
161 }, new TimeStampedPVCoordinates[] {
162 pvaRemote.shiftedBy(delta - tauD.getValue()),
163 localState.shiftedBy(delta).getPVCoordinates()
164 });
165
166
167 final double cOverLambda = Constants.SPEED_OF_LIGHT / wavelength;
168 final Gradient ambiguity = ambiguityDriver.getValue(nbEstimatedParamsPhase, parameterIndicesPhase);
169 final Gradient phase = tauD.add(dtLocal).subtract(dtRemote).multiply(cOverLambda).add(ambiguity);
170 final double[] phaseDerivatives = phase.getGradient();
171
172
173 estimatedPhase.setEstimatedValue(phase.getValue());
174 estimatedPhase.setStateDerivatives(0, Arrays.copyOfRange(phaseDerivatives, 0, 6));
175
176
177 for (final ParameterDriver phaseMeasurementDriver : getParametersDrivers()) {
178 final Integer index = parameterIndicesPhase.get(phaseMeasurementDriver.getName());
179 if (index != null) {
180 estimatedPhase.setParameterDerivatives(phaseMeasurementDriver, phaseDerivatives[index]);
181 }
182 }
183
184
185 return estimatedPhase;
186
187 }
188
189 }