Hey folks, I’ve been trying to build an Orekit propagator that closely matches the SLR precision ephemeris pulled from CDDIS for the Larets spacecraft (< 20m error per day of propagation). My propagator as it currently stands is only able to get to < 10km of error per day of propagation (see below).
I loaded in the SLR precision ephemeris using the SP3 parsing / propagation framework like this:
// Parsing the SP3 file with the intent to keep in GCRF
Path sp3File = Paths.get(this.getClass().getClassLoader().getResource(sp3DataFile).toURI());
SP3Parser parser = new SP3Parser();
SP3 file = parser.parse(
new DataSource(sp3File.toString(), () -> getClass().getResourceAsStream(sp3DataFile)));
// Pulling out the ephemeris for the Larets spacecraft
SP3Ephemeris ephem = file.getSatellites().get(sp3SatName);
// Converting the ephemeris into a propagator which will interpolate
Propagator sp3Prop = ephem.getPropagator();
And then essentially built my Orekit propagator and compared the resulting propagation over the course of 24 hours. Since the documentation doesn’t cover more complex cases, it’s difficult to know if I’m setting up the software correctly or if I’m missing a small detail that may be causing this. The propagation setup I’ve built looks like this:
public Propagator getNumPropagator(TimeStampedPVCoordinates pvCoords, Frame frame, int gravDegree, int gravOrder,
double coefAbsorb, double coefReflect, double crossSection, double dragCoef, double mass) {
// Create orbit from input PV coords
Orbit orbit = new CartesianOrbit(pvCoords, frame, OrekitUtils.MU);
SpacecraftState initialState = new SpacecraftState(orbit, mass);
// Create adaptive step integrator
double minStep = 0.001;
double maxstep = 1000.0;
double positionTolerance = 1.0e-4;
OrbitType propagationType = OrbitType.CARTESIAN;
double[][] tolerances = NumericalPropagator.tolerances(positionTolerance, orbit, propagationType);
AdaptiveStepsizeIntegrator integrator = new DormandPrince853Integrator(minStep, maxstep, tolerances[0],
tolerances[1]);
NumericalPropagator prop = new NumericalPropagator(integrator);
// Create Gravity Model
NormalizedSphericalHarmonicsProvider gravProvider = GravityFieldFactory.getNormalizedProvider(gravDegree,
gravOrder);
ForceModel gravModel = new HolmesFeatherstoneAttractionModel(frame, gravProvider);
prop.addForceModel(gravModel);
// Creating Lunar and Solar gravitational effects
ThirdBodyAttraction lunarGrav = new ThirdBodyAttraction(CelestialBodyFactory.getMoon());
ThirdBodyAttraction solarGrav = new ThirdBodyAttraction(CelestialBodyFactory.getSun());
prop.addForceModel(lunarGrav);
prop.addForceModel(solarGrav);
// Solid Earth Tides
SolidTides tides = new SolidTides(frame,
Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, Constants.EIGEN5C_EARTH_MU,
TideSystem.ZERO_TIDE,
IERSConventions.IERS_2010,
TimeScalesFactory.getUT1(IERSConventions.IERS_2010, false),
CelestialBodyFactory.getSun(), CelestialBodyFactory.getMoon());
prop.addForceModel(tides);
// Relativity
Relativity rel = new Relativity(Constants.EIGEN5C_EARTH_MU);
prop.addForceModel(rel);
// Solar Radiation Pressure Model
if (!Double.isNaN(coefAbsorb) && !Double.isNaN(coefReflect)) {
RadiationSensitive satSRPConfig = new IsotropicRadiationClassicalConvention(crossSection, coefAbsorb,
coefReflect);
SolarRadiationPressure srp = new SolarRadiationPressure(CelestialBodyFactory.getSun(),
Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS, satSRPConfig);
srp.addOccultingBody(CelestialBodyFactory.getMoon(),
Constants.MOON_EQUATORIAL_RADIUS);
prop.addForceModel(srp);
}
// Drag Model
if (!Double.isNaN(dragCoef)) {
BodyShape earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING, FramesFactory.getGCRF());
CssiSpaceWeatherData cssi = new CssiSpaceWeatherData("SpaceWeather-All-v1.2.txt");
MarshallSolarActivityFutureEstimation msafe = new MarshallSolarActivityFutureEstimation(
MarshallSolarActivityFutureEstimation.DEFAULT_SUPPORTED_NAMES,
MarshallSolarActivityFutureEstimation.StrengthLevel.AVERAGE);
DTM2000 dragModel = new DTM2000(cssi, CelestialBodyFactory.getSun(), earth);
// NRLMSISE00 dragModel = new NRLMSISE00(msafe, CelestialBodyFactory.getSun(), earth);
DragSensitive satDragConfig = new IsotropicDrag(crossSection, dragCoef);
DragForce drag = new DragForce(dragModel, satDragConfig);
prop.addForceModel(drag);
}
prop.setInitialState(initialState);
return prop;
}
Is there something I’m configuring incorrectly, or are there better models / practices for a more accurate propagator? Any help you can provide would be appreciated!
Nick