-
Notifications
You must be signed in to change notification settings - Fork 0
/
ECEF2WGS.m
118 lines (102 loc) · 2.95 KB
/
ECEF2WGS.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Converts vector ocordinates from ECEF frame to WGS84 frame
%
%%% references
% -------------
%[1] 'Aerospace Navigation Systems'; edited by A.V.Nebylv, J.Watson
%
%%% inputs
% ----------
% P : array, size(3,1), vector in ECEF Frame, meters
% deg : int, deg=1 for units in deg
% deg=0 for units in rad
%
%%% outputs
%-----------
% phi : float, latitide, deg or rad
% lambda : float, longitude, deg or rad
% h : altitude, meters
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [phi, lambda, h] = ECEF2WGS(P, deg)
x = P(1);
y = P(2);
z = P(3);
% WGS84 Model
a = 6378137.0; % meters % semi-major axis
b = 6356752.314; % meters % semi-minor axis
e = sqrt(1 - (b^2 / a^2));% eccentricity
%%% Step 1
if (x^2 + y^2) == 0 % if True algorithm stops here
if z > 0
phi = pi/2;
h = z - b;
else % z < 0
phi = -pi/2;
h = -z - b;
end
% return "Longitude cannot be defined", phi, h
lambda = 0;
else
%%% Step 2
% assuming x^2 + y^2 > 0
if x == 0
lambda_ = pi/2;
elseif x > 0
lambda_ = atan(y/x);
elseif x < 0 && y >= 0
lambda_ = pi + atan(y/x);
elseif x < 0 && y < 0
lambda_ = -pi + atan(y/x);
end
%%% Step 3
% sensitivity levels
e_phi = 0.01;
e_h = 0.01;
% starting values
phi_s = pi/2;
d_s = a / sqrt(1 - e^2);
h_s = 0;
%%% Step 4
% computing new values related to the latitude
phi_n = atan2(z*(d_s+h_s) , ((sqrt(x^2 + y^2))*((d_s*(1 - e^2))+h_s)));
d_n = a / sqrt(1 - ((e*sin(phi_n))^2));
%%% Step 5
% computing new altitude value
if phi_n <= pi/4 || phi_n >= -pi/4
h_n = (sqrt(x^2 + y^2)/cos(phi_n)) - d_n;
end
if phi_n > pi/4 || phi_n < -pi/4
h_n = (z/sin(phi_n)) - (d_n*(1 - e^2));
end
%%% Step 6
% Evaluating the convergence of the obtained value for phi
while abs(phi_n - phi_s) >= e_phi && abs(h_n - h_s) >= e_h % if not converged
phi_s = phi_n;
d_s = d_n;
h_s = h_n;
%%% Step 4
% computing new values related to the latitude
phi_n = atan2(z*(d_s+h_s), (sqrt(x^2 + y^2))*(d_s*(1 - e^2) + h_s));
d_n = a / sqrt(1 - ((e*sin(phi_n))^2));
%%% Step 5
% computing new altitude value
if phi_n <= pi/4 || phi_n >= -pi/4
h_n = (sqrt(x^2 + y^2)/cos(phi_n)) - d_n;
end
if phi_n > pi/4 || phi_n < -pi/4
h_n = (z/sin(phi_n)) - (d_n*(1 - e^2));
end
end
% when converged
% abs(phi_n - phi_s) >= e_phi and abs(h_n - h_s) >= e_h
lambda = lambda_; % in radians
phi = phi_n;
h = h_n;
if deg == 1
lambda = rad2deg(lambda_); % in degrees
phi = rad2deg(phi_n);
h = rad2deg(h_n);
end
end
end