Implementing Satellite J2Perturbation in STK Using orekit

Hello everyone, I would like to ask if using orekit can achieve j2p forecasting. I am using the BrouwerLyddanePropagatorTest class, but the calculated result seems to be inconsistent with stk

Hi @dreamdongx

Welcome to the Orekit forum.

That’s normal, Brouwer-Lyddane model implements the Zonal harmonics from J2 to J5. So you have more than just the J2 perturbation.

To implement a J2 only propagation model you can:

  • Initialize a NumericalPropagator
  • Create a HolmesFeatherstoneAttractionModel with only J2.

ForceModel gravityField = new HolmesFeatherstoneAttractionModel(FramesFactory.getITRF(IERSConventions.IERS_2010, true), GravityFieldFactory.getNormalizedProvider(2, 0));

  • Add the force model to your numerical propagator and propagate

To help you, you can look at the numerical propagation tutorial

Best regards,
Bryan

Hi Bryan,

Thank you so much for your response and the helpful solution you provided. Your explanation of the Brouwer-Lyddane model and the steps to implement a J2-only propagation model in Orekit was very clear and comprehensive.

I appreciate your time and efforts in assisting me with this issue. Your guidance has provided me with a better understanding of the model and how to apply it in my work. I will follow the steps you have recommended and implement the propagation model accordingly.

If I encounter any further difficulties or have further questions, I will definitely reach out to you for further assistance. Thank you once again for your invaluable support.

Best regards,
dreamdongx

Hi Bryan,
I followed the approach you provided to predict the orbit of the satellite, but it still seems different from STK. Did I make a mistake? Here is my code .Thank you in advance

public void testJ2P(){

        UTCScale utc = TimeScalesFactory.getUTC();
        AbsoluteDate initDate = new AbsoluteDate(2023, 9, 12, 04, 00, 00.000, utc);

        double a = 6675900;
        double e = 0.01256;
        double i = FastMath.toRadians(28.482);
        double omega = FastMath.toRadians(0);
        double rann = FastMath.toRadians(0);
        double mean = FastMath.toRadians(0);

        Orbit initOrbit = new KeplerianOrbit(a,e,i,omega,rann, mean, PositionAngle.MEAN,
                FramesFactory.getEME2000(), initDate,Constants.IERS2010_EARTH_MU);

        double dp = 1.0E-6;
        double minStep = 0.00001;
        double maxStep = 10000.0;
        ODEIntegrator integrator = new DormandPrince853IntegratorBuilder(minStep, maxStep, dp)
                .buildIntegrator(initOrbit, OrbitType.KEPLERIAN);

        // Initialize a NumericalPropagator
        NumericalPropagator propagator = new NumericalPropagator(integrator);
        propagator.setMu(Constants.EGM96_EARTH_MU);
        SpacecraftState initState = new SpacecraftState(initOrbit, 1000);
        propagator.setInitialState(initState);
        propagator.setPositionAngleType(PositionAngle.MEAN);

        // Create a HolmesFeatherstoneAttractionModel
        NormalizedSphericalHarmonicsProvider nshp = GravityFieldFactory.getNormalizedProvider(2, 0);
        HolmesFeatherstoneAttractionModel gravityField = new HolmesFeatherstoneAttractionModel(
                CelestialBodyFactory.getEarth().getBodyOrientedFrame(), nshp);

        // Add the force model
        propagator.addForceModel(gravityField);

        AbsoluteDate start = new AbsoluteDate(2023, 9, 12, 04, 00, 00.000, utc);
        AbsoluteDate end = new AbsoluteDate(2023, 9, 12, 05, 00, 00.000, utc);

        // Start forecasting
        while (start.isBefore(end)){
            TimeStampedPVCoordinates pvCoordinates = propagator.getPVCoordinates(start, FramesFactory.getEME2000());
            System.out.println(pvCoordinates);
            start = start.shiftedBy(60);
        }
    }
// myJ2P :{2023-09-12T04:01:00.000, P(6575521.924382813, 412315.4616164101, 223700.6558825176),
// stkJ2P :12 Sep 2023 04:01:00.000     6575.482849      412.975133      224.382459

Best regards,
dreamdongx

Your Orekit code is good.

But I maybe understood why you have differences. Please find below the description of STK’s J2Perturbation:

STK’s J2Perturbation and J4Perturbation propagators model only the secular drift in the elements (the drift in mean anomaly can best be seen as a change to the period of motion of the satellite)

In other words, Orekit’s numerical propagator computes osculating elements while STK’s J2-Perturbation computes secular elements. That’s why results are differents.
Unfortunately, we don’t have secular propagation model in Orekit. We have a semi-analytical theory (i.e., DSST) that can compute mean elements (i.e., the sum of secular and long terms variation).

To summarize, they are different ways to model orbital elements: osculating, mean and secular. And here it looks that we’re comparing two differents and that’s why results are differents. But both are corrects :smiley:

Regards,
Bryan

Thank you very much for your reply and detailed explanation. I understand why my code and STK produce different results.
Regards,
dreamdongx