Small gaps in eclipse detection

Hello, working with EclipseDetector I found some cases with strange behaviour. The detector detects eclipse exits few minutes after the begining then detects few minutes later the eclipse again. Is there any reason for that ?
Below are the traces and the code to reproduce.

Event eclipse occured 2010-01-01T00:02:06.303 increasing = true   => exit eclipse   : interval = 126 s
Event eclipse occured 2010-01-01T00:04:21.232 increasing = false  => enter eclipse  : interval = 134 s
Event eclipse occured 2010-01-01T00:39:13.692 increasing = true   => exit eclipse   : interval = 2092 s
Event eclipse occured 2010-01-01T01:36:40.076 increasing = false  => enter eclipse  : interval = 3446 s
Event eclipse occured 2010-01-01T01:40:52.681 increasing = true   => exit eclipse   : interval = 252 s
Event eclipse occured 2010-01-01T01:43:09.592 increasing = false  => enter eclipse  : interval = 136 s
Event eclipse occured 2010-01-01T02:18:01.664 increasing = true   => exit eclipse   : interval = 2092 s
Event eclipse occured 2010-01-01T03:15:26.454 increasing = false  => enter eclipse  : interval = 3444 s
Event eclipse occured 2010-01-01T03:19:39.059 increasing = true   => exit eclipse   : interval = 252 s
Event eclipse occured 2010-01-01T03:21:57.948 increasing = false  => enter eclipse  : interval = 138 s
Event eclipse occured 2010-01-01T03:56:49.637 increasing = true   => exit eclipse   : interval = 2091 s
Event eclipse occured 2010-01-01T04:54:12.832 increasing = false  => enter eclipse  : interval = 3443 s

Code

public class EclipseDetectorTest extends NumericalTest {

    private static final double INIT_MASS = 20;

    public static double minStep = 1e-8;
    public static double maxStep = 100;
    public static double[] vecAbsoluteTolerance = { 1e-5, 1e-5, 1e-5, 1e-8, 1e-8, 1e-8, 1e-5 };
    public static double[] vecRelativeTolerance = { 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10,
            1e-10 };

    public NumericalPropagator createPropagator(Orbit orbit) throws OrekitException {
        DormandPrince54Integrator integrator = new DormandPrince54Integrator(minStep, maxStep,
                vecAbsoluteTolerance, vecRelativeTolerance);

        final NumericalPropagator propagator = new NumericalPropagator(integrator);

        SpacecraftState iniState = new SpacecraftState(orbit, INIT_MASS);
        propagator.resetInitialState(iniState);

        return propagator;
    }

    public EclipseDetector buildEclipseDetector() throws OrekitException {
        PVCoordinatesProvider earth = CelestialBodyFactory.getEarth();
        PVCoordinatesProvider sun = CelestialBodyFactory.getSun();

        EclipseDetector detector = new EclipseDetector(maxStep, AbstractDetector.DEFAULT_THRESHOLD,
                sun, Constants.SUN_RADIUS, earth, Constants.EGM96_EARTH_EQUATORIAL_RADIUS)
                        .withUmbra().withHandler(new EventHandler<EclipseDetector>() {

                            AbsoluteDate lastDate;

                            @Override
                            public void init(final SpacecraftState s0, final AbsoluteDate t) {
                                lastDate = s0.getDate();
                            }

                            @Override
                            public Action eventOccurred(SpacecraftState s, EclipseDetector detector,
                                    boolean increasing) throws OrekitException {
                                int duration = (int) s.getDate().durationFrom(lastDate);
                                lastDate = s.getDate();
                                System.out.println("Event eclipse occured " + s.getDate()
                                        + " increasing = " + increasing + "  \t=> "
                                        + (increasing ? "exit eclipse" : "enter eclipse")
                                        + " \t: interval = " + duration + " s");
                                return Action.RESET_DERIVATIVES;
                            }
                        });
        return detector;
    }

    @Test
    public void testEclipseGap() throws OrekitException, IOException {
        AbsoluteDate date = new AbsoluteDate(2010, 01, 01, TimeScalesFactory.getUTC());
        double sma = Constants.EGM96_EARTH_EQUATORIAL_RADIUS + 700e3;
        double ecc = 0.1;
        double inc = FastMath.toRadians(60);
        double pa = 0.;
        double raan = 0.;
        double anomaly = 0.;

        Orbit initialOrbit = new KeplerianOrbit(sma, ecc, inc, pa, raan, anomaly,
                PositionAngle.MEAN, FramesFactory.getCIRF(IERSConventions.IERS_2010, true), date,
                Constants.EGM96_EARTH_MU);
        double duration = 3 * initialOrbit.getKeplerianPeriod(); // s

        NumericalPropagator numericalPropagator = createPropagator(initialOrbit);
        numericalPropagator.addEventDetector(buildEclipseDetector());

        numericalPropagator.propagate(initialOrbit.getDate().shiftedBy(duration));
        // eclipse starts then stops for few minutes then start again .... strange

    }

}

Hi Mikael,

The error comes from your orbit. With this very high eccentricity and an altitude at 700km, your periapsis is inside the earth (Earth Radius : 6378136.3 m, Periapsis : 6370322.67m).

Regards,
Romaric

Ah ah ah … sorry for the mistake.
By the way it could be nice to have an exception raised with bad inputs like this

There is an exception when the propagation is inside the Brillouin sphere if the spherical harmonics are used in the forces model.

We didn’t put a generic exception for trajectories that cross the earth because in particular cases (atmospheric reentry, sub-orbital trajectories, …), it is the expected behaviour.

So to be sure to understand, an exception would be raised only if we use perturbations (drag model would raise an exception too if I remember well). It looks like a side effect. But I agree it is not common and should not happen when we check inputs before launching the propagation.

In this case, the exceptions are linked to the computation of forces model and are purely mathematics. If the atmospheric model used does not have datas below a given altitude, it will raise an exception. It is the same for spherical harmonics that can’t be computed inside the Brillouin sphere.

If we don’t have mathematical problem during the propagation, it works.