Closed tmamedzadeh closed 5 years ago
Hi @Tarlan0001 ,
Currently, SatelliteToolbox.jl has functions to compute the rotation description (DCM or Quaternion) between the coordinate frames supported. Hence, you can represent the velocity in ECEF using the same matrix. However, I think that what you want is to change the time-derivative so that it is computed also with respect to the ECEF. In this case, you have to account for the Earth rotation rate.
So, let's say you have a position and velocity vector in J2000 reference frame and want to convert to PEF. Then you can do the following:
r_j2000 = [5102.50960000; 6123.01152000; 6378.13630000]
v_j2000 = [-4.7432196000; 0.7905366000; 5.5337561900]
# Earth rotation rate.
w = 7.292115146706979e-5
# Compute the rotation between J2000 to PEF at 2004-04-06 7:51:28.386009 UTC.
D_PEF_J2000 = rECItoECEF(J2000(), PEF(), DatetoJD(2004, 4, 6, 7, 51, 28.386009))
# Compute the position represented in ECEF.
r_pef = D_PEF_J2000*r_j2000
# Compute the velocity represented in ECEF and measured w.r.t. the same reference frame.
v_pef = D_PEF_J2000*v_j2000 - [0;0;w] × r_pef
If you want more precision, then you need to use EOP data to compute the Earth rotation rate:
eop = get_iers_eop()
LOD = eop.LOD[DatetoJD(2004, 4, 6, 7, 51, 28.386009)]
w = 7.292115146706979e-5*(1-LOD/86400)
Notice that if your desired ECEF is not PEF, then you should convert to PEF first (because we know how the Earth rotation vector is represented in this reference frame) and then convert to ITRF using rECEFtoECEF
.
I will leave your issue open so that I can add a function to automatically convert position, velocity, and acceleration between ECI and ECEF.
Thank you! A few questions:
rECEFtoECEF
conversion?
- How to convert velocity in rECEFtoECEF conversion?
In this case, you are converting PEF to ITRF, which are almost aligned. The difference is just the polar motion. Hence, you can neglect this movement and just convert using the rotation matrix, as if the relative angular velocity between both systems is zero.
- How to convert acceleration?
In this case, you just need to use the usual equation to convert the acceleration from one reference frame to another one in which there is relative angular movement between them. IIRC, this should be:
a_pef = D_PEF_J2000*a_j2000 - [0;0;w] × [0;0;w] × r_pef - 2*[0;0;w] × v_pef
(please, check this equation!)
- Does your conversion to ECI (from PEF or ITRF) consider polar motion?
This depends. If you are converting J2000 to PEF using rECItoECEF
, then it will not consider the polar motion because it will use the original IAU-76/FK5 theory. However, if the ECI frame is GCRF, TOD, or MOD and/or the ECEF frame is ITRF, then the polar motion will be taken into account.
Thanks a lot!
Also, y
and ECEF_ECI(ECI_ECEF(y,date),date)
gives slightly different velocities:
function harmonics(y,date)
println(y,ECEF_ECI(ECI_ECEF(y,date),date))
end
function ECEF_ECI(y,date)
LOD = eop.LOD[date]
e_vel = 7.292115146706979e-5*(1-LOD/86400)
D_GCRF_ITRF = rECEFtoECI(PEF(), GCRF(), date, eop)
r_gcrf = D_GCRF_ITRF*y[1:3]
v_gcrf = D_GCRF_ITRF*y[4:6] + [0;0;e_vel] × r_gcrf
return [r_gcrf; v_gcrf]
end
function ECI_ECEF(y,date)
LOD = eop.LOD[date]
e_vel = 7.292115146706979e-5*(1-LOD/86400)
D_GCRF_ITRF = rECItoECEF(GCRF(), PEF(), date, eop)
r_gcrf = D_GCRF_ITRF*y[1:3]
v_gcrf = D_GCRF_ITRF*y[4:6] - [0;0;e_vel] × r_gcrf
return [r_gcrf; v_gcrf]
end
harmonics(y,date)
[-9.76307e5, -4.83563e6, -5.03173e6, -794.400, 5474.53, -5094.50]
[-9.76307e5, -4.83563e6, -5.03173e6, -794.408, 5470.96, -5091.06]
Also, y and ECEF_ECI(ECI_ECEF(y,date),date) gives slightly different velocities:
Notice that the vectors in the operation [0;0;e_vel] × r_gcrf
must be represented in PEF. In ECI_ECEF
this is right. However, in ECEF_ECI
you are mixing vectors represented in PEF with vectors represented in GCRF inside the operations. In this case, the velocity equation must be:
v_gcrf = D_GCRF_ITRF*(y[4:6] + [0;0;e_vel] × y[1:3])
In this case:
[-976307.0, -4.83563e6, -5.03173e6, -794.4, 5474.53, -5094.5]
[-976307.0, -4.83563e6, -5.03173e6, -794.4, 5474.53, -5094.5]
If acceleration conversion to ECEf is
a_pef = D_PEF_J2000*a_j2000 - [0;0;w] × [0;0;w] × r_pef - 2*[0;0;w] × v_pef
Then acceleration to ECI is
a_j2000 = D_J2000_PEF*(y[7:9] + [0;0;w] × [0;0;w] × y[1:3] + 2*[0;0;w] × y[4:6])
Probably, the equation is wrong. It gave me -1.09E-2
acceleration, conversion to ECI even gave -8.1E-1
, but it should be less.. I couldn't check the equation...
When converting ECEFtoECEF acceleration also wouldn't change?
Your equations seem right. Can you please post a working code so that I can analyze?
When converting ECEFtoECEF acceleration also wouldn't change?
No, because you can consider that there is no relative angular velocity between PEF and ITRF.
Your equations seem right. Can you please post a working code so that I can analyze?
Yes. I would explain what I'm going to do: I'm calculating the acceleration by zonal harmonics (J2). I'm converting the state to ECEF, calculate acceleration and convert it back to ECI.
function harmonics(y,date)
y_ecef=ECI_ECEF([y;[0,0,0]],date)[1:6]
re2=y_ecef[1]^2 + y_ecef[2]^2 + y_ecef[3]^2
re3=re2^(3/2)
w = 1.5*J2*(Req^2/re2)*(1 - 5*y_ecef[3]^2/re2)
w2 = 1.5*J2*(Req^2/re2)*(3 - 5*y_ecef[3]^2/re2)
acc= [-GMe*y_ecef[1]*w/re3, -GMe*y_ecef[2]*w/re3, -GMe*y_ecef[3]*w2/re3]
return ECEF_ECI([y_ecef;acc],date)[7:9]
end
function ECEF_ECI(y,date)
LOD = eop.LOD[date]
e_vel = 7.292115146706979e-5*(1-LOD/86400)
D = rECEFtoECI(PEF(), GCRF(), date, eop)
r = D*y[1:3]
v = D*(y[4:6] + [0;0;e_vel] × y[1:3])
a = D*(y[7:9] + [0;0;e_vel] × [0;0;e_vel] × y[1:3] + 2*[0;0;e_vel] × y[4:6])
return [r;v;a]
end
function ECI_ECEF(y,date)
LOD = eop.LOD[date]
e_vel = 7.292115146706979e-5*(1-LOD/86400)
D = rECItoECEF(GCRF(), PEF(), date, eop)
r = D*y[1:3]
v = D*y[4:6] - [0;0;e_vel] × r
a = D*y[7:9] - [0;0;e_vel] × [0;0;e_vel] × r - 2*[0;0;e_vel] × v
return [r;v;a]
end
Your equations seem fine. What is the problem you are seeing?
EDIT: Ops, if I am correct, this acceleration you are computing is measured in inertial reference frame. Hence, you only need to convert the representation to ECI. I mean, the observed acceleration due to ECEF rotation is not taken into account there, only the gravitational acceleration by J2 zonal harmonic. My conclusion was obtained by thinking in a satellite on geostationary orbit. In this case, the acceleration of this satellite as seen by an observer on the Equator would be 0 (the satellite will not move with respect to the observer). However, your equations in ECEF will not be 0.
Sorry, I didn't understand. The equation a = D*(y[7:9] + [0;0;e_vel] × [0;0;e_vel] × y[1:3] + 2*[0;0;e_vel] × y[4:6])
considers the ECEF rotation when converting to ECI.
What change do you suggest in the code?
Yes. The last two terms basically convert an acceleration measured by an observer in ECEF to what an observer in ECI would have measured. Since your equation is computing the gravitational force due to Earth mass, it is already measured in an inertial frame, but represented in the ECEF. Then, if I am right, you just need to:
a = D*y[7:9]
To make this clear: the equation that computes a
provides a non-zero vector. On the other hand, for an observer in ECEF on the equator, a geostationary satellite (with inclination 0) would have a = [0;0;0]
and v = [0;0;0]
. Hence, it am almost sure that your equation that computes the acceleration is already measuring it with respect to ECI but it is represented in ECEF.
You are great!
Thanks :) If you need something, please ask! I will let this bug open to add a function to automatically convert r
and v
between reference frames.
And a
, please)
When are you planning this?
Sorry @Tarlan0001 , did not see your comment.
I am a little confused how to add the acceleration. The conversion between position and velocity is well known. You convert the orbit elements to state-vector (r
and v
), which are represented in ECI, and then transform to ECEF. The acceleration is a little trick. One problem is what you saw. Normally, the acceleration is measured in ECI but just represented in ECEF. I am not sure how to handle this. Any ideas?
I just make like this:
a_pef = D*y[7:9]
for ITRF->PEF
It gives, as I think, correct result.
@Tarlan0001
I talked to some friends and this is not really the default. Sometimes people will want to convert not only the representation, but also the frame in which the acceleration is measured, sometimes not. Hence, the result is correct for your case, but I am not sure if everyone will use this conversion as you are. I have to think more about it. Maybe, I need to add options for the user select if he/she wants to change the frame in which the derivative is being obtained.
Hi! Have you worked on the direct transformation of J2000->ITRF? Currently, the function transforms to PEF.
Hi @Tarlan0001 ,
I am not sure if I understood your question. The J2000 -> ITRF is working for rotating vectors:
eop = get_iers_eop_iau_1980("https://datacenter.iers.org/data/latestVersion/222_EOP_C04_14.XX.IAU1980222.txt")
D = rECItoECEF(J2000(), ITRF(), DatetoJD(2017,1,1,0,0,0), eop)
r_j2000 = [100;100;100]
r_itrf = D*r_j2000
Previously You suggested me to convert to PEF first and then from PEF to ITRF. Something changed?
Ah, I suggested you to convert to PEF
first in order to change the reference frame in which the velocity is measured. I think I understood what you asked now.
No, we still do not have an automatic conversion of the velocity vectors considering the change in the reference frame used to take the derivative.
This will be a little bit difficult, I think, because of the high number of reference frames we need to account for. I will think a little bit about it.
Do you want a function in which you pass the position, velocity, and acceleration in a ECI frame and it converts everything to an ECEF frame right? By converting I mean represent the vectors in the new frame and also change the reference frame in which the derivatives are take.
Yes, I need to convert the velocity and acceleration vectors from ECEF to ECI and vice versa.
Hi @Tarlan0001 !
After a very long wait (sorry...) I finally had time to implement this feature. We now have a structure to store the satellite state vector: SatelliteStateVector
, which has the position, velocity, and acceleration. Thus, the conversion between frames can now be done by:
julia> orb = Orbit(DatetoJD(2018,3,22,0,0,0), 42164e3, 0.0, 0.0, 0.0, 0.0, 0.0);
julia> sv_J2000 = kepler_to_sv(orb);
julia> sv_J2000.a = -m0/(norm(sv_J2000.r)^3)*sv_J2000.r
3-element SArray{Tuple{3},Float64,1,3}:
-0.22420958065533492
-0.0
-0.0
julia> sv_PEF = svECItoECEF(sv_J2000, J2000(), PEF(), sv_J2000.t);
julia> sv_PEF.r
3-element SArray{Tuple{3},Float64,1,3}:
-4.216000453942691e7
-575759.6147109803
73580.57875642928
julia> sv_PEF.v
3-element SArray{Tuple{3},Float64,1,3}:
0.0001549895587729111
-0.02353402210155764
-0.0953455261482022
julia> sv_PEF.a
3-element SArray{Tuple{3},Float64,1,3}:
-6.828454350002497e-7
1.4943389583025247e-8
-0.0003912691088927961
Notice that kepler_to_sv
, which converts orbit elements to position and velocity does not compute the acceleration.
If you can, please, test and let me know if everything is working. You can convert between any frame that is supported in this package using the functions svECItoECI
, svECItoECEF
, svECEFtoECI
, and sECEFtoECEF
.
Would like to mention here that SatelliteStateVector
is seems to be renamed to OrbitStateVector
.
Yes! We renamed it sometime ago :)
Actually, SatelliteToolbox is still going through a bump road :D API will change more often than I like. In this case, try to stick to a version (we follow semantic versioning here).
I have converted the coordinates from ECEF to ECI. How to convert velocities also?