Skip to content

Commit ddf2e0a

Browse files
committed
all code works but it doesn't converge
1 parent c389dc5 commit ddf2e0a

File tree

1 file changed

+53
-24
lines changed

1 file changed

+53
-24
lines changed

SLAM/EKFSLAM/ekf_slam.py

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import matplotlib.pyplot as plt
1212

1313
Cx = np.diag([1.0, 1.0, math.radians(30.0)])**2
14+
Cz = np.diag([1.0, 1.0])**2
15+
1416

1517
# Simulation parameter
1618
Qsim = np.diag([0.2])**2
@@ -110,7 +112,7 @@ def calc_LM_Pos(x, z):
110112
return zp
111113

112114

113-
def calc_mahalanobis_dist(xAug, PAug):
115+
def calc_mahalanobis_dist(xAug, PAug, z, iz):
114116

115117
nLM = calc_n_LM(xAug)
116118

@@ -123,21 +125,50 @@ def calc_mahalanobis_dist(xAug, PAug):
123125
else:
124126
lm = xAug[POSE_SIZE + LM_SIZE *
125127
i: POSE_SIZE + LM_SIZE * (i + 1), :]
126-
# y, S, H = calc_innovation(lm, xAug, PAug, z[iz, 0:2], il)
127-
# mdist=[mdist y'*inv(S)*y];%マハラノビス距離の計算
128+
y, S, H = calc_innovation(lm, xAug, PAug, z[iz, 0:2], i)
129+
mdist.append(y.T * np.linalg.inv(S) * y)
128130

129131
return mdist
130132

131-
# function [y,S,H]=CalcInnovation(lm,xEst,PEst,z,LMId)
132-
# %対応付け結果からイノベーションを計算する関数
133-
# global Q;
134-
# delta=lm-xEst(1:2);
135-
# q=delta'*delta;
136-
# zangle=atan2(delta(2),delta(1))-xEst(3);
137-
# zp=[sqrt(q) PI2PI(zangle)];%観測値の予測
138-
# y=(z-zp)';
139-
# H=jacobH(q,delta,xEst,LMId);
140-
# S=H*PEst*H'+Q;
133+
134+
def calc_innovation(lm, xEst, PEst, z, LMid):
135+
delta = lm - xEst[0:2]
136+
q = (delta.T * delta)[0, 0]
137+
zangle = math.atan2(delta[1], delta[0]) - xEst[2]
138+
zp = [math.sqrt(q), pi_2_pi(zangle)]
139+
y = (z - zp).T
140+
H = jacobH(q, delta, xEst, LMid + 1)
141+
S = H * PEst * H.T + Cz
142+
143+
return y, S, H
144+
145+
146+
def jacobH(q, delta, x, i):
147+
sq = math.sqrt(q)
148+
G = np.matrix([[-sq * delta[0, 0], - sq * delta[1, 0], 0, sq * delta[0, 0], sq * delta[1, 0]],
149+
[delta[1, 0], - delta[0, 0], - 1.0, - delta[1, 0], delta[0, 0]]])
150+
151+
G = G / q
152+
nLM = calc_n_LM(x)
153+
F1 = np.hstack((np.eye(3), np.zeros((3, 2 * nLM))))
154+
F2 = np.hstack((np.zeros((2, 3)), np.zeros((2, 2 * (i - 1))),
155+
np.eye(2), np.zeros((2, 2 * nLM - 2 * i))))
156+
157+
F = np.vstack((F1, F2))
158+
159+
H = G * F
160+
161+
return H
162+
163+
164+
def pi_2_pi(angle):
165+
while(angle > math.pi):
166+
angle = angle - 2.0 * math.pi
167+
168+
while(angle < -math.pi):
169+
angle = angle + 2.0 * math.pi
170+
171+
return angle
141172

142173

143174
def ekf_slam(xEst, PEst, u, z):
@@ -159,7 +190,7 @@ def ekf_slam(xEst, PEst, u, z):
159190
PAug = np.vstack((np.hstack((PEst, np.zeros((len(xEst), LM_SIZE)))),
160191
np.hstack((np.zeros((LM_SIZE, len(xEst))), initP))))
161192

162-
mah_dists = calc_mahalanobis_dist(xAug, PAug)
193+
mah_dists = calc_mahalanobis_dist(xAug, PAug, z, iz)
163194
minid = mah_dists.index(min(mah_dists))
164195
# print(minid)
165196

@@ -171,18 +202,16 @@ def ekf_slam(xEst, PEst, u, z):
171202
else:
172203
print("Old LM")
173204

174-
# print("DB LM")
175-
# lm=xEst(4+2*(I-1):5+2*(I-1));%対応付けられたランドマークデータの取得
176-
# %イノベーションの計算
177-
# [y,S,H]=CalcInnovation(lm,xEst,PEst,z(iz,1:2),I);
178-
# K = PEst*H'*inv(S);
179-
# xEst = xEst + K*y;
180-
# PEst = (eye(size(xEst,1)) - K*H)*PEst;
181-
# end
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)
208+
209+
K = PEst * H.T * np.linalg.inv(S)
210+
xEst = xEst + K * y
211+
PEst = (np.eye(len(xEst)) - K * H) * PEst
182212

183-
# xEst(3)=PI2PI(xEst(3));%角度補正
213+
xEst[2] = pi_2_pi(xEst[2])
184214

185-
print(len(xEst))
186215
return xEst, PEst
187216

188217

0 commit comments

Comments
 (0)