CPF parser ignores direction flag - causing an exception later

The Problem

Tested with Orekit 12.0.1.

As described in the forum, the CPF parser (org.orekit.files.ilrs.CPFParser:470) ignores the direction flag of position lines - index 1 in the generated array:

        /** Position values. */
        TEN("10") {
            /** {@inheritDoc} */
            @Override
            public void parse(final String line, final ParseInfo pi) {
                // Data contained in the line
                final String[] values = SEPARATOR.split(line);

                // Epoch
                final int mjd           = Integer.parseInt(values[2]);

The direction flag is ignored for the other implemented line type parser (20), too.

The possible directional flag values are, according to the CPF documentation (page 15):

Common epoch (0): 
  instantaneous vector between geocenter and target, without light-time iteration. This epoch is the same as found in the corresponding old TIV format.
Transmit (1):
  position vector contains light-time iterated travel time from the geocenter to the target at the transmit epoch.
Receive (2):
  position vector contains light-time iterated travel time from the target to the geocenter at the receive epoch.
  (The sign of each element is opposite to that of the transmit vector.)

For objects on the moon (apollo11, apollo 15 luna17 and luna21 on https://edc.dgfi.tum.de/pub/slr/cpf_predicts_v2/current) the inbound and outbound position vectors are given for the same time:

H1 CPF 2 OPA 2024 01 03 18 003 1 apollo11 OPA_ELP96
H2 100 100 0 2024 1 4 0 0 0 2024 1 8 23 45 0 900 0 1 0 0 0 3
H9
10 1 60313       0.0 0        16126075.681       398785441.280       -26042850.417
10 2 60313       0.0 0       -16202176.985      -398701851.546        26035563.466
30 1        -741.     -40216.       3643.    26.9
10 1 60313     900.0 0        41473086.247       396893016.626       -26449307.496
10 2 60313     900.0 0       -41543554.533      -396804772.095        26442015.393
30 1       -3370.     -40078.       3646.    26.9

The outcome

This causes an exception when interpolating between the points, because the time difference is zero:

Exception in thread "main" org.hipparchus.exception.MathIllegalArgumentException: duplicated abscissa 0 causes division by zero
	at org.hipparchus.analysis.interpolation.HermiteInterpolator.addSamplePoint(HermiteInterpolator.java:113)
	at org.orekit.utils.TimeStampedPVCoordinatesHermiteInterpolator.lambda$interpolate$0(TimeStampedPVCoordinatesHermiteInterpolator.java:148)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
	at org.orekit.utils.TimeStampedPVCoordinatesHermiteInterpolator.interpolate(TimeStampedPVCoordinatesHermiteInterpolator.java:146)
	at org.orekit.utils.TimeStampedPVCoordinatesHermiteInterpolator.interpolate(TimeStampedPVCoordinatesHermiteInterpolator.java:39)
	at org.orekit.time.AbstractTimeInterpolator.interpolate(AbstractTimeInterpolator.java:91)
	at org.orekit.files.general.EphemerisSegmentPropagator.getPVCoordinates(EphemerisSegmentPropagator.java:115)

Test-code

This exception can be generated with this code snippet:

CPF cpfFile = new CPFParser().parse(new DataSource("satellite.cpf", new DataSource.ReaderOpener()
{
	@Override
	public Reader openOnce() throws IOException
	{
		return new StringReader("H1 CPF 2 OPA 2024 01 03 18 003 1 apollo11 OPA_ELP96\n"
				+ "H2 100 100 0 2024 1 4 0 0 0 2024 1 8 23 45 0 900 0 1 0 0 0 3\n"
				+ "H9\n"
				+ "10 1 60313       0.0 0        16126075.681       398785441.280       -26042850.417\n"
				+ "10 2 60313       0.0 0       -16202176.985      -398701851.546        26035563.466\n"
				+ "30 1        -741.     -40216.       3643.    26.9\n"
				+ "10 1 60313     900.0 0        41473086.247       396893016.626       -26449307.496\n"
				+ "10 2 60313     900.0 0       -41543554.533      -396804772.095        26442015.393\n"
				+ "30 1       -3370.     -40078.       3646.    26.9\n"
				+ "10 1 60313    1800.0 0        66644291.059       393390899.000       -26855631.271\n"
				+ "10 2 60313    1800.0 0       -66708842.979      -393298378.023        26848334.019\n"
				+ "30 1       -5984.     -39769.       3648.    26.9\n"
				+ "10 1 60313    2700.0 0        91537552.217       388293816.394       -27261819.596\n"
				+ "10 2 60313    2700.0 0       -91595929.760      -388197414.474        27254517.199\n"
				+ "30 1       -8572.     -39289.       3651.    26.8\n"
				+ "10 1 60313    3600.0 0       116051895.405       381622972.022       -27667870.319\n"
				+ "10 2 60313    3600.0 0      -116103866.930      -381523100.119        27660562.779\n"
				+ "30 1      -11123.     -38641.       3653.    26.8\n"
				+ "10 1 60313    4500.0 0       140087920.030       373405955.825       -28073781.283\n"
				+ "10 2 60313    4500.0 0      -140133281.178      -373303038.613        28066468.603\n"
				+ "30 1      -13625.     -37827.       3656.    26.8\n"
				+ "10 1 60313    5400.0 0       163548202.818       363676629.997       -28479550.326\n"
				+ "10 2 60313    5400.0 0      -163586777.325      -363571104.045        28472232.508\n"
				+ "30 1      -16069.     -36852.       3658.    26.8\n"
				+ "99");
	}
}));
for (CPFEphemeris ephemerisEntry : cpfFile.getSatellites().values()) {
   ephemerisEntry.getPropagator().getPVCoordinates(ephemerisEntry.getStart(), FramesFactory.getITRF(IERSConventions.IERS_2010, true));
}

Solution

Ignore lines with direction flag value = 2 solves this issue. Probably it should be configurable which direction should be parsed?

Edited by Vincent CUCCHIETTI