1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19
20 import org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.orekit.frames.FieldKinematicTransform;
24 import org.orekit.frames.FieldStaticTransform;
25 import org.orekit.frames.FieldTransform;
26 import org.orekit.frames.Frame;
27 import org.orekit.frames.KinematicTransform;
28 import org.orekit.frames.OriginTransformProvider;
29 import org.orekit.frames.Predefined;
30 import org.orekit.frames.StaticTransform;
31 import org.orekit.frames.Transform;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.FieldAbsoluteDate;
34 import org.orekit.utils.FieldPVCoordinates;
35 import org.orekit.utils.PVCoordinates;
36 import org.orekit.utils.TimeStampedFieldPVCoordinates;
37 import org.orekit.utils.TimeStampedPVCoordinates;
38
39
40
41
42 class JPLCelestialBody implements CelestialBody {
43
44
45 private final String name;
46
47
48 private final String supportedNames;
49
50
51 private final JPLEphemeridesLoader.RawPVProvider rawPVProvider;
52
53
54 private final double gm;
55
56
57 private final double scale;
58
59
60 private final Frame definingFrameAlignedWithIcrf;
61
62
63 private final Frame icrfAlignedFrame;
64
65
66 private final Frame inertialFrame;
67
68
69 private final Frame bodyFrame;
70
71
72
73
74
75
76
77
78
79
80
81
82
83 JPLCelestialBody(final String name, final String supportedNames,
84 final JPLEphemeridesLoader.EphemerisType generateType,
85 final JPLEphemeridesLoader.RawPVProvider rawPVProvider,
86 final double gm, final double scale,
87 final IAUPole iauPole,
88 final Frame definingFrameAlignedWithICRF) {
89 this.name = name;
90 this.gm = gm;
91 this.scale = scale;
92 this.supportedNames = supportedNames;
93 this.rawPVProvider = rawPVProvider;
94 this.definingFrameAlignedWithIcrf = definingFrameAlignedWithICRF;
95 if (rawPVProvider instanceof JPLEphemeridesLoader.ZeroRawPVProvider) {
96
97
98
99 this.icrfAlignedFrame = definingFrameAlignedWithICRF;
100 } else {
101
102 final String icrfName;
103 if (JPLEphemeridesLoader.EphemerisType.SOLAR_SYSTEM_BARYCENTER == generateType) {
104
105
106
107 icrfName = Predefined.ICRF.getName();
108 } else {
109 icrfName = name + "/ICRF";
110 }
111 this.icrfAlignedFrame = new Frame(
112 definingFrameAlignedWithICRF,
113 new OriginTransformProvider(this, definingFrameAlignedWithICRF),
114 icrfName,
115 true);
116 }
117 if (iauPole == null || iauPole.isGcrfAligned()) {
118
119 this.inertialFrame = icrfAlignedFrame;
120 this.bodyFrame = icrfAlignedFrame;
121 } else {
122 this.inertialFrame = new InertiallyOriented(new JPLInertialTransformProvider(icrfAlignedFrame, this, iauPole));
123 this.bodyFrame = new BodyOriented(new JPLRotatingTransformProvider(iauPole));
124 }
125
126 }
127
128
129 @Override
130 public TimeStampedPVCoordinates getPVCoordinates(final AbsoluteDate date, final Frame frame) {
131
132
133 final PVCoordinates rawPV = rawPVProvider.getRawPV(date);
134 final TimeStampedPVCoordinates scaledPV = new TimeStampedPVCoordinates(date, scale, rawPV);
135
136
137 final Transform transform = definingFrameAlignedWithIcrf.getTransformTo(frame, date);
138
139
140 return transform.transformPVCoordinates(scaledPV);
141
142 }
143
144
145
146
147
148
149
150 @Override
151 public <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date,
152 final Frame frame) {
153
154
155 final FieldPVCoordinates<T> rawPV = rawPVProvider.getRawPV(date);
156 final TimeStampedFieldPVCoordinates<T> scaledPV = new TimeStampedFieldPVCoordinates<>(date, scale, rawPV);
157
158
159 final FieldTransform<T> transform = definingFrameAlignedWithIcrf.getTransformTo(frame, date);
160
161
162 return transform.transformPVCoordinates(scaledPV);
163
164 }
165
166
167 @Override
168 public Vector3D getVelocity(final AbsoluteDate date, final Frame frame) {
169
170
171 final PVCoordinates rawPV = rawPVProvider.getRawPV(date);
172 final TimeStampedPVCoordinates scaledPV = new TimeStampedPVCoordinates(date, scale, rawPV);
173
174
175 final KinematicTransform transform = definingFrameAlignedWithIcrf.getKinematicTransformTo(frame, date);
176
177
178 return transform.transformOnlyPV(scaledPV).getVelocity();
179
180 }
181
182
183 @Override
184 public Vector3D getPosition(final AbsoluteDate date, final Frame frame) {
185
186
187 final Vector3D rawPosition = rawPVProvider.getRawPosition(date);
188 final Vector3D scaledPosition = rawPosition.scalarMultiply(scale);
189
190
191 final StaticTransform transform = definingFrameAlignedWithIcrf.getStaticTransformTo(frame, date);
192
193
194 return transform.transformPosition(scaledPosition);
195 }
196
197
198 @Override
199 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPosition(final FieldAbsoluteDate<T> date, final Frame frame) {
200
201
202 final FieldVector3D<T> rawPosition = rawPVProvider.getRawPosition(date);
203 final FieldVector3D<T> scaledPosition = rawPosition.scalarMultiply(scale);
204
205
206 final FieldStaticTransform<T> transform = definingFrameAlignedWithIcrf.getStaticTransformTo(frame, date);
207
208
209 return transform.transformPosition(scaledPosition);
210 }
211
212
213 @Override
214 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getVelocity(final FieldAbsoluteDate<T> date, final Frame frame) {
215
216 final FieldPVCoordinates<T> rawPV = rawPVProvider.getRawPV(date);
217 final TimeStampedFieldPVCoordinates<T> scaledPV = new TimeStampedFieldPVCoordinates<>(date, scale, rawPV);
218
219
220 final FieldKinematicTransform<T> transform = definingFrameAlignedWithIcrf.getKinematicTransformTo(frame, date);
221
222
223 return transform.transformOnlyPV(scaledPV).getVelocity();
224 }
225
226
227 public String getName() {
228 return name;
229 }
230
231
232 public double getGM() {
233 return gm;
234 }
235
236 @Override
237 public Frame getIcrfAlignedFrame() {
238 return icrfAlignedFrame;
239 }
240
241
242 public Frame getInertiallyOrientedFrame() {
243 return inertialFrame;
244 }
245
246
247 public Frame getBodyOrientedFrame() {
248 return bodyFrame;
249 }
250
251
252 private class InertiallyOriented extends Frame {
253
254
255 private static final String INERTIAL_FRAME_SUFFIX = "/inertial";
256
257
258
259
260
261 InertiallyOriented(final JPLInertialTransformProvider transformProvider) {
262 super(transformProvider.getDefiningFrame(), transformProvider, name + INERTIAL_FRAME_SUFFIX, true);
263 }
264
265 }
266
267
268 private class BodyOriented extends Frame {
269
270
271
272
273 private static final String BODY_FRAME_SUFFIX = "/rotating";
274
275
276
277
278
279
280
281 BodyOriented(final JPLRotatingTransformProvider transformProvider) {
282 super(inertialFrame, transformProvider, name + BODY_FRAME_SUFFIX, false);
283 }
284 }
285 }