1010import math
1111import matplotlib .pyplot as plt
1212
13- Cx = np .diag ([1.0 , 1.0 , math .radians (30.0 )])** 2
14- Cz = np .diag ([1.0 , 1.0 ])** 2
15-
13+ # EKF state covariance
14+ Cx = np .diag ([0.5 , 0.5 , math .radians (30.0 )])** 2
1615
1716# Simulation parameter
1817Qsim = np .diag ([0.2 ])** 2
19- Rsim = np .diag ([1.0 , math .radians (30 .0 )])** 2
18+ Rsim = np .diag ([1.0 , math .radians (10 .0 )])** 2
2019
2120DT = 0.1 # time tick [s]
2221SIM_TIME = 50.0 # simulation time [s]
2322MAX_RANGE = 20.0 # maximum observation range
2423
25- M_DIST_TH = 1.0
26-
27- POSE_SIZE = 3 # [x,y,yaw]
28- LM_SIZE = 2 # [x,y]
24+ M_DIST_TH = 1.0 # Threshold of Mahalanobis distance for data association.
2925
30- # Particle filter parameter
31- NP = 100 # Number of Particle
32- NTh = NP / 2.0 # Number of particle for re-sampling
26+ STATE_SIZE = 3 # State size [x,y,yaw]
27+ LM_SIZE = 2 # LM srate size [x,y]
3328
3429show_animation = True
3530
@@ -50,12 +45,13 @@ def observation(xTrue, xd, u, RFID):
5045
5146 for i in range (len (RFID [:, 0 ])):
5247
53- dx = xTrue [ 0 , 0 ] - RFID [ i , 0 ]
54- dy = xTrue [ 1 , 0 ] - RFID [ i , 1 ]
48+ dx = RFID [ i , 0 ] - xTrue [ 0 , 0 ]
49+ dy = RFID [ i , 1 ] - xTrue [ 1 , 0 ]
5550 d = math .sqrt (dx ** 2 + dy ** 2 )
51+ angle = pi_2_pi (math .atan2 (dy , dx ))
5652 if d <= MAX_RANGE :
57- dn = d + np .random .randn () * Qsim [0 , 0 ] # add noise
58- zi = np .matrix ([dn , RFID [ i , 0 ], RFID [ i , 1 ] ])
53+ # dn = d + np.random.randn() * Qsim[0, 0] # add noise
54+ zi = np .matrix ([d , angle , i ])
5955 z = np .vstack ((z , zi ))
6056
6157 # add noise to input
@@ -84,20 +80,20 @@ def motion_model(x, u):
8480
8581
8682def calc_n_LM (x ):
87- n = int ((len (x ) - POSE_SIZE ) / LM_SIZE )
83+ n = int ((len (x ) - STATE_SIZE ) / LM_SIZE )
8884 return n
8985
9086
9187def jacob_motion (x , u ):
9288
93- Fx = np .hstack ((np .eye (POSE_SIZE ), np .zeros (
94- (POSE_SIZE , LM_SIZE * calc_n_LM (x )))))
89+ Fx = np .hstack ((np .eye (STATE_SIZE ), np .zeros (
90+ (STATE_SIZE , LM_SIZE * calc_n_LM (x )))))
9591
9692 jF = np .matrix ([[0.0 , 0.0 , - DT * u [0 ] * math .sin (x [2 , 0 ])],
9793 [0.0 , 0.0 , DT * u [0 ] * math .cos (x [2 , 0 ])],
9894 [0.0 , 0.0 , 0.0 ]])
9995
100- G = np .eye (POSE_SIZE ) + Fx .T * jF * Fx
96+ G = np .eye (STATE_SIZE ) + Fx .T * jF * Fx
10197
10298 return G , Fx ,
10399
@@ -123,8 +119,8 @@ def calc_mahalanobis_dist(xAug, PAug, z, iz):
123119 if i == nLM - 1 :
124120 mdist .append (M_DIST_TH )
125121 else :
126- lm = xAug [POSE_SIZE + LM_SIZE *
127- i : POSE_SIZE + LM_SIZE * (i + 1 ), :]
122+ lm = xAug [STATE_SIZE + LM_SIZE *
123+ i : STATE_SIZE + LM_SIZE * (i + 1 ), :]
128124 y , S , H = calc_innovation (lm , xAug , PAug , z [iz , 0 :2 ], i )
129125 mdist .append (y .T * np .linalg .inv (S ) * y )
130126
@@ -138,7 +134,7 @@ def calc_innovation(lm, xEst, PEst, z, LMid):
138134 zp = [math .sqrt (q ), pi_2_pi (zangle )]
139135 y = (z - zp ).T
140136 H = jacobH (q , delta , xEst , LMid + 1 )
141- S = H * PEst * H .T + Cz
137+ S = H * PEst * H .T + Cx [ 0 : 2 , 0 : 2 ]
142138
143139 return y , S , H
144140
@@ -173,16 +169,14 @@ def pi_2_pi(angle):
173169
174170def ekf_slam (xEst , PEst , u , z ):
175171 # Predict
176- xEst [0 :POSE_SIZE ] = motion_model (xEst [0 :POSE_SIZE ], u )
177- G , Fx = jacob_motion (xEst [0 :POSE_SIZE ], u )
178- PEst [0 :POSE_SIZE , 0 :POSE_SIZE ] = G .T * \
179- PEst [0 :POSE_SIZE , 0 :POSE_SIZE ] * G + Fx .T * Cx * Fx
180- initP = np .eye (2 ) * 1000.0
172+ xEst [0 :STATE_SIZE ] = motion_model (xEst [0 :STATE_SIZE ], u )
173+ G , Fx = jacob_motion (xEst [0 :STATE_SIZE ], u )
174+ PEst [0 :STATE_SIZE , 0 :STATE_SIZE ] = G .T * \
175+ PEst [0 :STATE_SIZE , 0 :STATE_SIZE ] * G + Fx .T * Cx * Fx
176+ initP = np .eye (2 )
181177
182178 # Update
183179 for iz in range (len (z [:, 0 ])): # for each observation
184- # print(iz)
185-
186180 zp = calc_LM_Pos (xEst , z [iz , :])
187181
188182 # Extend state and covariance matrix
@@ -192,7 +186,6 @@ def ekf_slam(xEst, PEst, u, z):
192186
193187 mah_dists = calc_mahalanobis_dist (xAug , PAug , z , iz )
194188 minid = mah_dists .index (min (mah_dists ))
195- # print(minid)
196189
197190 nLM = calc_n_LM (xAug )
198191 if minid == (nLM - 1 ):
@@ -202,9 +195,9 @@ def ekf_slam(xEst, PEst, u, z):
202195 else :
203196 print ("Old LM" )
204197
205- lm = xEst [POSE_SIZE + LM_SIZE *
206- iz : POSE_SIZE + LM_SIZE * (iz + 1 ), :]
207- y , S , H = calc_innovation (lm , xEst , PEst , z [iz , 0 :2 ], iz )
198+ lm = xEst [STATE_SIZE + LM_SIZE *
199+ minid : STATE_SIZE + LM_SIZE * (minid + 1 ), :]
200+ y , S , H = calc_innovation (lm , xEst , PEst , z [iz , 0 :2 ], minid )
208201
209202 K = PEst * H .T * np .linalg .inv (S )
210203 xEst = xEst + K * y
@@ -227,11 +220,11 @@ def main():
227220 [- 5.0 , 20.0 ]])
228221
229222 # State Vector [x y yaw v]'
230- xEst = np .matrix (np .zeros ((POSE_SIZE , 1 )))
231- xTrue = np .matrix (np .zeros ((POSE_SIZE , 1 )))
232- PEst = np .eye (POSE_SIZE )
223+ xEst = np .matrix (np .zeros ((STATE_SIZE , 1 )))
224+ xTrue = np .matrix (np .zeros ((STATE_SIZE , 1 )))
225+ PEst = np .eye (STATE_SIZE )
233226
234- xDR = np .matrix (np .zeros ((POSE_SIZE , 1 ))) # Dead reckoning
227+ xDR = np .matrix (np .zeros ((STATE_SIZE , 1 ))) # Dead reckoning
235228
236229 # history
237230 hxEst = xEst
@@ -246,20 +239,26 @@ def main():
246239
247240 xEst , PEst = ekf_slam (xEst , PEst , ud , z )
248241
249- x_state = xEst [0 :POSE_SIZE ]
242+ x_state = xEst [0 :STATE_SIZE ]
250243
251244 # store data history
252245 hxEst = np .hstack ((hxEst , x_state ))
253246 hxDR = np .hstack ((hxDR , xDR ))
254247 hxTrue = np .hstack ((hxTrue , xTrue ))
255248
249+ # print(xEst)
250+
256251 if show_animation :
257252 plt .cla ()
258253
259- for i in range (len (z [:, 0 ])):
260- plt .plot ([xTrue [0 , 0 ], z [i , 1 ]], [xTrue [1 , 0 ], z [i , 2 ]], "-k" )
261254 plt .plot (RFID [:, 0 ], RFID [:, 1 ], "*k" )
262255 plt .plot (xEst [0 ], xEst [1 ], ".r" )
256+
257+ # plot landmark
258+ for i in range (calc_n_LM (xEst )):
259+ plt .plot (xEst [STATE_SIZE + i * 2 ],
260+ xEst [STATE_SIZE + i * 2 + 1 ], "xg" )
261+
263262 plt .plot (np .array (hxTrue [0 , :]).flatten (),
264263 np .array (hxTrue [1 , :]).flatten (), "-b" )
265264 plt .plot (np .array (hxDR [0 , :]).flatten (),
@@ -269,6 +268,7 @@ def main():
269268 plt .axis ("equal" )
270269 plt .grid (True )
271270 plt .pause (0.001 )
271+ # input()
272272
273273
274274if __name__ == '__main__' :
0 commit comments