1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.orekit.time.AbsoluteDate;
23 import org.orekit.time.FieldAbsoluteDate;
24 import org.orekit.time.TimeScale;
25 import org.orekit.time.TimeStamped;
26 import org.orekit.utils.FieldPVCoordinates;
27 import org.orekit.utils.PVCoordinates;
28
29
30
31
32
33
34
35
36 class PosVelChebyshev implements TimeStamped {
37
38
39 private final TimeScale timeScale;
40
41
42 private final AbsoluteDate start;
43
44
45 private final double duration;
46
47
48 private final double[] xCoeffs;
49
50
51 private final double[] yCoeffs;
52
53
54 private final double[] zCoeffs;
55
56
57 private final double vScale;
58
59 private final double aScale;
60
61
62
63
64
65
66
67
68
69
70
71
72 PosVelChebyshev(final AbsoluteDate start, final TimeScale timeScale, final double duration,
73 final double[] xCoeffs, final double[] yCoeffs, final double[] zCoeffs) {
74 this.start = start;
75 this.timeScale = timeScale;
76 this.duration = duration;
77 this.xCoeffs = xCoeffs;
78 this.yCoeffs = yCoeffs;
79 this.zCoeffs = zCoeffs;
80 this.vScale = 2 / duration;
81 this.aScale = this.vScale * this.vScale;
82 }
83
84
85 public AbsoluteDate getDate() {
86 return start;
87 }
88
89
90
91
92
93 private double computeValueIndependentVariable(final AbsoluteDate date) {
94 return (2 * date.offsetFrom(start, timeScale) - duration) / duration;
95 }
96
97
98
99
100
101
102 private <T extends CalculusFieldElement<T>> T computeValueIndependentVariable(final FieldAbsoluteDate<T> date) {
103 return date.offsetFrom(new FieldAbsoluteDate<>(date.getField(), start), timeScale).multiply(2).subtract(duration).divide(duration);
104 }
105
106
107
108
109
110 public boolean inRange(final AbsoluteDate date) {
111 final double dt = date.offsetFrom(start, timeScale);
112 return dt >= -0.001 && dt <= duration + 0.001;
113 }
114
115
116
117
118
119 Vector3D getPosition(final AbsoluteDate date) {
120
121
122 final double t = computeValueIndependentVariable(date);
123 final double twoT = 2 * t;
124
125
126 double pKm1 = 1;
127 double pK = t;
128 double xP = xCoeffs[0];
129 double yP = yCoeffs[0];
130 double zP = zCoeffs[0];
131
132
133 for (int k = 1; k < xCoeffs.length; ++k) {
134
135
136 xP += xCoeffs[k] * pK;
137 yP += yCoeffs[k] * pK;
138 zP += zCoeffs[k] * pK;
139
140
141 final double pKm2 = pKm1;
142 pKm1 = pK;
143 pK = twoT * pKm1 - pKm2;
144
145 }
146
147 return new Vector3D(xP, yP, zP);
148 }
149
150
151
152
153
154
155 <T extends CalculusFieldElement<T>> FieldVector3D<T> getPosition(final FieldAbsoluteDate<T> date) {
156
157 final T zero = date.getField().getZero();
158 final T one = date.getField().getOne();
159
160
161 final T t = computeValueIndependentVariable(date);
162 final T twoT = t.add(t);
163
164
165 T pKm1 = one;
166 T pK = t;
167 T xP = zero.newInstance(xCoeffs[0]);
168 T yP = zero.newInstance(yCoeffs[0]);
169 T zP = zero.newInstance(zCoeffs[0]);
170
171
172 for (int k = 1; k < xCoeffs.length; ++k) {
173
174
175 xP = xP.add(pK.multiply(xCoeffs[k]));
176 yP = yP.add(pK.multiply(yCoeffs[k]));
177 zP = zP.add(pK.multiply(zCoeffs[k]));
178
179
180 final T pKm2 = pKm1;
181 pKm1 = pK;
182 pK = twoT.multiply(pKm1).subtract(pKm2);
183
184 }
185
186 return new FieldVector3D<>(xP, yP, zP);
187
188 }
189
190
191
192
193
194 PVCoordinates getPositionVelocityAcceleration(final AbsoluteDate date) {
195
196
197 final double t = computeValueIndependentVariable(date);
198 final double twoT = 2 * t;
199
200
201 double pKm1 = 1;
202 double pK = t;
203 double xP = xCoeffs[0];
204 double yP = yCoeffs[0];
205 double zP = zCoeffs[0];
206
207
208 double qKm1 = 0;
209 double qK = 1;
210 double xV = 0;
211 double yV = 0;
212 double zV = 0;
213
214
215 double rKm1 = 0;
216 double rK = 0;
217 double xA = 0;
218 double yA = 0;
219 double zA = 0;
220
221
222 for (int k = 1; k < xCoeffs.length; ++k) {
223
224
225 xP += xCoeffs[k] * pK;
226 yP += yCoeffs[k] * pK;
227 zP += zCoeffs[k] * pK;
228
229
230 xV += xCoeffs[k] * qK;
231 yV += yCoeffs[k] * qK;
232 zV += zCoeffs[k] * qK;
233
234
235 xA += xCoeffs[k] * rK;
236 yA += yCoeffs[k] * rK;
237 zA += zCoeffs[k] * rK;
238
239
240 final double pKm2 = pKm1;
241 pKm1 = pK;
242 pK = twoT * pKm1 - pKm2;
243
244
245 final double qKm2 = qKm1;
246 qKm1 = qK;
247 qK = twoT * qKm1 + 2 * pKm1 - qKm2;
248
249
250 final double rKm2 = rKm1;
251 rKm1 = rK;
252 rK = twoT * rKm1 + 4 * qKm1 - rKm2;
253
254 }
255
256 return new PVCoordinates(new Vector3D(xP, yP, zP),
257 new Vector3D(xV * vScale, yV * vScale, zV * vScale),
258 new Vector3D(xA * aScale, yA * aScale, zA * aScale));
259
260 }
261
262
263
264
265
266
267 <T extends CalculusFieldElement<T>> FieldPVCoordinates<T> getPositionVelocityAcceleration(final FieldAbsoluteDate<T> date) {
268
269 final T zero = date.getField().getZero();
270 final T one = date.getField().getOne();
271
272
273 final T t = computeValueIndependentVariable(date);
274 final T twoT = t.add(t);
275
276
277 T pKm1 = one;
278 T pK = t;
279 T xP = zero.newInstance(xCoeffs[0]);
280 T yP = zero.newInstance(yCoeffs[0]);
281 T zP = zero.newInstance(zCoeffs[0]);
282
283
284 T qKm1 = zero;
285 T qK = one;
286 T xV = zero;
287 T yV = zero;
288 T zV = zero;
289
290
291 T rKm1 = zero;
292 T rK = zero;
293 T xA = zero;
294 T yA = zero;
295 T zA = zero;
296
297
298 for (int k = 1; k < xCoeffs.length; ++k) {
299
300
301 xP = xP.add(pK.multiply(xCoeffs[k]));
302 yP = yP.add(pK.multiply(yCoeffs[k]));
303 zP = zP.add(pK.multiply(zCoeffs[k]));
304
305
306 xV = xV.add(qK.multiply(xCoeffs[k]));
307 yV = yV.add(qK.multiply(yCoeffs[k]));
308 zV = zV.add(qK.multiply(zCoeffs[k]));
309
310
311 xA = xA.add(rK.multiply(xCoeffs[k]));
312 yA = yA.add(rK.multiply(yCoeffs[k]));
313 zA = zA.add(rK.multiply(zCoeffs[k]));
314
315
316 final T pKm2 = pKm1;
317 pKm1 = pK;
318 pK = twoT.multiply(pKm1).subtract(pKm2);
319
320
321 final T qKm2 = qKm1;
322 qKm1 = qK;
323 qK = twoT.multiply(qKm1).add(pKm1.multiply(2)).subtract(qKm2);
324
325
326 final T rKm2 = rKm1;
327 rKm1 = rK;
328 rK = twoT.multiply(rKm1).add(qKm1.multiply(4)).subtract(rKm2);
329
330 }
331
332 return new FieldPVCoordinates<>(new FieldVector3D<>(xP, yP, zP),
333 new FieldVector3D<>(xV.multiply(vScale), yV.multiply(vScale), zV.multiply(vScale)),
334 new FieldVector3D<>(xA.multiply(aScale), yA.multiply(aScale), zA.multiply(aScale)));
335
336 }
337
338 }