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