Documente Academic
Documente Profesional
Documente Cultură
Funcin ode45.m
La funcin ode45 de Matlab nos permite resolver ecuaciones diferenciales y
sistemas de ecuaciones diferenciales por medio de mtodos numricos
basndose en el mtodo de Dormand-Prince. Este mtodo numrico de siete
etapas, pertenece a la familia de mtodos Runge-Kutta, y permite calcular
soluciones de cuarto y quinto orden. Evala seis veces la funcin por paso,
debido a que la etapa siete de un paso se evala en el mismo punto que el
primero del paso siguiente. Es un mtodo muy adecuado usar en interpolacin
local (cuando la solucin de orden superior es utilizada para continuar la
integracin) debido a que minimiza el error de la solucin de quinto orden a
diferencia de mtodos como el de Fehlberg que lo hace para la solucin de
cuarto orden.
La sintaxis en Matlab es:
[ t , x ] =ode 45 (odefun ,tspan , x 0, options , params)
x:
t:
Vector tiempo
odefun: Nombre de la funcin
tspan : Se pasa a la funcin el intervalo deseado de tiempo. Puede
especificarse como dos valores de tiempo (inicial y final) mediante la sintaxis
tspan=[ti , tf ] o bien puede especificarse los instantes en los que se quieren
los valores de las variables dependientes como tspan=[ t 0, t 1, tn ] .
x 0 : Vector de valores iniciales
options :
Funcin Vectorperifocal.m
La funcin Vectorperifocal nos va a computar el vector de estado (r,v) en el
marco geocntrico ecuatorial a partir de los elementos orbitales definidos por
el vector [coe].
Los elementos orbitales necesarios que hay que pasar a la funcin como datos
iniciales son:
h: momento angular (km^2/s)
e: excentricidad
h
= momento angular (km^2/s)
e
= excentricidad
RA
= ascension recta del nodo ascendente (rad)
i
= inclinacion de la orbita (rad)
w
= argumento del perigeo (rad)
TA
= anomalia verdadera (rad)
R3_w - Matriz de rotacion sobre el eje-z a traves del angulo w
R1_i - Matriz de rotacion sobre el eje-x a traves del angulo i
R3_W - Matriz de rotacion sobre el eje-z a traves del angulo RA
Q_pX - Matriz de transformacion del marco de referencia perifocal al
marco de referencia ecuatorial
rp
- vector de posicion en el marco perifocal (km)
vp
- vector de velocidad en el marco perifocal (km/s)
r
- vector de posicion en el marco geocentrico ecuatorial (km)
v
- vector velocidad en el marco geocentrico ecuatorial (km/s)
%}
% ---------------------------------------------global mu;
mu=398600;
h
e
RA
i
w
TA
=
=
=
=
=
=
coe(1);
coe(2);
coe(3);
coe(4);
coe(5);
coe(6);
0
cos(i)
-sin(i)
R3_w = [ cos(w)
-sin(w)
0
0
sin(i)
cos(i)];
sin(w)
cos(w)
0
0
0
1];
Funcin vectorestadotiempo.m
La funcin vectorestadotiempo va a calcular el vector de estado [R,V] en el
marco de referencia geocntrico ecuatorial a partir de un vector de estado
inicial [r0,v0] en el marco de referencia ecuatorial pasado un intervalo de
tiempo t.
Los valores de entrada de la funcin son:
1 Un vector de posicin inicial R0 de una fila y tres columnas
2 Un vector de velocidad inicial V0 de una fila y tres columnas
3 Un valor del intervalo de paso de tiempo t.
Esta funcin requiere las funciones adicionales Kepler.m y
coeficientesdeLagrange.m que son explicadas a continuacin de esta.
Los pasos de esta funcin son los siguientes:
1 Calcula los valores necesarios de velocidad inicial radial y el inverso del
semieje mayor necesarios para computar la anomala universal.
2 Calculo de la anomala universal mediante la funcin Kepler.m
3 Calculo de los coeficientes de Lagrange, sus derivadas y el vector de
posicin final R mediante la funcin coeficientesdeLagrange.m
Funcin Kepler.m
La funcin Kepler nos permite resolver la ecuacin de Kepler universal para
la anomala universal vista en el captulo 2 a travs del mtodo iterativo
explicado de Newton.
Los parmetros iniciales requeridos por la funcin son:
a: semieje mayor
vro: velocidad inicial radial
ro: norma del vector de posicin R0
end
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Funcin Stumpff.m
Permite2 evaluar las funciones C(z) y S(z) de Stumpff para un valor de entrada
z= .
Los valores de entrada necesarios son el valor de z.
Devuelve dos valores:
1 C: Evaluacin de la funcin C(z).
2 S: Evaluacin de la funcin S(z).
El cdigo puede verse a continuacin:
function [C,S] = stumpff(z)
%
%
% Esta funcion evalua las funciones C(z) y S(z) de Stumpff
%
% z - argumento de entrada
% C - Valor de salida de C(z)
% S - Valor de salida de S(z)
% -----------------------------------------------------------if z > 0
C = (1 - cos(sqrt(z)))/z;
S = (sqrt(z) - sin(sqrt(z)))/(sqrt(z))^3;
elseif z < 0
C = (cosh(sqrt(-z)) - 1)/(-z);
S = (sinh(sqrt(-z)) - sqrt(-z))/(sqrt(-z))^3;
else
C = 1/2;
S = 1/6;
end
Funcin coeficientesdeLagrange.m
Esta funcin permite computar los coeficientes de Lagrange, sus derivadas y
el vector de posicin R final para usar con la funcin
Vectorestadotiempo.m.
Los valores necesarios a introducir en la funcin como parmetros de entrada
son:
1 La anomala universal tras un tiempo t (procedente de la solucin de la
ecuacin de Kepler descrita anteriormente).
2 El inverso del semieje mayor
3 La posicin radial para el instante to inicial
Funcin eul2quat.m
La funcin eul2quat convierte los ngulos de Euler en un cuaternin.
La funcin pide como parmetros de entrada 3 valores respectivos para los
tres ngulos de Euler y devuelve un vector con el cuaternin o bien tres
%Salida:
%
q: Cuaternion correspondiente a la rotacion descrita por los
angulos de Euler.
%}
%Redefiniendo fi, teta y chi en radianes
%Calculo del cuaternion
for i = 1:length(e1)
q(i,:) = [cos(e2(i)/2)*cos((e1(i) + e3(i))/2);
-sin(e2(i)/2)*sin((e1(i) - e3(i))/2); sin(e2(i)/2)*cos((e1(i) e3(i))/2); cos(e2(i)/2)*sin((e1(i) + e3(i))/2)]';
end
Funcin quat2eul.m
La funcin quat2eul permite convertir los cuaterniones a ngulos de Euler por
medio de las relaciones trigonomtricas existentes entre ellos y vistas a lo
largo del proyecto. El cdigo es el siguiente:
%------------------------------------------------------------------------function [euler] = quat2eul(q)
%
%Funcion que convierte los cuaterniones a angulos de euler.
%
%Entrda
% Una matriz 4 x n de cuaterniones
%
%%Salida
%
euler: una matriz n x 3 de angulos de Euler correspondientes al
cuaternion introducido
% (fi teta chi)
%
%Relaciones trigonometricas usadas:
%q0 = cos((fi+chi)/2)cos(teta/2);
%q1 = cos((fi-chi)/2)sin(teta/2);
%q2 = sin((fi-chi)/2)sin(teta/2);
%q3 = sin((fi+chi)/2)cos(teta/2);
%
%Separacion del cuaternion en componentes
q0 = q(1,:);
q1 = q(2,:);
q2 = q(3,:);
q3 = q(4,:);
%Calculo de fi + chi y fi - chi
p1pp2 = atan2(q3,q0);
p1mp2 = atan2(q2,q1);
%Calculo de los angulos de Euler
chi = p1pp2 - p1mp2;
teta = 2*atan2(sqrt(q1.^2+q2.^2),sqrt(q0.^2+q3.^2));
fi = p1pp2 + p1mp2;
%Si el segundo angulo de Euler es cero entonces todas las rotaciones
pueden
%ser dadas por el primero o ultimo angulo de Euler
tetacero = abs(teta)<=1E-13;
%Tratar q1<0 cambiando el signo al cuaternion
changeref = ones(size(q0(tetacero)));
changeref(q0(tetacero)<0) = -1;
%Rotacion en torno a chi
chi(tetacero) = 2*asin(max(-1,min(1,changeref).*q3(tetacero)));
fi(tetacero) = 0;
%Salida en radianes
euler = [fi' teta' chi'];
end
%-------------------------------------------------------------------------
Funcin magfield.m
La funcin magfiel.m nos va a permitir calcular el vector campo magntico
terrestre en una ubicacin y una poca a partir del modelo WMM descrito en
el captulo 4. Los valores de entrada al programa son un vector de posicin, la
fecha exacta [ao, mes, dia, hora, minuto, segundo] el grado de expansin
% Note: this program was converted from FORTRAN code provided by the
% National Geophysical Data Center. See
http://www.ngdc.noaa.gov/seg/WMM/.
% Epoch
epoch=2015.00;
% Load Data for 2015
wmm=wmm2015_data;
% Constants for Degrees/Radians Conversions
dtr=pi/180;
rtd=180/pi;
% Get Length of Data
[mout,mout3]=size(r);
if mout3~=3, disp('r must be (m x 3)');end
% Initialize Field Vectors
bt_store=zeros(mout,1);br_store=zeros(mout,1);bp_store=zeros(mout,1);
t=[0:dt:(mout-1)*dt]';
% Convert from ECI to Lat, Long and Height if Needed
if type == 1
r_ecef=eci2ecef(r,yr,mth,day,hr,min,sec+t);
[lat,long,height]=ecef2llh(r_ecef);height=height/1000;
end
% Convert from ECEF to Lat, Long and Height if Needed
if type == 2
[lat,long,height]=ecef2llh(r);height=height/1000;
end
% Get Lat, Long and Height
if type == 3
lat=r(:,1);
long=r(:,2);
height=r(:,3)/1000;
end
% Convert to Radians
rlon=long*dtr;
rlat=lat*dtr;
% Get Sidereal Time and Ascending Node
theta=sidereal(yr,mth,day,hr,min,sec+t)*dtr;
alpha=rlon+theta;
c_alpha=cos(alpha);s_alpha=sin(alpha);
% Leap Year
if (mod(yr,400)&&~mod(yr,100))
% leapyear = false;
ndays = 365;
elseif ~mod(yr,4)
% leapyear = true;
ndays = 366;
else
% leapyear = false;
ndays = 365;
end
% Get Days Past First of Year
o1=ones(mout,1);
day_of_year = datenum(yr*o1,mth*o1,day*o1,hr*o1,min*o1,sec+t)datenum(yr,1,1);
% Find Days That Go Into Next Year
i_days=find(day_of_year > ndays);
% Get Decimal Year Time
if isempty(i_days) == 1
time = yr + day_of_year/ndays;
else
% Check Leap Year of New Year
time = yr + day_of_year/ndays;
yr_new=floor(time(i_days(1)));
if (mod(yr_new,400)&&~mod(yr_new,100))
% leapyear = false;
ndays_new = 365;
elseif ~mod(yr_new,4)
% leapyear = true;
ndays_new = 366;
else
% leapyear = false;
ndays_new = 365;
end
time=zeros(mout,1);
time(1:i_days(1)-1) = yr + day_of_year(1:i_days(1)-1)/ndays;
time(i_days(1):mout) = yr + (day_of_year(i_days:mout)ndays+ndays_new)/ndays_new;
end
% Get Spherical Harmonic Coefficients from Data
c=zeros(13,13);cd=zeros(13,13);
for i=1:length(wmm)
n=wmm(i,1);
m=wmm(i,2);
if (m <= n)
c(n+1,m+1)=wmm(i,3);
cd(n+1,m+1)=wmm(i,5);
end
if (m ~= 0)
c(m,n+1)=wmm(i,4);
cd(m,n+1)=wmm(i,6);
end
end
% Convert Schmidt Normalized Gauss Coefficients to Unnormalized
snorm=zeros(mln+1,mln+1);
k=zeros(mln+1,mln+1);
fn=zeros(mln+1,1);
fm=zeros(mln+1,1);
snorm(1,1)=1;
for n=2:mln+1
snorm(n,1)=snorm(n-1,1)*(2*(n-1)-1)/(n-1);
j=2;
for m=1:n
k(n,m)=((n-2)^2-(m-1)^2)/((2*(n-1)-1)*(2*(n-1)-3));
if m > 1
flnmj=((n-m+1)*j)/(n+m-2);
snorm(n,m)=snorm(n,m-1)*sqrt(flnmj);
j=1;
c(m-1,n)=snorm(n,m)*c(m-1,n);
cd(m-1,n)=snorm(n,m)*cd(m-1,n);
end
c(n,m)=snorm(n,m)*c(n,m);
cd(n,m)=snorm(n,m)*cd(n,m);
end
fn(n)=n;
fm(n)=n-1;
end
k(2,2)=0;
% Constant for WGS-84
a=6378.137;
b=6356.7523142;
re=6371.2;
a2=a^2;
b2=b^2;
c2=a2-b2;
a4=a2^2;
b4=b2^2;
c4=a4-b4;
% Sine and Cosine of Lat and Long
srlon=sin(rlon);
srlat=sin(rlat);
crlon=cos(rlon);
crlat=cos(rlat);
srlon2=srlon.^2;
srlat2=srlat.^2;
crlon2=crlon.^2;
crlat2=crlat.^2;
% Convert from Geodetic to Spherical Coordinates
q=(a2-c2*srlat2).^(0.5);
q1=height.*q;
q2=((q1+a2)./(q1+b2)).^2;
ct=srlat./((q2.*crlat2+srlat2).^(0.5));
st=(1-ct.^2).^(0.5);
r2=height.^2+2*q1+(a4-c4*srlat2)./(q.^2);
r=(r2).^(0.5);
d=(a2*crlat2+b2*srlat2).^(0.5);
ca=(height+d)./r;
sa=c2*crlat.*srlat./(r.*d);
% Main Loop
for i = 1:mout
% Update Time
dt_change=time(i)-epoch;
% Initialize Quantities
sp=zeros(13,1);
cp=zeros(13,1);
p=zeros(13,13);
dp=zeros(13,13);
pp=zeros(13,1);
p(1,1)=1;
pp(1)=1;
dp(1,1)=0;
sp(1)=0;
cp(1)=1;
sp(2)=srlon(i);
cp(2)=crlon(i);
for m=3:mln+1;
sp(m)=sp(2)*cp(m-1)+cp(2)*sp(m-1);
cp(m)=cp(2)*cp(m-1)-sp(2)*sp(m-1);
end
aor=re/r(i);
ar=aor^2;
br=0;
bt=0;
bp=0;
bpp=0;
tc=zeros(mln+1,mln+1);
% Loop for n and m
for n=2:mln+1
ar=ar*aor;
for m=1:n
% Compute Unnormalized Associated Legendre Polynomials and Derivatives
if (n == m)
p(n,m)=st(i)*p(n-1,m-1);
dp(n,m)=st(i)*dp(n-1,m-1)+ct(i)*p(n-1,m-1);
elseif (n == 2) & (m == 1)
p(n,m)=ct(i)*p(n-1,m);
dp(n,m)=ct(i)*dp(n-1,m)-st(i)*p(n-1,m);
elseif (n > 2) & (n ~= m)
if (m > n-2)
p(n-2,m)=0;
dp(n-2,m)=0;
end
p(n,m)=ct(i)*p(n-1,m)-k(n,m)*p(n-2,m);
dp(n,m)=ct(i)*dp(n-1,m)-st(i)*p(n-1,m)-k(n,m)*dp(n-2,m);
end
% Time Adjust the Gauss Coefficients
tc(n,m)=c(n,m)+dt_change*cd(n,m);
if (m ~= 1)
tc(m-1,n)=c(m-1,n)+dt_change*cd(m-1,n);
end
% Accumulate Terms of the Spherical Harmonic Expansions
par=ar*p(n,m);
if (m == 1)
temp1=tc(n,m)*cp(m);
temp2=tc(n,m)*sp(m);
else
temp1=tc(n,m)*cp(m)+tc(m-1,n)*sp(m);
temp2=tc(n,m)*sp(m)-tc(m-1,n)*cp(m);
end
bt=bt-ar*temp1*dp(n,m);
bp=bp+fm(m)*temp2*par;
br=br+fn(n)*temp1*par;
% Special Case: North/South Geographic Poles
if (st(i) == 0) & (m == 2)
if (n == 2)
pp(n)=pp(n-1);
else
pp(n)=ct(i)*pp(n-1)-k(n,m)*pp(n-2);
end
parp=ar*pp(n);
bpp=bpp+fm(m)*temp2*parp;
end
end
end
if (st(i) == 0)
bp=bpp;
else
bp=bp/st(i);
end
% Store Field Variables
bt_store(i)=bt;
br_store(i)=br;
bp_store(i)=bp;
end
% Rotate from Spherical to Geodetic Coordinates
b_ned=[-bt_store.*ca-br_store.*sa bp_store bt_store.*sa-br_store.*ca];
% Get ECI Coordinates
brbt=(br_store.*st+bt_store.*ct);
b_eci=[brbt.*c_alpha-bp_store.*s_alpha brbt.*s_alpha+bp_store.*c_alpha
br_store.*ct-bt_store.*st];
% Horizontal, Total Field, Declination and Dip
bh=(b_ned(:,1).^2+b_ned(:,2).^2).^(0.5);
ti=(bh.^2+b_ned(:,3).^2).^(0.5);
dec=atan2(b_ned(:,2),b_ned(:,1))*rtd;
dip=atan2(b_ned(:,3),bh)*rtd;
% Get ECEF Coordinates
b_ecef=eci2ecef(b_eci,yr,mth,day,hr,min,sec+t);
return
function out=wmm2015_data
out=[1
1 1
2 0
2 1
2 2
3 0
-29438.5
0.0
-1501.1
4796.2
-2445.3
0.0
3012.5
-2845.6
1676.6
-642.0
1351.1
0.0
10.7
17.9
-8.6
-3.3
2.4
3.1
0.0
-26.8
0.0
-27.1
-13.3
0.0
3 1
3 2
3 3
4 0
4 1
4 2
4 3
4 4
5 0
5 1
5 2
5 3
5 4
5 5
6 0
6 1
6 2
6 3
6 4
6 5
6 6
7 0
7 1
7 2
7 3
7 4
7 5
7 6
7 7
8 0
8 1
8 2
8 3
8 4
8 5
8 6
8 7
8 8
9 0
9 1
9 2
9 3
9 4
9 5
9 6
9 7
9 8
9 9
10 0
10 1
10 2
10 3
10 4
10 5
10 6
10 7
10 8
10 9
10 10
11 0
11 1
-2352.3
1225.6
581.9
907.2
813.7
120.3
-335.0
70.3
-232.6
360.1
192.4
-141.0
-157.4
4.3
69.5
67.4
72.8
-129.8
-29.0
13.2
-70.9
81.6
-76.1
-6.8
51.9
15.0
9.3
-2.8
6.7
24.0
8.6
-16.9
-3.2
-20.6
13.3
11.7
-16.0
-2.0
5.4
8.8
3.1
-3.1
0.6
-13.3
-0.1
8.7
-9.1
-10.5
-1.9
-6.5
0.2
0.6
-0.6
1.7
-0.7
2.1
2.3
-1.8
-3.6
3.1
-1.5
-115.3
245.0
-538.3
0.0
283.4
-188.6
180.9
-329.5
0.0
47.4
196.9
-119.4
16.1
100.1
0.0
-20.7
33.2
58.8
-66.5
7.3
62.5
0.0
-54.1
-19.4
5.6
24.4
3.3
-27.5
-2.3
0.0
10.2
-18.1
13.2
-14.6
16.2
5.7
-9.1
2.2
0.0
-21.6
10.8
11.7
-6.8
-6.9
7.8
1.0
-3.9
8.5
0.0
3.3
-0.3
4.6
4.4
-7.9
-0.6
-4.1
-2.8
-1.1
-8.7
0.0
-0.1
-6.2
-0.4
-10.4
-0.4
0.8
-9.2
4.0
-4.2
-0.2
0.1
-1.4
0.0
1.3
3.8
-0.5
-0.2
-0.6
2.4
-1.1
0.3
1.5
0.2
-0.2
-0.4
1.3
0.2
-0.4
-0.9
0.3
0.0
0.1
-0.5
0.5
-0.2
0.4
0.2
-0.4
0.3
0.0
-0.1
-0.1
0.4
-0.5
-0.2
0.1
0.0
-0.2
-0.1
0.0
0.0
-0.1
0.3
-0.1
-0.1
-0.1
0.0
-0.2
-0.1
-0.2
0.0
0.0
8.4
-0.4
2.3
0.0
-0.6
5.3
3.0
-5.3
0.0
0.4
1.6
-1.1
3.3
0.1
0.0
0.0
-2.2
-0.7
0.1
1.0
1.3
0.0
0.7
0.5
-0.2
-0.1
-0.7
0.1
0.1
0.0
-0.3
0.3
0.3
0.6
-0.1
-0.2
0.3
0.0
0.0
-0.2
-0.1
-0.2
0.1
0.1
0.0
-0.2
0.4
0.3
0.0
0.1
-0.1
0.0
0.0
-0.2
0.1
-0.1
-0.2
0.1
-0.1
0.0
0.0
11
11
11
11
11
11
11
11
11
11
12
12
12
12
12
12
12
12
12
12
12
12
12
2
3
4
5
6
7
8
9
10
11
0
1
2
3
4
5
6
7
8
9
10
11
12
-2.3
2.1
-0.9
0.6
-0.7
0.2
1.7
-0.2
0.4
3.5
-2.0
-0.3
0.4
1.3
-0.9
0.9
0.1
0.5
-0.4
-0.4
0.2
-0.9
0.0
2.1
-0.7
-1.1
0.7
-0.2
-2.1
-1.5
-2.5
-2.0
-2.3
0.0
-1.0
0.5
1.8
-2.2
0.3
0.7
-0.1
0.3
0.2
-0.9
-0.2
0.7
-0.1
0.1
0.0
0.0
0.0
0.0
0.0
0.0
-0.1
-0.1
0.1
0.0
0.0
0.1
-0.1
0.0
0.1
0.0
0.0
0.0
0.0
0.0
0.0
0.1
0.0
0.1
0.0
0.0
0.1
0.0
-0.1
0.0
-0.1
0.0
0.0
0.0
-0.1
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0];
function [lat,long,height]=ecef2llh(r_ecef)
% [lat,long,height] = ecef2llh(r_ecef)
%
% This program converts ECEF quantities into long, lat and height.
%
% The input is:
%
r_ecef = ECEF quantities in km (m x 3)
%
% The outputs are:
%
lat = geodetic latitude in degrees (m x 1)
%
long = longitude in degrees (m x 1)
%
height = height in meters (m x 1)
% John L. Crassidis 6/7/06
% This program uses a closed-form solution, which is valid as long as
% does not fall within 43 km of the Earth center. Details can be found
at:
% Zhu, J., "Exact Conversion of Earth-Centered-Earth-Fixed Coordinates
to
% Geodetic Coordinates," Journal of Guidance, Control and Dynamics,
% Vol. 16, No. 2, March-April 1993, pp. 389-391.
% Check Size of Input Vector
rad2deg=180/pi;
[mout,mout1]=size(r_ecef);
if mout1 ~= 3
disp(' r_ecef must be m x 3, where m is the total number of points')
end
% Constant for WGS-84
a=6378.137;
b=6356.7523142;
e2=0.00669437999;
% Conversion Parameters
w=(r_ecef(:,1).^2+r_ecef(:,2).^2).^(0.5);
l=e2/2;m=(w/a).^2;n=((1-e2)*r_ecef(:,3)/b).^2;
i=-(2*l^2+m+n)/2;k=l^2*(l^2-m-n);
mnl2=m.*n*l^2;
q=(m+n-4*l^2).^3/216+mnl2;
d=((2*q-mnl2).*mnl2).^(0.5);
beta=i/3-(q+d).^(1/3)-(q-d).^(1/3);
t=((beta.^2-k).^(0.5)-(beta+i)/2).^(0.5)-sign(m-n).*((betai)/2).^(0.5);
w1=w./(t+l);z1=(1-e2)*r_ecef(:,3)./(t-l);
% Compute Longitude
jj0=find((w-r_ecef(:,1))==0);
jj=find((w-r_ecef(:,1))~=0);
long=zeros(mout,1);
if isempty(jj) == 0
long(jj,:)=2*atan((w(jj)-r_ecef(jj,1))./r_ecef(jj,2))*rad2deg;
end
if isempty(jj0) == 0
long(jj0,:)=zeros(length(jj0),1);
end
% Compute Latitude
j0=find(w==0);
j=find(w~=0);
lat=zeros(mout,1);height=zeros(mout,1);
if isempty(j) == 0
lat(j,:)=atan(z1(j)./((1-e2)*w1(j)))*rad2deg;
height(j,:)=sign(t(j)-1+l).*((w(j)-w1(j)).^2+(r_ecef(j,3)z1(j)).^2).^(0.5)*1000;
end
if isempty(j0) == 0
lat(j0)=sign(r_ecef(j0,3))*90;
h(j0)=sign(r_ecef(j0,3))*r_ecef(j0,3)-b;
end
return
function r_ecef=llh2ecef(lat,long,height)
% r_ecef = llh2ecef(lat,long,height)
%
% This program converts long, lat and height into ECEF quantities.
%
% The inputs are:
%
lat = geodetic latitude in degrees (m x 1)
%
long = longitude in degrees (m x 1)
%
height = height in meters (m x 1)
%
% The output is:
%
r_ecef = ECEF quantities in km (m x 3)
% John L. Crassidis 6/7/06
deg2rad=pi/180;
% Get Length of Data
mout=length(lat);
if length(long) ~= mout
disp(' Lat, Long and Height Must Have Same Length')
end
if length(height) ~= mout
disp(' Lat, Long and Height Must Have Same Length')
end
% Constant for WGS-84
a=6378.137;
b=6356.7523142;
e2=0.00669437999;
% Convert Lat and Long to Degrees and Height to Km
lat=lat(:)*deg2rad;
long=long(:)*deg2rad;
height=height(:)/1000;
% Compute ECEF Quantities
n=a./((1-e2*sin(lat).^2).^(0.5));
x=(n+height).*cos(lat).*cos(long);
y=(n+height).*cos(lat).*sin(long);
z=(n*(1-e2)+height).*sin(lat);
r_ecef=[x y z];
return
function r_eci=ecef2eci(r_ecef,yr,mth,day,hr,min,sec)
% r_eci=ecef2eci(r_ecef,yr,mth,day,hr,min,sec)
%
% This program converts ECEF into ECI quantities.
%
% The inputs are:
%
r_ecef = ECEF quantities (m x 3)
%
yr = year (e.g. 2005), can be (m x 1)
%
mth = month, can be (m x 1)
%
day = day, can be (m x 1)
%
hr = hour (0-23), can be (m x 1)
%
min = minute (0-59),can be (m x 1)
%
sec = second (0-59), can be (m x 1)
%
% The output is:
%
r_eci= ECEF quantities (m x 3)
% John L. Crassidis 6/7/06
% Sidereal Time is Computed using Eq. (12.4) from Meeus, J.,
% Astronomical Algorithms, 2nd Edition, Willmann-Bell, Inc.,
% Richmond, VA, 1998.
% Check Size of Input Vector
[mout,mout1]=size(r_ecef);
if mout1 ~= 3
disp(' r_ecef must be m x 3, where m is the total number of points')
end
% Compute Day-of-Year
doy = day + 31*(mth-1) - fix(2.2+0.4*mth).*(mth>2) +
(mth>2).*(~rem(yr,4));
% Compute Julian Date
jd = 2415020 + (yr-1900)*365 + fix((yr-1901)/4) + (doy-1) + 0.5 + ...
(3600*hr + 60*min + sec) / 86400;
% Compute T
t=(jd-2451545)/36525;
% Compute Sidereal Angle
theta=(280.46061837+360.98564736629*(jd-2451545)+0.000387933*t.^2t.^3/38710000)*pi/180;
% Compute ECI Components
cost=cos(theta);sint=sin(theta);
r_eci(:,1)=cost.*r_ecef(:,1)-sint.*r_ecef(:,2);
r_eci(:,2)=sint.*r_ecef(:,1)+cost.*r_ecef(:,2);
r_eci(:,3)=r_ecef(:,3);
return
function r_ecef=eci2ecef(r_eci,yr,mth,day,hr,min,sec)
% r_ecef=eci2ecef(r_eci,yr,mth,day,hr,min,sec)
%
% This program converts ECI into ECEF quantities.
%
% The inputs are:
%
r_eci= ECEF quantities (m x 3)
%
yr = year (e.g. 2005), can be (m x 1)
%
mth = month, can be (m x 1)
%
day = day, can be (m x 1)
%
hr = hour (0-23), can be (m x 1)
%
min = minute (0-59),can be (m x 1)
%
sec = second (0-59), can be (m x 1)
%
% The output is:
%
r_ecef = ECEF quantities (m x 3)
% John L. Crassidis 6/7/06
% Sidereal Time is Computed using Eq. (12.4) from Meeus, J.,
% Astronomical Algorithms, 2nd Edition, Willmann-Bell, Inc.,
% Richmond, VA, 1998.
% Check Size of Input Vector
[mout,mout1]=size(r_eci);
if mout1 ~= 3
disp(' r_eci must be m x 3, where m is the total number of points')
end
% Compute Day-of-Year
doy = day + 31*(mth-1) - fix(2.2+0.4*mth).*(mth>2) +
(mth>2).*(~rem(yr,4));
% Compute Julian Date
jd = 2415020 + (yr-1900)*365 + fix((yr-1901)/4) + (doy-1) + 0.5 + ...
(3600*hr + 60*min + sec) / 86400;
% Compute T
t=(jd-2451545)/36525;
% Compute Sidereal Angle
theta=(280.46061837+360.98564736629*(jd-2451545)+0.000387933*t.^2t.^3/38710000)*pi/180;
% Compute ECEF Components
cost=cos(theta);sint=sin(theta);
r_ecef(:,1)=cost.*r_eci(:,1)+sint.*r_eci(:,2);
r_ecef(:,2)=-sint.*r_eci(:,1)+cost.*r_eci(:,2);
r_ecef(:,3)=r_eci(:,3);
return
function theta=sidereal(yr,mth,day,hr,min,sec)
% theta = sidereal(yr,mth,day,hr,min,sec)
%
% This program computes the mean sidereal time in degrees.
%
% The inputs are:
%
yr = year (e.g. 2005), can be (m x 1)
%
mth = month, can be (m x 1)
%
day = day, can be (m x 1)
%
hr = hour (0-23), can be (m x 1)
%
min = minute (0-59),can be (m x 1)
%
sec = second (0-59), can be (m x 1)
%
% The output is:
%
theta = sidereal time in degrees (m x 3)
% John L. Crassidis 6/7/06
% Sidereal Time is Computed using Eq. (12.4) from Meeus, J.,
% Astronomical Algorithms, 2nd Edition, Willmann-Bell, Inc.,
% Richmond, VA, 1998.
% Compute Day-of-Year
doy = day + 31*(mth-1) - fix(2.2+0.4*mth).*(mth>2) +
(mth>2).*(~rem(yr,4));
% Compute Julian Date
jd = 2415020 + (yr-1900)*365 + fix((yr-1901)/4) + (doy-1) + 0.5 + ...
(3600*hr + 60*min + sec) / 86400;
% Compute T
t=(jd-2451545)/36525;
% Compute Sidereal Angle
theta=280.46061837+360.98564736629*(jd-2451545)+0.000387933*t.^2t.^3/38710000;
mout=length(theta);
% Make Sidereal Angle from -360 to 360 Degrees
if (theta(1)<-360)
theta=theta+abs(fix(theta(1)/360))*360;
end
if (theta(1)>360)
theta=theta-abs(fix(theta(1)/360))*360;
end
return