1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.ndm.odm.omm;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.CharArrayWriter;
21 import java.io.IOException;
22 import java.net.URISyntaxException;
23 import java.nio.charset.StandardCharsets;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.HashMap;
27
28 import org.hipparchus.linear.Array2DRowRealMatrix;
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.MathUtils;
31 import org.junit.Assert;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.orekit.Utils;
35 import org.orekit.bodies.CelestialBodyFactory;
36 import org.orekit.data.DataContext;
37 import org.orekit.data.DataSource;
38 import org.orekit.errors.OrekitException;
39 import org.orekit.errors.OrekitMessages;
40 import org.orekit.files.ccsds.ndm.ParserBuilder;
41 import org.orekit.files.ccsds.ndm.WriterBuilder;
42 import org.orekit.files.ccsds.ndm.odm.CartesianCovariance;
43 import org.orekit.files.ccsds.ndm.odm.KeplerianElements;
44 import org.orekit.files.ccsds.ndm.odm.SpacecraftParameters;
45 import org.orekit.files.ccsds.ndm.odm.UserDefined;
46 import org.orekit.files.ccsds.utils.generation.Generator;
47 import org.orekit.files.ccsds.utils.generation.KvnGenerator;
48 import org.orekit.frames.FramesFactory;
49 import org.orekit.frames.LOFType;
50 import org.orekit.propagation.analytical.tle.TLE;
51 import org.orekit.time.AbsoluteDate;
52 import org.orekit.time.TimeScalesFactory;
53 import org.orekit.utils.Constants;
54 import org.orekit.utils.IERSConventions;
55
56 public class OmmParserTest {
57
58 @Before
59 public void setUp()
60 throws Exception {
61 Utils.setDataRoot("regular-data");
62 }
63
64 @Test
65 public void testParseOMM1() {
66
67
68 final String ex = "/ccsds/odm/omm/OMMExample1.txt";
69 final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
70
71
72 final OmmParser parser = new ParserBuilder().withMu(398600e9).withDefaultMass(1000.0).buildOmmParser();
73 final Omm file = parser.parseMessage(source);
74
75
76 Assert.assertEquals(3.0, file.getHeader().getFormatVersion(), 1.0e-10);
77 Assert.assertEquals(new AbsoluteDate(2007, 03, 06, 16, 00, 00,
78 TimeScalesFactory.getUTC()),
79 file.getHeader().getCreationDate());
80 Assert.assertEquals("NOAA/USA", file.getHeader().getOriginator());
81 Assert.assertNull(file.getHeader().getMessageId());
82
83
84
85 Assert.assertEquals("GOES 9", file.getMetadata().getObjectName());
86 Assert.assertEquals("1995-025A", file.getMetadata().getObjectID());
87 Assert.assertEquals("EARTH", file.getMetadata().getCenter().getName());
88 Assert.assertNotNull(file.getMetadata().getCenter().getBody());
89 Assert.assertEquals(CelestialBodyFactory.getEarth(), file.getMetadata().getCenter().getBody());
90 Assert.assertEquals(FramesFactory.getTEME(), file.getMetadata().getFrame());
91 Assert.assertEquals("UTC", file.getMetadata().getTimeSystem().name());
92 Assert.assertEquals("SGP/SGP4", file.getMetadata().getMeanElementTheory());
93 Assert.assertEquals("TEME", file.getMetadata().getFrame().toString());
94 Assert.assertTrue(file.getData().getTLEBlock().getComments().isEmpty());
95
96
97 KeplerianElements kep = file.getData().getKeplerianElementsBlock();
98 Assert.assertEquals(new AbsoluteDate(2007, 03, 05, 10, 34, 41.4264,
99 TimeScalesFactory.getUTC()),
100 file.getDate());
101 Assert.assertEquals(1.00273272 * FastMath.PI / 43200.0, kep.getMeanMotion(), 1e-10);
102 Assert.assertEquals(0.0005013, kep.getE(), 1e-10);
103 Assert.assertEquals(FastMath.toRadians(3.0539), kep.getI(), 1e-10);
104 Assert.assertEquals(FastMath.toRadians(81.7939), kep.getRaan(), 1e-10);
105 Assert.assertEquals(FastMath.toRadians(249.2363), kep.getPa(), 1e-10);
106 Assert.assertEquals(FastMath.toRadians(150.1602), kep.getAnomaly(), 1e-10);
107 Assert.assertEquals(398600.8 * 1e9, kep.getMu(), 1e-10);
108
109
110
111 OmmTle tle = file.getData().getTLEBlock();
112 Assert.assertEquals(0, tle.getEphemerisType());
113 Assert.assertEquals('U', tle.getClassificationType());
114 int[] noradIDExpected = new int[23581];
115 int[] noradIDActual = new int[tle.getNoradID()];
116 Assert.assertEquals(noradIDExpected[0], noradIDActual[0]);
117 Assert.assertEquals(925, tle.getElementSetNumber());
118 int[] revAtEpochExpected = new int[4316];
119 int[] revAtEpochActual = new int[tle.getRevAtEpoch()];
120 Assert.assertEquals(revAtEpochExpected[0], revAtEpochActual[0]);
121 Assert.assertEquals(0.0001, tle.getBStar(), 1e-10);
122 Assert.assertEquals(-0.00000113 * FastMath.PI / 1.86624e9, tle.getMeanMotionDot(), 1e-12);
123 Assert.assertEquals(0.0 * FastMath.PI / 5.3747712e13, tle.getMeanMotionDotDot(), 1e-10);
124 Assert.assertEquals(1995, file.getMetadata().getLaunchYear());
125 Assert.assertEquals(25, file.getMetadata().getLaunchNumber());
126 Assert.assertEquals("A", file.getMetadata().getLaunchPiece());
127 file.generateKeplerianOrbit();
128 try {
129 file.generateSpacecraftState();
130 } catch (OrekitException orekitException) {
131 Assert.assertEquals(OrekitMessages.CCSDS_UNKNOWN_SPACECRAFT_MASS, orekitException.getSpecifier());
132 }
133 TLE generated = file.generateTLE();
134 Assert.assertEquals("1 23581U 95025A 07064.44075725 -.00000113 00000-0 10000-3 0 9250", generated.getLine1());
135 Assert.assertEquals("2 23581 3.0539 81.7939 0005013 249.2363 150.1602 1.00273272 43169", generated.getLine2());
136 }
137
138 @Test
139 public void testParseOMM2KVN() throws URISyntaxException {
140 String name = "/ccsds/odm/omm/OMMExample2.txt";
141 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
142 final OmmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).buildOmmParser();
143
144 validateOMM2(parser.parseMessage(source));
145 }
146
147 @Test
148 public void testParseOMM2XML() throws URISyntaxException {
149 String name = "/ccsds/odm/omm/OMMExample2.xml";
150 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
151 final OmmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).buildOmmParser();
152
153 validateOMM2(parser.parseMessage(source));
154 }
155
156 @Test
157 public void testWriteOMM3() throws URISyntaxException, IOException {
158 final String name = "/ccsds/odm/omm/OMMExample2.xml";
159 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
160 OmmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).buildOmmParser();
161 final Omm original = parser.parseMessage(source);
162
163
164 final CharArrayWriter caw = new CharArrayWriter();
165 final Generator generator = new KvnGenerator(caw, OmmWriter.KVN_PADDING_WIDTH, "dummy", 60);
166 new WriterBuilder().buildOmmWriter().writeMessage(generator, original);
167
168
169 final byte[] bytes = caw.toString().getBytes(StandardCharsets.UTF_8);
170 final DataSource source2 = new DataSource(name, () -> new ByteArrayInputStream(bytes));
171 final Omm rebuilt = new ParserBuilder().buildOmmParser().parseMessage(source2);
172 validateOMM2(rebuilt);
173
174 }
175
176 private void validateOMM2(final Omm file) throws URISyntaxException {
177 Assert.assertEquals(3.0, file.getHeader().getFormatVersion(), 1.0e-10);
178 Assert.assertEquals("SGP/SGP4", file.getMetadata().getMeanElementTheory());
179 final KeplerianElements kep = file.getData().getKeplerianElementsBlock();
180 Assert.assertEquals(1.00273272, Constants.JULIAN_DAY * kep.getMeanMotion() / MathUtils.TWO_PI, 1e-10);
181 Assert.assertTrue(Double.isNaN(file.getData().getMass()));
182 CartesianCovariance covariance = file.getData().getCovarianceBlock();
183 Assert.assertEquals(FramesFactory.getTEME(), covariance.getReferenceFrame().asFrame());
184 Assert.assertEquals(6, covariance.getCovarianceMatrix().getRowDimension());
185 Assert.assertEquals(6, covariance.getCovarianceMatrix().getColumnDimension());
186 Assert.assertEquals(1995, file.getMetadata().getLaunchYear());
187 Assert.assertEquals(25, file.getMetadata().getLaunchNumber());
188 Assert.assertEquals("A", file.getMetadata().getLaunchPiece());
189 file.generateKeplerianOrbit();
190
191 Array2DRowRealMatrix covMatrix = new Array2DRowRealMatrix(6, 6);
192 double[] column1 = {
193 333.1349476038534, 461.8927349220216,
194 -307.0007847730449, -0.3349365033922630,
195 -0.2211832501084875, -0.3041346050686871
196 };
197 double[] column2 = {
198 461.8927349220216, 678.2421679971363,
199 -422.1234189514228, -0.4686084221046758,
200 -0.2864186892102733, -0.4989496988610662
201 };
202 double[] column3 = {
203 -307.0007847730449, -422.1234189514228,
204 323.1931992380369, 0.2484949578400095,
205 0.1798098699846038, 0.3540310904497689
206 };
207 double[] column4 = {
208 -0.3349365033922630, -0.4686084221046758,
209 0.2484949578400095, 0.0004296022805587290,
210 0.0002608899201686016, 0.0001869263192954590
211 };
212 double[] column5 = {
213 -0.2211832501084875, -0.2864186892102733,
214 0.1798098699846038, 0.0002608899201686016,
215 0.0001767514756338532, 0.0001008862586240695
216 };
217 double[] column6 = {
218 -0.3041346050686871, -0.4989496988610662,
219 0.3540310904497689, 0.0001869263192954590,
220 0.0001008862586240695, 0.0006224444338635500
221 };
222 covMatrix.setColumn(0, column1);
223 covMatrix.setColumn(1, column2);
224 covMatrix.setColumn(2, column3);
225 covMatrix.setColumn(3, column4);
226 covMatrix.setColumn(4, column5);
227 covMatrix.setColumn(5, column6);
228 for (int i = 0; i < 6; i++) {
229 for (int j = 0; j < 6; j++) {
230 Assert.assertEquals(covMatrix.getEntry(i, j),
231 covariance.getCovarianceMatrix().getEntry(i, j),
232 1e-15);
233 }
234 }
235
236 }
237
238 @Test
239 public void testParseOMM3() throws URISyntaxException {
240
241
242 final String name = "/ccsds/odm/omm/OMMExample3.txt";
243 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
244 final AbsoluteDate missionReferenceDate = new AbsoluteDate(2000, 1, 1, DataContext.getDefault().getTimeScales().getUTC());
245 final OmmParser parser = new ParserBuilder().
246 withMu(Constants.EIGEN5C_EARTH_MU).
247 withMissionReferenceDate(missionReferenceDate).
248 withDefaultMass(1000.0).
249 buildOmmParser();
250
251 final Omm file = parser.parseMessage(source);
252 final KeplerianElements kep = file.getData().getKeplerianElementsBlock();
253 Assert.assertEquals(2.0, file.getHeader().getFormatVersion(), 1.0e-10);
254 Assert.assertEquals(missionReferenceDate.shiftedBy(210840), file.getMetadata().getFrameEpoch());
255 Assert.assertEquals(6800e3, kep.getA(), 1e-10);
256
257 final SpacecraftParameters sp = file.getData().getSpacecraftParametersBlock();
258 Assert.assertEquals(300, sp.getMass(), 1e-10);
259 Assert.assertEquals(5, sp.getSolarRadArea(), 1e-10);
260 Assert.assertEquals(0.001, sp.getSolarRadCoeff(), 1e-10);
261
262 CartesianCovariance covariance = file.getData().getCovarianceBlock();
263 Assert.assertEquals(null, covariance.getReferenceFrame().asFrame());
264 Assert.assertEquals(null, covariance.getReferenceFrame().asCelestialBodyFrame());
265 Assert.assertEquals(LOFType.TNW, covariance.getReferenceFrame().asOrbitRelativeFrame().getLofType());
266
267 UserDefined ud = file.getData().getUserDefinedBlock();
268 HashMap<String, String> userDefinedParameters = new HashMap<String, String>();
269 userDefinedParameters.put("EARTH_MODEL", "WGS-84");
270 Assert.assertEquals(userDefinedParameters, ud.getParameters());
271 Assert.assertEquals(Arrays.asList("this is a comment", "here is another one"),
272 file.getHeader().getComments());
273 Assert.assertEquals(Collections.singletonList("this comment doesn't say much"),
274 file.getMetadata().getComments());
275 Assert.assertEquals(Collections.singletonList("the following data is what we're looking for"),
276 file.getData().getKeplerianElementsBlock().getComments());
277 Assert.assertEquals(Collections.singletonList("spacecraft data"),
278 file.getData().getSpacecraftParametersBlock().getComments());
279 Assert.assertEquals(Collections.singletonList("Covariance matrix"),
280 file.getData().getCovarianceBlock().getComments());
281 Assert.assertEquals(1995, file.getMetadata().getLaunchYear());
282 Assert.assertEquals(25, file.getMetadata().getLaunchNumber());
283 Assert.assertEquals("A", file.getMetadata().getLaunchPiece());
284 file.generateSpacecraftState();
285 file.generateKeplerianOrbit();
286
287 }
288
289 @Test
290 public void testWrongKeyword() throws URISyntaxException {
291
292
293 final String name = "/ccsds/odm/omm/OMM-wrong-keyword.txt";
294 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
295 final OmmParser parser = new ParserBuilder().
296 withMu(Constants.EIGEN5C_EARTH_MU).
297 withMissionReferenceDate(new AbsoluteDate()).
298 withDefaultMass(1000.0).
299 buildOmmParser();
300 try {
301 parser.parseMessage(source);
302 Assert.fail("an exception should have been thrown");
303 } catch (OrekitException oe) {
304 Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
305 Assert.assertEquals(9, ((Integer) oe.getParts()[0]).intValue());
306 Assert.assertTrue(((String) oe.getParts()[2]).startsWith("WRONG_KEYWORD"));
307 }
308 }
309
310 @Test
311 public void testOrbitFileInterface() {
312
313 final String name = "/ccsds/odm/omm/OMMExample1.txt";
314 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
315
316
317 final OmmParser parser = new ParserBuilder().
318 withMu(398600e9).
319 withMissionReferenceDate(new AbsoluteDate()).
320 withDefaultMass(1000.0).
321 buildOmmParser();
322
323 final Omm file = parser.parseMessage(source);
324
325 final String satId = "1995-025A";
326 Assert.assertEquals(satId, file.getMetadata().getObjectID());
327
328 }
329
330 @Test
331 public void testWrongODMType() {
332 final String name = "/ccsds/odm/oem/OEMExample1.txt";
333 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
334 try {
335 new ParserBuilder().
336 withConventions(IERSConventions.IERS_1996).
337 withMu(Constants.EIGEN5C_EARTH_MU).
338 withMissionReferenceDate(new AbsoluteDate()).
339 withDefaultMass(1000.0).
340 buildOmmParser().
341 parseMessage(source);
342 } catch (OrekitException oe) {
343 Assert.assertEquals(OrekitMessages.UNSUPPORTED_FILE_FORMAT, oe.getSpecifier());
344 Assert.assertEquals(name, oe.getParts()[0]);
345 }
346 }
347
348 @Test
349 public void testNumberFormatErrorType() {
350 final String name = "/ccsds/odm/omm/OMM-number-format-error.txt";
351 final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
352 try {
353 new ParserBuilder().
354 withConventions(IERSConventions.IERS_1996).
355 withMu(Constants.EIGEN5C_EARTH_MU).
356 withMissionReferenceDate(new AbsoluteDate()).
357 withDefaultMass(1000.0).
358 buildOmmParser().
359 parseMessage(source);
360 } catch (OrekitException oe) {
361 Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_ELEMENT_IN_FILE, oe.getSpecifier());
362 Assert.assertEquals("ARG_OF_PERICENTER", oe.getParts()[0]);
363 Assert.assertEquals(15, oe.getParts()[1]);
364 Assert.assertEquals(name, oe.getParts()[2]);
365 }
366 }
367
368 @Test
369 public void testNonExistentFile() throws URISyntaxException {
370 final String realName = "/ccsds/odm/omm/OMMExample1.txt";
371 final String wrongName = realName + "xxxxx";
372 final DataSource source = new DataSource(wrongName, () -> getClass().getResourceAsStream(wrongName));
373 try {
374 new ParserBuilder().
375 withConventions(IERSConventions.IERS_1996).
376 withMu(Constants.EIGEN5C_EARTH_MU).
377 withMissionReferenceDate(new AbsoluteDate()).
378 withDefaultMass(1000.0).
379 buildOmmParser().
380 parseMessage(source);
381 Assert.fail("an exception should have been thrown");
382 } catch (OrekitException oe) {
383 Assert.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
384 Assert.assertEquals(wrongName, oe.getParts()[0]);
385 }
386 }
387
388 }