1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.rugged.utils;
18
19 import java.io.Serializable;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import org.apache.commons.math3.util.FastMath;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.frames.Frame;
26 import org.orekit.frames.Transform;
27 import org.orekit.rugged.errors.DumpManager;
28 import org.orekit.rugged.errors.RuggedException;
29 import org.orekit.rugged.errors.RuggedMessages;
30 import org.orekit.time.AbsoluteDate;
31 import org.orekit.utils.AngularDerivativesFilter;
32 import org.orekit.utils.CartesianDerivativesFilter;
33 import org.orekit.utils.ImmutableTimeStampedCache;
34 import org.orekit.utils.TimeStampedAngularCoordinates;
35 import org.orekit.utils.TimeStampedCache;
36 import org.orekit.utils.TimeStampedPVCoordinates;
37
38
39
40
41 public class SpacecraftToObservedBody implements Serializable {
42
43
44 private static final long serialVersionUID = 20140909L;
45
46
47 private final Frame inertialFrame;
48
49
50 private final Frame bodyFrame;
51
52
53 private final AbsoluteDate minDate;
54
55
56 private final AbsoluteDate maxDate;
57
58
59 private final double tStep;
60
61
62 private final double overshootTolerance;
63
64
65 private final List<Transform> bodyToInertial;
66
67
68 private final List<Transform> inertialToBody;
69
70
71 private final List<Transform> scToInertial;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public SpacecraftToObservedBody(final Frame inertialFrame, final Frame bodyFrame,
92 final AbsoluteDate minDate, final AbsoluteDate maxDate, final double tStep,
93 final double overshootTolerance,
94 final List<TimeStampedPVCoordinates> positionsVelocities, final int pvInterpolationNumber,
95 final CartesianDerivativesFilter pvFilter,
96 final List<TimeStampedAngularCoordinates> quaternions, final int aInterpolationNumber,
97 final AngularDerivativesFilter aFilter)
98 throws RuggedException {
99 try {
100
101 this.inertialFrame = inertialFrame;
102 this.bodyFrame = bodyFrame;
103 this.minDate = minDate;
104 this.maxDate = maxDate;
105 this.overshootTolerance = overshootTolerance;
106
107
108 final AbsoluteDate minPVDate = positionsVelocities.get(0).getDate();
109 final AbsoluteDate maxPVDate = positionsVelocities.get(positionsVelocities.size() - 1).getDate();
110 if (minPVDate.durationFrom(minDate) > overshootTolerance) {
111 throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, minDate, minPVDate, maxPVDate);
112 }
113 if (maxDate.durationFrom(maxDate) > overshootTolerance) {
114 throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, maxDate, minPVDate, maxPVDate);
115 }
116
117 final AbsoluteDate minQDate = quaternions.get(0).getDate();
118 final AbsoluteDate maxQDate = quaternions.get(quaternions.size() - 1).getDate();
119 if (minQDate.durationFrom(minDate) > overshootTolerance) {
120 throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, minDate, minQDate, maxQDate);
121 }
122 if (maxDate.durationFrom(maxQDate) > overshootTolerance) {
123 throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, maxDate, minQDate, maxQDate);
124 }
125
126
127 final TimeStampedCache<TimeStampedPVCoordinates> pvCache =
128 new ImmutableTimeStampedCache<TimeStampedPVCoordinates>(pvInterpolationNumber, positionsVelocities);
129
130
131 final TimeStampedCache<TimeStampedAngularCoordinates> aCache =
132 new ImmutableTimeStampedCache<TimeStampedAngularCoordinates>(aInterpolationNumber, quaternions);
133
134 final int n = (int) FastMath.ceil(maxDate.durationFrom(minDate) / tStep);
135 this.tStep = tStep;
136 this.bodyToInertial = new ArrayList<Transform>(n);
137 this.inertialToBody = new ArrayList<Transform>(n);
138 this.scToInertial = new ArrayList<Transform>(n);
139 for (AbsoluteDate date = minDate; bodyToInertial.size() < n; date = date.shiftedBy(tStep)) {
140
141
142 final AbsoluteDate pvInterpolationDate;
143 if (date.compareTo(pvCache.getEarliest().getDate()) < 0) {
144 pvInterpolationDate = pvCache.getEarliest().getDate();
145 } else if (date.compareTo(pvCache.getLatest().getDate()) > 0) {
146 pvInterpolationDate = pvCache.getLatest().getDate();
147 } else {
148 pvInterpolationDate = date;
149 }
150 final TimeStampedPVCoordinates interpolatedPV =
151 TimeStampedPVCoordinates.interpolate(pvInterpolationDate, pvFilter,
152 pvCache.getNeighbors(pvInterpolationDate));
153 final TimeStampedPVCoordinates pv = interpolatedPV.shiftedBy(date.durationFrom(pvInterpolationDate));
154
155
156 final AbsoluteDate aInterpolationDate;
157 if (date.compareTo(aCache.getEarliest().getDate()) < 0) {
158 aInterpolationDate = aCache.getEarliest().getDate();
159 } else if (date.compareTo(aCache.getLatest().getDate()) > 0) {
160 aInterpolationDate = aCache.getLatest().getDate();
161 } else {
162 aInterpolationDate = date;
163 }
164 final TimeStampedAngularCoordinates interpolatedQuaternion =
165 TimeStampedAngularCoordinates.interpolate(aInterpolationDate, aFilter,
166 aCache.getNeighbors(aInterpolationDate));
167 final TimeStampedAngularCoordinates quaternion = interpolatedQuaternion.shiftedBy(date.durationFrom(aInterpolationDate));
168
169
170 scToInertial.add(new Transform(date,
171 new Transform(date, quaternion.revert()),
172 new Transform(date, pv)));
173
174
175 final Transform b2i = bodyFrame.getTransformTo(inertialFrame, date);
176 bodyToInertial.add(b2i);
177 inertialToBody.add(b2i.getInverse());
178
179 }
180
181 } catch (OrekitException oe) {
182 throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
183 }
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197 public SpacecraftToObservedBody(final Frame inertialFrame, final Frame bodyFrame,
198 final AbsoluteDate minDate, final AbsoluteDate maxDate, final double tStep,
199 final double overshootTolerance,
200 final List<Transform> bodyToInertial, final List<Transform> scToInertial) {
201
202 this.inertialFrame = inertialFrame;
203 this.bodyFrame = bodyFrame;
204 this.minDate = minDate;
205 this.maxDate = maxDate;
206 this.tStep = tStep;
207 this.overshootTolerance = overshootTolerance;
208 this.bodyToInertial = bodyToInertial;
209 this.scToInertial = scToInertial;
210
211 this.inertialToBody = new ArrayList<Transform>(bodyToInertial.size());
212 for (final Transform b2i : bodyToInertial) {
213 inertialToBody.add(b2i.getInverse());
214 }
215
216 }
217
218
219
220
221 public Frame getInertialFrame() {
222 return inertialFrame;
223 }
224
225
226
227
228 public Frame getBodyFrame() {
229 return bodyFrame;
230 }
231
232
233
234
235 public AbsoluteDate getMinDate() {
236 return minDate;
237 }
238
239
240
241
242 public AbsoluteDate getMaxDate() {
243 return maxDate;
244 }
245
246
247
248
249 public double getTStep() {
250 return tStep;
251 }
252
253
254
255
256 public double getOvershootTolerance() {
257 return overshootTolerance;
258 }
259
260
261
262
263
264
265 public Transform getScToInertial(final AbsoluteDate date)
266 throws RuggedException {
267 return interpolate(date, scToInertial);
268 }
269
270
271
272
273
274
275 public Transform getInertialToBody(final AbsoluteDate date)
276 throws RuggedException {
277 return interpolate(date, inertialToBody);
278 }
279
280
281
282
283
284
285 public Transform getBodyToInertial(final AbsoluteDate date)
286 throws RuggedException {
287 return interpolate(date, bodyToInertial);
288 }
289
290
291
292
293
294
295
296 private Transform interpolate(final AbsoluteDate date, final List<Transform> list)
297 throws RuggedException {
298
299
300 if (!isInRange(date)) {
301 throw new RuggedException(RuggedMessages.OUT_OF_TIME_RANGE, date, minDate, maxDate);
302 }
303
304 final double s = date.durationFrom(list.get(0).getDate()) / tStep;
305 final int index = FastMath.max(0, FastMath.min(list.size() - 1, (int) FastMath.rint(s)));
306
307 DumpManager.dumpTransform(this, index, bodyToInertial.get(index), scToInertial.get(index));
308
309 final Transform close = list.get(index);
310 return close.shiftedBy(date.durationFrom(close.getDate()));
311
312 }
313
314
315
316
317
318 public boolean isInRange(final AbsoluteDate date) {
319 return (minDate.durationFrom(date) <= overshootTolerance) &&
320 (date.durationFrom(maxDate) <= overshootTolerance);
321 }
322
323 }