Skip to content

DSSTPropagator: initialIsOsculating should be updated after first propagation

In DSSTPropagator, when the first state injected is osculating and the propagation is set to PropagationType.MEAN, there's a bug if several propagations are called successively.

Test

  • Setting up a DSST propagator in LEO orbit
  • Only J2 as perturbing force, the mean semi-major axis should remain constant
        final double step = 60.;
        final Frame gcrf = FramesFactory.getGCRF();
        final AttitudeProvider attitude = new FrameAlignedProvider(gcrf);
        
        final Orbit initialOrbit = new KeplerianOrbit(7000e3, 1.e-3, FastMath.toRadians(98.), 0., 0., 0.,
                                                      PositionAngleType.ECCENTRIC, gcrf,
                                                      AbsoluteDate.ARBITRARY_EPOCH, Constants.EGM96_EARTH_MU);
        final SpacecraftState initialState = new SpacecraftState(initialOrbit);
        final ClassicalRungeKuttaIntegrator integrator = new ClassicalRungeKuttaIntegrator(step);
        final DSSTPropagator propagator = new DSSTPropagator(integrator, PropagationType.MEAN);
        propagator.setInitialState(initialState, PropagationType.OSCULATING);
        propagator.addForceModel(new DSSTZonal(GravityFieldFactory.getUnnormalizedProvider(2, 0)));
        propagator.setAttitudeProvider(attitude);

        System.out.println("Initial OSC SMA : " + initialOrbit.getDate() + " / " + initialOrbit.getA() / 1000.  + " km");
        
        // Initial mean state
        final SpacecraftState initialMeanState = DSSTPropagator.computeMeanState(initialState, attitude, propagator.getAllForceModels());
        System.out.println("Initial MEAN SMA: " + initialMeanState.getDate() + " / " + initialMeanState.getA() / 1000.  + " km");
        
        final AbsoluteDate t0 = initialOrbit.getDate();
        
        
        for (int i = 0; i < 10; i++) {
            SpacecraftState state = propagator.propagate(t0.shiftedBy(i * step));
            System.out.println("MEAN SMA        : " + state.getDate() + " / " + state.getA() / 1000.  + " km");
        }

Output with v12.1.2 We observe a drop in SMA of about 9km every minute which is inconsistent with the model.
Note also that the first propagated SMA (with DT = 0 s) should be 6990.723 and not 7000, but I think it's a known behavior of DSST.

Initial OSC SMA : 2000-01-01T11:59:28.000Z / 7000.0 km
Initial MEAN SMA: 2000-01-01T11:59:28.000Z / 6990.723156948779 km
MEAN SMA        : 2000-01-01T11:59:28.000Z / 7000.0 km
MEAN SMA        : 2000-01-01T12:00:28.000Z / 6990.723156948779 km
MEAN SMA        : 2000-01-01T12:01:28.000Z / 6981.520864216672 km
MEAN SMA        : 2000-01-01T12:02:28.000Z / 6972.547504639528 km
MEAN SMA        : 2000-01-01T12:03:28.000Z / 6963.953859837731 km
MEAN SMA        : 2000-01-01T12:04:28.000Z / 6955.884651549706 km
MEAN SMA        : 2000-01-01T12:05:28.000Z / 6948.476204445237 km
MEAN SMA        : 2000-01-01T12:06:28.000Z / 6941.854259324915 km
MEAN SMA        : 2000-01-01T12:07:28.000Z / 6936.1319611642375 km
MEAN SMA        : 2000-01-01T12:08:28.000Z / 6931.408042602054 km

Cause of the bug The problem comes from the fact that the attribute initialIsOsculating is initialized to true and never changed afterward.
After each propagation, the state is reinitialized with the result of this propagation. This state is MEAN.
However, for the next propagation, the propagator considers that it is OSCULATING because of initialIsOsculating = True.
So a conversion from osculating to mean is performed when it shouldn't.
The drop in SMA observed is the result of successive erroneous osculating to mean conversions.

Fix Consider the propagation type in AbstractIntegratedPropagator.integrateDynamics when resetting the state at the end of propagation.