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 org.hipparchus.analysis.UnivariateFunction;
20 import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
21 import org.hipparchus.analysis.solvers.UnivariateSolver;
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.hipparchus.util.FastMath;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.estimation.Context;
26 import org.orekit.frames.Frame;
27 import org.orekit.frames.Transform;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.utils.Constants;
31 import org.orekit.utils.PVCoordinates;
32 import org.orekit.utils.ParameterDriver;
33 import org.orekit.utils.TimeStampedPVCoordinates;
34
35 import java.util.Arrays;
36 import java.util.Map;
37
38
39
40
41
42 public class TurnAroundRangeMeasurementCreator extends MeasurementCreator {
43
44 private final Context context;
45 private final Vector3D antennaPhaseCenter;
46 private final ObservableSatellite satellite;
47
48 public TurnAroundRangeMeasurementCreator(final Context context) {
49 this(context, Vector3D.ZERO);
50 }
51
52 public TurnAroundRangeMeasurementCreator(final Context context, final Vector3D antennaPhaseCenter) {
53 this.context = context;
54 this.antennaPhaseCenter = antennaPhaseCenter;
55 this.satellite = new ObservableSatellite(0);
56 }
57
58 public void init(SpacecraftState s0, AbsoluteDate t, double step) {
59 for (Map.Entry<GroundStation, GroundStation> entry : context.TARstations.entrySet()) {
60 for (final GroundStation station : Arrays.asList(entry.getKey(), entry.getValue())) {
61 for (ParameterDriver driver : Arrays.asList(station.getClockOffsetDriver(),
62 station.getEastOffsetDriver(),
63 station.getNorthOffsetDriver(),
64 station.getZenithOffsetDriver(),
65 station.getPrimeMeridianOffsetDriver(),
66 station.getPrimeMeridianDriftDriver(),
67 station.getPolarOffsetXDriver(),
68 station.getPolarDriftXDriver(),
69 station.getPolarOffsetYDriver(),
70 station.getPolarDriftYDriver())) {
71 if (driver.getReferenceDate() == null) {
72 driver.setReferenceDate(s0.getDate());
73 }
74 }
75
76 }
77 }
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 public void handleStep(final SpacecraftState currentState) {
104 try {
105 for (Map.Entry<GroundStation, GroundStation> entry : context.TARstations.entrySet()) {
106
107 final GroundStation primaryStation = entry.getKey();
108 final GroundStation secondaryStation = entry.getValue();
109 final AbsoluteDate date = currentState.getDate();
110 final Frame inertial = currentState.getFrame();
111 final Vector3D position = currentState.toStaticTransform().getInverse().transformPosition(antennaPhaseCenter);
112
113
114 if ((primaryStation.getBaseFrame().getTrackingCoordinates(position, inertial, date).getElevation() > FastMath.toRadians(30.0))&&
115 (secondaryStation.getBaseFrame().getTrackingCoordinates(position, inertial, date).getElevation() > FastMath.toRadians(30.0))) {
116
117
118 final UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 5);
119
120
121
122 final Vector3D secondaryStationPosition =
123 secondaryStation.getOffsetToInertial(inertial, date, false).transformPosition(Vector3D.ZERO);
124
125
126
127
128
129
130 final double secondaryTauD = solver.solve(1000, new UnivariateFunction() {
131 public double value(final double x) {
132 final SpacecraftState transitState = currentState.shiftedBy(-x);
133 final double d = Vector3D.distance(transitState.toStaticTransform().getInverse().transformPosition(antennaPhaseCenter),
134 secondaryStationPosition);
135 return d - x * Constants.SPEED_OF_LIGHT;
136 }
137 }, -1.0, 1.0);
138
139
140
141
142 final double secondaryTauU = solver.solve(1000, new UnivariateFunction() {
143 public double value(final double x) {
144 final SpacecraftState transitState = currentState.shiftedBy(+x);
145 final double d = Vector3D.distance(transitState.toStaticTransform().getInverse().transformPosition(antennaPhaseCenter),
146 secondaryStationPosition);
147 return d - x * Constants.SPEED_OF_LIGHT;
148 }
149 }, -1.0, 1.0);
150
151
152
153
154
155
156 final SpacecraftState S1 = currentState.shiftedBy(-secondaryTauD);
157 final Vector3D P1 = S1.toStaticTransform().getInverse().transformPosition(antennaPhaseCenter);
158 final AbsoluteDate T1 = date.shiftedBy(-secondaryTauD);
159
160
161 final Vector3D P2 = currentState.shiftedBy(+secondaryTauU).toStaticTransform().getInverse().transformPosition(antennaPhaseCenter);
162 final AbsoluteDate T2 = date.shiftedBy(+secondaryTauU);
163
164
165
166
167
168 final double primaryTauD = solver.solve(1000, new UnivariateFunction() {
169 public double value(final double x) {
170 final Transform t = primaryStation.getOffsetToInertial(inertial, T2.shiftedBy(+x), false);
171 final double d = Vector3D.distance(P2, t.transformPosition(Vector3D.ZERO));
172 return d - x * Constants.SPEED_OF_LIGHT;
173 }
174 }, -1.0, 1.0);
175
176 final AbsoluteDate primaryReceptionDate = T2.shiftedBy(+primaryTauD);
177 final TimeStampedPVCoordinates primaryStationAtReception =
178 primaryStation.getOffsetToInertial(inertial, primaryReceptionDate, false).
179 transformPVCoordinates(new TimeStampedPVCoordinates(primaryReceptionDate, PVCoordinates.ZERO));
180
181
182
183
184
185 final double primaryTauU = AbstractMeasurement.signalTimeOfFlightAdjustableEmitter(primaryStationAtReception, P1, T1, inertial);
186
187 final AbsoluteDate primaryEmissionDate = T1.shiftedBy(-primaryTauU);
188
189 final Vector3D primaryStationAtEmission =
190 primaryStation.getOffsetToInertial(inertial, primaryEmissionDate, false).transformPosition(Vector3D.ZERO);
191
192
193
194 final double secondaryDownLinkDistance = Vector3D.distance(P1, secondaryStationPosition);
195 final double secondaryUpLinkDistance = Vector3D.distance(P2, secondaryStationPosition);
196
197
198 final double primaryUpLinkDistance = Vector3D.distance(P1, primaryStationAtEmission);
199 final double primaryDownLinkDistance = Vector3D.distance(P2, primaryStationAtReception.getPosition());
200
201 addMeasurement(new TurnAroundRange(primaryStation, secondaryStation, primaryReceptionDate,
202 0.5 * (primaryUpLinkDistance + secondaryDownLinkDistance +
203 secondaryUpLinkDistance + primaryDownLinkDistance), 1.0, 10, satellite));
204 }
205
206 }
207 } catch (OrekitException oe) {
208 throw new OrekitException(oe);
209 }
210 }
211
212 }