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.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
22 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23 import org.hipparchus.geometry.euclidean.threed.Rotation;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.orekit.bodies.BodyShape;
26 import org.orekit.bodies.FieldGeodeticPoint;
27 import org.orekit.bodies.GeodeticPoint;
28 import org.orekit.data.BodiesElements;
29 import org.orekit.data.FundamentalNutationArguments;
30 import org.orekit.frames.FieldStaticTransform;
31 import org.orekit.frames.FieldTransform;
32 import org.orekit.frames.Frame;
33 import org.orekit.frames.StaticTransform;
34 import org.orekit.frames.TopocentricFrame;
35 import org.orekit.frames.Transform;
36 import org.orekit.frames.TransformProvider;
37 import org.orekit.models.earth.displacement.StationDisplacement;
38 import org.orekit.time.AbsoluteDate;
39 import org.orekit.time.FieldAbsoluteDate;
40 import org.orekit.utils.ParameterDriver;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 class GroundStationTransformProvider implements TransformProvider {
64
65
66
67
68 private final Frame frame;
69
70
71 private final EstimatedEarthFrameProvider estimatedEarthFrameProvider;
72
73
74 private final Frame estimatedEarthFrame;
75
76
77 private final TopocentricFrame baseFrame;
78
79
80 private final FundamentalNutationArguments arguments;
81
82
83 private final StationDisplacement[] displacements;
84
85
86 private final ParameterDriver eastOffsetDriver;
87
88
89 private final ParameterDriver northOffsetDriver;
90
91
92 private final ParameterDriver zenithOffsetDriver;
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 GroundStationTransformProvider(final Frame frame, final TopocentricFrame baseFrame,
108 final ParameterDriver eastOffsetDriver,
109 final ParameterDriver northOffsetDriver,
110 final ParameterDriver zenithOffsetDriver,
111 final EstimatedEarthFrameProvider estimatedEarthFrameProvider,
112 final FundamentalNutationArguments fundamentalNutationArguments,
113 final StationDisplacement... displacements) {
114 this.frame = frame;
115 this.baseFrame = baseFrame;
116
117 this.estimatedEarthFrameProvider = estimatedEarthFrameProvider;
118 this.estimatedEarthFrame = new Frame(baseFrame.getParent(), estimatedEarthFrameProvider,
119 baseFrame.getParent() + "-estimated");
120 this.arguments = fundamentalNutationArguments;
121
122 this.displacements = displacements.clone();
123 this.eastOffsetDriver = eastOffsetDriver;
124 this.northOffsetDriver = northOffsetDriver;
125 this.zenithOffsetDriver = zenithOffsetDriver;
126 }
127
128
129 @Override
130 public Transform getTransform(final AbsoluteDate date) {
131
132 final Transform intermediateToBody = estimatedEarthFrameProvider.getTransform(date).getInverse();
133
134
135 final BodyShape baseShape = baseFrame.getParentShape();
136 final Vector3D origin = getOrigin(date);
137
138 final GeodeticPoint originGP = baseShape.transform(origin, baseShape.getBodyFrame(), date);
139 final Transform offsetToIntermediate =
140 new Transform(date,
141 new Transform(date,
142 new Rotation(Vector3D.PLUS_I, Vector3D.PLUS_K,
143 originGP.getEast(), originGP.getZenith()),
144 Vector3D.ZERO),
145 new Transform(date, origin));
146 if (baseFrame.getParent() == frame) {
147 return new Transform(date, offsetToIntermediate, intermediateToBody);
148 }
149
150
151 final Transform bodyToInert = baseFrame.getParent().getTransformTo(frame, date);
152
153 return new Transform(date, offsetToIntermediate, new Transform(date, intermediateToBody, bodyToInert));
154 }
155
156
157 @Override
158 public StaticTransform getStaticTransform(final AbsoluteDate date) {
159
160 final StaticTransform intermediateToBody = estimatedEarthFrameProvider.getStaticTransform(date).getInverse();
161
162
163 final BodyShape baseShape = baseFrame.getParentShape();
164 final Vector3D origin = getOrigin(date);
165
166 final GeodeticPoint originGP = baseShape.transform(origin, baseShape.getBodyFrame(), date);
167 final StaticTransform offsetToIntermediate = StaticTransform.compose(date,
168 StaticTransform.of(date,
169 new Rotation(Vector3D.PLUS_I, Vector3D.PLUS_K,
170 originGP.getEast(), originGP.getZenith())),
171 StaticTransform.of(date, origin));
172 if (baseFrame.getParent() == frame) {
173 return StaticTransform.compose(date, offsetToIntermediate, intermediateToBody);
174 }
175
176
177 final StaticTransform bodyToInert = baseFrame.getParent().getStaticTransformTo(frame, date);
178
179 return StaticTransform.compose(date, offsetToIntermediate, StaticTransform.compose(date, intermediateToBody, bodyToInert));
180 }
181
182
183
184
185
186
187 private Vector3D getOrigin(final AbsoluteDate date) {
188 final double x = eastOffsetDriver.getValue(date);
189 final double y = northOffsetDriver.getValue(date);
190 final double z = zenithOffsetDriver.getValue(date);
191 final Frame bodyFrame = baseFrame.getParentShape().getBodyFrame();
192 final StaticTransform staticTopoToBody = baseFrame.getStaticTransformTo(bodyFrame, date);
193 final Vector3D originBeforeDisplacement = staticTopoToBody.transformPosition(new Vector3D(x, y, z));
194 return originBeforeDisplacement.add(computeDisplacement(date, originBeforeDisplacement));
195 }
196
197
198
199
200
201
202
203 private Vector3D computeDisplacement(final AbsoluteDate date, final Vector3D position) {
204 Vector3D displacement = Vector3D.ZERO;
205 if (arguments != null) {
206 final BodiesElements elements = arguments.evaluateAll(date);
207 for (final StationDisplacement sd : displacements) {
208
209
210 displacement = displacement.add(sd.displacement(elements, estimatedEarthFrame, position));
211 }
212 }
213 return displacement;
214 }
215
216
217 @Override
218 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
219
220
221 final FieldTransform<T> intermediateToBody = estimatedEarthFrameProvider.getTransform(date).getInverse();
222
223
224 final FieldVector3D<T> origin = getOrigin(date);
225 return getTransform(date, origin, intermediateToBody);
226
227 }
228
229 <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date,
230 final FieldVector3D<T> origin,
231 final FieldTransform<T> intermediateToBody) {
232 final Field<T> field = date.getField();
233 final FieldVector3D<T> zero = FieldVector3D.getZero(field);
234 final FieldVector3D<T> plusI = FieldVector3D.getPlusI(field);
235 final FieldVector3D<T> plusK = FieldVector3D.getPlusK(field);
236 final FieldGeodeticPoint<T> originGP = baseFrame.getParentShape().transform(origin,
237 baseFrame.getParentShape().getBodyFrame(), date);
238 final FieldTransform<T> offsetToIntermediate =
239 new FieldTransform<>(date,
240 new FieldTransform<>(date,
241 new FieldRotation<>(plusI, plusK,
242 originGP.getEast(), originGP.getZenith()),
243 zero),
244 new FieldTransform<>(date, origin));
245
246
247 if (baseFrame.getParent() == frame) {
248 return new FieldTransform<>(date, offsetToIntermediate, intermediateToBody);
249 }
250 final FieldTransform<T> bodyToInert = baseFrame.getParent().getTransformTo(frame, date);
251
252 return new FieldTransform<>(date, offsetToIntermediate,
253 new FieldTransform<>(date, intermediateToBody, bodyToInert));
254
255 }
256
257
258 @Override
259 public <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getStaticTransform(final FieldAbsoluteDate<T> date) {
260
261
262 final FieldStaticTransform<T> intermediateToBody = estimatedEarthFrameProvider.getStaticTransform(date).getInverse();
263
264 final FieldVector3D<T> origin = new FieldVector3D<>(date.getField(), getOrigin(date.toAbsoluteDate()));
265
266 final Field<T> field = date.getField();
267 final FieldVector3D<T> plusI = FieldVector3D.getPlusI(field);
268 final FieldVector3D<T> plusK = FieldVector3D.getPlusK(field);
269 final FieldGeodeticPoint<T> originGP = baseFrame.getParentShape().transform(origin,
270 baseFrame.getParentShape().getBodyFrame(), date);
271 final FieldStaticTransform<T> offsetToIntermediate = FieldStaticTransform.compose(date,
272 FieldStaticTransform.of(date,
273 new FieldRotation<>(plusI, plusK, originGP.getEast(), originGP.getZenith())),
274 FieldStaticTransform.of(date, origin));
275
276
277 if (baseFrame.getParent() == frame) {
278 return FieldStaticTransform.compose(date, offsetToIntermediate, intermediateToBody);
279 }
280 final FieldStaticTransform<T> bodyToInert = baseFrame.getParent().getStaticTransformTo(frame, date);
281
282 return FieldStaticTransform.compose(date, offsetToIntermediate,
283 FieldStaticTransform.compose(date, intermediateToBody, bodyToInert));
284 }
285
286
287
288
289
290
291
292 private <T extends CalculusFieldElement<T>> FieldVector3D<T> getOrigin(final FieldAbsoluteDate<T> date) {
293 final AbsoluteDate absoluteDate = date.toAbsoluteDate();
294 final Field<T> field = date.getField();
295 final T x = field.getZero().newInstance(eastOffsetDriver.getValue(absoluteDate));
296 final T y = field.getZero().newInstance(northOffsetDriver.getValue(absoluteDate));
297 final T z = field.getZero().newInstance(zenithOffsetDriver.getValue(absoluteDate));
298 final Frame bodyFrame = baseFrame.getParentShape().getBodyFrame();
299 final FieldStaticTransform<T> staticTopoToBody = baseFrame.getStaticTransformTo(bodyFrame, date);
300 final FieldVector3D<T> originBeforeDisplacement = staticTopoToBody.transformPosition(new FieldVector3D<>(x, y, z));
301 return originBeforeDisplacement.add(computeDisplacement(absoluteDate, originBeforeDisplacement.toVector3D()));
302 }
303
304 }