Skip to content

Commit d37dad8

Browse files
committed
first release ICP SLAM
1 parent 0b24ba5 commit d37dad8

File tree

1 file changed

+71
-59
lines changed

1 file changed

+71
-59
lines changed

SLAM/iterative_closest_point/iterative_closest_point.py

Lines changed: 71 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,48 @@
1010
import numpy as np
1111
import matplotlib.pyplot as plt
1212

13+
# ICP parameters
14+
EPS = 0.0001
15+
MAXITER = 100
1316

14-
def update_homogenerous_matrix(Hin, R, T):
15-
16-
H = np.matrix(np.zeros((3, 3))) # translation vector
17-
18-
H[0, 0] = R[0, 0]
19-
H[1, 0] = R[1, 0]
20-
H[0, 1] = R[0, 1]
21-
H[1, 1] = R[1, 1]
22-
H[2, 2] = 1.0
23-
24-
H[0, 2] = T[0, 0]
25-
H[1, 2] = T[1, 0]
26-
27-
if Hin is None:
28-
return H
29-
else:
30-
return Hin * H
17+
show_animation = True
3118

3219

3320
def ICP_matching(pdata, data):
3421
H = None # homogeneraous transformation matrix
3522

36-
# ICP
37-
EPS = 0.0001
38-
maxIter = 100
39-
4023
dError = 1000.0
4124
preError = 1000.0
4225
count = 0
4326

4427
while dError >= EPS:
4528
count += 1
4629

47-
error = nearest_neighbor_assosiation(pdata, data)
48-
Rt, Tt = SVD_motion_estimation(pdata, data)
30+
if show_animation:
31+
plt.cla()
32+
plt.plot(pdata[0, :], pdata[1, :], ".r")
33+
plt.plot(data[0, :], data[1, :], ".b")
34+
plt.plot(0.0, 0.0, "xr")
35+
plt.axis("equal")
36+
plt.pause(1.0)
37+
38+
inds, error = nearest_neighbor_assosiation(pdata, data)
39+
Rt, Tt = SVD_motion_estimation(pdata[:, inds], data)
4940

41+
# update current points
5042
data = (Rt * data) + Tt
5143

5244
H = update_homogenerous_matrix(H, Rt, Tt)
5345

5446
dError = abs(preError - error)
5547
preError = error
48+
print("Residual:", error)
5649

5750
if dError <= EPS:
58-
print("Converge", dError, count)
51+
print("Converge", error, dError, count)
5952
break
60-
elif maxIter <= count:
53+
elif MAXITER <= count:
54+
print("Not Converge...", error, dError, count)
6155
break
6256

6357
R = np.matrix(H[0:2, 0:2])
@@ -66,19 +60,47 @@ def ICP_matching(pdata, data):
6660
return R, T
6761

6862

63+
def update_homogenerous_matrix(Hin, R, T):
64+
65+
H = np.matrix(np.zeros((3, 3)))
66+
67+
H[0, 0] = R[0, 0]
68+
H[1, 0] = R[1, 0]
69+
H[0, 1] = R[0, 1]
70+
H[1, 1] = R[1, 1]
71+
H[2, 2] = 1.0
72+
73+
H[0, 2] = T[0, 0]
74+
H[1, 2] = T[1, 0]
75+
76+
if Hin is None:
77+
return H
78+
else:
79+
return Hin * H
80+
81+
6982
def nearest_neighbor_assosiation(pdata, data):
7083

84+
# calc the sum of residual errors
7185
ddata = pdata - data
72-
7386
d = np.linalg.norm(ddata, axis=0)
74-
7587
error = sum(d)
7688

89+
# calc index with nearest neighbor assosiation
90+
inds = []
7791
for i in range(data.shape[1]):
78-
for ii in range(data.shape[1]):
79-
print(i)
92+
minid = -1
93+
mind = float("inf")
94+
for ii in range(pdata.shape[1]):
95+
d = np.linalg.norm(pdata[:, ii] - data[:, i])
96+
97+
if mind >= d:
98+
mind = d
99+
minid = ii
100+
101+
inds.append(minid)
80102

81-
return error
103+
return inds, error
82104

83105

84106
def SVD_motion_estimation(pdata, data):
@@ -104,35 +126,25 @@ def main():
104126
# simulation parameters
105127
nPoint = 10
106128
fieldLength = 50.0
107-
motion = [0.5, 1.0, math.radians(-40.0)] # movement [x[m],y[m],yaw[deg]]
108-
# transitionSigma=0.01;%並進方向の移動誤差標準偏差[m]
109-
# thetaSigma=1; %回転方向の誤差標準偏差[deg]
110-
111-
# previous point data
112-
px = (np.random.rand(nPoint) - 0.5) * fieldLength
113-
py = (np.random.rand(nPoint) - 0.5) * fieldLength
114-
115-
cx = [math.cos(motion[2]) * x - math.sin(motion[2]) * y + motion[0]
116-
for (x, y) in zip(px, py)]
117-
cy = [math.sin(motion[2]) * x + math.cos(motion[2]) * y + motion[1]
118-
for (x, y) in zip(px, py)]
119-
120-
pdata = np.matrix(np.vstack((px, py)))
121-
# print(pdata)
122-
data = np.matrix(np.vstack((cx, cy)))
123-
# print(data)
124-
odata = data[:, :]
125-
126-
R, T = ICP_matching(pdata, data)
127-
128-
fdata = (R * odata) + T
129-
130-
plt.plot(px, py, ".b")
131-
plt.plot(cx, cy, ".r")
132-
plt.plot(fdata[0, :], fdata[1, :], "xk")
133-
plt.plot(0.0, 0.0, "xr")
134-
plt.axis("equal")
135-
plt.show()
129+
motion = [0.5, 2.0, math.radians(-10.0)] # movement [x[m],y[m],yaw[deg]]
130+
131+
nsim = 3 # number of simulation
132+
133+
for _ in range(nsim):
134+
135+
# previous points
136+
px = (np.random.rand(nPoint) - 0.5) * fieldLength
137+
py = (np.random.rand(nPoint) - 0.5) * fieldLength
138+
pdata = np.matrix(np.vstack((px, py)))
139+
140+
# current points
141+
cx = [math.cos(motion[2]) * x - math.sin(motion[2]) * y + motion[0]
142+
for (x, y) in zip(px, py)]
143+
cy = [math.sin(motion[2]) * x + math.cos(motion[2]) * y + motion[1]
144+
for (x, y) in zip(px, py)]
145+
data = np.matrix(np.vstack((cx, cy)))
146+
147+
R, T = ICP_matching(pdata, data)
136148

137149

138150
if __name__ == '__main__':

0 commit comments

Comments
 (0)