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