1
1
"""
2
2
3
- Iterative Closet Point (ICP) SLAM example
3
+ Iterative Closest Point (ICP) SLAM example
4
4
5
5
author: Atsushi Sakai (@Atsushi_twi)
6
6
17
17
show_animation = True
18
18
19
19
20
- def ICP_matching (pdata , data ):
20
+ def ICP_matching (ppoints , cpoints ):
21
+ """
22
+ Iterative Closest Point matching
23
+
24
+ - input
25
+ ppoints: 2D points in the previous frame
26
+ cpoints: 2D points in the current frame
27
+
28
+ - output
29
+ R: Rotation matrix
30
+ T: Translation vector
31
+
32
+ """
21
33
H = None # homogeneraous transformation matrix
22
34
23
35
dError = 1000.0
@@ -29,17 +41,17 @@ def ICP_matching(pdata, data):
29
41
30
42
if show_animation :
31
43
plt .cla ()
32
- plt .plot (pdata [0 , :], pdata [1 , :], ".r" )
33
- plt .plot (data [0 , :], data [1 , :], ".b" )
44
+ plt .plot (ppoints [0 , :], ppoints [1 , :], ".r" )
45
+ plt .plot (cpoints [0 , :], cpoints [1 , :], ".b" )
34
46
plt .plot (0.0 , 0.0 , "xr" )
35
47
plt .axis ("equal" )
36
48
plt .pause (1.0 )
37
49
38
- inds , error = nearest_neighbor_assosiation (pdata , data )
39
- Rt , Tt = SVD_motion_estimation (pdata [:, inds ], data )
50
+ inds , error = nearest_neighbor_assosiation (ppoints , cpoints )
51
+ Rt , Tt = SVD_motion_estimation (ppoints [:, inds ], cpoints )
40
52
41
53
# update current points
42
- data = (Rt * data ) + Tt
54
+ cpoints = (Rt * cpoints ) + Tt
43
55
44
56
H = update_homogenerous_matrix (H , Rt , Tt )
45
57
@@ -79,20 +91,20 @@ def update_homogenerous_matrix(Hin, R, T):
79
91
return Hin * H
80
92
81
93
82
- def nearest_neighbor_assosiation (pdata , data ):
94
+ def nearest_neighbor_assosiation (ppoints , cpoints ):
83
95
84
96
# calc the sum of residual errors
85
- ddata = pdata - data
86
- d = np .linalg .norm (ddata , axis = 0 )
97
+ dcpoints = ppoints - cpoints
98
+ d = np .linalg .norm (dcpoints , axis = 0 )
87
99
error = sum (d )
88
100
89
101
# calc index with nearest neighbor assosiation
90
102
inds = []
91
- for i in range (data .shape [1 ]):
103
+ for i in range (cpoints .shape [1 ]):
92
104
minid = - 1
93
105
mind = float ("inf" )
94
- for ii in range (pdata .shape [1 ]):
95
- d = np .linalg .norm (pdata [:, ii ] - data [:, i ])
106
+ for ii in range (ppoints .shape [1 ]):
107
+ d = np .linalg .norm (ppoints [:, ii ] - cpoints [:, i ])
96
108
97
109
if mind >= d :
98
110
mind = d
@@ -103,13 +115,13 @@ def nearest_neighbor_assosiation(pdata, data):
103
115
return inds , error
104
116
105
117
106
- def SVD_motion_estimation (pdata , data ):
118
+ def SVD_motion_estimation (ppoints , cpoints ):
107
119
108
- pm = np .matrix (np .mean (pdata , axis = 1 ))
109
- cm = np .matrix (np .mean (data , axis = 1 ))
120
+ pm = np .matrix (np .mean (ppoints , axis = 1 ))
121
+ cm = np .matrix (np .mean (cpoints , axis = 1 ))
110
122
111
- pshift = np .matrix (pdata - pm )
112
- cshift = np .matrix (data - cm )
123
+ pshift = np .matrix (ppoints - pm )
124
+ cshift = np .matrix (cpoints - cm )
113
125
114
126
W = cshift * pshift .T
115
127
u , s , vh = np .linalg .svd (W )
@@ -135,16 +147,16 @@ def main():
135
147
# previous points
136
148
px = (np .random .rand (nPoint ) - 0.5 ) * fieldLength
137
149
py = (np .random .rand (nPoint ) - 0.5 ) * fieldLength
138
- pdata = np .matrix (np .vstack ((px , py )))
150
+ ppoints = np .matrix (np .vstack ((px , py )))
139
151
140
152
# current points
141
153
cx = [math .cos (motion [2 ]) * x - math .sin (motion [2 ]) * y + motion [0 ]
142
154
for (x , y ) in zip (px , py )]
143
155
cy = [math .sin (motion [2 ]) * x + math .cos (motion [2 ]) * y + motion [1 ]
144
156
for (x , y ) in zip (px , py )]
145
- data = np .matrix (np .vstack ((cx , cy )))
157
+ cpoints = np .matrix (np .vstack ((cx , cy )))
146
158
147
- R , T = ICP_matching (pdata , data )
159
+ R , T = ICP_matching (ppoints , cpoints )
148
160
149
161
150
162
if __name__ == '__main__' :
0 commit comments