1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical.tle;
18
19
20 import static org.junit.Assert.fail;
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.text.ParseException;
27
28 import org.hipparchus.CalculusFieldElement;
29 import org.hipparchus.Field;
30 import org.hipparchus.analysis.differentiation.DSFactory;
31 import org.hipparchus.analysis.differentiation.DerivativeStructure;
32 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
33 import org.hipparchus.util.CombinatoricsUtils;
34 import org.hipparchus.util.Decimal64;
35 import org.hipparchus.util.Decimal64Field;
36 import org.hipparchus.util.FastMath;
37 import org.hipparchus.util.MathArrays;
38 import org.junit.Assert;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.orekit.Utils;
42 import org.orekit.errors.OrekitException;
43 import org.orekit.errors.OrekitMessages;
44 import org.orekit.frames.Frame;
45 import org.orekit.frames.FramesFactory;
46 import org.orekit.orbits.FieldCartesianOrbit;
47 import org.orekit.propagation.FieldPropagator;
48 import org.orekit.propagation.FieldSpacecraftState;
49 import org.orekit.time.DateComponents;
50 import org.orekit.time.FieldAbsoluteDate;
51 import org.orekit.time.TimeComponents;
52 import org.orekit.time.TimeScalesFactory;
53 import org.orekit.utils.Constants;
54 import org.orekit.utils.FieldPVCoordinates;
55 import org.orekit.utils.TimeStampedFieldPVCoordinates;
56
57 public class FieldTLETest {
58
59
60
61 @Test
62 public void testTLEFormat() {
63 doTestTLEFormat(Decimal64Field.getInstance());
64 }
65
66 @Test
67 public void TestIssue196() {
68 doTestIssue196(Decimal64Field.getInstance());
69 }
70
71 @Test
72 public void testSymmetry() {
73 doTestSymmetry(Decimal64Field.getInstance());
74 }
75
76 @Test
77 public void testBug74() {
78 doTestBug74(Decimal64Field.getInstance());
79 }
80
81 @Test
82 public void testBug77() {
83 doTestBug77(Decimal64Field.getInstance());
84 }
85
86 @Test
87 public void testDirectConstruction() {
88 doTestDirectConstruction(Decimal64Field.getInstance());
89 }
90
91 @Test
92 public void testGenerateAlpha5() {
93 doTestGenerateAlpha5(Decimal64Field.getInstance());
94 }
95
96 @Test
97 public void testBug77TooLargeSecondDerivative() {
98 doTestBug77TooLargeSecondDerivative(Decimal64Field.getInstance());
99 }
100
101 @Test
102 public void testBug77TooLargeBStar() {
103 doTestBug77TooLargeBStar(Decimal64Field.getInstance());
104 }
105
106 @Test
107 public void testBug77TooLargeEccentricity() {
108 doTestBug77TooLargeEccentricity(Decimal64Field.getInstance());
109 }
110
111 @Test
112 public void testBug77TooLargeSatelliteNumber1() {
113 doTestBug77TooLargeSatelliteNumber1(Decimal64Field.getInstance());
114 }
115
116 @Test
117 public void testBug77TooLargeSatelliteNumber2() {
118 doTestBug77TooLargeSatelliteNumber2(Decimal64Field.getInstance());
119 }
120
121 @Test(expected=OrekitException.class)
122 public void testDifferentSatNumbers() {
123 doTestDifferentSatNumbers(Decimal64Field.getInstance());
124 }
125
126 @Test
127 public void testChecksumOK() {
128 doTestChecksumOK();
129 }
130
131 @Test
132 public void testWrongChecksum1() {
133 doTestWrongChecksum1();
134 }
135
136 @Test
137 public void testWrongChecksum2() {
138 doTestWrongChecksum2();
139 }
140
141 @Test
142 public void testSatCodeCompliance() throws IOException, OrekitException, ParseException {
143 doTestSatCodeCompliance(Decimal64Field.getInstance());
144 }
145
146 @Test
147 public void testZeroInclination() {
148 doTestZeroInclination(Decimal64Field.getInstance());
149 }
150
151 @Test
152 public void testSymmetryAfterLeapSecondIntroduction() {
153 doTestSymmetryAfterLeapSecondIntroduction(Decimal64Field.getInstance());
154 }
155
156 @Test
157 public void testOldTLE() {
158 doTestOldTLE(Decimal64Field.getInstance());
159 }
160
161 @Test
162 public void testEqualTLE() {
163 doTestEqualTLE(Decimal64Field.getInstance());
164 }
165
166 @Test
167 public void testNonEqualTLE() {
168 doTestNonEqualTLE(Decimal64Field.getInstance());
169 }
170
171 @Test
172 public void testIssue388() {
173 doTestIssue388(Decimal64Field.getInstance());
174 }
175
176 @Test
177 public void testIssue664NegativeRaanPa() {
178 doTestIssue664NegativeRaanPa(Decimal64Field.getInstance());
179 }
180
181 @Test
182 public void testDifferentFields() {
183 String line1 = "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20";
184 String line2 = "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62";
185 final DSFactory factory = new DSFactory(1, 1);
186 FieldTLE<DerivativeStructure> tleA = new FieldTLE<>(factory.getDerivativeField(), line1, line2);
187 FieldTLE<Decimal64> tleB = new FieldTLE<>(Decimal64Field.getInstance(), line1, line2);
188 try {
189 tleA.equals(tleB);
190 fail("an exception should have been thrown");
191 } catch (Exception e) {
192
193 }
194 }
195
196 public <T extends CalculusFieldElement<T>> void doTestTLEFormat(Field<T> field) {
197
198 String line1 = "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20";
199 String line2 = "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62";
200
201 Assert.assertTrue(TLE.isFormatOK(line1, line2));
202
203 FieldTLE<T> tle = new FieldTLE<T>(field, line1, line2);
204 Assert.assertEquals(27421, tle.getSatelliteNumber(), 0);
205 Assert.assertEquals(2002, tle.getLaunchYear());
206 Assert.assertEquals(21, tle.getLaunchNumber());
207 Assert.assertEquals("A", tle.getLaunchPiece());
208 Assert.assertEquals(-0.0089879, tle.getBStar(), 0);
209 Assert.assertEquals(0, tle.getEphemerisType());
210 Assert.assertEquals(98.749, FastMath.toDegrees(tle.getI().getReal()), 1e-10);
211 Assert.assertEquals(199.5121, FastMath.toDegrees(tle.getRaan().getReal()), 1e-10);
212 Assert.assertEquals(0.0001333, tle.getE().getReal(), 1e-10);
213 Assert.assertEquals(133.9522, FastMath.toDegrees(tle.getPerigeeArgument().getReal()), 1e-10);
214 Assert.assertEquals(226.1918, FastMath.toDegrees(tle.getMeanAnomaly().getReal()), 1e-10);
215 Assert.assertEquals(14.26113993, tle.getMeanMotion().getReal() * Constants.JULIAN_DAY / (2 * FastMath.PI), 0);
216 Assert.assertEquals(tle.getRevolutionNumberAtEpoch(), 6, 0);
217 Assert.assertEquals(tle.getElementNumber(), 2 , 0);
218
219 line1 = "1 T7421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 28";
220 line2 = "2 T7421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 60";
221 Assert.assertTrue(TLE.isFormatOK(line1, line2));
222
223 tle = new FieldTLE<T>(field, line1, line2);
224 Assert.assertEquals(277421, tle.getSatelliteNumber(), 0);
225
226 line1 = "1 I7421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 28";
227 line2 = "2 I7421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 60";
228 Assert.assertFalse(TLE.isFormatOK(line1, line2));
229 try {
230 new FieldTLE<T>(field, line1, line2);
231 Assert.fail("an exception should have been thrown");
232 } catch (NumberFormatException nfe) {
233
234 }
235
236 line1 = "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20";
237 line2 = "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14*26113993 62";
238 Assert.assertFalse(TLE.isFormatOK(line1, line2));
239
240 line1 = "1 27421 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20";
241 line2 = "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62";
242 Assert.assertFalse(TLE.isFormatOK(line1, line2));
243
244 line1 = "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20";
245 line2 = "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 10006113993 62";
246 Assert.assertFalse(TLE.isFormatOK(line1, line2));
247
248 line1 = "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879 2 0 20";
249 line2 = "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62";
250 Assert.assertFalse(TLE.isFormatOK(line1, line2));
251 }
252
253
254 public <T extends CalculusFieldElement<T>> void doTestIssue196(Field<T> field) {
255
256 String line1A = "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20";
257 String line1B = "1 27421U 02021A 02124.48976499 -.0002147 00000-0 -89879-2 0 20";
258 String line2 = "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62";
259
260 Assert.assertTrue(TLE.isFormatOK(line1A, line2));
261 FieldTLE<T> tleA = new FieldTLE<T>(field, line1A, line2);
262 Assert.assertTrue(TLE.isFormatOK(line1B, line2));
263 TLE tleB = new TLE(line1B, line2);
264 Assert.assertEquals(tleA.getSatelliteNumber(), tleB.getSatelliteNumber(), 0);
265 Assert.assertEquals(tleA.getLaunchYear(), tleB.getLaunchYear());
266 Assert.assertEquals(tleA.getLaunchNumber(), tleB.getLaunchNumber());
267 Assert.assertEquals(tleA.getLaunchPiece(), tleB.getLaunchPiece());
268 Assert.assertEquals(tleA.getBStar(), tleB.getBStar(), 0);
269 Assert.assertEquals(tleA.getEphemerisType(), tleB.getEphemerisType());
270 Assert.assertEquals(tleA.getI().getReal(), tleB.getI(), 1e-10);
271 Assert.assertEquals(tleA.getRaan().getReal(), tleB.getRaan(), 1e-10);
272 Assert.assertEquals(tleA.getE().getReal(), tleB.getE(), 1e-10);
273 Assert.assertEquals(tleA.getPerigeeArgument().getReal(), tleB.getPerigeeArgument(), 1e-10);
274 Assert.assertEquals(tleA.getMeanAnomaly().getReal(), tleB.getMeanAnomaly(), 1e-10);
275 Assert.assertEquals(tleA.getMeanMotion().getReal(), tleB.getMeanMotion(), 0);
276 Assert.assertEquals(tleA.getRevolutionNumberAtEpoch(), tleB.getRevolutionNumberAtEpoch(), 0);
277 Assert.assertEquals(tleA.getElementNumber(), tleB.getElementNumber(), 0);
278
279 }
280
281 public <T extends CalculusFieldElement<T>>void doTestSymmetry(Field<T> field) {
282 checkSymmetry(field, "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
283 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
284 checkSymmetry(field, "1 31928U 98067BA 08269.84884916 .00114257 17652-4 13615-3 0 4412",
285 "2 31928 51.6257 175.4142 0001703 41.9031 318.2112 16.08175249 68368");
286 checkSymmetry(field, "1 T7421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 28",
287 "2 T7421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 60");
288 }
289
290 private <T extends CalculusFieldElement<T>> void checkSymmetry(Field<T> field, String line1, String line2) {
291 FieldTLE<T> tleRef = new FieldTLE<T>(field, line1, line2);
292 FieldTLE<T> tle = new FieldTLE<T>(tleRef.getSatelliteNumber(), tleRef.getClassification(),
293 tleRef.getLaunchYear(), tleRef.getLaunchNumber(), tleRef.getLaunchPiece(),
294 tleRef.getEphemerisType(), tleRef.getElementNumber(), tleRef.getDate(),
295 tleRef.getMeanMotion(), tleRef.getMeanMotionFirstDerivative(),
296 tleRef.getMeanMotionSecondDerivative(), tleRef.getE(), tleRef.getI(),
297 tleRef.getPerigeeArgument(), tleRef.getRaan(), tleRef.getMeanAnomaly(),
298 tleRef.getRevolutionNumberAtEpoch(), tleRef.getBStar());
299 Assert.assertEquals(line1, tle.getLine1());
300 Assert.assertEquals(line2, tle.getLine2());
301 }
302
303 public <T extends CalculusFieldElement<T>> void doTestBug74(Field<T> field) {
304 checkSymmetry(field, "1 00001U 00001A 12026.45833333 2.94600864 39565-9 16165-7 1 12",
305 "2 00001 127.0796 254.4522 0000000 224.9662 0.4817 0.00000000 11");
306 }
307
308 public <T extends CalculusFieldElement<T> >void doTestBug77(Field<T> field) {
309 checkSymmetry(field, "1 05555U 71086J 12026.96078249 -.00000004 00001-9 01234-9 0 9082",
310 "2 05555 74.0161 228.9750 0075476 328.9888 30.6709 12.26882470804545");
311 }
312
313 public <T extends CalculusFieldElement<T>> void doTestDirectConstruction(Field<T> field) {
314 final T T_zero = field.getZero();
315 FieldTLE<T> tleA = new FieldTLE<T>(5555, 'U', 1971, 86, "J", 0, 908,
316 new FieldAbsoluteDate<T>(field, new DateComponents(2012, 26),
317 new TimeComponents(0.96078249 * Constants.JULIAN_DAY),
318 TimeScalesFactory.getUTC()),
319 T_zero.add(taylorConvert(12.26882470, 1)), T_zero.add(taylorConvert(-0.00000004, 2)), T_zero.add(taylorConvert(0.00001e-9, 3)),
320 T_zero.add(0.0075476), T_zero.add(FastMath.toRadians(74.0161)), T_zero.add(FastMath.toRadians(328.9888)),
321 T_zero.add(FastMath.toRadians(228.9750)), T_zero.add(FastMath.toRadians(30.6709)), 80454, 0.01234e-9);
322 FieldTLE<T> tleB = new FieldTLE<T>(field, "1 05555U 71086J 12026.96078249 -.00000004 00001-9 01234-9 0 9082",
323 "2 05555 74.0161 228.9750 0075476 328.9888 30.6709 12.26882470804545");
324 Assert.assertEquals(tleA.getSatelliteNumber(), tleB.getSatelliteNumber(), 0);
325 Assert.assertEquals(tleA.getLaunchYear(), tleB.getLaunchYear());
326 Assert.assertEquals(tleA.getLaunchNumber(), tleB.getLaunchNumber());
327 Assert.assertEquals(tleA.getLaunchPiece(), tleB.getLaunchPiece());
328 Assert.assertEquals(tleA.getBStar() , tleB.getBStar(), 0);
329 Assert.assertEquals(tleA.getEphemerisType(), tleB.getEphemerisType());
330 Assert.assertEquals(tleA.getI().getReal(), tleB.getI().getReal(), 1e-10);
331 Assert.assertEquals(tleA.getRaan().getReal(), tleB.getRaan().getReal(), 1e-10);
332 Assert.assertEquals(tleA.getE().getReal(), tleB.getE().getReal(), 1e-10);
333 Assert.assertEquals(tleA.getPerigeeArgument().getReal(), tleB.getPerigeeArgument().getReal(), 1e-10);
334 Assert.assertEquals(tleA.getMeanAnomaly().getReal(), tleB.getMeanAnomaly().getReal(), 1e-10);
335 Assert.assertEquals(tleA.getMeanMotion().getReal(), tleB.getMeanMotion().getReal(), 0);
336 Assert.assertEquals(tleA.getRevolutionNumberAtEpoch(), tleB.getRevolutionNumberAtEpoch(), 0);
337 Assert.assertEquals(tleA.getElementNumber(), tleB.getElementNumber(), 0);
338 }
339
340 public <T extends CalculusFieldElement<T>> void doTestGenerateAlpha5(Field<T> field) {
341 final T T_zero = field.getZero();
342 FieldTLE<T> tle = new FieldTLE<T>(339999, 'U', 1971, 86, "J", 0, 908,
343 new FieldAbsoluteDate<T>(field, new DateComponents(2012, 26),
344 new TimeComponents(0.96078249 * Constants.JULIAN_DAY),
345 TimeScalesFactory.getUTC()),
346 T_zero.add(taylorConvert(12.26882470, 1)),
347 T_zero.add(taylorConvert(-0.00000004, 2)),
348 T_zero.add(taylorConvert(0.00001e-9, 3)),
349 T_zero.add(0.0075476), T_zero.add(FastMath.toRadians(74.0161)),
350 T_zero.add(FastMath.toRadians(328.9888)),
351 T_zero.add(FastMath.toRadians(228.9750)),
352 T_zero.add(FastMath.toRadians(30.6709)),
353 80454, 0.01234e-9);
354 Assert.assertEquals("1 Z9999U 71086J 12026.96078249 -.00000004 00001-9 01234-9 0 9088", tle.getLine1());
355 Assert.assertEquals("2 Z9999 74.0161 228.9750 0075476 328.9888 30.6709 12.26882470804541", tle.getLine2());
356 }
357
358 public <T extends CalculusFieldElement<T>> void doTestBug77TooLargeSecondDerivative(Field<T> field) {
359 try {
360 final T T_zero = field.getZero();
361 FieldTLE<T> tle = new FieldTLE<T>(5555, 'U', 1971, 86, "J", 0, 908,
362 new FieldAbsoluteDate<T>(field, new DateComponents(2012, 26),
363 new TimeComponents(0.96078249 * Constants.JULIAN_DAY),
364 TimeScalesFactory.getUTC()),
365 T_zero.add(taylorConvert(12.26882470, 1)), T_zero.add(taylorConvert(-0.00000004, 2)), T_zero.add(taylorConvert(0.99999e11, 3)),
366 T_zero.add(0.0075476), T_zero.add(FastMath.toRadians(74.0161)), T_zero.add(FastMath.toRadians(328.9888)),
367 T_zero.add(FastMath.toRadians(228.9750)), T_zero.add(FastMath.toRadians(30.6709)), 80454, 0.01234e-9);
368 tle.getLine1();
369 Assert.fail("an exception should have been thrown");
370 } catch (OrekitException oe) {
371 Assert.assertEquals(OrekitMessages.TLE_INVALID_PARAMETER, oe.getSpecifier());
372 Assert.assertEquals(5555, ((Integer) oe.getParts()[0]).intValue());
373 Assert.assertEquals("meanMotionSecondDerivative", oe.getParts()[1]);
374 }
375 }
376
377 public <T extends CalculusFieldElement<T>> void doTestBug77TooLargeBStar(Field<T> field) {
378 try {
379 final T T_zero = field.getZero();
380 FieldTLE<T> tle = new FieldTLE<T>(5555, 'U', 1971, 86, "J", 0, 908,
381 new FieldAbsoluteDate<T>(field, new DateComponents(2012, 26),
382 new TimeComponents(0.96078249 * Constants.JULIAN_DAY),
383 TimeScalesFactory.getUTC()),
384 T_zero.add(taylorConvert(12.26882470, 1)), T_zero.add(taylorConvert(-0.00000004, 2)), T_zero.add(taylorConvert(0.00001e-9, 3)),
385 T_zero.add(0.0075476), T_zero.add(FastMath.toRadians(74.0161)), T_zero.add(FastMath.toRadians(328.9888)),
386 T_zero.add(FastMath.toRadians(228.9750)), T_zero.add(FastMath.toRadians(30.6709)), 80454, 0.99999e11);
387 tle.getLine1();
388 Assert.fail("an exception should have been thrown");
389 } catch (OrekitException oe) {
390 Assert.assertEquals(OrekitMessages.TLE_INVALID_PARAMETER, oe.getSpecifier());
391 Assert.assertEquals(5555, ((Integer) oe.getParts()[0]).intValue());
392 Assert.assertEquals("B*", oe.getParts()[1]);
393 }
394 }
395
396 public <T extends CalculusFieldElement<T>> void doTestBug77TooLargeEccentricity(Field<T> field) {
397 try {
398 final T T_zero = field.getZero();
399 FieldTLE<T> tle = new FieldTLE<T>(5555, 'U', 1971, 86, "J", 0, 908,
400 new FieldAbsoluteDate<T>(field, new DateComponents(2012, 26),
401 new TimeComponents(0.96078249 * Constants.JULIAN_DAY),
402 TimeScalesFactory.getUTC()),
403 T_zero.add(taylorConvert(12.26882470, 1)), T_zero.add(taylorConvert(-0.00000004, 2)), T_zero.add(taylorConvert(0.00001e-9, 3)),
404 T_zero.add(1.0075476), T_zero.add(FastMath.toRadians(74.0161)), T_zero.add(FastMath.toRadians(328.9888)),
405 T_zero.add(FastMath.toRadians(228.9750)), T_zero.add(FastMath.toRadians(30.6709)), 80454, 0.01234e-9);
406 tle.getLine2();
407 Assert.fail("an exception should have been thrown");
408 } catch (OrekitException oe) {
409 Assert.assertEquals(OrekitMessages.TLE_INVALID_PARAMETER, oe.getSpecifier());
410 Assert.assertEquals(5555, ((Integer) oe.getParts()[0]).intValue());
411 Assert.assertEquals("eccentricity", oe.getParts()[1]);
412 }
413 }
414
415 public <T extends CalculusFieldElement<T>> void doTestBug77TooLargeSatelliteNumber1(Field<T> field) {
416 try {
417 final T T_zero = field.getZero();
418 FieldTLE<T> tle = new FieldTLE<T>(1000000, 'U', 1971, 86, "J", 0, 908,
419 new FieldAbsoluteDate<T>(field, new DateComponents(2012, 26),
420 new TimeComponents(0.96078249 * Constants.JULIAN_DAY),
421 TimeScalesFactory.getUTC()),
422 T_zero.add(taylorConvert(12.26882470, 1)), T_zero.add(taylorConvert(-0.00000004, 2)), T_zero.add(taylorConvert(0.00001e-9, 3)),
423 T_zero.add(0.0075476), T_zero.add(FastMath.toRadians(74.0161)), T_zero.add(FastMath.toRadians(328.9888)),
424 T_zero.add(FastMath.toRadians(228.9750)), T_zero.add(FastMath.toRadians(30.6709)), 80454, 0.01234e-9);
425 tle.getLine1();
426 Assert.fail("an exception should have been thrown");
427 } catch (OrekitException oe) {
428 Assert.assertEquals(OrekitMessages.TLE_INVALID_PARAMETER, oe.getSpecifier());
429 Assert.assertEquals(1000000, ((Integer) oe.getParts()[0]).intValue());
430 Assert.assertEquals("satelliteNumber-1", oe.getParts()[1]);
431 }
432 }
433
434 public <T extends CalculusFieldElement<T>> void doTestBug77TooLargeSatelliteNumber2(Field<T> field) {
435 try {
436 final T T_zero = field.getZero();
437 FieldTLE<T> tle = new FieldTLE<T>(1000000, 'U', 1971, 86, "J", 0, 908,
438 new FieldAbsoluteDate<T>(field, new DateComponents(2012, 26),
439 new TimeComponents(0.96078249 * Constants.JULIAN_DAY),
440 TimeScalesFactory.getUTC()),
441 T_zero.add(taylorConvert(12.26882470, 1)), T_zero.add(taylorConvert(-0.00000004, 2)), T_zero.add(taylorConvert(0.00001e-9, 3)),
442 T_zero.add(0.0075476), T_zero.add(FastMath.toRadians(74.0161)), T_zero.add(FastMath.toRadians(328.9888)),
443 T_zero.add(FastMath.toRadians(228.9750)), T_zero.add(FastMath.toRadians(30.6709)), 80454, 0.01234e-9);
444 tle.getLine2();
445 Assert.fail("an exception should have been thrown");
446 } catch (OrekitException oe) {
447 Assert.assertEquals(OrekitMessages.TLE_INVALID_PARAMETER, oe.getSpecifier());
448 Assert.assertEquals(1000000, ((Integer) oe.getParts()[0]).intValue());
449 Assert.assertEquals("satelliteNumber-2", oe.getParts()[1]);
450 }
451 }
452
453 final double taylorConvert(final double m, final int n) {
454
455 return m * 2 * FastMath.PI * CombinatoricsUtils.factorial(n) / FastMath.pow(Constants.JULIAN_DAY, n);
456 }
457
458 public <T extends CalculusFieldElement<T>> void doTestDifferentSatNumbers(Field<T> field) {
459 new FieldTLE<T>(field, "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
460 "2 27422 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
461 }
462
463 public void doTestChecksumOK() {
464 FieldTLE.isFormatOK("1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
465 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
466 }
467
468 public void doTestWrongChecksum1() {
469 try {
470 FieldTLE.isFormatOK("1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 21",
471 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
472 Assert.fail("an exception should have been thrown");
473 } catch (OrekitException oe) {
474 Assert.assertEquals(OrekitMessages.TLE_CHECKSUM_ERROR, oe.getSpecifier());
475 Assert.assertEquals(1, ((Integer) oe.getParts()[0]).intValue());
476 Assert.assertEquals("0", oe.getParts()[1]);
477 Assert.assertEquals("1", oe.getParts()[2]);
478 Assert.assertEquals("1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 21",
479 oe.getParts()[3]);
480 }
481 }
482
483 public void doTestWrongChecksum2() {
484 try {
485 FieldTLE.isFormatOK("1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
486 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 61");
487 Assert.fail("an exception should have been thrown");
488 } catch (OrekitException oe) {
489 Assert.assertEquals(OrekitMessages.TLE_CHECKSUM_ERROR, oe.getSpecifier());
490 Assert.assertEquals(2, ((Integer) oe.getParts()[0]).intValue());
491 Assert.assertEquals("2", oe.getParts()[1]);
492 Assert.assertEquals("1", oe.getParts()[2]);
493 Assert.assertEquals("2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 61",
494 oe.getParts()[3]);
495 }
496 }
497
498 public <T extends CalculusFieldElement<T>>void doTestSatCodeCompliance(Field<T> field) throws IOException, OrekitException, ParseException {
499
500 BufferedReader rEntry = null;
501 BufferedReader rResults = null;
502 final T T_zero = field.getZero();
503
504 InputStream inEntry =
505 FieldTLETest.class.getResourceAsStream("/tle/extrapolationTest-data/SatCode-entry");
506 rEntry = new BufferedReader(new InputStreamReader(inEntry));
507
508 try {
509 InputStream inResults =
510 FieldTLETest.class.getResourceAsStream("/tle/extrapolationTest-data/SatCode-results");
511 rResults = new BufferedReader(new InputStreamReader(inResults));
512
513 try {
514 double cumulated = 0;
515 boolean stop = false;
516
517 String rline = rResults.readLine();
518
519 while (!stop) {
520 if (rline == null) break;
521
522 String[] title = rline.split(" ");
523
524 if (title[0].matches("r")) {
525
526 String eline;
527 int count = 0;
528 String[] header = new String[4];
529 for (eline = rEntry.readLine(); (eline != null) && (eline.charAt(0)=='#'); eline = rEntry.readLine()) {
530 header[count++] = eline;
531 }
532 String line1 = eline;
533 String line2 = rEntry.readLine();
534 Assert.assertTrue(TLE.isFormatOK(line1, line2));
535
536 FieldTLE<T> tle = new FieldTLE<T>(field, line1, line2);
537
538 int satNum = Integer.parseInt(title[1]);
539 Assert.assertTrue(satNum==tle.getSatelliteNumber());
540 final T[] parameters;
541 parameters = MathArrays.buildArray(field, 1);
542 parameters[0] = field.getZero().add(tle.getBStar());
543 FieldTLEPropagator<T> ex = FieldTLEPropagator.selectExtrapolator(tle, parameters);
544 for (rline = rResults.readLine(); (rline!=null)&&(rline.charAt(0)!='r'); rline = rResults.readLine()) {
545
546 String[] data = rline.split(" ");
547 double minFromStart = Double.parseDouble(data[0]);
548 T pX = T_zero.add(1000*Double.parseDouble(data[1]));
549 T pY = T_zero.add(1000*Double.parseDouble(data[2]));
550 T pZ = T_zero.add(1000*Double.parseDouble(data[3]));
551 T vX = T_zero.add(1000*Double.parseDouble(data[4]));
552 T vY = T_zero.add(1000*Double.parseDouble(data[5]));
553 T vZ = T_zero.add(1000*Double.parseDouble(data[6]));
554 FieldVector3D<T> testPos = new FieldVector3D<T>(pX, pY, pZ);
555 FieldVector3D<T> testVel = new FieldVector3D<T>(vX, vY, vZ);
556
557 FieldAbsoluteDate<T> date = tle.getDate().shiftedBy(minFromStart * 60);
558 FieldPVCoordinates<T> results = ex.getPVCoordinates(date, parameters);
559 double normDifPos = testPos.subtract(results.getPosition()).getNorm().getReal();
560 double normDifVel = testVel.subtract(results.getVelocity()).getNorm().getReal();
561
562 cumulated += normDifPos;
563 Assert.assertEquals(0, normDifPos, 2e-3);
564 Assert.assertEquals(0, normDifVel, 7e-4);
565
566
567 }
568 }
569 }
570 Assert.assertEquals(0, cumulated, 0.026);
571 } finally {
572 if (rResults != null) {
573 rResults.close();
574 }
575 }
576 } finally {
577 if (rEntry != null) {
578 rEntry.close();
579 }
580 }
581 }
582
583 public <T extends CalculusFieldElement<T>> void doTestZeroInclination(Field<T> field) {
584 FieldTLE<T> tle = new FieldTLE<T>(field,"1 26451U 00043A 10130.13784012 -.00000276 00000-0 10000-3 0 3866",
585 "2 26451 000.0000 266.1044 0001893 160.7642 152.5985 01.00271160 35865");
586 final T[] parameters;
587 parameters = MathArrays.buildArray(field, 1);
588 parameters[0].add(tle.getBStar());
589 FieldTLEPropagator<T> propagator = FieldTLEPropagator.selectExtrapolator(tle, parameters);
590 FieldPVCoordinates<T> pv = propagator.propagate(tle.getDate().shiftedBy(100)).getPVCoordinates();
591 Assert.assertEquals(42171546.979560345, pv.getPosition().getNorm().getReal(), 1.0e-3);
592 Assert.assertEquals(3074.1890089357994, pv.getVelocity().getNorm().getReal(), 1.0e-6);
593 }
594
595 public <T extends CalculusFieldElement<T>> void doTestSymmetryAfterLeapSecondIntroduction(Field<T> field) {
596 checkSymmetry(field, "1 34602U 09013A 12187.35117436 .00002472 18981-5 42406-5 0 9995",
597 "2 34602 96.5991 210.0210 0006808 112.8142 247.3865 16.06008103193411");
598 }
599
600 public <T extends CalculusFieldElement<T>> void doTestOldTLE(Field<T> field) {
601 String line1 = "1 15427U 85091.94293084 0.00000051 00000+0 32913-4 0 179";
602 String line2 = "2 15427 98.9385 46.0219 0015502 321.4354 38.5705 14.11363211 15580";
603 Assert.assertTrue(TLE.isFormatOK(line1, line2));
604 FieldTLE<T> tle = new FieldTLE<T>(field, line1, line2);
605 Assert.assertEquals(15427, tle.getSatelliteNumber());
606 Assert.assertEquals(0.00000051,
607 tle.getMeanMotionFirstDerivative().getReal() * Constants.JULIAN_DAY * Constants.JULIAN_DAY / (4 * FastMath.PI),
608 1.0e-15);
609 }
610
611 public <T extends CalculusFieldElement<T>> void doTestEqualTLE(Field<T> field) {
612 FieldTLE<T> tleA = new FieldTLE<T>(field, "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
613 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
614 FieldTLE<T> tleB = new FieldTLE<T>(field, "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
615 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
616 Assert.assertTrue(tleA.equals(tleB));
617 }
618
619 public <T extends CalculusFieldElement<T>> void doTestNonEqualTLE(Field<T> field) {
620 FieldTLE<T> tleA = new FieldTLE<T>(field, "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
621 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
622 FieldTLE<T> tleB = new FieldTLE<T>(field, "1 05555U 71086J 12026.96078249 -.00000004 00001-9 01234-9 0 9082",
623 "2 05555 74.0161 228.9750 0075476 328.9888 30.6709 12.26882470804545");
624 Assert.assertFalse(tleA.equals(tleB));
625 }
626
627 public <T extends CalculusFieldElement<T>> void doTestIssue388(Field<T> field) {
628 final T T_zero = field.getZero();
629 FieldTLE<T> tleRef = new FieldTLE<T>(field, "1 27421U 02021A 02124.48976499 -.00021470 00000-0 -89879-2 0 20",
630 "2 27421 98.7490 199.5121 0001333 133.9522 226.1918 14.26113993 62");
631 FieldTLE<T> tleOriginal = new FieldTLE<T>(27421, 'U', 2002, 21, "A", TLE.DEFAULT, 2,
632 new FieldAbsoluteDate<T>(field, "2002-05-04T11:45:15.695", TimeScalesFactory.getUTC()),
633 T_zero.add(FastMath.toRadians(14.26113993 * 360 / Constants.JULIAN_DAY)),
634 T_zero.add(FastMath.toRadians(-.00021470 * 360 * 2 / (Constants.JULIAN_DAY * Constants.JULIAN_DAY))),
635 T_zero.add(FastMath.toRadians(0.0)),
636 T_zero.add(1.333E-4), T_zero.add(FastMath.toRadians(98.7490)),
637 T_zero.add(FastMath.toRadians(133.9522)), T_zero.add(FastMath.toRadians(199.5121)), T_zero.add(FastMath.toRadians(226.1918)),
638 6, -0.0089879);
639 Assert.assertEquals(tleRef.getLine1(), tleOriginal.getLine1());
640 Assert.assertEquals(tleRef.getLine2(), tleOriginal.getLine2());
641 FieldTLE<T> changedBStar = new FieldTLE<T>(27421, 'U', 2002, 21, "A", TLE.DEFAULT, 2,
642 new FieldAbsoluteDate<T>(field, "2002-05-04T11:45:15.695", TimeScalesFactory.getUTC()),
643 T_zero.add(FastMath.toRadians(14.26113993 * 360 / Constants.JULIAN_DAY)),
644 T_zero.add(FastMath.toRadians(-.00021470 * 360 * 2 / (Constants.JULIAN_DAY * Constants.JULIAN_DAY))),
645 T_zero.add(FastMath.toRadians(0.0)),
646 T_zero.add(1.333E-4), T_zero.add(FastMath.toRadians(98.7490)),
647 T_zero.add(FastMath.toRadians(133.9522)), T_zero.add(FastMath.toRadians(199.5121)), T_zero.add(FastMath.toRadians(226.1918)),
648 6, 1.0e-4);
649 Assert.assertEquals(tleRef.getLine1().replace("-89879-2", " 10000-3"), changedBStar.getLine1());
650 Assert.assertEquals(tleRef.getLine2(), changedBStar.getLine2());
651 Assert.assertEquals(1.0e-4, new FieldTLE<T>(field, changedBStar.getLine1(), changedBStar.getLine2()).getBStar(), 1.0e-15);
652 }
653
654 public <T extends CalculusFieldElement<T>> void doTestIssue664NegativeRaanPa(Field<T> field) {
655 final T T_zero = field.getZero();
656 FieldTLE<T> tle = new FieldTLE<T>(99999, 'X', 2020, 42, "F", 0, 999,
657 new FieldAbsoluteDate<T>(field, "2020-01-01T01:00:00.000", TimeScalesFactory.getUTC()), T_zero.add(0.0011010400252833312), T_zero.add(0.0),
658 T_zero.add(0.0), T_zero.add(0.0016310523359516962), T_zero.add(1.6999188604164899),
659 T_zero.add(-3.219351286726724), T_zero.add(-2.096689019811356),
660 T_zero.add(2.157567545975006), 1, 1e-05);
661
662
663 Assert.assertEquals(tle.getLine1(), "1 99999X 20042F 20001.04166667 .00000000 00000-0 10000-4 0 9997");
664 Assert.assertEquals(tle.getLine2(), "2 99999 97.3982 239.8686 0016311 175.5448 123.6195 15.14038717 18");
665 }
666
667 @Test
668 public void testStateToTLELeo() {
669 doTestStateToTLELeo(Decimal64Field.getInstance());
670 }
671
672 private <T extends CalculusFieldElement<T>> void doTestStateToTLELeo(final Field<T> field) {
673 final FieldTLE<T> leoTLE = new FieldTLE<>(field, "1 31135U 07013A 11003.00000000 .00000816 00000+0 47577-4 0 11",
674 "2 31135 2.4656 183.9084 0021119 236.4164 60.4567 15.10546832 15");
675 checkConversion(leoTLE, field);
676 }
677
678 @Test
679 public void testStateToTLEGeo() {
680 doTestStateToTLEGeo(Decimal64Field.getInstance());
681 }
682
683 private <T extends CalculusFieldElement<T>> void doTestStateToTLEGeo(final Field<T> field) {
684 final FieldTLE<T> geoTLE = new FieldTLE<>(field, "1 27508U 02040A 12021.25695307 -.00000113 00000-0 10000-3 0 7326",
685 "2 27508 0.0571 356.7800 0005033 344.4621 218.7816 1.00271798 34501");
686 checkConversion(geoTLE, field);
687 }
688
689 private <T extends CalculusFieldElement<T>> void checkConversion(final FieldTLE<T> tle, final Field<T> field)
690 {
691
692 FieldPropagator<T> p = FieldTLEPropagator.selectExtrapolator(tle, tle.getParameters(field));
693 final FieldTLE<T> converted = FieldTLE.stateToTLE(p.getInitialState(), tle);
694
695 Assert.assertEquals(tle.getSatelliteNumber(), converted.getSatelliteNumber());
696 Assert.assertEquals(tle.getClassification(), converted.getClassification());
697 Assert.assertEquals(tle.getLaunchYear(), converted.getLaunchYear());
698 Assert.assertEquals(tle.getLaunchNumber(), converted.getLaunchNumber());
699 Assert.assertEquals(tle.getLaunchPiece(), converted.getLaunchPiece());
700 Assert.assertEquals(tle.getElementNumber(), converted.getElementNumber());
701 Assert.assertEquals(tle.getRevolutionNumberAtEpoch(), converted.getRevolutionNumberAtEpoch());
702
703 final double eps = 1.0e-7;
704 Assert.assertEquals(tle.getMeanMotion().getReal(), converted.getMeanMotion().getReal(), eps * tle.getMeanMotion().getReal());
705 Assert.assertEquals(tle.getE().getReal(), converted.getE().getReal(), eps * tle.getE().getReal());
706 Assert.assertEquals(tle.getI().getReal(), converted.getI().getReal(), eps * tle.getI().getReal());
707 Assert.assertEquals(tle.getPerigeeArgument().getReal(), converted.getPerigeeArgument().getReal(), eps * tle.getPerigeeArgument().getReal());
708 Assert.assertEquals(tle.getRaan().getReal(), converted.getRaan().getReal(), eps * tle.getRaan().getReal());
709 Assert.assertEquals(tle.getMeanAnomaly().getReal(), converted.getMeanAnomaly().getReal(), eps * tle.getMeanAnomaly().getReal());
710 Assert.assertEquals(tle.getMeanAnomaly().getReal(), converted.getMeanAnomaly().getReal(), eps * tle.getMeanAnomaly().getReal());
711 Assert.assertEquals(tle.getBStar(), converted.getBStar(), eps * tle.getBStar());
712
713 }
714
715 @Test
716 public void testStateToTleISS() {
717 doTestStateToTleISS(Decimal64Field.getInstance());
718 }
719
720 private <T extends CalculusFieldElement<T>> void doTestStateToTleISS(final Field<T> field) {
721
722
723 final FieldTLE<T> tleISS = new FieldTLE<>(field, "1 25544U 98067A 21035.14486477 .00001026 00000-0 26816-4 0 9998",
724 "2 25544 51.6455 280.7636 0002243 335.6496 186.1723 15.48938788267977");
725
726
727 final FieldTLEPropagator<T> propagator = FieldTLEPropagator.selectExtrapolator(tleISS, tleISS.getParameters(field));
728
729
730 final FieldSpacecraftState<T> state = propagator.propagate(tleISS.getDate());
731
732
733 final FieldTLE<T> rebuilt = FieldTLE.stateToTLE(state, tleISS);
734
735
736 final double eps = 1.0e-7;
737 Assert.assertEquals(tleISS.getSatelliteNumber(), rebuilt.getSatelliteNumber());
738 Assert.assertEquals(tleISS.getClassification(), rebuilt.getClassification());
739 Assert.assertEquals(tleISS.getLaunchYear(), rebuilt.getLaunchYear());
740 Assert.assertEquals(tleISS.getLaunchNumber(), rebuilt.getLaunchNumber());
741 Assert.assertEquals(tleISS.getLaunchPiece(), rebuilt.getLaunchPiece());
742 Assert.assertEquals(tleISS.getElementNumber(), rebuilt.getElementNumber());
743 Assert.assertEquals(tleISS.getRevolutionNumberAtEpoch(), rebuilt.getRevolutionNumberAtEpoch());
744 Assert.assertEquals(tleISS.getMeanMotion().getReal(), rebuilt.getMeanMotion().getReal(), eps * tleISS.getMeanMotion().getReal());
745 Assert.assertEquals(tleISS.getE().getReal(), rebuilt.getE().getReal(), eps * tleISS.getE().getReal());
746 Assert.assertEquals(tleISS.getI().getReal(), rebuilt.getI().getReal(), eps * tleISS.getI().getReal());
747 Assert.assertEquals(tleISS.getPerigeeArgument().getReal(), rebuilt.getPerigeeArgument().getReal(), eps * tleISS.getPerigeeArgument().getReal());
748 Assert.assertEquals(tleISS.getRaan().getReal(), rebuilt.getRaan().getReal(), eps * tleISS.getRaan().getReal());
749 Assert.assertEquals(tleISS.getMeanAnomaly().getReal(), rebuilt.getMeanAnomaly().getReal(), eps * tleISS.getMeanAnomaly().getReal());
750 Assert.assertEquals(tleISS.getMeanAnomaly().getReal(), rebuilt.getMeanAnomaly().getReal(), eps * tleISS.getMeanAnomaly().getReal());
751 Assert.assertEquals(tleISS.getBStar(), rebuilt.getBStar(), eps * tleISS.getBStar());
752 }
753
754 @Test
755 public void testIssue802() {
756 doTestIssue802(Decimal64Field.getInstance());
757 }
758
759 private <T extends CalculusFieldElement<T>> void doTestIssue802(final Field<T> field) {
760
761
762 final FieldTLE<T> tleISS = new FieldTLE<>(field, "1 25544U 98067A 21035.14486477 .00001026 00000-0 26816-4 0 9998",
763 "2 25544 51.6455 280.7636 0002243 335.6496 186.1723 15.48938788267977");
764
765
766 final FieldTLEPropagator<T> propagator = FieldTLEPropagator.selectExtrapolator(tleISS, tleISS.getParameters(field));
767
768
769 final FieldSpacecraftState<T> state = propagator.propagate(tleISS.getDate());
770
771
772 final Frame eme2000 = FramesFactory.getEME2000();
773 final TimeStampedFieldPVCoordinates<T> pv = state.getPVCoordinates(eme2000);
774 final FieldCartesianOrbit<T> orbit = new FieldCartesianOrbit<T>(pv, eme2000, state.getMu());
775
776
777 final FieldTLE<T> rebuilt = FieldTLE.stateToTLE(new FieldSpacecraftState<T>(orbit), tleISS);
778
779
780 Assert.assertEquals(tleISS.getLine1(), rebuilt.getLine1());
781 Assert.assertEquals(tleISS.getLine2(), rebuilt.getLine2());
782 }
783
784 @Test
785 public void testToTLE() {
786 doTestToTLE(Decimal64Field.getInstance());
787 }
788
789 private <T extends CalculusFieldElement<T>> void doTestToTLE(final Field<T> field) {
790 final TLE tle = new TLE("1 25544U 98067A 21035.14486477 .00001026 00000-0 26816-4 0 9998",
791 "2 25544 51.6455 280.7636 0002243 335.6496 186.1723 15.48938788267977");
792 final FieldTLE<T> fieldTle = new FieldTLE<T>(field, tle.getLine1(), tle.getLine2());
793 final TLE rebuilt = fieldTle.toTLE();
794 Assert.assertTrue(rebuilt.equals(tle));
795 Assert.assertEquals(tle.toString(), rebuilt.toString());
796 }
797
798 @Test
799 public void testIssue781() {
800
801 final DSFactory factory = new DSFactory(6, 3);
802 final String line1 = "1 05709U 71116A 21105.62692147 .00000088 00000-0 00000-0 0 9999";
803 final String line2 = "2 05709 10.8207 310.3659 0014139 71.9531 277.0561 0.99618926100056";
804 Assert.assertTrue(TLE.isFormatOK(line1, line2));
805
806 final FieldTLE<DerivativeStructure> fieldTLE = new FieldTLE<>(factory.getDerivativeField(), line1, line2);
807 final FieldTLEPropagator<DerivativeStructure> tlePropagator = FieldTLEPropagator.selectExtrapolator(fieldTLE, fieldTLE.getParameters(factory.getDerivativeField()));
808 final FieldTLE<DerivativeStructure> fieldTLE1 = FieldTLE.stateToTLE(tlePropagator.getInitialState(), fieldTLE);
809 Assert.assertEquals(line2, fieldTLE1.getLine2());
810
811 }
812
813 @Before
814 public void setUp() {
815 Utils.setDataRoot("regular-data");
816 }
817
818 }