Commit aefb93db authored by Bryan Cazabonne's avatar Bryan Cazabonne
Browse files

Enhanced parsing of SP3 files.

parent 1bb81b06
......@@ -21,6 +21,9 @@
</properties>
<body>
<release version="11.1.1" date="TBD" description="TBD">
<action dev="bryan" type="update" issue="895">
Enhanced parsing of SP3 files.
</action>
<action dev="luc" type="add" issue="902">
Take additional derivatives into account in {Field}SpacecraftState.shiftedBy.
</action>
......
......@@ -19,6 +19,8 @@ package org.orekit.files.sp3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Scanner;
......@@ -28,10 +30,12 @@ import java.util.stream.Stream;
import org.hipparchus.exception.LocalizedCoreFormats;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.orekit.annotation.DefaultDataContext;
import org.orekit.data.DataContext;
import org.orekit.data.DataSource;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitIllegalArgumentException;
import org.orekit.errors.OrekitMessages;
import org.orekit.files.general.EphemerisFileParser;
import org.orekit.files.sp3.SP3.SP3Coordinate;
......@@ -39,7 +43,9 @@ import org.orekit.files.sp3.SP3.SP3FileType;
import org.orekit.frames.Frame;
import org.orekit.gnss.TimeSystem;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.DateComponents;
import org.orekit.time.DateTimeComponents;
import org.orekit.time.TimeComponents;
import org.orekit.time.TimeScale;
import org.orekit.time.TimeScales;
import org.orekit.utils.CartesianDerivativesFilter;
......@@ -524,7 +530,7 @@ public class SP3Parser implements EphemerisFileParser<SP3> {
},
/** Parser for comments. */
HEADER_COMMENTS("^/\\*.*") {
HEADER_COMMENTS("^[%]?/\\*.*|") {
/** {@inheritDoc} */
@Override
......@@ -551,14 +557,95 @@ public class SP3Parser implements EphemerisFileParser<SP3> {
final int day = Integer.parseInt(line.substring(11, 13).trim());
final int hour = Integer.parseInt(line.substring(14, 16).trim());
final int minute = Integer.parseInt(line.substring(17, 19).trim());
final double second = Double.parseDouble(line.substring(20, 31).trim());
pi.latestEpoch = new AbsoluteDate(year, month, day,
hour, minute, second,
pi.timeScale);
final double second = Double.parseDouble(line.substring(20).trim());
// some SP3 files have weird epochs as in the following two examples, where
// the middle dates are wrong
//
// * 2016 7 6 16 58 0.00000000
// PL51 11872.234459 3316.551981 101.400098 999999.999999
// VL51 8054.606014 -27076.640110 -53372.762255 999999.999999
// * 2016 7 6 16 60 0.00000000
// PL51 11948.228978 2986.113872 -538.901114 999999.999999
// VL51 4605.419303 -27972.588048 -53316.820671 999999.999999
// * 2016 7 6 17 2 0.00000000
// PL51 11982.652569 2645.786926 -1177.549463 999999.999999
// VL51 1128.248622 -28724.293303 -53097.358387 999999.999999
//
// * 2016 7 6 23 58 0.00000000
// PL51 3215.382310 -7958.586164 8812.395707
// VL51 -18058.659942 -45834.335707 -34496.540437
// * 2016 7 7 24 0 0.00000000
// PL51 2989.229334 -8494.421415 8385.068555
// VL51 -19617.027447 -43444.824985 -36706.159070
// * 2016 7 7 0 2 0.00000000
// PL51 2744.983592 -9000.639164 7931.904779
// VL51 -21072.925764 -40899.633288 -38801.567078
//
// In the first case, the date should really be 2016 7 6 17 0 0.00000000,
// i.e as the minutes field overflows, the hours field should be incremented
// In the second case, the date should really be 2016 7 7 0 0 0.00000000,
// i.e. as the hours field overflows, the day field should be kept as is
// we cannot be sure how carry was managed when these bogus files were written
// so we try different options, incrementing or not previous field, and selecting
// the closest one to expected date
DateComponents dc = new DateComponents(year, month, day);
final List<AbsoluteDate> candidates = new ArrayList<>();
int h = hour;
int m = minute;
double s = second;
if (s >= 60.0) {
s -= 60;
addCandidate(candidates, dc, h, m, s, pi.timeScale);
m++;
}
if (m > 59) {
m = 0;
addCandidate(candidates, dc, h, m, s, pi.timeScale);
h++;
}
if (h > 23) {
h = 0;
addCandidate(candidates, dc, h, m, s, pi.timeScale);
dc = new DateComponents(dc, 1);
}
addCandidate(candidates, dc, h, m, s, pi.timeScale);
final AbsoluteDate expected = pi.latestEpoch == null ?
pi.file.getEpoch() :
pi.latestEpoch.shiftedBy(pi.file.getEpochInterval());
pi.latestEpoch = null;
for (final AbsoluteDate candidate : candidates) {
if (FastMath.abs(candidate.durationFrom(expected)) < 0.01 * pi.file.getEpochInterval()) {
pi.latestEpoch = candidate;
}
}
if (pi.latestEpoch == null) {
// no date recognized, just parse again the initial fields
// in order to generate again an exception
pi.latestEpoch = new AbsoluteDate(year, month, day, hour, minute, second, pi.timeScale);
}
pi.nbEpochs++;
}
/** Add an epoch candidate to a list.
* @param candidates list of candidates
* @param dc date components
* @param hour hour number from 0 to 23
* @param minute minute number from 0 to 59
* @param second second number from 0.0 to 60.0 (excluded)
* @param timeScale time scale
* @since 11.1.1
*/
private void addCandidate(final List<AbsoluteDate> candidates, final DateComponents dc,
final int hour, final int minute, final double second,
final TimeScale timeScale) {
try {
candidates.add(new AbsoluteDate(dc, new TimeComponents(hour, minute, second), timeScale));
} catch (OrekitIllegalArgumentException oiae) {
// ignored
}
}
/** {@inheritDoc} */
@Override
public Stream<LineParser> allowedNext() {
......@@ -586,7 +673,7 @@ public class SP3Parser implements EphemerisFileParser<SP3> {
pi.latestPosition = new Vector3D(x * 1000, y * 1000, z * 1000);
// clock (microsec)
pi.latestClock = line.length() <= 46 ?
pi.latestClock = line.trim().length() <= 46 ?
DEFAULT_CLOCK_VALUE :
Double.parseDouble(line.substring(46, 60).trim()) * 1e-6;
......@@ -670,7 +757,7 @@ public class SP3Parser implements EphemerisFileParser<SP3> {
final Vector3D velocity = new Vector3D(xv / 10d, yv / 10d, zv / 10d);
// clock rate in file is 1e-4 us / s
final double clockRateChange = line.length() <= 46 ?
final double clockRateChange = line.trim().length() <= 46 ?
DEFAULT_CLOCK_VALUE :
Double.parseDouble(line.substring(46, 60).trim()) * 1e-4;
......
......@@ -567,6 +567,170 @@ public class SP3ParserTest {
}
@Test
public void testIssue895HeaderComment() {
// Test issue 895
final String ex = "/sp3/issue895-header-comment.sp3";
final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
final SP3 file = new SP3Parser().parse(source);
// Verify
Assert.assertEquals(TimeSystem.UTC, file.getTimeSystem());
Assert.assertEquals(SP3.SP3FileType.LEO, file.getType());
}
@Test
public void testIssue895ClockRecord() {
// Test issue 895
final String ex = "/sp3/issue895-clock-record.sp3";
final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
final SP3 file = new SP3Parser().parse(source);
// Verify
Assert.assertEquals(TimeSystem.UTC, file.getTimeSystem());
Assert.assertEquals(SP3.SP3FileType.LEO, file.getType());
Assert.assertEquals(1, file.getSatelliteCount());
final List<SP3Coordinate> coords = file.getSatellites().get("L51").getCoordinates();
Assert.assertEquals(1, coords.size());
final SP3Coordinate coord = coords.get(0);
// 2021 12 26 0 0 0.00000000
Assert.assertEquals(new AbsoluteDate(2021, 12, 26, 0, 0, 0,
TimeScalesFactory.getUTC()), coord.getDate());
// PL51 5029.867893 1304.362160 -11075.527276 999999.999999
// VL51 -17720.521773 -55720.482742 -14441.695083 999999.999999
checkPVEntry(new PVCoordinates(new Vector3D(5029867.893, 1304362.160, -11075527.276),
new Vector3D(-1772.0521773, -5572.0482742, -1444.1695083)),
coord);
}
@Test
public void testIssue895RolloverMinutes() {
// Test issue 895
final String ex = "/sp3/issue895-minutes-increment.sp3";
final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
final SP3 file = new SP3Parser().parse(source);
// Verify
Assert.assertEquals(TimeSystem.UTC, file.getTimeSystem());
Assert.assertEquals(SP3.SP3FileType.LEO, file.getType());
Assert.assertEquals(1, file.getSatelliteCount());
final List<SP3Coordinate> coords = file.getSatellites().get("L51").getCoordinates();
Assert.assertEquals(91, coords.size());
final SP3Coordinate coord30 = coords.get(30);
// 2016 7 6 16 60 0.00000000
Assert.assertEquals(new AbsoluteDate(2016, 7, 6, 17, 0, 0,
TimeScalesFactory.getUTC()), coord30.getDate());
// PL51 11948.228978 2986.113872 -538.901114 999999.999999
// VL51 4605.419303 -27972.588048 -53316.820671 999999.999999
checkPVEntry(new PVCoordinates(new Vector3D(11948228.978, 2986113.872, -538901.114),
new Vector3D(460.5419303, -2797.2588048, -5331.6820671)),
coord30);
final SP3Coordinate coord31 = coords.get(31);
// 2016 7 6 17 2 0.00000000
Assert.assertEquals(new AbsoluteDate(2016, 7, 6, 17, 2, 0,
TimeScalesFactory.getUTC()), coord31.getDate());
// PL51 11982.652569 2645.786926 -1177.549463 999999.999999
// VL51 1128.248622 -28724.293303 -53097.358387 999999.999999
checkPVEntry(new PVCoordinates(new Vector3D(11982652.569, 2645786.926, -1177549.463),
new Vector3D(112.8248622, -2872.4293303, -5309.7358387)),
coord31);
final SP3Coordinate coord60 = coords.get(60);
// 2016 7 6 17 60 0.00000000
Assert.assertEquals(new AbsoluteDate(2016, 7, 6, 18, 0, 0,
TimeScalesFactory.getUTC()), coord60.getDate());
// PL51 -1693.056569 -4123.276630 -11431.599723 999999.999999
// VL51 -59412.268951 4066.817074 7604.890337 999999.999999
checkPVEntry(new PVCoordinates(new Vector3D(-1693056.569, -4123276.630, -11431599.723),
new Vector3D(-5941.2268951, 406.6817074, 760.4890337)),
coord60);
}
@Test
public void testIssue895RolloverHours() {
// Test issue 895
final String ex = "/sp3/issue895-hours-increment.sp3";
final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
final SP3 file = new SP3Parser().parse(source);
// Verify
Assert.assertEquals(TimeSystem.UTC, file.getTimeSystem());
Assert.assertEquals(SP3.SP3FileType.LEO, file.getType());
Assert.assertEquals(1, file.getSatelliteCount());
final List<SP3Coordinate> coords = file.getSatellites().get("L51").getCoordinates();
Assert.assertEquals(61, coords.size());
final SP3Coordinate coord30 = coords.get(30);
// 2016 7 7 24 0 0.00000000
Assert.assertEquals(new AbsoluteDate(2016, 7, 7, 0, 0, 0,
TimeScalesFactory.getUTC()), coord30.getDate());
//PL51 2989.229334 -8494.421415 8385.068555
//VL51 -19617.027447 -43444.824985 -36706.159070
checkPVEntry(new PVCoordinates(new Vector3D(2989229.334, -8494421.415, 8385068.555),
new Vector3D(-1961.7027447, -4344.4824985, -3670.6159070)),
coord30);
final SP3Coordinate coord31 = coords.get(31);
// 2016 7 7 0 2 0.00000000
Assert.assertEquals(new AbsoluteDate(2016, 7, 7, 0, 2, 0,
TimeScalesFactory.getUTC()), coord31.getDate());
// PL51 2744.983592 -9000.639164 7931.904779
// VL51 -21072.925764 -40899.633288 -38801.567078
checkPVEntry(new PVCoordinates(new Vector3D(2744983.592, -9000639.164, 7931904.779),
new Vector3D(-2107.2925764, -4089.9633288, -3880.1567078)),
coord31);
}
@Test
public void testIssue895SecondDigits() {
// Test issue 895
final String ex = "/sp3/issue895-second-digits.sp3";
final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
final SP3 file = new SP3Parser().parse(source);
// Verify
Assert.assertEquals(TimeSystem.UTC, file.getTimeSystem());
Assert.assertEquals(SP3.SP3FileType.LEO, file.getType());
Assert.assertEquals(1, file.getSatelliteCount());
final List<SP3Coordinate> coords = file.getSatellites().get("L51").getCoordinates();
Assert.assertEquals(1, coords.size());
final SP3Coordinate coord = coords.get(0);
// 2016 7 3 0 0 0.1234
Assert.assertEquals(new AbsoluteDate(2016, 7, 3, 0, 0, 0.1234,
TimeScalesFactory.getUTC()), coord.getDate());
}
@Before
public void setUp() {
Utils.setDataRoot("regular-data");
......
#cV2021 12 26 0 0 0.00000000 1 SLR SLR08 FIT COMB
## 2190 0.00000000 120.00000000 59574 0.0000000000000
+ 1 L51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
%c L cc UTC ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%c cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%f 0.0000000 0.000000000 0.00000000000 0.000000000000000
%f 0.0000000 0.000000000 0.00000000000 0.000000000000000
%i 0 0 0 0 0 0 0 0 0
%i 0 0 0 0 0 0 0 0 0
%/* ilrsa.orb.lageos1.220101.v70.sp3 Reference TRF: SLRF2008
%/* Input orbits: ASI v70, ESA v70, GFZ v70, JCET v70,
%/* NSGF v70,
%/* Combination details in README_CC.ilrsa
* 2021 12 26 0 0 0.00000000
PL51 5029.867893 1304.362160 -11075.527276 999999.999999
VL51 -17720.521773 -55720.482742 -14441.695083 999999.999999
EOF
#cV2016 2 28 0 0 0.00000000 1 SLR ECF FIT NSGF
## 1886 0.00000000 120.00000000 57446 0.0000000000000
+ 1 L52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
%c L cc UTC ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%c cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%f 0.0000000 0.000000000 0.00000000000 0.000000000000000
%f 0.0000000 0.000000000 0.00000000000 0.000000000000000
%i 0 0 0 0 0 0 0 0 0
%i 0 0 0 0 0 0 0 0 0
%/* ilrsa.orb.lageos1.220101.v70.sp3 Reference TRF: SLRF2008
%/* Input orbits: ASI v70, ESA v70, GFZ v70, JCET v70,
%/* NSGF v70,
%/* Combination details in README_CC.ilrsa
* 2016 2 28 0 0 0.00000000
PL52 2228.470946 7268.265924 9581.471543
VL52 -44856.945000 24321.151000 -7116.222800
EOF
#cV2016 7 3 0 0 0.00000000 61 SLR SLR05 FIT DGFI
##32766 0.00000000 120.00000000 57572 0.0000000000000
+ 1 L51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
%c L cc UTC ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%c cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%f 0.0000000 0.000000000 0.00000000000 0.000000000000000
%f 0.0000000 0.000000000 0.00000000000 0.000000000000000
%i 0 0 0 0 0 0 0 0 0
%i 0 0 0 0 0 0 0 0 0
/* CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
/* DGFI SP3c orbit, for dogsoc 5.3
/* SLRF2008 reference frame
/* CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
* 2016 7 6 23 0 0.00000000
PL51 -18.694061 10007.024778 7021.310634
VL51 31073.123661 -29742.961948 42688.432574
* 2016 7 6 23 2 0.00000000
PL51 350.791703 9631.722035 7522.271308
VL51 30483.230302 -32789.594355 40783.298513
* 2016 7 6 23 4 0.00000000
PL51 712.320867 9220.527702 7999.601268
VL51 29747.709297 -35722.944318 38751.044940
* 2016 7 6 23 6 0.00000000
PL51 1064.171884 8774.870419 8451.814195
VL51 28870.999105 -38531.549052 36598.255802
* 2016 7 6 23 8 0.00000000
PL51 1404.680294 8296.313440 8877.505053
VL51 27858.171297 -41204.442899 34331.889540
* 2016 7 6 23 10 0.00000000
PL51 1732.246158 7786.548407 9275.354423
VL51 26714.903456 -43731.201474 31959.253673
* 2016 7 6 23 12 0.00000000
PL51 2045.341159 7247.388595 9644.132544
VL51 25447.449445 -46101.983105 29487.978431
* 2016 7 6 23 14 0.00000000
PL51 2342.515323 6680.761689 9982.703016
VL51 24062.607228 -48307.567421 26925.989575
* 2016 7 6 23 16 0.00000000
PL51 2622.403346 6088.702112 10290.026182
VL51 22567.684453 -50339.390956 24281.480530
* 2016 7 6 23 18 0.00000000
PL51 2883.730493 5473.342941 10565.162171
VL51 20970.461986 -52189.579672 21562.883961
* 2016 7 6 23 20 0.00000000
PL51 3125.318045 4836.907459 10807.273595
VL51 19279.155612 -53850.978308 18778.842927
* 2016 7 6 23 22 0.00000000
PL51 3346.088287 4181.700365 11015.627901
VL51 17502.376118 -55317.176494 15938.181713
* 2016 7 6 23 24 0.00000000
PL51 3545.068996 3510.098700 11189.599364
VL51 15649.087965 -56582.531572 13049.876463
* 2016 7 6 23 26 0.00000000
PL51 3721.397430 2824.542509 11328.670742
VL51 13728.566751 -57642.188102 10123.025729
* 2016 7 6 23 28 0.00000000
PL51 3874.323808 2127.525296 11432.434558
VL51 11750.355696 -58492.094024 7166.821025
* 2016 7 6 23 30 0.00000000
PL51 4003.214250 1421.584307 11500.594046
VL51 9724.221330 -59129.013495 4190.517481
* 2016 7 6 23 32 0.00000000
PL51 4107.553189 709.290669 11532.963740
VL51 7660.108615 -59550.536387 1203.404692
* 2016 7 6 23 34 0.00000000
PL51 4186.945243 -6.760556 11529.469706
VL51 5568.095665 -59755.084496 -1785.222167
* 2016 7 6 23 36 0.00000000
PL51 4241.116541 -723.960375 11490.149447
VL51 3458.348287 -59741.914475 -4766.090893
* 2016 7 6 23 38 0.00000000
PL51 4269.915497 -1439.695885 11415.151452
VL51 1341.074518 -59511.117535 -7729.980394
* 2016 7 6 23 40 0.00000000
PL51 4273.313050 -2151.360268 11304.734418
VL51 -773.520666 -59063.615972 -10667.748362
* 2016 7 6 23 42 0.00000000
PL51 4251.402356 -2856.362729 11159.266141
VL51 -2875.280274 -58401.156555 -13570.358414
* 2016 7 6 23 44 0.00000000
PL51 4204.397942 -3552.138333 10979.222084
VL51 -4954.139693 -57526.300866 -16428.906650
* 2016 7 6 23 46 0.00000000
PL51 4132.634342 -4236.157715 10765.183635
VL51 -7000.170387 -56442.412637 -19234.647557
* 2016 7 6 23 48 0.00000000
PL51 4036.564196 -4905.936606 10517.836047
VL51 -9003.622724 -55153.642182 -21979.019232
* 2016 7 6 23 50 0.00000000
PL51 3916.755860 -5559.045173 10237.966096
VL51 -10954.967785 -53664.908007 -24653.667848
* 2016 7 6 23 52 0.00000000
PL51 3773.890509 -6193.117109 9926.459433
VL51 -12844.938007 -51981.875694 -27250.471338
* 2016 7 6 23 54 0.00000000
PL51 3608.758761 -6805.858460 9584.297671
VL51 -14664.566508 -50110.934154 -29761.562241
* 2016 7 6 23 56 0.00000000
PL51 3422.256843 -7395.056147 9212.555193
VL51 -16405.224970 -48059.169366 -32179.349682
* 2016 7 6 23 58 0.00000000
PL51 3215.382310 -7958.586164 8812.395707
VL51 -18058.659942 -45834.335707 -34496.540437
* 2016 7 7 24 0 0.00000000
PL51 2989.229334 -8494.421415 8385.068555
VL51 -19617.027447 -43444.824985 -36706.159070
* 2016 7 7 0 2 0.00000000
PL51 2744.983592 -9000.639164 7931.904779
VL51 -21072.925764 -40899.633288 -38801.567078
* 2016 7 7 0 4 0.00000000
PL51 2483.916774 -9475.428080 7454.312971
VL51 -22419.426306 -38208.325796 -40776.481044
* 2016 7 7 0 6 0.00000000
PL51 2207.380729 -9917.094843 6953.774907
VL51 -23650.102454 -35380.999634 -42624.989746
* 2016 7 7 0 8 0.00000000
PL51 1916.801279 -10324.070297 6431.840983
VL51 -24759.056259 -32428.244948 -44341.570189
* 2016 7 7 0 10 0.00000000
PL51 1613.671725 -10694.915124 5890.125469
VL51 -25740.942939 -29361.104305 -45921.102541
* 2016 7 7 0 12 0.00000000
PL51 1299.546074 -11028.325020 5330.301583
VL51 -26590.993059 -26191.030571 -47358.883933
* 2016 7 7 0 14 0.00000000
PL51 976.032017 -11323.135361 4754.096410
VL51 -27305.032334 -22929.843410 -48650.641100
* 2016 7 7 0 16 0.00000000
PL51 644.783673 -11578.325338 4163.285682
VL51 -27879.498972 -19589.684552 -49792.541827
* 2016 7 7 0 18 0.00000000
PL51 307.494156 -11793.021545 3559.688417
VL51 -28311.458508 -16182.971986 -50781.205176
* 2016 7 7 0 20 0.00000000
PL51 -34.112036 -11966.501017 2945.161452
VL51 -28598.616058 -12722.353234 -51613.710469
* 2016 7 7 0 22 0.00000000
PL51 -378.286750 -12098.193698 2321.593871
VL51 -28739.325956 -9220.657881 -52287.604983
* 2016 7 7 0 24 0.00000000
PL51 -723.266021 -12187.684343 1690.901352
VL51 -28732.598739 -5690.849527 -52800.910357
* 2016 7 7 0 26 0.00000000
PL51 -1067.277967 -12234.713827 1055.020439
VL51 -28578.105451 -2145.977340 -53152.127673
* 2016 7 7 0 28 0.00000000
PL51 -1408.550731 -12239.179889 415.902767
VL51 -28276.179256 1400.872600 -53340.241211
* 2016 7 7 0 30 0.00000000
PL51 -1745.320425 -12201.137279 -224.490750
VL51 -27827.814366 4936.626001 -53364.720862
* 2016 7 7 0 32 0.00000000
PL51 -2075.839039 -12120.797322 -864.195760
VL51 -27234.662280 8448.268907 -53225.523209
* 2016 7 7 0 34 0.00000000
PL51 -2398.382294 -11998.526910 -1501.250306
VL51 -26499.025368 11922.895935 -52923.091281
* 2016 7 7 0 36 0.00000000
PL51 -2711.257401 -11834.846907 -2133.700662
VL51 -25623.847825 15347.758022 -52458.352972
* 2016 7 7 0 38 0.00000000
PL51 -3012.810694 -11630.429993 -2759.607129
VL51 -24612.704026 18710.309519 -51832.718163
* 2016 7 7 0 40 0.00000000
PL51 -3301.435113 -11386.097944 -3377.049800
VL51 -23469.784344 21998.254462 -51048.074529
* 2016 7 7 0 42 0.00000000
PL51 -3575.577495 -11102.818361 -3984.134261
VL51 -22199.878464 25199.591874 -50106.782068
* 2016 7 7 0 44 0.00000000
PL51 -3833.745655 -10781.700867 -4578.997216
VL51 -20808.356282 28302.659921 -49011.666357
* 2016 7 7 0 46 0.00000000
PL51 -4074.515222 -10423.992777 -5159.812034
VL51 -19301.146441 31296.178781 -47766.010569
* 2016 7 7 0 48 0.00000000
PL51 -4296.536205 -10031.074261 -5724.794178
VL51 -17684.712593 34169.292081 -46373.546254
* 2016 7 7 0 50 0.00000000
PL51 -4498.539254 -9604.453028 -6272.206531
VL51 -15966.027479 36911.606738 -44838.442942
* 2016 7 7 0 52 0.00000000
PL51 -4679.341613 -9145.758532 -6800.364582
VL51 -14152.544928 39513.231104 -43165.296579
* 2016 7 7 0 54 0.00000000
PL51 -4837.852706 -8656.735735 -7307.641463
VL51 -12252.169856 41964.811258 -41359.116834
* 2016 7 7 0 56 0.00000000
PL51 -4973.079364 -8139.238447 -7792.472840
VL51 -10273.226406 44257.565353 -39425.313323
* 2016 7 7 0 58 0.00000000
PL51 -5084.130657 -7595.222265 -8253.361618
VL51 -8224.424311 46383.315891 -37369.680766
* 2016 7 7 1 0 0.00000000
PL51 -5170.222310 -7026.737140 -8688.882471
VL51 -6114.823626 48334.519838 -35198.383132