[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Orekit Users] Assistance in converting TLE to LLA on Geo Objects



Luc,

Thanks!  I see now where I went wrong, and I appreciate your assistance.  The hints were very useful!

--Ryan

-----Original Message-----
From: orekit-users-request@orekit.org [mailto:orekit-users-request@orekit.org] On Behalf Of MAISONOBE Luc
Sent: Wednesday, July 31, 2013 3:11 AM
To: orekit-users@orekit.org
Subject: Re: [Orekit Users] Assistance in converting TLE to LLA on Geo Objects

Hi Ryan,

ryan.waterer@mtsi-va.com a écrit :

> Hello all, I?m hoping that you can help me!
>
> I?m trying to calculate the Lat/Long/Altitude (LLA) of GEO objects if 
> I?m only given a TLE.  I can?t guarantee that the system I?m using 
> this for will have access to the internet, and I?ll need to do this 
> dynamically.
>
> I?ve gone over the documentation and other sites to figure out how to 
> use OREKit to do all the heavy lifting for me (great tool btw!  I?m liking it).
> What I?ve come up with is the following, although it appears to be
> 2-3 degrees
> off  of what appears to be truth data (I?m using GOES satellites for 
> testing which are well known and have plenty of documentation of where 
> these satellites are located).  Can you please let me know what I?m doing wrong?
> Unfortunately, I'm a novice in astrodynamics and I don't fully 
> understand what I'm trying to do.
>
> With my current results, I?m off 3 degrees wth GOES 12, 2.6 on GOES 
> 13, and
> 2.7 with GOES 14.  I?m sure that I?ve either mis-configured something, 
> or have just gotten really lucky in being that close in these 
> calculations.
>
> Thank you in advance for your assistance!
>
> --Ryan
>
> public void calculateLLA() throws OrekitException {
> 		// configure Orekit
> 		Autoconfiguration.configureOrekit();

Using Autoconfiguration is not a good thing. This class is only a dirty hack set up so that the tutorials are easy to set up and work in a few different but classical cases (date in either home directory or current directory, in either zip or expanded format, or even everything within an eclipse IDE project). IT is not meant to be used for production. You should rather use something as follows, considering you have set up an orekit-data folder somewhere on your
computer:

    DataProvider provider =
     new DirectoryCrawler(new File("the-path-to-orekit-data-folder"));
    DataProvidersManager.getInstance().addProvider(provider);

>
> 		// GOES -13 (GEO) TLE from SpaceTrack on 7/29/2013
> 		String card1 = "1 29155U 06018A   13210.23162706 -.00000268
> 00000-0  10000-3 0  6652";
> 		String card2 = "2 29155 000.0933 259.9903 0003625 191.6068
> 224.2324 01.00270872 26322";
>
> 		System.out.println("Is the TLE format ok? : "
> 				+ TLE.isFormatOK(card1, card2));
> 		TLE tle = new TLE(card1, card2);
>
> 		TLEPropagator tleProp = TLEPropagator.selectExtrapolator(tle);
>
> 		// Initial date in UTC time scale
> 		TimeScale utc = TimeScalesFactory.getUTC();
> 		AbsoluteDate initialDate = new AbsoluteDate(2013, 07, 29, 23, 30,
> 				00.000, utc);
>
> 		AbsoluteDate extrapDate = initialDate;
> 		SpacecraftState newState = tleProp.propagate(extrapDate);
>
> 		CartesianOrbit currentOrbit = (CartesianOrbit) newState.getOrbit();
> 		extrapDate = new AbsoluteDate(extrapDate, 600, utc);
> 		PVCoordinates pv = currentOrbit.getPVCoordinates();
>
> 		Transform trans = FramesFactory.getEME2000().getTransformTo(
> 				FramesFactory.getITRF2005(), extrapDate);
> 		Vector3D posITRS = trans.transformPosition(pv.getPosition());

The previous lines can be simplified (and fixed since there is a slight error) as follows:

     Vector3D posITRS = newState.getPVCoordinates(FramesFactory.getITRF2005());

All the underlying frames conversions will be done for you.

The slight error in your code is that the TLE propagator does not propagate orbits in the EME2000 frame but rather in the TEME frame, which is a strange frame used only by TLE. Due to precession, the TEME frame is not fixed with respect to EME2000. This may explain part of the difference.

Another and very important part of the difference is that public TLE data is often very crude. Kilometers errors are frequent, and there are cases were hundreds of kilometers errors or even worse have been encountered. So depending on what your reference position come from, you may get large errors. If your reference position was also computed by another mean but based on the same TLE, then you should have matching results (but they may well not be the true position of the spacecraft). If your reference position was computed from other data (for example orbit determination by the operational system), then the reference will in most cases be much more accurate and a difference will mainly be a consequence of a bad TLE.

> 		System.out.println("X: " + posITRS.getX() + " Y: " +
> posITRS.getY()
> 				+ " Z:" + posITRS.getZ());
>
> 		// Quick check on the calculation for longitude:
> 		//
> http://www.mathworks.com/help/aeroblks/ecefpositiontolla.html
> 		// longitude = atan ( py / px);
> 		double longitude = FastMath.atan2(posITRS.getY(), posITRS.getX());
> 		System.out.println("Longititude: " + FastMath.toDegrees(longitude));
>
> 		OneAxisEllipsoid oae = new OneAxisEllipsoid(
> 				Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
> 				Constants.WGS84_EARTH_FLATTENING,
> FramesFactory.getEME2000());
>
> 		GeodeticPoint gp = oae.transform(posITRS, 
> FramesFactory.getEME2000(),
> 				new AbsoluteDate());

The two previous statements are wrong. The OneAxisEllipsoid object should not be set up with an inertially oriented frame like the EME2000, but should should be set up with a frame that represents Earth rotation (i.e. which is fixed with respect to Earth), like ITRF.  
Also in the call oae.transform, the two first argument must be consistent. If you give a position in ITRF, then you should use ITRF as the second argument. If you give EME2000 as the second argument, then you should provide a position in EME2000. You cannot mix. The reason for that is that you give a position in forst argument, you specify in the second argument in which frame you did provide the first argument, then the object which remembers the rotating frame in which it was built will do the transform if it need to. So if you decided to already provides the position in ITRF *and* passed ITRF as the second argument, then the object will notice it is already the same frame it was built with and it will not transform the cartesian position before computing the angle. If on the other hand you provide a position in EME2000 *and* pass EME2000 as the second argument, then the object will notice EME2000 is not the same as the ITRF frame it was built with, so it will first perform the transformation to convert the EME2000 position into ITRF and then compute the angles.

Hope this helps,
Luc

>
> 		System.out.println("Altitude: " + gp.getAltitude() + "  Long="
> 				+ FastMath.toDegrees(gp.getLongitude()) + "
> Lat= "
> 				+ FastMath.toDegrees(gp.getLatitude()));
>
> 		System.out
> 				.println("Does the manual calculated longitutde meet the OREKit 
> longitude? "
> 						+
> (FastMath.toDegrees(longitude) == FastMath
>
> .toDegrees(gp.getLongitude())));
> 	}
>
>



----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.