-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathKPS_State2Kepler.m
148 lines (123 loc) · 3.56 KB
/
KPS_State2Kepler.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% KPS_State2Kepler.m
% KPS
%
% Author: Kareem Omar
% kareem.omar@uah.edu
% https://github.com/komrad36
%
% Last updated Feb 12, 2016
% This application is entirely my own work.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Converts state vectors to Keplerian orbital elements.
%
% A state vector may be directly supplied, OR a single number
% can be supplied - a time in seconds. KPS_State2Kepler will
% search through the most recent KPS run and retrieve the
% first state vector AFTER that time for conversion.
%
function [a, e, w, Omega, i, M] = KPS_State2Kepler(r, v)
% if in time retrieval mode
if isscalar(r) && nargin == 1
% grab data from files
t_val = r;
f_t = fopen('t.bin', 'r');
if (f_t == -1)
error('Failed to open file.')
end %if
t = fread(f_t, Inf, 'double');
% discard last entry in case it is corrupt
% (if it's being written realtime)
t = t(1:end-1);
f_r = fopen('r.bin', 'r');
if (f_r == -1)
error('Failed to open file.')
end %if
r = fread(f_r, Inf, 'double');
r = r(1:3*ceil(numel(r)/3) - 3);
f_v = fopen('v.bin', 'r');
if (f_v == -1)
error('Failed to open file.')
end %if
v = fread(f_v, Inf, 'double');
v = v(1:3*ceil(numel(v)/3) - 3);
fclose('all');
if t_val >= t(1)
for i = 1:numel(t)
if t(i) >= t_val
% found the first time step after requested time
r = r(3*i - 2:3*i);
v = v(3*i - 2:3*i);
fprintf('\nTime: %.14g s\n', t(i))
clear t
break
end %if
end %for
end %if
if exist('t', 'var')
error('Requested time not in range of files!')
end %if
end %if
if numel(r) ~= 3 || numel(v) ~= 3
error('r and v should be Cartesian orbital state 3-vectors, units of meters')
end %if
% Earth gravitational parameter
GM = 398600441800000.0;
rad_to_deg = 180.0/pi;
v_mag = norm(v);
r_mag = norm(r);
% orbital momentum
h = cross(r, v);
% eccentricity vector
e_vec = cross(v, h)/GM-r/r_mag;
% scalar eccentricity
e = norm(e_vec);
% ascending node vector
n = [-h(2), h(1), 0.0];
n_mag = norm(n);
% true anomaly
nu = real(acos(dot(e_vec, r)/(e*r_mag)));
if dot(r, v) < 0.0
nu = 2*pi - nu;
end %if
% inclination
i = real(acos(h(3)/norm(h)));
% eccentric anomaly
E = real(2*atan2(tan(0.5*nu), sqrt((1+e)/(1-e))));
if E < 0
E = E + 2*pi;
end %if
% RAAN
Omega = real(acos(n(1)/n_mag));
if n(2) < 0.0
Omega = 2*pi - Omega;
end %if
% argument of periapsis
w = real(acos(dot(n, e_vec)/(n_mag*e)));
if e_vec(3) < 0.0
w = 2*pi - w;
end %if
% mean anomaly
M = E - e*sin(E);
if M < 0
M = M + 2*pi;
end %if
% semi-major axis
a = 1.0/(2.0/r_mag-v_mag*v_mag/GM);
nu = nu*rad_to_deg;
i = i*rad_to_deg;
E = E*rad_to_deg;
Omega = Omega*rad_to_deg;
w = w*rad_to_deg;
M = M*rad_to_deg;
fprintf('\nPosition Vector: %.14g, %.14g, %.14g m\n', r)
fprintf('Velocity Vector: %.14g, %.14g, %.14g m/s\n', v)
fprintf('True Anomaly: %.14g degrees\n', nu)
fprintf('Mean Anomaly: %.14g degrees\n', M)
fprintf('Eccentric Anomaly: %.14g degrees\n', E)
fprintf('Semi-major Axis: %.14g m\n', a)
fprintf('Eccentricity: %.14g\n', e)
fprintf('Argument of Periapsis: %.14g degrees\n', w)
fprintf('Longitude of Ascending Node: %.14g degrees\n', Omega)
fprintf('Inclination: %.14g degrees\n\n', i)