1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.ndm.adm.apm;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.hipparchus.complex.Quaternion;
24 import org.orekit.attitudes.Attitude;
25 import org.orekit.errors.OrekitException;
26 import org.orekit.errors.OrekitMessages;
27 import org.orekit.files.ccsds.ndm.adm.AttitudeType;
28 import org.orekit.files.ccsds.section.CommentsContainer;
29 import org.orekit.files.ccsds.section.Data;
30 import org.orekit.frames.Frame;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.utils.PVCoordinatesProvider;
33 import org.orekit.utils.TimeStampedAngularCoordinates;
34
35
36
37
38
39
40 public class ApmData implements Data {
41
42
43 private final CommentsContainer commentsBlock;
44
45
46 private final AbsoluteDate epoch;
47
48
49 private final ApmQuaternion quaternionBlock;
50
51
52 private final Euler eulerBlock;
53
54
55
56
57 private final AngularVelocity angularVelocityBlock;
58
59
60 private final SpinStabilized spinStabilizedBlock;
61
62
63 private final Inertia inertia;
64
65
66 private final List<Maneuver> maneuvers;
67
68
69
70
71
72
73
74
75
76
77 public ApmData(final CommentsContainer commentsBlock,
78 final AbsoluteDate epoch,
79 final ApmQuaternion quaternionBlock,
80 final Euler eulerBlock,
81 final AngularVelocity angularVelocityBlock,
82 final SpinStabilized spinStabilizedBlock,
83 final Inertia inertia) {
84 this.commentsBlock = commentsBlock;
85 this.epoch = epoch;
86 this.quaternionBlock = quaternionBlock;
87 this.eulerBlock = eulerBlock;
88 this.angularVelocityBlock = angularVelocityBlock;
89 this.spinStabilizedBlock = spinStabilizedBlock;
90 this.inertia = inertia;
91 this.maneuvers = new ArrayList<>();
92 }
93
94
95 @Override
96 public void validate(final double version) {
97
98 if (version < 2.0) {
99
100 if (quaternionBlock == null) {
101
102 new ApmQuaternion().validate(version);
103 }
104 } else {
105
106 if (quaternionBlock == null && eulerBlock == null && angularVelocityBlock == null &&
107 spinStabilizedBlock == null && inertia == null) {
108 throw new OrekitException(OrekitMessages.CCSDS_INCOMPLETE_DATA);
109 }
110 }
111
112 if (quaternionBlock != null) {
113 quaternionBlock.validate(version);
114 }
115 if (eulerBlock != null) {
116 eulerBlock.validate(version);
117 }
118 if (angularVelocityBlock != null) {
119 angularVelocityBlock.validate(version);
120 }
121 if (spinStabilizedBlock != null) {
122 spinStabilizedBlock.validate(version);
123 }
124 if (inertia != null) {
125 inertia.validate(version);
126 }
127 for (final Maneuver maneuver : maneuvers) {
128 maneuver.validate(version);
129 }
130
131 }
132
133
134
135
136 public List<String> getComments() {
137 return commentsBlock.getComments();
138 }
139
140
141
142
143
144
145 public AbsoluteDate getEpoch() {
146 return epoch;
147 }
148
149
150
151
152 public ApmQuaternion getQuaternionBlock() {
153 return quaternionBlock;
154 }
155
156
157
158
159 public Euler getEulerBlock() {
160 return eulerBlock;
161 }
162
163
164
165
166
167 public AngularVelocity getAngularVelocityBlock() {
168 return angularVelocityBlock;
169 }
170
171
172
173
174 public SpinStabilized getSpinStabilizedBlock() {
175 return spinStabilizedBlock;
176 }
177
178
179
180
181 public Inertia getInertiaBlock() {
182 return inertia;
183 }
184
185
186
187
188
189 public int getNbManeuvers() {
190 return maneuvers.size();
191 }
192
193
194
195
196
197 public List<Maneuver> getManeuvers() {
198 return Collections.unmodifiableList(maneuvers);
199 }
200
201
202
203
204
205
206 public Maneuver getManeuver(final int index) {
207 return maneuvers.get(index);
208 }
209
210
211
212
213
214 public void addManeuver(final Maneuver maneuver) {
215 maneuvers.add(maneuver);
216 }
217
218
219
220
221
222
223 public boolean hasManeuvers() {
224 return !maneuvers.isEmpty();
225 }
226
227
228
229
230
231
232
233
234
235
236 public Attitude getAttitude(final Frame frame, final PVCoordinatesProvider pvProvider) {
237
238 if (quaternionBlock != null) {
239
240 final Quaternion q = quaternionBlock.getQuaternion();
241
242 final TimeStampedAngularCoordinates tac;
243 if (quaternionBlock.hasRates()) {
244
245 final Quaternion qDot = quaternionBlock.getQuaternionDot();
246 tac = AttitudeType.QUATERNION_DERIVATIVE.build(true, quaternionBlock.getEndpoints().isExternal2SpacecraftBody(),
247 null, true, epoch,
248 q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3(),
249 qDot.getQ0(), qDot.getQ1(), qDot.getQ2(), qDot.getQ3());
250 } else if (angularVelocityBlock != null) {
251
252 tac = AttitudeType.QUATERNION_ANGVEL.build(true,
253 quaternionBlock.getEndpoints().isExternal2SpacecraftBody(),
254 null, true, epoch,
255 q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3(),
256 angularVelocityBlock.getAngVelX(),
257 angularVelocityBlock.getAngVelY(),
258 angularVelocityBlock.getAngVelZ());
259 } else if (eulerBlock != null && eulerBlock.hasRates()) {
260
261 final double[] rates = eulerBlock.getRotationRates();
262 if (eulerBlock.hasAngles()) {
263
264 final double[] angles = eulerBlock.getRotationAngles();
265 tac = AttitudeType.EULER_ANGLE_DERIVATIVE.build(true,
266 eulerBlock.getEndpoints().isExternal2SpacecraftBody(),
267 eulerBlock.getEulerRotSeq(), eulerBlock.isSpacecraftBodyRate(), epoch,
268 angles[0], angles[1], angles[2],
269 rates[0], rates[1], rates[2]);
270 } else {
271
272
273 tac = AttitudeType.QUATERNION_EULER_RATES.build(true,
274 eulerBlock.getEndpoints().isExternal2SpacecraftBody(),
275 eulerBlock.getEulerRotSeq(), eulerBlock.isSpacecraftBodyRate(), epoch,
276 q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3(),
277 rates[0], rates[1], rates[2]);
278 }
279
280 } else {
281
282 tac = AttitudeType.QUATERNION.build(true, quaternionBlock.getEndpoints().isExternal2SpacecraftBody(),
283 null, true, epoch,
284 q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3());
285 }
286
287
288 return quaternionBlock.getEndpoints().build(frame, pvProvider, tac);
289
290 } else if (eulerBlock != null) {
291
292 final double[] angles = eulerBlock.getRotationAngles();
293
294 final TimeStampedAngularCoordinates tac;
295 if (eulerBlock.hasRates()) {
296
297 final double[] rates = eulerBlock.getRotationRates();
298 tac = AttitudeType.EULER_ANGLE_DERIVATIVE.build(true,
299 eulerBlock.getEndpoints().isExternal2SpacecraftBody(),
300 eulerBlock.getEulerRotSeq(), eulerBlock.isSpacecraftBodyRate(), epoch,
301 angles[0], angles[1], angles[2],
302 rates[0], rates[1], rates[2]);
303 } else if (angularVelocityBlock != null) {
304
305 tac = AttitudeType.EULER_ANGLE_ANGVEL.build(true,
306 eulerBlock.getEndpoints().isExternal2SpacecraftBody(),
307 eulerBlock.getEulerRotSeq(), eulerBlock.isSpacecraftBodyRate(), epoch,
308 angles[0], angles[1], angles[2],
309 angularVelocityBlock.getAngVelX(),
310 angularVelocityBlock.getAngVelY(),
311 angularVelocityBlock.getAngVelZ());
312 } else {
313
314 tac = AttitudeType.EULER_ANGLE.build(true,
315 eulerBlock.getEndpoints().isExternal2SpacecraftBody(),
316 eulerBlock.getEulerRotSeq(), eulerBlock.isSpacecraftBodyRate(), epoch,
317 angles[0], angles[1], angles[2]);
318 }
319
320
321 return eulerBlock.getEndpoints().build(frame, pvProvider, tac);
322
323 } else if (spinStabilizedBlock != null) {
324
325
326 final TimeStampedAngularCoordinates tac;
327 if (spinStabilizedBlock.hasNutation()) {
328
329 tac = AttitudeType.SPIN_NUTATION.build(true, true, null, true, epoch,
330 spinStabilizedBlock.getSpinAlpha(),
331 spinStabilizedBlock.getSpinDelta(),
332 spinStabilizedBlock.getSpinAngle(),
333 spinStabilizedBlock.getSpinAngleVel(),
334 spinStabilizedBlock.getNutation(),
335 spinStabilizedBlock.getNutationPeriod(),
336 spinStabilizedBlock.getNutationPhase());
337 } else if (spinStabilizedBlock.hasMomentum()) {
338
339 tac = AttitudeType.SPIN_NUTATION_MOMENTUM.build(true, true, null, true, epoch,
340 spinStabilizedBlock.getSpinAlpha(),
341 spinStabilizedBlock.getSpinDelta(),
342 spinStabilizedBlock.getSpinAngle(),
343 spinStabilizedBlock.getSpinAngleVel(),
344 spinStabilizedBlock.getMomentumAlpha(),
345 spinStabilizedBlock.getMomentumDelta(),
346 spinStabilizedBlock.getNutationVel());
347 } else {
348
349 tac = AttitudeType.SPIN.build(true, true, null, true, epoch,
350 spinStabilizedBlock.getSpinAlpha(),
351 spinStabilizedBlock.getSpinDelta(),
352 spinStabilizedBlock.getSpinAngle(),
353 spinStabilizedBlock.getSpinAngleVel());
354 }
355
356
357 return spinStabilizedBlock.getEndpoints().build(frame, pvProvider, tac);
358
359 } else {
360 throw new OrekitException(OrekitMessages.CCSDS_INCOMPLETE_DATA);
361 }
362
363 }
364
365 }