1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.ndm.adm.aem;
18
19 import java.net.URISyntaxException;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
24 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
25 import org.hipparchus.geometry.euclidean.threed.Rotation;
26 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
27 import org.hipparchus.geometry.euclidean.threed.RotationOrder;
28 import org.hipparchus.geometry.euclidean.threed.Vector3D;
29 import org.hipparchus.util.Binary64;
30 import org.hipparchus.util.Binary64Field;
31 import org.hipparchus.util.FastMath;
32 import org.hipparchus.util.MathUtils;
33 import org.junit.jupiter.api.Assertions;
34 import org.junit.jupiter.api.BeforeEach;
35 import org.junit.jupiter.api.Test;
36 import org.orekit.Utils;
37 import org.orekit.attitudes.Attitude;
38 import org.orekit.attitudes.BoundedAttitudeProvider;
39 import org.orekit.attitudes.FieldAttitude;
40 import org.orekit.bodies.CelestialBodyFactory;
41 import org.orekit.data.DataContext;
42 import org.orekit.data.DataSource;
43 import org.orekit.errors.OrekitException;
44 import org.orekit.errors.OrekitMessages;
45 import org.orekit.files.ccsds.definitions.CelestialBodyFrame;
46 import org.orekit.files.ccsds.definitions.OrbitRelativeFrame;
47 import org.orekit.files.ccsds.definitions.SpacecraftBodyFrame;
48 import org.orekit.files.ccsds.definitions.TimeSystem;
49 import org.orekit.files.ccsds.ndm.ParserBuilder;
50 import org.orekit.files.ccsds.ndm.adm.AttitudeType;
51 import org.orekit.files.ccsds.section.Segment;
52 import org.orekit.frames.FramesFactory;
53 import org.orekit.frames.ITRFVersion;
54 import org.orekit.orbits.CircularOrbit;
55 import org.orekit.orbits.FieldCircularOrbit;
56 import org.orekit.orbits.PositionAngleType;
57 import org.orekit.time.AbsoluteDate;
58 import org.orekit.time.FieldAbsoluteDate;
59 import org.orekit.time.TimeOffset;
60 import org.orekit.time.TimeScale;
61 import org.orekit.time.TimeScalesFactory;
62 import org.orekit.utils.AngularDerivativesFilter;
63 import org.orekit.utils.Constants;
64 import org.orekit.utils.IERSConventions;
65 import org.orekit.utils.TimeStampedAngularCoordinates;
66
67 public class AEMParserTest {
68
69 @BeforeEach
70 public void setUp()
71 throws Exception {
72 Utils.setDataRoot("regular-data");
73 }
74
75 @Test
76 public void testParseAEM01() {
77 final String ex = "/ccsds/adm/aem/AEMExample01.txt";
78 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
79 final Aem file = new ParserBuilder().buildAemParser().parseMessage(source);
80 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
81 final Segment<AemMetadata, AemData> segment1 = file.getSegments().get(1);
82 final AbsoluteDate start = new AbsoluteDate("1996-11-28T22:08:02.5555", TimeScalesFactory.getUTC());
83 Assertions.assertEquals(0.0, start.durationFrom(file.getSatellites().get("1996-062A").getStart()), Double.MIN_VALUE);
84 final AbsoluteDate end = new AbsoluteDate("1996-12-28T21:23:00.5555", TimeScalesFactory.getUTC());
85 Assertions.assertEquals(0.0, end.durationFrom(file.getSatellites().get("1996-062A").getStop()), Double.MIN_VALUE);
86 Assertions.assertEquals("1996-062A", file.getSatellites().get("1996-062A").getId());
87 Assertions.assertEquals(1.0, file.getHeader().getFormatVersion(), Double.MIN_VALUE);
88 Assertions.assertEquals(new AbsoluteDate(2002, 11, 4, 17, 22, 31.0, TimeScalesFactory.getUTC()),
89 file.getHeader().getCreationDate());
90 Assertions.assertEquals("NASA/JPL", file.getHeader().getOriginator());
91 Assertions.assertEquals("UTC", segment0.getMetadata().getTimeSystem().name());
92 Assertions.assertEquals("MARS GLOBAL SURVEYOR", segment0.getMetadata().getObjectName());
93 Assertions.assertEquals("1996-062A", segment0.getMetadata().getObjectID());
94 Assertions.assertEquals("MARS BARYCENTER", segment0.getMetadata().getCenter().getName());
95 Assertions.assertEquals(1996, segment0.getMetadata().getLaunchYear());
96 Assertions.assertEquals(62, segment0.getMetadata().getLaunchNumber());
97 Assertions.assertEquals("A", segment0.getMetadata().getLaunchPiece());
98 Assertions.assertFalse(segment0.getMetadata().getHasCreatableBody());
99 Assertions.assertNull(segment0.getMetadata().getCenter().getBody());
100 Assertions.assertEquals(new AbsoluteDate(1996, 11, 28, 21, 29, new TimeOffset(7, TimeOffset.SECOND,
101 255500, TimeOffset.MICROSECOND),
102 TimeScalesFactory.getUTC()),
103 segment0.getMetadata().getStartTime());
104 Assertions.assertEquals(new AbsoluteDate(1996, 11, 30, 1, 28, new TimeOffset(2, TimeOffset.SECOND,
105 555500, TimeOffset.MICROSECOND),
106 TimeScalesFactory.getUTC()),
107 segment0.getMetadata().getStopTime());
108 Assertions.assertEquals(new AbsoluteDate(1996, 11, 28, 22, 8, new TimeOffset(2, TimeOffset.SECOND,
109 555500, TimeOffset.MICROSECOND),
110 TimeScalesFactory.getUTC()),
111 segment0.getMetadata().getUseableStartTime());
112 Assertions.assertEquals(new AbsoluteDate(1996, 11, 30, 1, 18, new TimeOffset(2, TimeOffset.SECOND,
113 555500, TimeOffset.MICROSECOND),
114 TimeScalesFactory.getUTC()),
115 segment0.getMetadata().getUseableStopTime());
116 Assertions.assertEquals("HERMITE", segment0.getMetadata().getInterpolationMethod());
117 Assertions.assertEquals(7, segment0.getMetadata().getInterpolationDegree());
118 Assertions.assertFalse(segment0.getMetadata().isFirst());
119 Assertions.assertEquals("EME2000", segment0.getMetadata().getEndpoints().getFrameA().getName());
120 Assertions.assertEquals(SpacecraftBodyFrame.BaseEquipment.SC_BODY,
121 segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getBaseEquipment());
122 Assertions.assertEquals("1",
123 segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getLabel());
124 Assertions.assertTrue(segment0.getMetadata().getEndpoints().isA2b());
125 Assertions.assertEquals(AttitudeType.QUATERNION, segment1.getMetadata().getAttitudeType());
126 Assertions.assertEquals(AngularDerivativesFilter.USE_R, segment0.getMetadata().getAttitudeType().getAngularDerivativesFilter());
127 verifyAngularCoordinates(new TimeStampedAngularCoordinates(new AbsoluteDate(1996, 11, 28, 21, 29,
128 new TimeOffset(7, TimeOffset.SECOND,
129 255500, TimeOffset.MICROSECOND),
130 TimeScalesFactory.getUTC()),
131 new Rotation(0.68427, 0.56748, 0.03146, 0.45689, false),
132 Vector3D.ZERO,
133 Vector3D.ZERO),
134 segment0.getData().getAngularCoordinates().get(0), 1.0e-5);
135 verifyAngularCoordinates(new TimeStampedAngularCoordinates(new AbsoluteDate(1996, 11, 28, 22, 8,
136 new TimeOffset(3, TimeOffset.SECOND,
137 555500, TimeOffset.MICROSECOND),
138 TimeScalesFactory.getUTC()),
139 new Rotation(0.74533, 0.42319, -0.45697, 0.23784, false),
140 Vector3D.ZERO,
141 Vector3D.ZERO),
142 segment0.getData().getAngularCoordinates().get(1), 1.0e-5);
143 verifyAngularCoordinates(new TimeStampedAngularCoordinates(new AbsoluteDate(1996, 11, 28, 22, 8,
144 new TimeOffset(4, TimeOffset.SECOND,
145 555500, TimeOffset.MICROSECOND),
146 TimeScalesFactory.getUTC()),
147 new Rotation(0.45652, -0.84532, 0.26974, -0.06532, false),
148 Vector3D.ZERO,
149 Vector3D.ZERO),
150 segment0.getData().getAngularCoordinates().get(2), 1.0e-5);
151 ArrayList<String> ephemeridesDataLinesComment = new ArrayList<>();
152 ephemeridesDataLinesComment.add("This file was produced by M.R. Somebody, MSOO NAV/JPL, 2002 OCT 04.");
153 ephemeridesDataLinesComment.add("It is to be used for attitude reconstruction only. The relative accuracy of these");
154 ephemeridesDataLinesComment.add("attitudes is 0.1 degrees per axis.");
155 Assertions.assertEquals(ephemeridesDataLinesComment, segment0.getMetadata().getComments());
156
157 Assertions.assertEquals("UTC", segment1.getMetadata().getTimeSystem().name());
158 Assertions.assertEquals("MARS GLOBAL SURVEYOR", segment1.getMetadata().getObjectName());
159 Assertions.assertEquals("1996-062A", segment1.getMetadata().getObjectID());
160 Assertions.assertEquals("MARS BARYCENTER", segment1.getMetadata().getCenter().getName());
161 Assertions.assertEquals(1996, segment1.getMetadata().getLaunchYear());
162 Assertions.assertEquals(62, segment1.getMetadata().getLaunchNumber());
163 Assertions.assertEquals("A", segment1.getMetadata().getLaunchPiece());
164 Assertions.assertFalse(segment1.getMetadata().getHasCreatableBody());
165 Assertions.assertNull(segment1.getMetadata().getCenter().getBody());
166 Assertions.assertEquals(new AbsoluteDate(1996, 12, 18, 12, 5, new TimeOffset(555500, TimeOffset.MICROSECOND), TimeScalesFactory.getUTC()),
167 segment1.getMetadata().getStartTime());
168 Assertions.assertEquals(new AbsoluteDate(1996, 12, 28, 21, 28, new TimeOffset(555500, TimeOffset.MICROSECOND), TimeScalesFactory.getUTC()),
169 segment1.getMetadata().getStopTime());
170 Assertions.assertEquals(new AbsoluteDate(1996, 12, 18, 12, 10, new TimeOffset(555500, TimeOffset.MICROSECOND), TimeScalesFactory.getUTC()),
171 segment1.getMetadata().getUseableStartTime());
172 Assertions.assertEquals(new AbsoluteDate(1996, 12, 28, 21, 23, new TimeOffset(555500, TimeOffset.MICROSECOND), TimeScalesFactory.getUTC()),
173 segment1.getMetadata().getUseableStopTime());
174 Assertions.assertFalse(segment1.getMetadata().isFirst());
175 Assertions.assertEquals("EME2000", segment0.getMetadata().getEndpoints().getFrameA().getName());
176 Assertions.assertEquals(SpacecraftBodyFrame.BaseEquipment.SC_BODY,
177 segment0.getMetadata().getEndpoints().getSpacecraftBodyFrame().asSpacecraftBodyFrame().getBaseEquipment());
178 Assertions.assertEquals("1",
179 segment0.getMetadata().getEndpoints().getSpacecraftBodyFrame().asSpacecraftBodyFrame().getLabel());
180 Assertions.assertTrue(segment0.getMetadata().getEndpoints().isA2b());
181 Assertions.assertEquals(AttitudeType.QUATERNION, segment1.getMetadata().getAttitudeType());
182 Assertions.assertEquals(AngularDerivativesFilter.USE_R, segment0.getMetadata().getAttitudeType().getAngularDerivativesFilter());
183 verifyAngularCoordinates(new TimeStampedAngularCoordinates(new AbsoluteDate(1996, 12, 18, 12, 5, new TimeOffset(555500, TimeOffset.MICROSECOND),
184 TimeScalesFactory.getUTC()),
185 new Rotation(0.72501, -0.64585, 0.018542, -0.23854, false),
186 Vector3D.ZERO,
187 Vector3D.ZERO),
188 segment1.getData().getAngularCoordinates().get(0), 1.0e-5);
189 verifyAngularCoordinates(new TimeStampedAngularCoordinates(new AbsoluteDate(1996, 12, 18, 12, 10, new TimeOffset(5, TimeOffset.SECOND,
190 555500,
191 TimeOffset.MICROSECOND),
192 TimeScalesFactory.getUTC()),
193 new Rotation(-0.16767, 0.87451, -0.43475, 0.13458, false),
194 Vector3D.ZERO,
195 Vector3D.ZERO),
196 segment1.getData().getAngularCoordinates().get(1), 1.0e-5);
197 verifyAngularCoordinates(new TimeStampedAngularCoordinates(new AbsoluteDate(1996, 12, 18, 12, 10, new TimeOffset(10, TimeOffset.SECOND,
198 555500, TimeOffset.MICROSECOND),
199 TimeScalesFactory.getUTC()),
200 new Rotation(-0.71418, 0.03125, -0.65874, 0.23458, false),
201 Vector3D.ZERO,
202 Vector3D.ZERO),
203 segment1.getData().getAngularCoordinates().get(2), 1.0e-5);
204 ArrayList<String> ephemeridesDataLinesComment2 = new ArrayList<>();
205 ephemeridesDataLinesComment2.add("This block begins after trajectory correction maneuver TCM-3.");
206 Assertions.assertEquals(ephemeridesDataLinesComment2, segment1.getMetadata().getComments());
207 }
208
209 @Test
210 public void testParseAEM02() {
211 final String name = "/ccsds/adm/aem/AEMExample02.txt";
212 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
213 AemParser parser = new ParserBuilder().
214 withMissionReferenceDate(new AbsoluteDate("1996-12-17T00:00:00.000",
215 TimeScalesFactory.getUTC())).
216 buildAemParser();
217
218 final Aem file = parser.parse(source);
219 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
220 final List<String> headerComment = new ArrayList<>();
221 headerComment.add("comment");
222 Assertions.assertEquals(headerComment, file.getHeader().getComments());
223 final List<String> metadataComment = new ArrayList<>();
224 metadataComment.add("This file was produced by M.R. Somebody, MSOO NAV/JPL, 2002 OCT 04.");
225 metadataComment.add("It is to be used for attitude reconstruction only. The relative accuracy of these");
226 metadataComment.add("attitudes is 0.1 degrees per axis.");
227 Assertions.assertEquals(metadataComment, segment0.getMetadata().getComments());
228 Assertions.assertEquals("EME2000", segment0.getMetadata().getEndpoints().getFrameA().getName());
229 Assertions.assertEquals(SpacecraftBodyFrame.BaseEquipment.SC_BODY,
230 segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getBaseEquipment());
231 Assertions.assertEquals("1",
232 segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getLabel());
233 List<AemSegment> blocks = file.getSegments();
234 Assertions.assertEquals(1, blocks.size());
235 Assertions.assertEquals(IERSConventions.IERS_2010, parser.getConventions());
236 Assertions.assertTrue(parser.isSimpleEOP());
237 Assertions.assertEquals(0.0, parser.getMissionReferenceDate().durationFrom(new AbsoluteDate(1996, 12, 17, 0, 0, 0.0,
238 TimeScalesFactory.getUTC())), 1.0e-5);
239 Assertions.assertEquals(DataContext.getDefault(), parser.getDataContext());
240 Assertions.assertEquals((new AbsoluteDate("1996-12-17T00:00:00.000",
241 TimeScalesFactory.getUTC())),
242 parser.getMissionReferenceDate());
243 }
244
245 @Test
246 public void testParseKvnAEM03() {
247 final String ex = "/ccsds/adm/aem/AEMExample03.txt";
248 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
249 validateAEM03(new ParserBuilder().buildAemParser().parseMessage(source));
250 }
251
252 @Test
253 public void testParseXmlAEM03() {
254 final String ex = "/ccsds/adm/aem/AEMExample03.xml";
255 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
256 final AemParser parser = new ParserBuilder().buildAemParser();
257 validateAEM03(parser.parse(source));
258 }
259
260 private void validateAEM03(final Aem file) {
261
262 final TimeScale utc = TimeScalesFactory.getUTC();
263 Assertions.assertEquals(1.0, file.getHeader().getFormatVersion(), 1.0e-15);
264 Assertions.assertEquals(0,
265 file.getHeader().getCreationDate().durationFrom(new AbsoluteDate("2008-071T17:09:49", utc)),
266 1.0e-12);
267 Assertions.assertEquals("GSFC FDF", file.getHeader().getOriginator());
268 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
269 Assertions.assertEquals("ST5-224", segment0.getMetadata().getObjectName());
270 Assertions.assertEquals("2006224", segment0.getMetadata().getObjectID());
271 Assertions.assertEquals("J2000", segment0.getMetadata().getEndpoints().getFrameA().getName());
272 Assertions.assertEquals("SC_BODY_1", segment0.getMetadata().getEndpoints().getFrameB().getName());
273 Assertions.assertTrue(segment0.getMetadata().getEndpoints().isA2b());
274 Assertions.assertEquals(TimeSystem.UTC, segment0.getMetadata().getTimeSystem());
275 Assertions.assertEquals(0,
276 segment0.getMetadata().getStartTime().durationFrom(new AbsoluteDate("2006-090T05:00:00.071", utc)),
277 1.0e-12);
278 Assertions.assertEquals(0,
279 segment0.getMetadata().getUseableStartTime().durationFrom(new AbsoluteDate("2006-090T05:00:00.071", utc)),
280 1.0e-12);
281 Assertions.assertEquals(0,
282 segment0.getMetadata().getUseableStopTime().durationFrom(new AbsoluteDate("2006-090T05:00:00.946", utc)),
283 1.0e-12);
284 Assertions.assertEquals(0,
285 segment0.getMetadata().getStopTime().durationFrom(new AbsoluteDate("2006-090T05:00:00.946", utc)),
286 1.0e-12);
287 Assertions.assertEquals(AttitudeType.SPIN, segment0.getMetadata().getAttitudeType());
288 Assertions.assertEquals(1, segment0.getData().getComments().size());
289 Assertions.assertEquals("Spin KF ground solution, SPINKF rates", segment0.getData().getComments().get(0));
290 Assertions.assertEquals(8, segment0.getData().getAngularCoordinates().size());
291 TimeStampedAngularCoordinates prev = null;
292 for (TimeStampedAngularCoordinates tac : segment0.getData().getAngularCoordinates()) {
293 if (prev != null) {
294 double dt = tac.getDate().durationFrom(prev.getDate());
295 double dR = Rotation.distance(tac.getRotation(), prev.getRotation());
296 double meanRate = 0.5 * (prev.getRotationRate().getNorm() + tac.getRotationRate().getNorm());
297 Assertions.assertEquals(dR, dt * meanRate, 1.3e-3);
298 }
299 prev = tac;
300 }
301
302 }
303
304 @Test
305 public void testParseAEM04() {
306 final TimeScale utc = TimeScalesFactory.getUTC();
307 final String ex = "/ccsds/adm/aem/AEMExample04.txt";
308 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
309 final AemParser parser = new ParserBuilder().buildAemParser();
310 final Aem file = parser.parseMessage(source);
311 Assertions.assertEquals(1.0, file.getHeader().getFormatVersion(), 1.0e-15);
312 Assertions.assertEquals(0,
313 file.getHeader().getCreationDate().durationFrom(new AbsoluteDate("2021-04-13T08:41:42", utc)),
314 1.0e-12);
315 Assertions.assertEquals("CS GROUP", file.getHeader().getOriginator());
316 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
317 Assertions.assertEquals("COPIHUE", segment0.getMetadata().getObjectName());
318 Assertions.assertEquals("2100-017F", segment0.getMetadata().getObjectID());
319 Assertions.assertEquals(2100, segment0.getMetadata().getLaunchYear());
320 Assertions.assertEquals(17, segment0.getMetadata().getLaunchNumber());
321 Assertions.assertEquals("F", segment0.getMetadata().getLaunchPiece());
322 Assertions.assertEquals("EME2000", segment0.getMetadata().getEndpoints().getFrameA().getName());
323 Assertions.assertEquals("SC_BODY_1", segment0.getMetadata().getEndpoints().getFrameB().getName());
324 Assertions.assertTrue(segment0.getMetadata().getEndpoints().isA2b());
325 Assertions.assertEquals(TimeSystem.UTC, segment0.getMetadata().getTimeSystem());
326 Assertions.assertEquals(0,
327 segment0.getMetadata().getStartTime().durationFrom(new AbsoluteDate("2021-12-31T00:00:00.000", utc)),
328 1.0e-12);
329 Assertions.assertEquals(0,
330 segment0.getMetadata().getUseableStartTime().durationFrom(new AbsoluteDate("2021-12-31T00:00:00.500", utc)),
331 1.0e-12);
332 Assertions.assertEquals(0,
333 segment0.getMetadata().getUseableStopTime().durationFrom(new AbsoluteDate("2021-12-31T00:00:05.500", utc)),
334 1.0e-12);
335 Assertions.assertEquals(0,
336 segment0.getMetadata().getStopTime().durationFrom(new AbsoluteDate("2021-12-31T00:00:06.000", utc)),
337 1.0e-12);
338 Assertions.assertEquals(AttitudeType.QUATERNION_DERIVATIVE, segment0.getMetadata().getAttitudeType());
339 Assertions.assertEquals("HERMITE", segment0.getMetadata().getInterpolationMethod());
340 Assertions.assertEquals(3, segment0.getMetadata().getInterpolationDegree());
341 Assertions.assertEquals(1, segment0.getData().getComments().size());
342 Assertions.assertEquals(13, segment0.getData().getAngularCoordinates().size());
343 TimeStampedAngularCoordinates prev = null;
344 for (TimeStampedAngularCoordinates tac : segment0.getData().getAngularCoordinates()) {
345 if (prev != null) {
346 double dt = tac.getDate().durationFrom(prev.getDate());
347 double dR = Rotation.distance(tac.getRotation(), prev.getRotation());
348 double meanRate = 0.5 * (prev.getRotationRate().getNorm() + tac.getRotationRate().getNorm());
349 Assertions.assertEquals(dR, dt * meanRate, 1.5e-6);
350 }
351 prev = tac;
352 }
353
354 }
355
356 @Test
357 public void testParseAEM05() {
358 final String ex = "/ccsds/adm/aem/AEMExample05.txt";
359 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
360 final AemParser parser = new ParserBuilder().buildAemParser();
361 final Aem file = parser.parseMessage(source);
362 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
363 final List<String> headerComment = new ArrayList<>();
364 headerComment.add("comment");
365 Assertions.assertEquals(headerComment, file.getHeader().getComments());
366 final List<String> metadataComment = new ArrayList<>();
367 metadataComment.add("This file was produced by M.R. Somebody, MSOO NAV/JPL, 2002 OCT 04.");
368 metadataComment.add("It is to be used for attitude reconstruction only. The relative accuracy of these");
369 metadataComment.add("attitudes is 0.1 degrees per axis.");
370 Assertions.assertEquals(metadataComment, segment0.getMetadata().getComments());
371 Assertions.assertEquals("UTC", segment0.getMetadata().getTimeSystem().name());
372 Assertions.assertEquals("MARS GLOBAL SURVEYOR", segment0.getMetadata().getObjectName());
373 Assertions.assertEquals("1996-062A", segment0.getMetadata().getObjectID());
374 Assertions.assertEquals("MARS BARYCENTER", segment0.getMetadata().getCenter().getName());
375 Assertions.assertEquals(1996, segment0.getMetadata().getLaunchYear());
376 Assertions.assertEquals(62, segment0.getMetadata().getLaunchNumber());
377 Assertions.assertEquals("A", segment0.getMetadata().getLaunchPiece());
378 Assertions.assertEquals(RotationOrder.ZXY, segment0.getMetadata().getEulerRotSeq());
379 Assertions.assertTrue(segment0.getMetadata().rateFrameIsA());
380 Assertions.assertFalse(segment0.getMetadata().getHasCreatableBody());
381 Assertions.assertNull(segment0.getMetadata().getCenter().getBody());
382
383
384 final AbsoluteDate refDate = new AbsoluteDate(1996, 11, 28, 21, 29, 7.2555, TimeScalesFactory.getUTC());
385
386
387 final TimeStampedAngularCoordinates ac = segment0.getData().getAngularCoordinates().get(0);
388 final FieldRotation<UnivariateDerivative1> r = ac.toUnivariateDerivative1Rotation();
389 final UnivariateDerivative1[] angles = r.getAngles(segment0.getMetadata().getEulerRotSeq(),
390 RotationConvention.FRAME_TRANSFORM);
391 Assertions.assertEquals(0.0, refDate.durationFrom(ac.getDate()), 1.0e-5);
392 Assertions.assertEquals(0.0, ac.getRotationAcceleration().getNorm(), 1.0e-5);
393 Assertions.assertEquals(-26.78, FastMath.toDegrees(angles[0].getValue()), 1.0e-2);
394 Assertions.assertEquals(46.26, FastMath.toDegrees(angles[1].getValue()), 1.0e-2);
395 Assertions.assertEquals(144.10, FastMath.toDegrees(angles[2].getValue()), 1.0e-2);
396 Assertions.assertEquals(0.10450, FastMath.toDegrees(angles[0].getFirstDerivative()), 1.0e-5);
397 Assertions.assertEquals(0.03214, FastMath.toDegrees(angles[1].getFirstDerivative()), 1.0e-5);
398 Assertions.assertEquals(0.02156, FastMath.toDegrees(angles[2].getFirstDerivative()), 1.0e-5);
399 }
400
401 @Test
402 public void testParseAEM06a() {
403 final String ex = "/ccsds/adm/aem/AEMExample06a.txt";
404 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
405 final AemParser parser = new ParserBuilder().buildAemParser();
406
407 final Aem file = parser.parseMessage(source);
408 final TimeStampedAngularCoordinates ac = file.getSegments().get(0).getAngularCoordinates().get(7);
409 final Vector3D lastSpin = ac.getRotation().applyInverseTo(Vector3D.PLUS_K);
410 Assertions.assertEquals(268.45119, FastMath.toDegrees(MathUtils.normalizeAngle(lastSpin.getAlpha(), FastMath.PI)), 1.0e-5);
411 Assertions.assertEquals(68.317275, FastMath.toDegrees(lastSpin.getDelta()), 1.0e-5);
412 }
413
414 @Test
415 public void testParseAEM06b() {
416 final String ex = "/ccsds/adm/aem/AEMExample06b.txt";
417 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
418 final AemParser parser = new ParserBuilder().buildAemParser();
419
420 final Aem file = parser.parseMessage(source);
421 final TimeStampedAngularCoordinates ac = file.getSegments().get(0).getAngularCoordinates().get(7);
422 final Vector3D lastSpin = ac.getRotation().applyInverseTo(Vector3D.PLUS_K);
423 Assertions.assertEquals(268.45119, FastMath.toDegrees(MathUtils.normalizeAngle(lastSpin.getAlpha(), FastMath.PI)), 1.0e-5);
424 Assertions.assertEquals(68.317275, FastMath.toDegrees(lastSpin.getDelta()), 1.0e-5);
425 }
426
427 @Test
428 public void testParseAEM07() {
429 final String ex = "/ccsds/adm/aem/AEMExample07.txt";
430 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
431 final AemParser parser = new ParserBuilder().buildAemParser();
432 final Aem file = parser.parseMessage(source);
433 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
434 final List<String> headerComment = new ArrayList<>();
435 headerComment.add("comment");
436 Assertions.assertEquals(headerComment, file.getHeader().getComments());
437 final List<String> metadataComment = new ArrayList<>();
438 metadataComment.add("This file was produced by M.R. Somebody, MSOO NAV/JPL, 2002 OCT 04.");
439 metadataComment.add("It is to be used for attitude reconstruction only. The relative accuracy of these");
440 metadataComment.add("attitudes is 0.1 degrees per axis.");
441 Assertions.assertEquals(metadataComment, segment0.getMetadata().getComments());
442 Assertions.assertEquals(TimeSystem.UTC, segment0.getMetadata().getTimeSystem());
443 Assertions.assertEquals("MARS GLOBAL SURVEYOR", segment0.getMetadata().getObjectName());
444 Assertions.assertEquals("1996-062A", segment0.getMetadata().getObjectID());
445 Assertions.assertEquals("MARS BARYCENTER", segment0.getMetadata().getCenter().getName());
446 Assertions.assertEquals(1996, segment0.getMetadata().getLaunchYear());
447 Assertions.assertEquals(62, segment0.getMetadata().getLaunchNumber());
448 Assertions.assertEquals("A", segment0.getMetadata().getLaunchPiece());
449 Assertions.assertFalse(segment0.getMetadata().getHasCreatableBody());
450 Assertions.assertNull(segment0.getMetadata().getCenter().getBody());
451 Assertions.assertEquals(CelestialBodyFrame.EME2000, segment0.getMetadata().getEndpoints().getFrameA().asCelestialBodyFrame());
452 Assertions.assertEquals(SpacecraftBodyFrame.BaseEquipment.SC_BODY, segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getBaseEquipment());
453 Assertions.assertEquals("1", segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getLabel());
454 Assertions.assertTrue(segment0.getMetadata().getEndpoints().isA2b());
455 Assertions.assertEquals(new AbsoluteDate("2002-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
456 segment0.getMetadata().getStartTime());
457 Assertions.assertEquals(new AbsoluteDate("2002-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
458 segment0.getMetadata().getUseableStartTime());
459 Assertions.assertEquals(new AbsoluteDate("2002-12-18T12:02:00.331", TimeScalesFactory.getUTC()),
460 segment0.getMetadata().getUseableStopTime());
461 Assertions.assertEquals(new AbsoluteDate("2002-12-18T12:02:00.331", TimeScalesFactory.getUTC()),
462 segment0.getMetadata().getStopTime());
463 Assertions.assertEquals(AttitudeType.QUATERNION, segment0.getMetadata().getAttitudeType());
464 Assertions.assertFalse(segment0.getMetadata().isFirst());
465 Assertions.assertEquals("HERMITE", segment0.getMetadata().getInterpolationMethod());
466 Assertions.assertEquals(7, segment0.getMetadata().getInterpolationDegree());
467
468 final AbsoluteDate refDate = new AbsoluteDate("2002-12-18T12:00:00.331", TimeScalesFactory.getUTC());
469
470 Assertions.assertEquals(3, segment0.getData().getAngularCoordinates().size());
471 final TimeStampedAngularCoordinates ac0 = segment0.getData().getAngularCoordinates().get(0);
472 Assertions.assertEquals(0.0, ac0.getDate().durationFrom(refDate), 1.0e-5);
473 Assertions.assertEquals(0.0,
474 Rotation.distance(new Rotation(0.68427, 0.56748, 0.03146, 0.45689, true),
475 ac0.getRotation()),
476 1.0e-10);
477 final TimeStampedAngularCoordinates ac1 = segment0.getData().getAngularCoordinates().get(1);
478 Assertions.assertEquals(60.0, ac1.getDate().durationFrom(refDate), 1.0e-5);
479 Assertions.assertEquals(0.0,
480 Rotation.distance(new Rotation(0.74533, 0.42319, -0.45697, 0.23784, true),
481 ac1.getRotation()),
482 1.0e-10);
483 final TimeStampedAngularCoordinates ac2 = segment0.getData().getAngularCoordinates().get(2);
484 Assertions.assertEquals(120.0, ac2.getDate().durationFrom(refDate), 1.0e-5);
485 Assertions.assertEquals(0.0,
486 Rotation.distance(new Rotation(0.45652, -0.84532, 0.26974, -0.06532, true),
487 ac2.getRotation()),
488 1.0e-10);
489
490 }
491
492 @Test
493 public void testParseAEM11() {
494 final String ex = "/ccsds/adm/aem/AEMExample11.xml";
495 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
496 final AemParser parser = new ParserBuilder().buildAemParser();
497 final Aem file = parser.parseMessage(source);
498 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
499 final List<String> headerComment = new ArrayList<>();
500 headerComment.add("This example shows an AEM with a rotation");
501 Assertions.assertEquals(headerComment, file.getHeader().getComments());
502 final List<String> metadataComment = new ArrayList<>();
503 metadataComment.add("The relative accuracy of these");
504 metadataComment.add("attitudes is 0.1 degrees per axis.");
505 Assertions.assertEquals(metadataComment, segment0.getMetadata().getComments());
506 Assertions.assertEquals(TimeSystem.UTC, segment0.getMetadata().getTimeSystem());
507 Assertions.assertEquals("FICTITIOUS", segment0.getMetadata().getObjectName());
508 Assertions.assertEquals("2020-224A", segment0.getMetadata().getObjectID());
509 Assertions.assertEquals("EARTH", segment0.getMetadata().getCenter().getName());
510 Assertions.assertEquals(CelestialBodyFrame.J2000, segment0.getMetadata().getEndpoints().getFrameA().asCelestialBodyFrame());
511 Assertions.assertEquals(SpacecraftBodyFrame.BaseEquipment.SC_BODY, segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getBaseEquipment());
512 Assertions.assertEquals("1", segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getLabel());
513 Assertions.assertTrue(segment0.getMetadata().getEndpoints().isA2b());
514 Assertions.assertEquals(new AbsoluteDate("2020-090T05:00:00.071", TimeScalesFactory.getUTC()),
515 segment0.getMetadata().getStartTime());
516 Assertions.assertEquals(new AbsoluteDate("2020-090T05:00:00.946", TimeScalesFactory.getUTC()),
517 segment0.getMetadata().getStopTime());
518 Assertions.assertEquals(AttitudeType.EULER_ANGLE_DERIVATIVE, segment0.getMetadata().getAttitudeType());
519
520 final AbsoluteDate refDate = new AbsoluteDate("2020-090T05:00:00.071", TimeScalesFactory.getUTC());
521
522 Assertions.assertEquals(2, segment0.getData().getAngularCoordinates().size());
523 final TimeStampedAngularCoordinates ac0 = segment0.getData().getAngularCoordinates().get(0);
524 Assertions.assertEquals(0.0, ac0.getDate().durationFrom(refDate), 1.0e-5);
525 Assertions.assertEquals(0.0,
526 Rotation.distance(new Rotation(RotationOrder.XYZ, RotationConvention.FRAME_TRANSFORM,
527 FastMath.toRadians(45),
528 FastMath.toRadians(0.9),
529 FastMath.toRadians(15)),
530 ac0.getRotation()),
531 1.0e-10);
532 final TimeStampedAngularCoordinates ac1 = segment0.getData().getAngularCoordinates().get(1);
533 Assertions.assertEquals(0.875, ac1.getDate().durationFrom(refDate), 1.0e-5);
534 Assertions.assertEquals(0.0,
535 Rotation.distance(new Rotation(RotationOrder.XYZ, RotationConvention.FRAME_TRANSFORM,
536 FastMath.toRadians(50),
537 FastMath.toRadians(1.9),
538 FastMath.toRadians(1.5)),
539 ac1.getRotation()),
540 1.0e-10);
541
542 }
543
544 @Test
545 public void testParseAEM13() {
546 final TimeScale tai = TimeScalesFactory.getTAI();
547 final String ex = "/ccsds/adm/aem/AEMExample13.xml";
548 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
549 final AemParser parser = new ParserBuilder().buildAemParser();
550 final Aem file = parser.parseMessage(source);
551 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
552 Assertions.assertEquals(TimeSystem.TAI, segment0.getMetadata().getTimeSystem());
553 Assertions.assertEquals("OREKIT SAT", segment0.getMetadata().getObjectName());
554 Assertions.assertEquals("2020-012A", segment0.getMetadata().getObjectID());
555 Assertions.assertEquals(OrbitRelativeFrame.LVLH, segment0.getMetadata().getEndpoints().getFrameA().asOrbitRelativeFrame());
556 Assertions.assertEquals(SpacecraftBodyFrame.BaseEquipment.IMU_FRAME, segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getBaseEquipment());
557 Assertions.assertEquals("1", segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getLabel());
558 Assertions.assertFalse(segment0.getMetadata().getEndpoints().isA2b());
559 Assertions.assertEquals(new AbsoluteDate("2021-04-15T13:31:20.000", tai), segment0.getMetadata().getStartTime());
560 Assertions.assertEquals(new AbsoluteDate("2021-04-15T13:31:23.000", tai), segment0.getMetadata().getStopTime());
561 Assertions.assertEquals(AttitudeType.QUATERNION_DERIVATIVE, segment0.getMetadata().getAttitudeType());
562 Assertions.assertTrue(segment0.getMetadata().isFirst());
563
564 final AbsoluteDate refDate = new AbsoluteDate("2021-04-15T13:31:20.000", tai);
565
566 Assertions.assertEquals(7, segment0.getData().getAngularCoordinates().size());
567 final TimeStampedAngularCoordinates ac0 = segment0.getData().getAngularCoordinates().get(0);
568 Assertions.assertEquals(0.0, ac0.getDate().durationFrom(refDate), 1.0e-5);
569 Assertions.assertEquals(0.0,
570 Rotation.distance(new Rotation(-0.488615, -0.402157, 0.581628, 0.511111, true),
571 ac0.getRotation()),
572 1.0e-10);
573 final TimeStampedAngularCoordinates ac1 = segment0.getData().getAngularCoordinates().get(1);
574 Assertions.assertEquals(0.5, ac1.getDate().durationFrom(refDate), 1.0e-5);
575 Assertions.assertEquals(0.0,
576 Rotation.distance(new Rotation(-0.488765, -0.402027, 0.581486, 0.511231, true),
577 ac1.getRotation()),
578 1.0e-10);
579 final TimeStampedAngularCoordinates ac2 = segment0.getData().getAngularCoordinates().get(2);
580 Assertions.assertEquals(1.0, ac2.getDate().durationFrom(refDate), 1.0e-5);
581 Assertions.assertEquals(0.0,
582 Rotation.distance(new Rotation(-0.488916, -0.401898, 0.581344, 0.511350, true),
583 ac2.getRotation()),
584 1.0e-10);
585
586 final CircularOrbit o = new CircularOrbit(6992992, -5e-04, 1.2e-03,
587 FastMath.toRadians(97.83), FastMath.toRadians(80.95),
588 FastMath.toRadians(179.86), PositionAngleType.MEAN,
589 FramesFactory.getEME2000(),
590 new AbsoluteDate("2021-04-15T13:31:22.000", tai),
591 Constants.EIGEN5C_EARTH_MU);
592 final FieldCircularOrbit<Binary64> fo =
593 new FieldCircularOrbit<>(new Binary64(o.getA()),
594 new Binary64(o.getCircularEx()), new Binary64(o.getCircularEy()),
595 new Binary64(o.getI()), new Binary64(o.getRightAscensionOfAscendingNode()),
596 new Binary64(o.getAlphaM()), PositionAngleType.MEAN,
597 o.getFrame(), new FieldAbsoluteDate<>(Binary64Field.getInstance(), o.getDate()),
598 new Binary64(o.getMu()));
599 final AemSatelliteEphemeris ephemeris = file.getSatellites().get("2020-012A");
600 final BoundedAttitudeProvider provider = ephemeris.getAttitudeProvider();
601 Attitude a = provider.getAttitude(o, o.getDate(), o.getFrame());
602 FieldAttitude<Binary64> fa = provider.getAttitude(fo, fo.getDate(), fo.getFrame());
603 Assertions.assertEquals(a.getRotation().getQ0(), fa.getRotation().getQ0().getReal(), 0.00001);
604 Assertions.assertEquals(a.getRotation().getQ1(), fa.getRotation().getQ1().getReal(), 0.00001);
605 Assertions.assertEquals(a.getRotation().getQ2(), fa.getRotation().getQ2().getReal(), 0.00001);
606 Assertions.assertEquals(a.getRotation().getQ3(), fa.getRotation().getQ3().getReal(), 0.00001);
607
608 }
609
610 @Test
611 public void testParseAEM14() {
612 final TimeScale tai = TimeScalesFactory.getTAI();
613 final String ex = "/ccsds/adm/aem/AEMExample14.txt";
614 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
615 final AemParser parser = new ParserBuilder().buildAemParser();
616 final Aem file = parser.parseMessage(source);
617
618 final Segment<AemMetadata, AemData> segment0 = file.getSegments().get(0);
619 Assertions.assertEquals(TimeSystem.TAI, segment0.getMetadata().getTimeSystem());
620 Assertions.assertEquals("MMS", segment0.getMetadata().getObjectName());
621 Assertions.assertEquals("2015-011A", segment0.getMetadata().getObjectID());
622 Assertions.assertEquals("EME2000", segment0.getMetadata().getEndpoints().getFrameA().getName());
623 Assertions.assertEquals(SpacecraftBodyFrame.BaseEquipment.SC_BODY, segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getBaseEquipment());
624 Assertions.assertEquals("1", segment0.getMetadata().getEndpoints().getFrameB().asSpacecraftBodyFrame().getLabel());
625 Assertions.assertEquals(new AbsoluteDate("2023-01-01T00:00:00.000", tai), segment0.getMetadata().getStartTime());
626 Assertions.assertEquals(new AbsoluteDate("2023-01-01T00:04:30.000", tai), segment0.getMetadata().getStopTime());
627 Assertions.assertEquals(AttitudeType.EULER_ANGLE_DERIVATIVE, segment0.getMetadata().getAttitudeType());
628 Assertions.assertEquals(RotationOrder.ZXZ, segment0.getMetadata().getEulerRotSeq());
629 Assertions.assertEquals(10, segment0.getData().getAngularCoordinates().size());
630
631 Assertions.assertEquals(AttitudeType.SPIN_NUTATION_MOMENTUM,
632 file.getSegments().get(1).getMetadata().getAttitudeType());
633 Assertions.assertEquals(AttitudeType.QUATERNION,
634 file.getSegments().get(2).getMetadata().getAttitudeType());
635 Assertions.assertEquals(AttitudeType.QUATERNION_ANGVEL,
636 file.getSegments().get(3).getMetadata().getAttitudeType());
637 Assertions.assertEquals(AttitudeType.EULER_ANGLE_ANGVEL,
638 file.getSegments().get(4).getMetadata().getAttitudeType());
639
640 }
641
642 @Test
643 public void testWrongNDMType() {
644 final String name = "/ccsds/odm/opm/OPMExample1.txt";
645 try {
646 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
647 new ParserBuilder().buildAemParser().parseMessage(source);
648 Assertions.fail("an exception should have been thrown");
649 } catch (OrekitException oe) {
650 Assertions.assertEquals(OrekitMessages.UNSUPPORTED_FILE_FORMAT, oe.getSpecifier());
651 Assertions.assertEquals(name, oe.getParts()[0]);
652 }
653 }
654
655 @Test
656 public void testNonExistentFile() throws URISyntaxException {
657 final String realName = getClass().getResource("/ccsds/adm/aem/AEMExample01.txt").toURI().getPath();
658 final String wrongName = realName + "xxxxx";
659 final DataSource source = new DataSource(wrongName, () -> getClass().getResourceAsStream(wrongName));
660 try {
661 new ParserBuilder().buildAemParser().parseMessage(source);
662 Assertions.fail("an exception should have been thrown");
663 } catch (OrekitException oe) {
664 Assertions.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
665 Assertions.assertEquals(wrongName, oe.getParts()[0]);
666 }
667 }
668
669 @Test
670 public void testMissingAttitudeType() {
671 try {
672 final String name = "/ccsds/adm/aem/AEM-missing-attitude-type.txt";
673 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
674 new ParserBuilder().buildAemParser().parseMessage(source);
675 Assertions.fail("an exception should have been thrown");
676 } catch (OrekitException oe) {
677 Assertions.assertEquals(OrekitMessages.UNINITIALIZED_VALUE_FOR_KEY, oe.getSpecifier());
678 Assertions.assertEquals(AemMetadataKey.ATTITUDE_TYPE.name(), oe.getParts()[0]);
679 }
680 }
681
682 @Test
683 public void testInconsistentDirection() {
684 try {
685 final String name = "/ccsds/adm/aem/AEM-inconsistent-direction.txt";
686 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
687 new ParserBuilder().buildAemParser().parseMessage(source);
688 Assertions.fail("an exception should have been thrown");
689 } catch (OrekitException oe) {
690 Assertions.assertEquals(OrekitMessages.CCSDS_KEYWORD_NOT_ALLOWED_IN_VERSION, oe.getSpecifier());
691 Assertions.assertEquals(AemMetadataKey.ATTITUDE_DIR, oe.getParts()[0]);
692 Assertions.assertEquals(2.0, (Double) oe.getParts()[1], 1.0e-15);
693 }
694 }
695
696 @Test
697 public void testInconsistentQuaternionType() {
698 try {
699 final String name = "/ccsds/adm/aem/AEM-inconsistent-quaternion-type.txt";
700 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
701 new ParserBuilder().buildAemParser().parseMessage(source);
702 Assertions.fail("an exception should have been thrown");
703 } catch (OrekitException oe) {
704 Assertions.assertEquals(OrekitMessages.CCSDS_KEYWORD_NOT_ALLOWED_IN_VERSION, oe.getSpecifier());
705 Assertions.assertEquals(AemMetadataKey.QUATERNION_TYPE, oe.getParts()[0]);
706 Assertions.assertEquals(2.0, (Double) oe.getParts()[1], 1.0e-15);
707 }
708 }
709
710 @Test
711 public void testLowerCaseValue() {
712
713 String file = "/ccsds/adm/aem/aemLowerCaseValue.aem";
714 final DataSource source = new DataSource(file, () -> getClass().getResourceAsStream(file));
715
716
717 Aem actual = new ParserBuilder().buildAemParser().parseMessage(source);
718
719
720 Assertions.assertEquals(
721 CelestialBodyFactory.getEarth(),
722 actual.getSegments().get(0).getMetadata().getCenter().getBody());
723 }
724
725 @Test
726 public void testWrongFile() {
727 final String name = "/ccsds/odm/opm/OPMExample1.txt";
728 try {
729 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
730 new ParserBuilder().buildAemParser().parseMessage(source);
731 Assertions.fail("an exception should have been thrown");
732 } catch (OrekitException oe) {
733 Assertions.assertEquals(OrekitMessages.UNSUPPORTED_FILE_FORMAT, oe.getSpecifier());
734 Assertions.assertEquals(name, oe.getParts()[0]);
735 }
736 }
737
738 @Test
739 public void testWrongKeyword() {
740
741 final String name = "/ccsds/adm/aem/AEM-wrong-keyword.txt";
742 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
743 try {
744 new ParserBuilder().buildAemParser().parseMessage(source);
745 Assertions.fail("an exception should have been thrown");
746 } catch (OrekitException oe) {
747 Assertions.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
748 Assertions.assertEquals(24, ((Integer) oe.getParts()[0]).intValue());
749 Assertions.assertTrue(((String) oe.getParts()[2]).startsWith("WRONG_KEYWORD"));
750 }
751 }
752
753 @Test
754 public void testEphemerisNumberFormatErrorType() {
755 final String name = "/ccsds/adm/aem/AEM-ephemeris-number-format-error.txt";
756 try {
757 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
758 new ParserBuilder().buildAemParser().parseMessage(source);
759 Assertions.fail("an exception should have been thrown");
760 } catch (OrekitException oe) {
761 Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
762 Assertions.assertEquals(28, oe.getParts()[0]);
763 Assertions.assertEquals(name, oe.getParts()[1]);
764 Assertions.assertEquals("1996-11-28T22:08:03.5555 0.42319 this-is-not-a-number 0.23784 0.74533", oe.getParts()[2]);
765 }
766 }
767
768 @Test
769 public void testKeywordWithinEphemeris() {
770
771 final String name = "/ccsds/adm/aem/AEM-keyword-within-ephemeris.txt";
772 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
773 try {
774 new ParserBuilder().buildAemParser().parseMessage(source);
775 Assertions.fail("an exception should have been thrown");
776 } catch (OrekitException oe) {
777 Assertions.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
778 Assertions.assertEquals(29, ((Integer) oe.getParts()[0]).intValue());
779 Assertions.assertTrue(((String) oe.getParts()[2]).startsWith("USER_DEFINED_TEST_KEY"));
780 }
781 }
782
783 @Test
784 public void testWrongRotationSequence() {
785
786 final String name = "/ccsds/adm/aem/AEM-inconsistent-rotation-sequence.txt";
787 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
788 try {
789 new ParserBuilder().buildAemParser().parseMessage(source);
790 Assertions.fail("an exception should have been thrown");
791 } catch (OrekitException oe) {
792 Assertions.assertEquals(OrekitMessages.CCSDS_INVALID_ROTATION_SEQUENCE, oe.getSpecifier());
793 Assertions.assertEquals("7051995", oe.getParts()[0]);
794 Assertions.assertEquals(22, ((Integer) oe.getParts()[1]).intValue());
795 Assertions.assertEquals(name, oe.getParts()[2]);
796 }
797 }
798
799 @Test
800 public void testSpuriousMetaDataSection() {
801 final String name = "/ccsds/adm/aem/spurious-metadata.txt";
802 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
803 try {
804 new ParserBuilder().buildAemParser().parseMessage(source);
805 Assertions.fail("an exception should have been thrown");
806 } catch (OrekitException oe) {
807 Assertions.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
808 Assertions.assertEquals(26, ((Integer) oe.getParts()[0]).intValue());
809 Assertions.assertEquals("META", oe.getParts()[2]);
810 }
811 }
812
813 @Test
814 public void testMissingConvention() {
815 final String ex = "/ccsds/adm/aem/AEMExample01.txt";
816 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
817 final Aem file = new ParserBuilder().buildAemParser().parseMessage(source);
818 try {
819 file.getConventions();
820 } catch (OrekitException oe) {
821 Assertions.assertEquals(OrekitMessages.CCSDS_UNKNOWN_CONVENTIONS, oe.getSpecifier());
822 }
823 }
824
825 private void verifyAngularCoordinates(final TimeStampedAngularCoordinates expected,
826 final TimeStampedAngularCoordinates actual,
827 final double threshold) {
828
829 Assertions.assertEquals(0.0, expected.getDate().durationFrom(actual.getDate()), threshold);
830
831
832 Assertions.assertEquals(expected.getRotation().getQ0(), actual.getRotation().getQ0(), threshold);
833 Assertions.assertEquals(expected.getRotation().getQ1(), actual.getRotation().getQ1(), threshold);
834 Assertions.assertEquals(expected.getRotation().getQ2(), actual.getRotation().getQ2(), threshold);
835 Assertions.assertEquals(expected.getRotation().getQ3(), actual.getRotation().getQ3(), threshold);
836
837 Assertions.assertEquals(0.0, expected.getRotationRate().distance(actual.getRotationRate()), threshold);
838 }
839
840
841
842
843
844 @Test
845 public void testDefaultInterpolationDegree() {
846
847 final String name = "/ccsds/adm/aem/AEMExample01.txt";
848 ParserBuilder builder = new ParserBuilder();
849
850 final DataSource source1 = new DataSource(name, () -> getClass().getResourceAsStream(name));
851 final Aem file = builder.buildAemParser().parseMessage(source1);
852 Assertions.assertEquals(7, file.getSegments().get(0).getMetadata().getInterpolationDegree());
853 Assertions.assertEquals(1, file.getSegments().get(1).getMetadata().getInterpolationDegree());
854
855 final DataSource source2 = new DataSource(name, () -> getClass().getResourceAsStream(name));
856 final Aem file2 = builder.withDefaultInterpolationDegree(5).buildAemParser().parseMessage(source2);
857 Assertions.assertEquals(7, file2.getSegments().get(0).getMetadata().getInterpolationDegree());
858 Assertions.assertEquals(5, file2.getSegments().get(1).getMetadata().getInterpolationDegree());
859 }
860
861 @Test
862 public void testIssue739() {
863 final String ex = "/ccsds/adm/aem/AEMExample08.txt";
864 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
865 final Aem file = new ParserBuilder().buildAemParser().parseMessage(source);
866 final AemSegment segment0 = file.getSegments().get(0);
867 Assertions.assertEquals(CelestialBodyFrame.GTOD, segment0.getMetadata().getEndpoints().getFrameB().asCelestialBodyFrame());
868
869 final BoundedAttitudeProvider provider = segment0.getAttitudeProvider();
870 Attitude attitude = provider.getAttitude(null, new AbsoluteDate("1996-11-28T22:08:03.555", TimeScalesFactory.getUTC()), null);
871 Rotation rotation = attitude.getRotation();
872 Assertions.assertEquals(0.42319, rotation.getQ1(), 0.0001);
873 Assertions.assertEquals(-0.45697, rotation.getQ2(), 0.0001);
874 Assertions.assertEquals(0.23784, rotation.getQ3(), 0.0001);
875 Assertions.assertEquals(0.74533, rotation.getQ0(), 0.0001);
876 Assertions.assertEquals(0.0, provider.getMinDate().durationFrom(segment0.getMetadata().getStart()), 0.0001);
877 Assertions.assertEquals(0.0, provider.getMaxDate().durationFrom(segment0.getMetadata().getStop()), 0.0001);
878
879 }
880
881 @Test
882 public void testIssue739_2() {
883 final String ex = "/ccsds/adm/aem/AEMExample09.txt";
884 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
885 final Aem file = new ParserBuilder().buildAemParser().parseMessage(source);
886 final AemSegment segment0 = file.getSegments().get(0);
887 Assertions.assertEquals(FramesFactory.getITRF(ITRFVersion.ITRF_1993, IERSConventions.IERS_2010, true),
888 segment0.getMetadata().getEndpoints().getFrameA().asFrame());
889
890 final BoundedAttitudeProvider provider = segment0.getAttitudeProvider();
891 Attitude attitude = provider.getAttitude(null, new AbsoluteDate("1996-11-28T22:08:03.555", TimeScalesFactory.getUTC()), null);
892 Rotation rotation = attitude.getRotation();
893 Assertions.assertEquals(0.42319, rotation.getQ1(), 0.0001);
894 Assertions.assertEquals(-0.45697, rotation.getQ2(), 0.0001);
895 Assertions.assertEquals(0.23784, rotation.getQ3(), 0.0001);
896 Assertions.assertEquals(0.74533, rotation.getQ0(), 0.0001);
897 Assertions.assertEquals(0.0, provider.getMinDate().durationFrom(segment0.getMetadata().getStart()), 0.0001);
898 Assertions.assertEquals(0.0, provider.getMaxDate().durationFrom(segment0.getMetadata().getStop()), 0.0001);
899
900 }
901
902 }