Skip to content
This repository was archived by the owner on Nov 19, 2023. It is now read-only.

Commit 603f5c2

Browse files
committed
Adiciona o exemplo do UKF apresentado na parte 02.
1 parent eff5834 commit 603f5c2

File tree

1 file changed

+289
-0
lines changed

1 file changed

+289
-0
lines changed
+289
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
% -------------------------------------------------------------------------
2+
%
3+
% File : Unscented KalmanFilterLocalization.m
4+
%
5+
% Discription : Mobible robot localization sample code with
6+
% Unscented Kalman Filter (UKF)
7+
%
8+
% Environment : Matlab
9+
%
10+
% Author : Atsushi Sakai
11+
%
12+
% Copyright (c): 2014 Atsushi Sakai
13+
%
14+
% License : Modified BSD Software License Agreement
15+
% -------------------------------------------------------------------------
16+
17+
function [] = UnscentedKalmanFilterLocalization()
18+
19+
close all;
20+
clear all;
21+
22+
disp('Unscented Kalman Filter (UKF) sample program start!!')
23+
24+
time = 0;
25+
endtime = 80; % [sec]
26+
global dt;
27+
dt = 0.5; % [sec]
28+
29+
nSteps = ceil((endtime - time)/dt);
30+
31+
result.time=[];
32+
result.xTrue=[];
33+
result.xd=[];
34+
result.xEst=[];
35+
result.z=[];
36+
result.PEst=[];
37+
result.u=[];
38+
39+
% State Vector [x y yaw v]'
40+
xEst=[1 1 0 0.65]';
41+
42+
% True State
43+
xTrue=xEst;
44+
45+
% Dead Reckoning
46+
xd=xTrue;
47+
48+
% Observation vector [x y yaw v]'
49+
z=[1 1 0 0.65]';
50+
51+
% Covariance Matrix for predict
52+
Q=diag([0.1 0.1 toRadian(1) 0.05]).^2;
53+
54+
% Covariance Matrix for observation
55+
R=diag([1.5 1.5 toRadian(3) 0.05]).^2;
56+
57+
% Simulation parameter
58+
global Qsigma
59+
Qsigma=diag([0.1 toRadian(20)]).^2;
60+
61+
global Rsigma
62+
Rsigma=diag([1.5 1.5 toRadian(3) 0.05]).^2;
63+
64+
% UKF Parameter
65+
alpha=0.001;
66+
beta =2;
67+
kappa=0;
68+
69+
n=length(xEst);%size of state vector
70+
lamda=alpha^2*(n+kappa)-n;
71+
72+
%calculate weights
73+
wm=[lamda/(lamda+n)];
74+
wc=[(lamda/(lamda+n))+(1-alpha^2+beta)];
75+
for i=1:2*n
76+
wm=[wm 1/(2*(n+lamda))];
77+
wc=[wc 1/(2*(n+lamda))];
78+
end
79+
gamma=sqrt(n+lamda);
80+
81+
PEst = eye(4);
82+
tic;
83+
% Main loop
84+
for i=1 : nSteps
85+
time = time + dt;
86+
% Input
87+
u=doControl(time);
88+
% Observation
89+
[z,xTrue,xd,u]=Observation(xTrue, xd, u);
90+
91+
% ------ Unscented Kalman Filter --------
92+
% Predict
93+
sigma=GenerateSigmaPoints(xEst,PEst,gamma);
94+
sigma=PredictMotion(sigma,u);
95+
xPred=(wm*sigma')';
96+
PPred=CalcSimgaPointsCovariance(xPred,sigma,wc,Q);
97+
98+
% Update
99+
y = z - h(xPred);
100+
sigma=GenerateSigmaPoints(xPred,PPred,gamma);
101+
zSigma=PredictObservation(sigma);
102+
zb=(wm*sigma')';
103+
St=CalcSimgaPointsCovariance(zb,zSigma,wc,R);
104+
Pxz=CalcPxz(sigma,xPred,zSigma,zb,wc);
105+
K=Pxz*inv(St);
106+
xEst = xPred + K*y;
107+
PEst=PPred-K*St*K';
108+
109+
% Simulation Result
110+
result.time=[result.time; time];
111+
result.xTrue=[result.xTrue; xTrue'];
112+
result.xd=[result.xd; xd'];
113+
result.xEst=[result.xEst;xEst'];
114+
result.z=[result.z; z'];
115+
result.PEst=[result.PEst; diag(PEst)'];
116+
result.u=[result.u; u'];
117+
118+
%Animation (remove some flames)
119+
if rem(i,5)==0
120+
plot(xTrue(1),xTrue(2),'.b');hold on;
121+
plot(z(1),z(2),'.g');hold on;
122+
plot(xd(1),xd(2),'.r');hold on;
123+
plot(xEst(1),xEst(2),'.k');hold on;
124+
ShowErrorEllipse(xEst,PEst);
125+
axis equal;
126+
grid on;
127+
drawnow;
128+
129+
end
130+
131+
132+
end
133+
toc
134+
135+
136+
DrawGraph(result);
137+
138+
139+
140+
function ShowErrorEllipse(xEst,PEst)
141+
%????????????????
142+
Pxy=PEst(1:2,1:2);%x,y???????
143+
[eigvec, eigval]=eig(Pxy);%?????????????
144+
%??????????????????
145+
if eigval(1,1)>=eigval(2,2)
146+
bigind=1;
147+
smallind=2;
148+
else
149+
bigind=2;
150+
smallind=1;
151+
end
152+
153+
chi=9.21;%??????????????99%
154+
155+
%????
156+
t=0:10:360;
157+
a=sqrt(eigval(bigind,bigind)*chi);
158+
b=sqrt(eigval(smallind,smallind)*chi);
159+
x=[a*cosd(t);
160+
b*sind(t)];
161+
%??????????
162+
angle = atan2(eigvec(bigind,2),eigvec(bigind,1));
163+
if(angle < 0)
164+
angle = angle + 2*pi;
165+
end
166+
167+
%???????
168+
R=[cos(angle) sin(angle);
169+
-sin(angle) cos(angle)];
170+
x=R*x;
171+
plot(x(1,:)+xEst(1),x(2,:)+xEst(2))
172+
173+
function sigma=PredictMotion(sigma,u)
174+
% Sigma Points predition with motion model
175+
for i=1:length(sigma(1,:))
176+
sigma(:,i)=f(sigma(:,i),u);
177+
end
178+
179+
function sigma=PredictObservation(sigma)
180+
% Sigma Points predition with observation model
181+
for i=1:length(sigma(1,:))
182+
sigma(:,i)=h(sigma(:,i));
183+
end
184+
185+
function P=CalcSimgaPointsCovariance(xPred,sigma,wc,N)
186+
nSigma=length(sigma(1,:));
187+
d=sigma-repmat(xPred,1,nSigma);
188+
P=N;
189+
for i=1:nSigma
190+
P=P+wc(i)*d(:,i)*d(:,i)';
191+
end
192+
193+
function P=CalcPxz(sigma,xPred,zSigma,zb,wc)
194+
nSigma=length(sigma(1,:));
195+
dx=sigma-repmat(xPred,1,nSigma);
196+
dz=zSigma-repmat(zb,1,nSigma);
197+
P=zeros(length(sigma(:,1)));
198+
for i=1:nSigma
199+
P=P+wc(i)*dx(:,i)*dz(:,i)';
200+
end
201+
202+
function sigma=GenerateSigmaPoints(xEst,PEst,gamma)
203+
sigma=xEst;
204+
Psqrt=sqrtm(PEst);
205+
n=length(xEst);
206+
%Positive direction
207+
for ip=1:n
208+
sigma=[sigma xEst+gamma*Psqrt(:,ip)];
209+
end
210+
%Negative direction
211+
for in=1:n
212+
sigma=[sigma xEst-gamma*Psqrt(:,in)];
213+
end
214+
215+
function x = f(x, u)
216+
% Motion Model
217+
218+
global dt;
219+
220+
F = [1 0 0 0
221+
0 1 0 0
222+
0 0 1 0
223+
0 0 0 0];
224+
225+
B = [
226+
dt*cos(x(3)) 0
227+
dt*sin(x(3)) 0
228+
0 dt
229+
1 0];
230+
231+
x= F*x+B*u;
232+
233+
function z = h(x)
234+
%Observation Model
235+
236+
H = [1 0 0 0
237+
0 1 0 0
238+
0 0 1 0
239+
0 0 0 1 ];
240+
241+
z=H*x;
242+
243+
function u = doControl(time)
244+
%Calc Input Parameter
245+
T=10; % [sec]
246+
247+
% [V yawrate]
248+
V=1.0; % [m/s]
249+
yawrate = 5; % [deg/s]
250+
251+
u =[ V*(1-exp(-time/T)) toRadian(yawrate)*(1-exp(-time/T))]';
252+
253+
254+
%Calc Observation from noise prameter
255+
function [z, x, xd, u] = Observation(x, xd, u)
256+
global Qsigma;
257+
global Rsigma;
258+
259+
x=f(x, u);% Ground Truth
260+
u=u+Qsigma*randn(2,1);%add Process Noise
261+
xd=f(xd, u);% Dead Reckoning
262+
z=h(x+Rsigma*randn(4,1));%Simulate Observation
263+
264+
265+
function []=DrawGraph(result)
266+
%Plot Result
267+
268+
figure(1);
269+
x=[ result.xTrue(:,1:2) result.xEst(:,1:2) result.z(:,1:2)];
270+
set(gca, 'fontsize',12, 'fontname', 'times');
271+
%plot(x(:,5), x(:,6),'.g','linewidth', 1); hold on;%gps
272+
plot(x(:,1), x(:,2),'-b','linewidth', 1); hold on;%observação direta
273+
plot(x(:,3), x(:,4),'-r','linewidth', 1); hold on;%UKF
274+
plot(result.xd(:,1), result.xd(:,2),'--k','linewidth', 1); hold on;%DEAD recogn
275+
276+
title('UKF - Comparação', 'fontsize', 16, 'fontname', 'times');
277+
xlabel('X (m)', 'fontsize', 16, 'fontname', 'times');
278+
ylabel('Y (m)', 'fontsize', 16, 'fontname', 'times');
279+
legend('Observação Direta','UKF','Dead Reckoning');
280+
grid on;
281+
axis equal;
282+
283+
function radian = toRadian(degree)
284+
% degree to radian
285+
radian = degree/180*pi;
286+
287+
function degree = toDegree(radian)
288+
% radian to degree
289+
degree = radian/pi*180;

0 commit comments

Comments
 (0)