66
77"""
88
9- # pw=Normalize(pw,NP);%正規化
10- # [px,pw]=Resampling(px,pw,NTh,NP);%リサンプリング
11- # xEst=px*pw';%最終推定値は期待値
12-
13- # %Animation (remove some flames)
14- # if rem(i,5)==0
15- # hold off;
16- # arrow=0.5;
17- # %パーティクル表示
18- # for ip=1:NP
19- # quiver(px(1,ip),px(2,ip),arrow*cos(px(3,ip)),arrow*sin(px(3,ip)),'ok');hold on;
20- # end
21- # plot(result.xTrue(:,1),result.xTrue(:,2),'.b');hold on;
22- # plot(RFID(:,1),RFID(:,2),'pk','MarkerSize',10);hold on;
23- # %観測線の表示
24- # if~isempty(z)
25- # for iz=1:length(z(:,1))
26- # ray=[xTrue(1:2)';z(iz,2:3)];
27- # plot(ray(:,1),ray(:,2),'-r');hold on;
28- # end
29- # end
30- # plot(result.xd(:,1),result.xd(:,2),'.k');hold on;
31- # plot(result.xEst(:,1),result.xEst(:,2),'.r');hold on;
32- # axis equal;
33- # grid on;
34- # drawnow;
35- #
36- # function [px,pw]=Resampling(px,pw,NTh,NP)
37- # %リサンプリングを実施する関数
38- # %アルゴリズムはLow Variance Sampling
39- # Neff=1.0/(pw*pw');
40- # if Neff<NTh %リサンプリング
41- # wcum=cumsum(pw);
42- # base=cumsum(pw*0+1/NP)-1/NP;%乱数を加える前のbase
43- # resampleID=base+rand/NP;%ルーレットを乱数分増やす
44- # ppx=px;%データ格納用
45- # ind=1;%新しいID
46- # for ip=1:NP
47- # while(resampleID(ip)>wcum(ind))
48- # ind=ind+1;
49- # end
50- # px(:,ip)=ppx(:,ind);%LVSで選ばれたパーティクルに置き換え
51- # pw(ip)=1/NP;%尤度は初期化
52- # end
53- # end
54-
55- # function pw=Normalize(pw,NP)
56- # %重みベクトルを正規化する関数
57- # sumw=sum(pw);
58- # if sumw~=0
59- # pw=pw/sum(pw);%正規化
60- # else
61- # pw=zeros(1,NP)+1/NP;
62- # end
63-
64-
65- # function p=Gauss(x,u,sigma)
66- # %ガウス分布の確率密度を計算する関数
67- # p=1/sqrt(2*pi*sigma^2)*exp(-(x-u)^2/(2*sigma^2));
68-
69- # %Calc Observation from noise prameter
70- # function [z, x, xd, u] = Observation(x, xd, u, RFID,MAX_RANGE)
71- # global Qsigma;
72- # global Rsigma;
73-
74- # x=f(x, u);% Ground Truth
75- # u=u+sqrt(Qsigma)*randn(2,1);%add Process Noise
76- # xd=f(xd, u);% Dead Reckoning
77- # %Simulate Observation
78- # z=[];
79- # for iz=1:length(RFID(:,1))
80- # d=norm(RFID(iz,:)-x(1:2)');
81- # if d<MAX_RANGE %観測範囲内
82- # z=[z;[d+sqrt(Rsigma)*randn(1,1) RFID(iz,:)]];
83- # end
84-
859import numpy as np
8610import math
8711import matplotlib .pyplot as plt
8812
8913# Estimation parameter of EKF
90- Q = np .diag ([0.1 , 0.1 , math . radians ( 1.0 ), 1.0 ])** 2
14+ Q = np .diag ([0.1 ])** 2 # range error
9115R = np .diag ([1.0 , math .radians (40.0 )])** 2
9216
9317# Simulation parameter
94- Qsim = np .diag ([0.5 , 0.5 ])** 2
18+ Qsim = np .diag ([0.2 ])** 2
9519Rsim = np .diag ([1.0 , math .radians (30.0 )])** 2
9620
9721DT = 0.1 # time tick [s]
@@ -125,7 +49,8 @@ def observation(xTrue, xd, u, RFID):
12549 dy = xTrue [1 , 0 ] - RFID [i , 1 ]
12650 d = math .sqrt (dx ** 2 + dy ** 2 )
12751 if d <= MAX_RANGE :
128- zi = np .matrix ([d , RFID [i , 0 ], RFID [i , 1 ]])
52+ dn = d + np .random .randn () * Qsim [0 , 0 ] # add noise
53+ zi = np .matrix ([dn , RFID [i , 0 ], RFID [i , 1 ]])
12954 z = np .vstack ((z , zi ))
13055
13156 # add noise to input
@@ -155,50 +80,83 @@ def motion_model(x, u):
15580 return x
15681
15782
158- def observation_model ( x ):
159- # Observation Model
160- H = np . matrix ([
161- [ 1 , 0 , 0 , 0 ],
162- [ 0 , 1 , 0 , 0 ]
163- ])
83+ def gauss_likelihood ( x , sigma ):
84+ p = 1.0 / math . sqrt ( 2.0 * math . pi * sigma ** 2 ) * \
85+ math . exp ( - x ** 2 / ( 2 * sigma ** 2 ))
86+
87+ return p
88+
16489
165- z = H * x
90+ def calc_covariance (xEst , px , pw ):
91+ cov = np .matrix (np .zeros ((3 , 3 )))
16692
167- return z
93+ for i in range (px .shape [1 ]):
94+ dx = (px [:, i ] - xEst )[0 :3 ]
95+ cov += pw [0 , i ] * dx * dx .T
16896
97+ return cov
16998
170- def pf_estimation (px , pw , xEst , PEst , z , u ):
17199
172- # Predict
100+ def pf_localization (px , pw , xEst , PEst , z , u ):
101+ """
102+ Localization with Particle filter
103+ """
104+
173105 for ip in range (NP ):
174106 x = px [:, ip ]
175- # w = pw[ip]
107+ w = pw [0 , ip ]
176108
109+ # Predict with ramdom input sampling
177110 ud1 = u [0 , 0 ] + np .random .randn () * Rsim [0 , 0 ]
178111 ud2 = u [1 , 0 ] + np .random .randn () * Rsim [1 , 1 ]
179112 ud = np .matrix ([ud1 , ud2 ]).T
180-
181113 x = motion_model (x , ud )
182114
183- px [:, ip ] = x
184-
185115 # Calc Inportance Weight
186116 for i in range (len (z [:, 0 ])):
187117 dx = x [0 , 0 ] - z [i , 1 ]
188118 dy = x [1 , 0 ] - z [i , 2 ]
189119 prez = math .sqrt (dx ** 2 + dy ** 2 )
190120 dz = prez - z [i , 0 ]
191- # w=w*Gauss(dz,0,sqrt(R));
192- # end
193- # px(:,ip)=x;%格納
194- # pw(ip)=w;
195- # end
121+ w = w * gauss_likelihood (dz , math .sqrt (Q [0 , 0 ]))
122+
123+ px [:, ip ] = x
124+ pw [0 , ip ] = w
125+
126+ pw = pw / pw .sum () # normalize
196127
197128 xEst = px * pw .T
129+ PEst = calc_covariance (xEst , px , pw )
130+
131+ px , pw = resampling (px , pw )
198132
199133 return xEst , PEst , px , pw
200134
201135
136+ def resampling (px , pw ):
137+ """
138+ low variance re-sampling
139+ """
140+
141+ Neff = 1.0 / (pw * pw .T )[0 , 0 ] # Effective particle number
142+ if Neff < NTh :
143+ wcum = np .cumsum (pw )
144+ base = np .cumsum (pw * 0.0 + 1 / NP ) - 1 / NP
145+ resampleid = base + np .random .rand (base .shape [1 ]) / NP
146+
147+ inds = []
148+ ind = 0
149+ for ip in range (NP ):
150+ while resampleid [0 , ip ] > wcum [0 , ind ]:
151+ ind += 1
152+ inds .append (ind )
153+
154+ px = px [:, inds ]
155+ pw = np .matrix (np .zeros ((1 , NP ))) + 1.0 / NP # init weight
156+
157+ return px , pw
158+
159+
202160def plot_covariance_ellipse (xEst , PEst ):
203161 Pxy = PEst [0 :2 , 0 :2 ]
204162 eigval , eigvec = np .linalg .eig (Pxy )
@@ -242,7 +200,6 @@ def main():
242200
243201 px = np .matrix (np .zeros ((4 , NP ))) # Particle store
244202 pw = np .matrix (np .zeros ((1 , NP ))) + 1.0 / NP # Particle weight
245-
246203 xDR = np .matrix (np .zeros ((4 , 1 ))) # Dead reckoning
247204
248205 # history
@@ -256,7 +213,7 @@ def main():
256213
257214 xTrue , z , xDR , ud = observation (xTrue , xDR , u , RFID )
258215
259- xEst , PEst , px , pw = pf_estimation (px , pw , xEst , PEst , z , ud )
216+ xEst , PEst , px , pw = pf_localization (px , pw , xEst , PEst , z , ud )
260217
261218 # store data history
262219 hxEst = np .hstack ((hxEst , xEst ))
0 commit comments