Skip to content

Commit 747eb7f

Browse files
Merge pull request utat-ss#1 from max01110/EKG
EKF
2 parents a6a49c4 + 0094688 commit 747eb7f

26 files changed

+553
-0
lines changed

EKF/Dynamics.slx

47.6 KB
Binary file not shown.

EKF/Dynamics.slx.r2021a

36.5 KB
Binary file not shown.

EKF/Dynamics.slxc

5.56 KB
Binary file not shown.

EKF/Eu2Quat.m

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function q = Eu2Quat(phi_theta_psi)
2+
%%%Input is a Nx3 vector and output is a Nx4 vector
3+
4+
phi = phi_theta_psi(1);
5+
theta = phi_theta_psi(2);
6+
psi = phi_theta_psi(3);
7+
8+
q0 = cos(phi/2).*cos(theta/2).*cos(psi/2) + sin(phi/2).*sin(theta/2).*sin(psi/2);
9+
q1 = sin(phi/2).*cos(theta/2).*cos(psi/2) - cos(phi/2).*sin(theta/2).*sin(psi/2);
10+
q2= cos(phi/2).*sin(theta/2).*cos(psi/2) + sin(phi/2).*cos(theta/2).*sin(psi/2);
11+
q3 = cos(phi/2).*cos(theta/2).*sin(psi/2) - sin(phi/2).*sin(theta/2).*cos(psi/2);
12+
13+
q = [q0,q1,q2,q3]';
14+
% Copyright - Carlos Montalvo 2015
15+
% You may freely distribute this file but please keep my name in here
16+
% as the original owner

EKF/Quat2Eu.m

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function ptp = Quat2Eu(q0123)
2+
%%ptp = quat2euler(q0123)
3+
%input is a Nx4 vector with quaternions.
4+
%output is a Nx3 vector of 3-2-1 euler angles
5+
6+
s = size(q0123);
7+
if s(1) == 4 && s(2) == 1
8+
q0123=q0123';
9+
end
10+
q0 = q0123(:,1);
11+
q1 = q0123(:,2);
12+
q2 = q0123(:,3);
13+
q3 = q0123(:,4);
14+
15+
ptp(:,1) = (atan2(2.*(q0.*q1 + q2.*q3),1-2.*(q1.^2 + q2.^2))); %phi
16+
ptp(:,2) = asin(2.*(q0.*q2-q3.*q1)); %theta
17+
ptp(:,3) = atan2(2.*(q0.*q3 + q1.*q2),1-2.*(q2.^2 + q3.^2)); %psi
18+
19+
ptp = real(ptp);
20+
21+
% Copyright - Carlos Montalvo 2015
22+
% You may freely distribute this file but please keep my name in here
23+
% as the original owner

EKF/Satellite.m

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
function dstatedt = Satellite(t,state)
2+
%%genericState = [q0123;p;q;r];
3+
global m invI I
4+
5+
%%select states
6+
q0123 = state(1:4);
7+
p = state(5);
8+
q = state(6);
9+
r = state(7);
10+
pqr = state(5:7);
11+
12+
%%%Rotational Kinematics
13+
%Derivative of Quaternions
14+
PQRMAT = [0 -p -q -r;p 0 r -q;q -r 0 p;r q -p 0];
15+
q0123dot = 0.5*PQRMAT*q0123;
16+
17+
%%%Rotational Dynamics
18+
%%%Total External Disturbance Moments
19+
LMN = [0;0;0];
20+
H = I*pqr;
21+
pqrdot = invI*(LMN - cross(pqr,H));
22+
23+
%%%Return Derivatives State
24+
dstatedt = [q0123dot;pqrdot];
25+
26+
%%%Discretization (check this)
27+
%dt = 1;
28+
%dstatedt_dis = state + dstatedt*dt;
29+
end

EKF/earth_sphere.m

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
function [xx,yy,zz] = earth_sphere(varargin)
2+
%EARTH_SPHERE Generate an earth-sized sphere.
3+
% [X,Y,Z] = EARTH_SPHERE(N) generates three (N+1)-by-(N+1)
4+
% matrices so that SURFACE(X,Y,Z) produces a sphere equal to
5+
% the radius of the earth in kilometers. The continents will be
6+
% displayed.
7+
%
8+
% [X,Y,Z] = EARTH_SPHERE uses N = 50.
9+
%
10+
% EARTH_SPHERE(N) and just EARTH_SPHERE graph the earth as a
11+
% SURFACE and do not return anything.
12+
%
13+
% EARTH_SPHERE(N,'mile') graphs the earth with miles as the unit rather
14+
% than kilometers. Other valid inputs are 'ft' 'm' 'nm' 'miles' and 'AU'
15+
% for feet, meters, nautical miles, miles, and astronomical units
16+
% respectively.
17+
%
18+
% EARTH_SPHERE(AX,...) plots into AX instead of GCA.
19+
%
20+
% Examples:
21+
% earth_sphere('nm') produces an earth-sized sphere in nautical miles
22+
%
23+
% earth_sphere(10,'AU') produces 10 point mesh of the Earth in
24+
% astronomical units
25+
%
26+
% h1 = gca;
27+
% earth_sphere(h1,'mile')
28+
% hold on
29+
% plot3(x,y,z)
30+
% produces the Earth in miles on axis h1 and plots a trajectory from
31+
% variables x, y, and z
32+
% Clay M. Thompson 4-24-1991, CBM 8-21-92.
33+
% Will Campbell, 3-30-2010
34+
% Copyright 1984-2010 The MathWorks, Inc.
35+
%% Input Handling
36+
[cax,args,nargs] = axescheck(varargin{:}); % Parse possible Axes input
37+
error(nargchk(0,2,nargs)); % Ensure there are a valid number of inputs
38+
% Handle remaining inputs.
39+
% Should have 0 or 1 string input, 0 or 1 numeric input
40+
j = 0;
41+
k = 0;
42+
n = 50; % default value
43+
units = 'km'; % default value
44+
for i = 1:nargs
45+
if ischar(args{i})
46+
units = args{i};
47+
j = j+1;
48+
elseif isnumeric(args{i})
49+
n = args{i};
50+
k = k+1;
51+
end
52+
end
53+
if j > 1 || k > 1
54+
error('Invalid input types')
55+
end
56+
%% Calculations
57+
% Scale factors
58+
Scale = {'km' 'm' 'mile' 'miles' 'nm' 'au' 'ft';
59+
1 1000 0.621371192237334 0.621371192237334 0.539956803455724 6.6845871226706e-009 3280.839895};
60+
% Identify which scale to use
61+
try
62+
myscale = 6378.1363*Scale{2,strcmpi(Scale(1,:),units)};
63+
catch %#ok<*CTCH>
64+
error('Invalid units requested. Please use m, km, ft, mile, miles, nm, or AU')
65+
end
66+
67+
% -pi <= theta <= pi is a row vector.
68+
% -pi/2 <= phi <= pi/2 is a column vector.
69+
theta = (-n:2:n)/n*pi;
70+
phi = (-n:2:n)'/n*pi/2;
71+
cosphi = cos(phi); cosphi(1) = 0; cosphi(n+1) = 0;
72+
sintheta = sin(theta); sintheta(1) = 0; sintheta(n+1) = 0;
73+
x = myscale*cosphi*cos(theta);
74+
y = myscale*cosphi*sintheta;
75+
z = myscale*sin(phi)*ones(1,n+1);
76+
%% Plotting
77+
if nargout == 0
78+
cax = newplot(cax);
79+
% Load and define topographic data
80+
load('topo.mat','topo','topomap1');
81+
% Rotate data to be consistent with the Earth-Centered-Earth-Fixed
82+
% coordinate conventions. X axis goes through the prime meridian.
83+
% http://en.wikipedia.org/wiki/Geodetic_system#Earth_Centred_Earth_Fixed_.28ECEF_or_ECF.29_coordinates
84+
%
85+
% Note that if you plot orbit trajectories in the Earth-Centered-
86+
% Inertial, the orientation of the contintents will be misleading.
87+
topo2 = [topo(:,181:360) topo(:,1:180)]; %#ok<NODEF>
88+
89+
% Define surface settings
90+
props.FaceColor= 'texture';
91+
props.EdgeColor = 'none';
92+
props.FaceLighting = 'phong';
93+
props.Cdata = topo2;
94+
% Create the sphere with Earth topography and adjust colormap
95+
surface(x,y,z,props,'parent',cax)
96+
colormap(topomap1)
97+
% Replace the calls to surface and colormap with these lines if you do
98+
% not want the Earth's topography displayed.
99+
% surf(x,y,z,'parent',cax)
100+
% shading flat
101+
% colormap gray
102+
103+
% Refine figure
104+
axis equal
105+
xlabel(['X [' units ']'])
106+
ylabel(['Y [' units ']'])
107+
zlabel(['Z [' units ']'])
108+
view(127.5,30)
109+
else
110+
xx = x; yy = y; zz = z;
111+
end

EKF/inertia.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
%%%Moments of Inertia Cubesat
2+
Ix = 0.9;
3+
Iy = 0.9;
4+
Iz = 0.3;
5+
I = [Ix,0,0;0,Iy,0;0,0,Iz]; %%kg-m^2
6+
invI = inv(I);

EKF/main.m

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
%%% Clear workspace
2+
clear
3+
clc
4+
close all
5+
6+
%%%Simulated noise parameters
7+
% Process noise covariance
8+
Q = 1e-7;
9+
p_noise = [Q;Q;Q;Q;Q;Q;Q];
10+
% Measurement noise covariance
11+
Re = 5e-6;
12+
m_noise = [Re;Re;Re;Re;0.0001*Re;0.0001*Re;0.0001*Re];
13+
% Sampling time
14+
Ts = 0.1; % [s]
15+
16+
%%%Get Earth Parameters for orbit
17+
planet
18+
19+
%%%Cubesat parameters
20+
global m invI I
21+
m = 2.6; %%mass in kilograms
22+
inertia
23+
24+
%%%Initial Conditions Position and Velocity
25+
altitude = 408*1000; %%meters
26+
x0 = R + altitude;
27+
y0 = 0;
28+
z0 = 0;
29+
xdot0 = 0;
30+
inclination = deg2rad(56);
31+
semi_major = norm([x0;y0;z0]); %%Orbit Radius for circular orbit
32+
vcircular = sqrt(mu/semi_major); %%Orbital Speed from Vis-Viva Equation with a=r
33+
ydot0 = vcircular*cos(inclination);
34+
zdot0 = vcircular*sin(inclination);
35+
36+
%%%Initial Conditions Attitude and Angular velocity
37+
%Initialize Euler Angles
38+
phi0 = 0;
39+
theta0 = 0;
40+
psi0 = 0;
41+
ptp0 = [phi0;theta0;psi0];
42+
q0123_0 = Eu2Quat(ptp0); %Transform to quat initial conditions
43+
44+
%Initial Angular Velocity (Body Frame)
45+
p0=0.01;
46+
q0=0.01;
47+
r0=0;
48+
49+
%Initial Conditions state vector
50+
stateinitial = [q0123_0;p0;q0;r0];
51+
52+
%%%Orbit time parameters Circular Orbit
53+
period = 2*pi/sqrt(mu)*semi_major^(3/2); %%Tcircular
54+
number_of_orbits = 1;
55+
tfinal = period*number_of_orbits;
56+
tspan = [0,tfinal];
57+
58+
%%%This is where we integrate the equations of motion
59+
[tout,stateout] = ode45(@Satellite,tspan,stateinitial);
60+
%{
61+
%%%Convert state to kilometers
62+
stateout(:,1:6) = stateout(:,1:6)/1000;
63+
64+
%%%Extract the state vector
65+
xout = stateout(:,1);
66+
yout = stateout(:,2);
67+
zout = stateout(:,3);
68+
%}
69+
q0123out = stateout(:,1:4);
70+
ptpout = Quat2Eu(q0123out);
71+
pqrout = stateout(:,5:7);
72+
%{
73+
%%%Make an Earth
74+
[X,Y,Z] = sphere(100);
75+
X = X*R/1000;
76+
Y = Y*R/1000;
77+
Z = Z*R/1000;
78+
79+
%%%Plot 3D orbit
80+
fig = figure();
81+
set(fig,'color','white')
82+
plot3(xout,yout,zout,'b-','LineWidth',4)
83+
xlabel('X')
84+
ylabel('Y')
85+
zlabel('Z')
86+
grid on
87+
hold on
88+
earth_sphere()
89+
axis equal
90+
91+
%%%Plot Quaternions
92+
fig2 = figure();
93+
set(fig2,'color','white')
94+
plot(tout,q0123out,'-','LineWidth',2);
95+
grid on
96+
xlabel('Time (sec)')
97+
ylabel('Quaternions')
98+
legend('q0','q1','q2','q3')
99+
100+
%%%Plot Euler Angles
101+
fig3 = figure();
102+
set(fig3,'color','white')
103+
plot(tout,ptpout*180/pi,'-','LineWidth',2);
104+
grid on
105+
xlabel('Time (sec)')
106+
ylabel('Euler Angles (deg)')
107+
legend('Phi','Theta','Psi')
108+
109+
%%%Plot Angular Velocity
110+
fig4 = figure();
111+
set(fig4,'color','white')
112+
plot(tout,pqrout,'-','LineWidth',2);
113+
grid on
114+
xlabel('Time (sec)')
115+
ylabel('Angular Velocity (rad/s)')
116+
legend('p','q','r')
117+
%}
118+

EKF/myMeasurementFcn.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function y = myMeasurementFcn(x)
2+
% x = [q0123;p;q;r]
3+
q0123 =x(1:4);
4+
pqr = x(5:7);
5+
y = [q0123;pqr];
6+
end

0 commit comments

Comments
 (0)