Help with ITRF to GCRF transform

Hi,
I ran into a discrepancy transforming position vectors from ECEF to ECI. I’ve debugged a little bit, but I am not sure where in my setup I’ve gone wrong.
Here is the test position and results computed with (1) an Earth-to-Inertial transformation matrix from (//hpiers.obspm.fr) and (2) from orekit.

Test Epoch:            2024-07-25T23:35:04.000Z
ECF Position           [    -3527287.368000    -1810409.322000    -6170937.914000 ] meters
ECI Position (iers)    [    -3253940.447016     2285967.165928    -6163281.472694 ] meters
ECI Position (orkt)    [    -3253926.302215     2285982.797904    -6163283.142573 ] meters
Difference (orkt-iers) [          14.144800          15.631976          -1.669879 ] meters

I’ve also verified the IERS-derived answer via other means (STK and my own transform package). I would expect any differences to be at the sub-meter level, so 14-15 meters is quite large.

Here are the loaded data files from the test (getLoadedDataNames). I am using the EOPC04 .csv file for 2024, downloaded from the iers data center.

Loaded Data Names:
    D:\orekit-data\tai-utc.dat
    D:\orekit-data\itrf-versions.conf
    D:\orekit-data\Earth-Orientation-Parameters\eopc04_14_IAU2000.24.csv

And here is the code (I am working in matlab). I am testing with orekit 12.2.1 at the moment.

Thanks for your help!
Mike

%% Standalone test for ECEF-ECI error
% Set the data context
dataContextDir = setOrktEnv();
DM             = orkt.setDataContext(dataContextDir);
% DM is org.orekit.data.DataContext.getDefault().getDataProvidersManager()
% (set up with a crawler pointed at the dataContextDir)

% Set time scale and coordinate frames
UTC  = org.orekit.time.TimeScalesFactory.getUTC();
ECI  = org.orekit.frames.FramesFactory.getGCRF();
IERS = org.orekit.utils.IERSConventions.IERS_2010;
ITRF = org.orekit.frames.FramesFactory.getITRF(IERS, true);

% Test eoch and ECEF position.
posEpoch = org.orekit.time.AbsoluteDate(2024,07,25,23,35,4.0,UTC);
posECEF  = [ -3527287.368 -1810409.322 -6170937.914 ];

% Earth orientation from
% https://hpiers.obspm.fr/eop-pc/index.php?index=rotation&lang=en
% MJD TAI          /  year / month / day / hour / min / sec
% 60516.983113425929 2024  7 25 23 35  4.0000004  
%  0.46355095867413  0.88606705136011  0.00238520571195   R11 R12 R13
% -0.88606961347737  0.46355219621129  0.00003820676984   R21 R22 R23
% -0.00107181358630 -0.00213116908804  0.99999715466293   R31 R32 R33
% qs q1 q2 q3
% -0.85543852928605  0.00063399525028 -0.00101030617043  0.51790298313910
Ti_e_iers = [  0.46355095867413  0.88606705136011  0.00238520571195
              -0.88606961347737  0.46355219621129  0.00003820676984
              -0.00107181358630 -0.00213116908804  0.99999715466293 ];

% Get the orekit rotation matrix
Ti_e_orkt = ITRF.getStaticTransformTo(ECI,posEpoch).getRotation().getMatrix();

% Transform ECEF position
posECI_iers = posECEF*Ti_e_iers';

% NB: I know I can to this directly from ITRF, but debugging here.
posECI_orkt = posECEF*Ti_e_orkt';

% Print results
fprintf("Test Epoch:            %s\n",string(posEpoch));
fprintf("ECF Position           [ %18.6f %18.6f %18.6f ] meters\n",posECEF);
fprintf("ECI Position (iers)    [ %18.6f %18.6f %18.6f ] meters\n",posECI_iers);
fprintf("ECI Position (orkt)    [ %18.6f %18.6f %18.6f ] meters\n",posECI_orkt);
fprintf("Difference (orkt-iers) [ %18.6f %18.6f %18.6f ] meters\n",posECI_orkt-posECI_iers);

% Dump the loaded database file names
fprintf("\nLoaded Data Names:\n");
it    = DM.getLoadedDataNames.iterator;
while(it.hasNext)
    nxt = it.next;
    fprintf("    %s\n",string(nxt));
end

Update:
There are two versions of the EOP files here:
https://datacenter.iers.org/products/eop/long-term/c04_14/iau2000/
with a csv version in /csv.

The original file I used is

https://datacenter.iers.org/products/eop/long-term/c04_14/iau2000/csv/eopc04_14_IAU2000.24.csv

and this is the file with which I had an erroneous transformation.

However with the text version of the same file,

https://datacenter.iers.org/products/eop/long-term/c04_14/iau2000/eopc04_14_IAU2000.24

I get the correct transformation.

Apparently the csv version is not being parsed correctly. I’m not sure if this a bug or it is simply not supported.

But it is easy enough to retrieve the text version now that I know.

Thanks!
Mike

Which version of Orekit do you use?
IERS changed its csv format in november 2023, adding new columns… that are empty and shifting the remaining columns.
This was a huge problem and I complained about this for operational systems, considering IERS notified about the format change only 4 weeks before implementing it, reusing an existing URL for the new files and creating a new URL for the old format, hence just mixing up URL/format association. I complained, citing risks on operational systems, and IERS answered:

Unfortunately, we cannot change the planned procedure for the upcoming
format change. It would cause too much confusion. We apologize for any
inconvenience this may cause.

This is why I wonder which version of Orekit you use as we had to be creative to follow IERS shenanigans. If you use a recent Orekit, this would perhaps imply we were not creative enough.

Hi Luc

I am using 12.2.1.

Thank you!

-Mike

It should work with 12.2.1 as it was introduced in 12.0, so it is probably a bug.
Could you open a bug report referring to the files you used?

Luc,

Just to make sure I’m doing the right thing. To “open a bug report” I have to sign up for an account at gitlab.orekit.org and create an “Issue”? (already registered-just verifying).

Thank you,
Mike

Yes, this is what you have to do.
I see you have opened the issue, I will try to look at it