Hi All,
I am trying to convert from TLE to Cartesian and viceversa, but I am not fully sure that I am following the correct procedure.
Below you can find the code:
public class TLEConversionNumericalModel {
public static void main(String[] args) throws OrekitException {
String orekitDataPath = args[0];
DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(new File(orekitDataPath)));
TLE inputTle = new TLE("1 31135U 07013A 11003.00000000 .00000816 00000+0 47577-4 0 11",
"2 31135 2.4656 183.9084 0021119 236.4164 60.4567 15.10546832 15");
// Retrieve the correct propagator that was used to generate the TLE (SGP4 or SDP4)
Propagator tlePropagator = TLEPropagator.selectExtrapolator(inputTle);
// Initial reference Orbit for the builder
Orbit referenceOrbit = tlePropagator.getInitialState().getOrbit();
/*
* Numerical Propagator to fit the samples generated by the TLE propagator
*/
// Adaptive stepsize
double minStep = 1e-3;
double maxStep = 600;
double dP = 1e-3;
DormandPrince853IntegratorBuilder dormandBuilder = new DormandPrince853IntegratorBuilder(minStep, maxStep, dP);
NumericalPropagatorBuilder numericalPropBuilder = new NumericalPropagatorBuilder(referenceOrbit, dormandBuilder, PositionAngle.TRUE, 1.0);
setUpPropagatorBuilderForceModels(numericalPropBuilder);
FiniteDifferencePropagatorConverter numericalFitter = new FiniteDifferencePropagatorConverter(numericalPropBuilder, 1.0e-3, 1000);
double duration = 86400.0;
double stepSize = 300.0;
Double points = duration / stepSize;
System.out.println("START NUMERICAL PROPAGATOR FITTING");
numericalFitter.convert(tlePropagator, duration, points.intValue());
System.out.println("END NUMERICAL PROPAGATOR FITTING");
NumericalPropagator numericalPropagator = (NumericalPropagator) numericalFitter.getAdaptedPropagator();
/*
* Convert Back to TLE
*/
Orbit orbit = numericalPropagator.getInitialState().getOrbit();
// Convert to keplerian orbit to get missing elements for the TLEtemplate
KeplerianOrbit keplerianOrbit = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(orbit);
TLE tleTempalte = new TLE(inputTle.getSatelliteNumber(),
inputTle.getClassification(),
inputTle.getLaunchYear(),
inputTle.getLaunchNumber(),
inputTle.getLaunchPiece(),
inputTle.getEphemerisType(),
inputTle.getElementNumber(),
inputTle.getDate(),
keplerianOrbit.getKeplerianMeanMotion(),
0.0,
0.0,
keplerianOrbit.getE(),
keplerianOrbit.getI(),
keplerianOrbit.getPerigeeArgument(),
keplerianOrbit.getRightAscensionOfAscendingNode(),
keplerianOrbit.getMeanAnomaly(),
0,
0);
TLEPropagatorBuilder builder = new TLEPropagatorBuilder(tleTempalte, PositionAngle.TRUE, 1.0);
FiniteDifferencePropagatorConverter tleFitter = new FiniteDifferencePropagatorConverter(builder, 1e-3, 1000);
System.out.println("START TLE PROPAGATOR FITTING");
tleFitter.convert(numericalPropagator, duration, points.intValue(), TLEPropagatorBuilder.B_STAR);
System.out.println("END TLE PROPAGATORFITTING");
TLEPropagator propTLE = (TLEPropagator) tleFitter.getAdaptedPropagator();
TLE outputTLE = propTLE.getTLE();
System.out.println("INPUT TLE");
System.out.println(inputTle);
System.out.println("OUTPUT TLE");
System.out.println(outputTLE);
}
private static void setUpPropagatorBuilderForceModels(NumericalPropagatorBuilder propagatorBuilder) throws OrekitException {
/*
* Add the forces to the Numerical Builder
*/
// Create Earth
OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, false));
// Earth Geopotential
NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(4, 0);
HolmesFeatherstoneAttractionModel geopotentialForce = new HolmesFeatherstoneAttractionModel(earth.getBodyFrame(), provider);
// Solar Radiation Pressure
CelestialBody sun = CelestialBodyFactory.getSun();
double solarRadiationPressureCoefficient = 1.4;
double solarRadiationPressureArea = 10;
RadiationSensitive radiationSensitive = new IsotropicRadiationSingleCoefficient(solarRadiationPressureArea, solarRadiationPressureCoefficient);
SolarRadiationPressure srp = new SolarRadiationPressure(sun, earth.getEquatorialRadius(), radiationSensitive);
// Third Bodies
ThirdBodyAttraction thirdbodyMoon = new ThirdBodyAttraction(CelestialBodyFactory.getMoon());
ThirdBodyAttraction thirdbodySun = new ThirdBodyAttraction(sun);
// Drag
HarrisPriester atmosphere = new HarrisPriester(sun, earth);
double cd = 1.2;
double area = 5;
IsotropicDrag spacecraft = new IsotropicDrag(area, cd);
DragForce drag = new DragForce(atmosphere, spacecraft);
/*
* Add force models
*/
propagatorBuilder.addForceModel(drag);
propagatorBuilder.addForceModel(geopotentialForce);
propagatorBuilder.addForceModel(srp);
propagatorBuilder.addForceModel(thirdbodyMoon);
propagatorBuilder.addForceModel(thirdbodySun);
}
}
What I am doing is:
- Building the corresponding TLEPropagator from a TLE
- Create and set up a NumericalPropagatorBuilder to be given in input to the FiniteDifferencePropagatorConverter
- Get the NumericalPropagator as a result of the fitting procedure on the internal generated samples
at this point I query for the PVCoordinates of the initial state of the spacecraft from the NumericalPropagator to use it for regenerate a set of TLE, by repeating the procedure above. Inverting the roles of the two propagators.
Is this the right approach?
The input and output TLE are the following:
- Input TLE:
1 31135U 07013A 11003.00000000 .00000816 00000+0 47577-4 0 11
2 31135 2.4656 183.9084 0021119 236.4164 60.4567 15.10546832 15 - Output TLE:
1 31135U 07013A 11003.00000000 .00000000 00000-0 14638-3 0 18
2 31135 2.4656 183.9084 0021118 236.4174 60.4567 15.10545148 03
I believe that the small differences in the mean elements are due to the different force models used by the TLEPropagator and NumericalPropagator.
But what I don’t understand is why the Bstar coefficients are so different. Should they not be the same ? Or am I missing something?
Thank you really much for your reply and for this forum, it is really useful!
Leonardo