1010import math
1111import matplotlib .pyplot as plt
1212
13+ # Estimation parameter
14+ Q = np .diag ([0.5 , 0.5 ])** 2
15+ R = np .diag ([1.0 , math .radians (30.0 )])** 2
1316
14- # Covariance Matrix for motion
15- # Q=diag([0.1 0.1 toRadian(1) 0.05]).^2;
16-
17- # % Covariance Matrix for observation
18- # R=diag([1.5 1.5 toRadian(3) 0.05]).^2;
19-
20- # % Simulation parameter
21- # global Qsigma
22- # Qsigma=diag([0.1 toRadian(20)]).^2; %[v yawrate]
23-
24- # global Rsigma
25- # Rsigma=diag([1.5 1.5 toRadian(3) 0.05]).^2;%[x y z yaw v]
26-
27- # PEst = eye(4);
28-
29- # u=doControl(time);
30- # % Observation
31- # [z,xTrue,xd,u]=Observation(xTrue, xd, u);
32-
33- # % ------ Kalman Filter --------
34- # % Predict
35- # xPred = f(xEst, u);
36- # F=jacobF(xPred, u);
37- # PPred= F*PEst*F' + Q;
38-
39- # % Update
40- # H=jacobH(xPred);
41- # y = z - h(xPred);
42- # S = H*PPred*H' + R;
43- # K = PPred*H'*inv(S);
44- # xEst = xPred + K*y;
45- # PEst = (eye(size(xEst,1)) - K*H)*PPred;
46-
47- # % Simulation Result
48- # result.time=[result.time; time];
49- # result.xTrue=[result.xTrue; xTrue'];
50- # result.xd=[result.xd; xd'];
51- # result.xEst=[result.xEst;xEst'];
52- # result.z=[result.z; z'];
53- # result.PEst=[result.PEst; diag(PEst)'];
54- # result.u=[result.u; u'];
55-
56- # %Animation (remove some flames)
57- # if rem(i,5)==0
58- # %hold off;
59- # plot(result.xTrue(:,1),result.xTrue(:,2),'.b');hold on;
60- # plot(result.z(:,1),result.z(:,2),'.g');hold on;
61- # plot(result.xd(:,1),result.xd(:,2),'.k');hold on;
62- # plot(result.xEst(:,1),result.xEst(:,2),'.r');hold on;
63- # ShowErrorEllipse(xEst,PEst);
64- # axis equal;
65- # grid on;
66- # drawnow;
67- # %movcount=movcount+1;
68- # %mov(movcount) = getframe(gcf);% アニメーションのフレームをゲットする
69- # end
70- # end
71- # toc
72- # %アニメーション保存
73- # %movie2avi(mov,'movie.avi');
17+ # Simulation parameter
18+ Qsim = np .diag ([0.5 , 0.5 ])** 2
19+ Rsim = np .diag ([1.0 , math .radians (30.0 )])** 2
7420
75- # DrawGraph(result);
7621
7722# function ShowErrorEllipse(xEst,PEst)
7823# %誤差分散円を計算し、表示する関数
15499# 0 0 0 1];
155100
156101
157- # function [z, x, xd, u] = Observation(x, xd, u)
158- # %Calc Observation from noise prameter
159- # global Qsigma;
160- # global Rsigma;
161-
162- # x=f(x, u);% Ground Truth
163- # u=u+Qsigma*randn(2,1);%add Process Noise
164- # xd=f(xd, u);% Dead Reckoning
165- # z=h(x+Rsigma*randn(4,1));%Simulate Observation
166-
167-
168- # function []=DrawGraph(result)
169- # %Plot Result
170-
171- # figure(1);
172- # x=[ result.xTrue(:,1:2) result.xEst(:,1:2) result.z(:,1:2)];
173- # set(gca, 'fontsize', 16, 'fontname', 'times');
174- # plot(x(:,5), x(:,6),'.g','linewidth', 4); hold on;
175- # plot(x(:,1), x(:,2),'-.b','linewidth', 4); hold on;
176- # plot(x(:,3), x(:,4),'r','linewidth', 4); hold on;
177- # plot(result.xd(:,1), result.xd(:,2),'--k','linewidth', 4); hold on;
178-
179- # title('EKF Localization Result', 'fontsize', 16, 'fontname', 'times');
180- # xlabel('X (m)', 'fontsize', 16, 'fontname', 'times');
181- # ylabel('Y (m)', 'fontsize', 16, 'fontname', 'times');
182- # legend('Ground Truth','GPS','Dead Reckoning','EKF','Error Ellipse');
183- # grid on;
184- # axis equal;
185-
186102# function angle=Pi2Pi(angle)
187103# %ロボットの角度を-pi~piの範囲に補正する関数
188104# angle = mod(angle, 2*pi);
194110# angle(i) = angle(i) + 2*pi;
195111
196112
197- # function radian = toRadian(degree)
198- # % degree to radian
199- # radian = degree/180*pi;
200-
201- # function degree = toDegree(radian)
202- # % radian to degree
203- # degree = radian/pi*180;
204-
205113DT = 0.1 # time tick [s]
206114SIM_TIME = 60.0 # simulation time [s]
207115
@@ -215,12 +123,21 @@ def do_control():
215123 return u
216124
217125
218- # z, xTrue, xd, u = Observation(xTrue, xd, u)
219126def observation (xTrue , xd , u ):
220127
221128 xTrue = motion_model (xTrue , u )
222129
223- return xTrue
130+ zx = xTrue [0 , 0 ] + np .random .randn () * Qsim [0 , 0 ]
131+ zy = xTrue [1 , 0 ] + np .random .randn () * Qsim [1 , 1 ]
132+ z = np .matrix ([zx , zy ])
133+
134+ ud1 = u [0 , 0 ] + np .random .randn () * Rsim [0 , 0 ]
135+ ud2 = u [1 , 0 ] + np .random .randn () * Rsim [1 , 1 ]
136+ ud = np .matrix ([ud1 , ud2 ]).T
137+
138+ xd = motion_model (xd , ud )
139+
140+ return xTrue , z , xd , ud
224141
225142
226143def motion_model (x , u ):
@@ -240,29 +157,49 @@ def motion_model(x, u):
240157 return x
241158
242159
160+ def ekf_estimation (xEst , PEst , u ):
161+
162+ # Predict
163+ xPred = motion_model (xEst , u )
164+ # F=jacobF(xPred, u);
165+ # PPred= F*PEst*F' + Q;
166+
167+ # Update
168+ # H=jacobH(xPred);
169+ # y = z - h(xPred);
170+ # S = H*PPred*H' + R;
171+ # K = PPred*H'*inv(S);
172+ # xEst = xPred + K*y;
173+ xEst = xPred
174+ # PEst = (eye(size(xEst,1)) - K*H)*PPred;
175+
176+ return xEst
177+
178+
243179def main ():
244180 print (__file__ + " start!!" )
245181
246182 time = 0.0
247183 # State Vector [x y yaw v]'
248- # xEst = np.matrix(np.zeros((3 , 1)))
184+ xEst = np .matrix (np .zeros ((4 , 1 )))
249185 xTrue = np .matrix (np .zeros ((4 , 1 )))
186+ PEst = np .eye (4 )
250187
251188 # Dead Reckoning
252189 xDR = np .matrix (np .zeros ((4 , 1 )))
253190
254- # Observation vector
255- # z = np.matrix(np.zeros((2, 1)))
256-
257191 while SIM_TIME >= time :
258- # print(time)
259192 time += DT
260-
261193 u = do_control ()
262194
263- xTrue = observation (xTrue , xDR , u )
195+ xTrue , z , xDR , ud = observation (xTrue , xDR , u )
196+
197+ xEst = ekf_estimation (xEst , PEst , ud )
264198
265- plt .plot (xTrue [0 , 0 ], xTrue [1 , 0 ], ".r" )
199+ plt .plot (xTrue [0 , 0 ], xTrue [1 , 0 ], ".b" )
200+ plt .plot (xDR [0 , 0 ], xDR [1 , 0 ], ".k" )
201+ plt .plot (z [0 , 0 ], z [0 , 1 ], ".g" )
202+ plt .plot (xEst [0 , 0 ], xEst [1 , 0 ], ".r" )
266203 plt .axis ("equal" )
267204 plt .grid (True )
268205 plt .pause (0.001 )
0 commit comments