# Transform ECI to ECEF

I need to transform ECI to ECEF coordinate. Here, I need the formula in math and algorithm. I have looking for the formula in the internet, but I can find one. I have x, y, z cartesian coord in ECI. And want to transform it to ECEF coord. Anybody knows the formula and algorithm?

• It's always a good idea to search the site before posting. There are several questions about this already. space.stackexchange.com/q/36887/6944 Sep 14, 2019 at 15:50

The Explanatory Supplement to the Astronomical Almanac has all the equations you need. Take a look at chapters 3 and 4.

Keep in mind you need some clear definitions of what you mean by ECEF and ECI. Most people utilize WGS84 for ECEF, but that is not a requirement. Similarly ECI could be J2000 or ICRF

In general you will need 4 steps to convert from ECI to ECEF:

1. Calculate earth's precession
2. Calculate earth's nutation
3. Account for earth's rotation including UTC-UT1 offset
4. Account for polar motion
5. Convert to lan/lon if desired

The first two transformations are purely analytical, and can be obtained from books like the Explanatory Supplement. The third and fourth transformation rely on irregularly varying parameters that have to be updated for a specific date.

The help system for the Systems ToolKit (STK) has some excellent descriptions on various frames and transformation process, but not actual equations.

• Thank you, its solved. I just count precesison effect and Account for earth's rotation. Nov 1, 2019 at 0:28

I know this is a old/dead post but I essentially took on the same challenge and when I googled the answer I kept being brought here. I wanted to add some information here so anyone in the future who Google's "How to compute ECI to ECEF or how to compute ECEF to ECI?" Can avoid some of the short falls I fell into or sifting through hundreds of papers on the subject. I winded up buying the very expensive 3rd edition of the "Explanatory Supplement to the Astronomical Almanac" edited by S.E.Urban and P.K.Seidelmann to help me (Great book by the way). Here's my solution. It just does position but I'm planning on understanding velocity and acceleration next.

What Carlos said is dead on. Except what was chapter 3 and 4 in the 2nd edition he linked is now chapter 6. If we define what we mean by ECI as the J2000.0 ... $$$$x_{CRS} = BPNTW\cdot x_{TRS}$$$$ from page 208 of the book. $$$$B=Bias\space rotation \space matrix\\ P=Precession\space rotation \space matrix\\ N=Nutation\space rotation \space matrix\\ T=Earth\space rotation\space rotation \space matrix\\ W=Polar\space motion\space rotation\space matrix$$$$ There are multiple ways to compute each and therefor they all change your definition of what ECI means.

Starting with the bias matrix. They give one in the book. There's also others which could be found on the internet like this paper if you're not completely bored this far in.

The next is the precession matrix. This one is a lot more interesting as it's a series of rotations that are dependent on time. It's also where it gets a lot more complicated and you can read about the more complicated form here or in the book. I'm going to describe the much simpler form as a function of zeta, theta, and z (page 217 if you buy the 3rd edition of the book. If you're serious about this I highly recommend it as it's great for all sorts of orbital fun). Precession could be writen as ... $$$$P=R_3(-z_a)R_2(\theta_a)R_3(-\zeta_a)\\ R_3(-z_a) = \begin{pmatrix}cos(z_a) & -sin_(z_a) & 0 \\\ sin_(z_a) & cos(z_a) & 0 \\\ 0 & 0 & 1\end{pmatrix}\\ R_2(\theta_a) = \begin{pmatrix}cos(\theta_a) & 0 & sin_(\theta_a)\\\ 0 & 1 & 0 \\\ -sin_(\theta_a) & 0 & cos(\theta_a)\end{pmatrix}\\ R_3(-\zeta_a) = \begin{pmatrix}cos(\zeta_a) & -sin_(\zeta_a) & 0 \\\ sin_(\zeta_a) & cos(\zeta_a) & 0 \\\ 0 & 0 & 1\end{pmatrix}\\$$$$

Expand it out and you should get the matrix for precession as ... $$$$P=\begin{pmatrix} cos(z_a)cos(\theta_a)cos(\zeta_a)-sin(z_a)sin(\zeta_a) & -cos(z_a)cos(\theta_a)sin(\zeta_a)-sin(z_a)cos(\zeta_a) & -cos(z_a)sin(\theta_a) \\\ sin(z_a)cos(\theta_a)cos(\zeta_a)+cos(z_a)sin(\zeta_a) & -sin(z_a)cos(\theta_a)sin(\zeta_a)+cos(z_a)cos(\zeta_a) & -sin(z_a)sin(\theta_a) \\\ sin(\theta_a)cos(\zeta_a) & -sin(\theta_a)sin(\zeta_a) & cos(\theta_a) \end{pmatrix}$$$$

You can look up what each means on your own time as this is only the second matrix and will be a very long explanation if I go into too much detail. They're all functions of time in Julian centuries since J2000.0 which is exactly 36525 days. Here's one set of coefficients there are many others and they will give slightly different answers. They're all in arcseconds per century.

$$$$\zeta_a(T) = 2.650545 + 2306.083227*T + 0.2988499 * T^2 + 0.1801828*T^3 + Higher\space Order\space Terms\\ z_a(T) = -2.650545 + 2306.077181*T + 1.0927348 * T^2 + 0.1826837*T^3 + Higher\space Order\space Terms\\ \theta_a(T) = 2004.191903 * T - 0.4294934 * T^2 - 0.04182264 * T^3 + Higher\space Order\space Terms\\$$$$

Look in my github repo under toluene/config/config.yml for the complete definition of the coefficients.

Now we get into nutation. This one is very complicated and I suggest this reading. Page 45 and 46 in the reading have definitions for psi and epsilon you'll need. Has the added bonus of the nutation series you'll need at the bottom. Page 225 of the book has the nutation rotation matrix from Emerson 1973.

$$$$N= \begin{pmatrix} cos(\Delta\psi) & -sin(\Delta\psi)cos(\epsilon_a) & -sin(\Delta\psi)sin(\epsilon_a) \\\ sin(\Delta\psi)cos(\epsilon) & cos(\Delta\psi)cos(\epsilon)cos(\epsilon_a)+ sin(\epsilon)sin(\epsilon_a) & cos(\Delta\psi)cos(\epsilon)sin(\epsilon_a)-sin(\epsilon)cos(\epsilon_a) \\\ sin(\Delta\psi)sin(\epsilon) & cos(\Delta\psi)sin(\epsilon)cos(\epsilon_a)- cos(\epsilon)sin(\epsilon_a) & cos(\Delta\psi)sin(\epsilon)sin(\epsilon_a) + cos(\epsilon)cos(\epsilon_a) \end{pmatrix}$$$$

where

$$$$\epsilon=\epsilon_a+\Delta\epsilon$$$$

epsilon_a is a function of time in julian centuries and is given in arc seconds also. The config file I was talking about earlier has the coefficients for epsilon_a also.

$$$$\epsilon_a(T) = 84381.406000 - 46.836769T - 0.0001831T^2 + 0.00200340T^3 - 0.000000576T^4 - 0.0000000434T^5$$$$

Look in the paper for the definitions of Delta psi and Delta epsilon.

I won't really go into the matrix T as Jai Willems answer and the discussion beneath should be sufficient and this response is already dragging on.

Polar motion is pretty negligible in most cases. Example in matlab you need to tell ecef2eci to account for it manually as it doesn't do it by default. If you're really curious I won't drag on my answer any longer and tell you to look here. It completely relies on up to date observation data that could be found there.

As for ECEF to ECI you compute all the matricies the same way and take their transpose as they're orthogonal.

To anyone crazy enough to read the insanity I went through and still want to compute ECI to ECEF, I hope you find this helpful, and best of luck.

• Welcome! And thanks!
– Ludo
Nov 27, 2023 at 15:18

The ECI and ECEF frames have approximately the same origin and $$z$$ axis and only differ by an angular component on the $$xy$$ plane. This angular difference can be used to rotate a vector from one frame to the other.

The $$x_{ECEF}$$ axis rotates along the equatorial plane about $$z_{ECI}=z_{ECEF}$$. The angle that it makes with the $$x_{ECI}$$ axis is known as the Earth Rotation Angle (ERA) or Greenwich Sidereal Angle. To convert between ECI and ECEF frames, we must first gain the ERA denoted as $$\gamma\in[0, 2\pi]$$.

We begin at an epoch, say J2000, where the ERA is known to be $$280.46$$ degrees. Using the elapsed time since epoch, we can propagate the epoch ERA through time to a date of interest. Stated mathematically in the following block equation, the Earth rotation rate is given by $$360.985...$$ degrees per day, $$\Delta T$$ is the elapsed time in days since the epoch, and $$280.46$$ is the ERA at $$\Delta T=0$$.

$$$$\label{eqERA} \gamma = 360.9856123035484\times\Delta T + 280.46$$$$

To convert a vector between the ECI and ECEF frames requires rotating the vector about the $$z$$-axis by the Greenwich Sidereal Angle, $$\gamma$$, using the rotational matrix given in the following block equation. These conversions can be seen in equations the final two equations where $$\mu_{C'}^C$$ converts coordinates from frame $$C$$ to frame $$C'$$.

$$$$\label{eqEz} E_3^\theta = \begin{pmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \\ \end{pmatrix}$$$$

$$$$\label{eqECEF2ECI} \vec{V}_{ECI} = \mu_{ECI}^{ECEF}\;\vec{V}_{ECEF} = E_3^\gamma\;\vec{V}_{ECEF}$$$$ $$$$\label{eqECI2ECEF} \vec{V}_{ECEF} = \mu_{ECEF}^{ECI}\;\vec{V}_{ECI} = E_3^{-\gamma}\;\vec{V}_{ECI}$$$$

• This is a good approximation, but technically not correct. ECI and ECEF do NOT have the Z axis aligned. They differ by the precession and nutation of the earth's axis. If you don't take this into account your transformation will be off by kilometers on the surface of the earth. Certainly not correct if you are going out of the way to establish your ECI frame as J2000. Jun 8, 2021 at 18:29
• You make a good point Carlos, although for some applications, such an approximation can still be valid. A team I am a part of are applying this algorithm to a cube satellite mission taking images of ground locations. Validating against the Astropy library, this method has a 100% accuracy with a tolerance of ~13 km. This error is apparently large but is only a 0.2% change in the overall ECEF coordinates. Although, now that you have made me aware off this, I am going to look into incorporating such effects into our approach. Thanks! Jun 9, 2021 at 18:07
• I would just recommend using SPICE to do all your heavylifting here! spiceypy.readthedocs.io/en/main naif.jpl.nasa.gov/naif
– Shen
Mar 29, 2022 at 18:34
• I don't think this transformation is correct actually. I think since theta and velocity are changing with respect to time, you have to add a "dTheta * dE3" term. May 11, 2022 at 18:12