1
1
"""
2
2
3
- Graph SLAM example
3
+ Graph based SLAM example
4
4
5
5
author: Atsushi Sakai (@Atsushi_twi)
6
6
14
14
15
15
16
16
# Simulation parameter
17
- Qsim = np .diag ([0.2 , math .radians (1 .0 )])** 2
18
- Rsim = np .diag ([1 .0 , math .radians (10 .0 )])** 2
17
+ Qsim = np .diag ([0.0 , math .radians (0 .0 )])** 2
18
+ Rsim = np .diag ([0 .0 , math .radians (00 .0 )])** 2
19
19
20
20
DT = 1.0 # time tick [s]
21
- SIM_TIME = 50 .0 # simulation time [s]
21
+ SIM_TIME = 20 .0 # simulation time [s]
22
22
MAX_RANGE = 20.0 # maximum observation range
23
23
STATE_SIZE = 3 # State size [x,y,yaw]
24
24
@@ -37,12 +37,12 @@ class Edge():
37
37
def __init__ (self ):
38
38
self .e = np .zeros ((3 , 1 ))
39
39
self .omega = np .zeros ((3 , 3 )) # information matrix
40
- self .d_t = 0.0
41
- self .d_td = 0.0
42
- self .yaw_t = 0.0
43
- self .yaw_td = 0.0
44
- self .angle_t = 0.0
45
- self .angle_td = 0.0
40
+ self .d1 = 0.0
41
+ self .d2 = 0.0
42
+ self .yaw1 = 0.0
43
+ self .yaw2 = 0.0
44
+ self .angle1 = 0.0
45
+ self .angle2 = 0.0
46
46
self .id1 = 0
47
47
self .id2 = 0
48
48
@@ -65,32 +65,32 @@ def calc_rotational_matrix(angle):
65
65
return Rt
66
66
67
67
68
- def calc_edge (xt , yt , yawt , xtd , ytd , yawtd , dt ,
69
- anglet , phit , dtd , angletd , phitd , t , td ):
68
+ def calc_edge (x1 , y1 , yaw1 , x2 , y2 , yaw2 , d1 ,
69
+ angle1 , phi1 , d2 , angle2 , phi2 , t1 , t2 ):
70
70
edge = Edge ()
71
71
72
- tangle1 = pi_2_pi (yawt + anglet )
73
- tangle2 = pi_2_pi (yawt + anglet )
74
- t1 = dt * math .cos (tangle1 )
75
- t2 = dtd * math .cos (tangle2 )
76
- t3 = dt * math .sin (tangle1 )
77
- t4 = dtd * math .sin (tangle2 )
72
+ tangle1 = pi_2_pi (yaw1 + angle1 )
73
+ tangle2 = pi_2_pi (yaw2 + angle2 )
74
+ tmp1 = d1 * math .cos (tangle1 )
75
+ tmp2 = d2 * math .cos (tangle2 )
76
+ tmp3 = d1 * math .sin (tangle1 )
77
+ tmp4 = d2 * math .sin (tangle2 )
78
78
79
- edge .e [0 , 0 ] = xtd - xt - t1 + t2
80
- edge .e [1 , 0 ] = ytd - yt - t3 + t4
81
- edge .e [2 , 0 ] = pi_2_pi (yawtd - yawt - phit + phitd )
79
+ edge .e [0 , 0 ] = x2 - x1 - tmp1 + tmp2
80
+ edge .e [1 , 0 ] = y2 - y1 - tmp3 + tmp4
81
+ edge .e [2 , 0 ] = pi_2_pi (yaw2 - yaw1 - phi1 + phi2 )
82
82
83
- sig_t = cal_observation_sigma (dt )
84
- sig_td = cal_observation_sigma (dtd )
83
+ sig_t = cal_observation_sigma (d1 )
84
+ sig_td = cal_observation_sigma (d2 )
85
85
86
86
Rt = calc_rotational_matrix (tangle1 )
87
87
Rtd = calc_rotational_matrix (tangle2 )
88
88
89
89
edge .omega = np .linalg .inv (Rt * sig_t * Rt .T + Rtd * sig_td * Rtd .T )
90
- edge .d_t , edge .d_td = dt , dtd
91
- edge .yaw_t , edge .yaw_td = yawt , yawtd
92
- edge .angle_t , edge .angle_td = anglet , angletd
93
- edge .id1 , edge .id2 = t , td
90
+ edge .d1 , edge .d2 = d1 , d2
91
+ edge .yaw1 , edge .yaw2 = yaw1 , yaw2
92
+ edge .angle1 , edge .angle2 = angle1 , angle2
93
+ edge .id1 , edge .id2 = t1 , t2
94
94
95
95
return edge
96
96
@@ -100,40 +100,35 @@ def calc_edges(xlist, zlist):
100
100
edges = []
101
101
zids = list (itertools .combinations (range (len (zlist )), 2 ))
102
102
103
- for (t , td ) in zids :
104
- # print(xlist)
105
- # print(zlist)
106
- xt , yt , yawt = xlist [0 , t ], xlist [1 , t ], xlist [2 , t ]
107
- xtd , ytd , yawtd = xlist [0 , td ], xlist [1 , td ], xlist [2 , td ]
108
- # print(zlist[t])
109
- # print(zlist[td])
110
-
111
- for iz1 in range (len (zlist [t ][:, 0 ])):
112
- for iz2 in range (len (zlist [td ][:, 0 ])):
113
- if zlist [t ][iz1 , 3 ] == zlist [td ][iz2 , 3 ]:
114
- dt , anglet , phit = zlist [t ][iz1 ,
115
- 0 ], zlist [t ][iz1 , 1 ], zlist [t ][iz1 , 2 ]
116
- dtd , angletd , phitd = zlist [td ][iz2 ,
117
- 0 ], zlist [td ][iz2 , 1 ], zlist [td ][iz2 , 2 ]
118
-
119
- edge = calc_edge (xt , yt , yawt , xtd , ytd , yawtd , dt ,
120
- anglet , phit , dtd , angletd , phitd , t , td )
103
+ for (t1 , t2 ) in zids :
104
+ x1 , y1 , yaw1 = xlist [0 , t1 ], xlist [1 , t1 ], xlist [2 , t1 ]
105
+ x2 , y2 , yaw2 = xlist [0 , t2 ], xlist [1 , t2 ], xlist [2 , t2 ]
106
+
107
+ for iz1 in range (len (zlist [t1 ][:, 0 ])):
108
+ for iz2 in range (len (zlist [t2 ][:, 0 ])):
109
+ if zlist [t1 ][iz1 , 3 ] == zlist [t2 ][iz2 , 3 ]:
110
+ d1 = zlist [t1 ][iz1 , 0 ]
111
+ angle1 , phi1 = zlist [t1 ][iz1 , 1 ], zlist [t1 ][iz1 , 2 ]
112
+ d2 = zlist [t2 ][iz2 , 0 ]
113
+ angle2 , phi2 = zlist [t2 ][iz2 , 1 ], zlist [t2 ][iz2 , 2 ]
114
+
115
+ edge = calc_edge (x1 , y1 , yaw1 , x2 , y2 , yaw2 , d1 ,
116
+ angle1 , phi1 , d2 , angle2 , phi2 , t1 , t2 )
121
117
122
118
edges .append (edge )
123
- break
124
119
125
120
return edges
126
121
127
122
128
123
def calc_jacobian (edge ):
129
- t = edge .yaw_t + edge .angle_t
130
- A = np .matrix ([[- 1.0 , 0 , edge .d_t * math .sin (t )],
131
- [0 , - 1.0 , - edge .d_t * math .cos (t )],
124
+ t1 = edge .yaw1 + edge .angle1
125
+ A = np .matrix ([[- 1.0 , 0 , edge .d1 * math .sin (t1 )],
126
+ [0 , - 1.0 , - edge .d1 * math .cos (t1 )],
132
127
[0 , 0 , - 1.0 ]])
133
128
134
- td = edge .yaw_td + edge .angle_td
135
- B = np .matrix ([[1.0 , 0 , - edge .d_td * math .sin (td )],
136
- [0 , 1.0 , edge .d_td * math .cos (td )],
129
+ t2 = edge .yaw2 + edge .angle2
130
+ B = np .matrix ([[1.0 , 0 , - edge .d2 * math .sin (t2 )],
131
+ [0 , 1.0 , edge .d2 * math .cos (t2 )],
137
132
[0 , 0 , 1.0 ]])
138
133
139
134
return A , B
@@ -143,27 +138,25 @@ def fill_H_and_b(H, b, edge):
143
138
144
139
A , B = calc_jacobian (edge )
145
140
146
- id1 = edge .id1 * 3
147
- id2 = edge .id2 * 3
141
+ id1 = edge .id1 * STATE_SIZE
142
+ id2 = edge .id2 * STATE_SIZE
148
143
149
- H [id1 :id1 + 3 , id1 :id1 + 3 ] += A .T * edge .omega * A
150
- H [id1 :id1 + 3 , id2 :id2 + 3 ] += A .T * edge .omega * B
151
- H [id2 :id2 + 3 , id1 :id1 + 3 ] += B .T * edge .omega * A
152
- H [id2 :id2 + 3 , id2 :id2 + 3 ] += B .T * edge .omega * B
144
+ H [id1 :id1 + STATE_SIZE , id1 :id1 + STATE_SIZE ] += A .T * edge .omega * A
145
+ H [id1 :id1 + STATE_SIZE , id2 :id2 + STATE_SIZE ] += A .T * edge .omega * B
146
+ H [id2 :id2 + STATE_SIZE , id1 :id1 + STATE_SIZE ] += B .T * edge .omega * A
147
+ H [id2 :id2 + STATE_SIZE , id2 :id2 + STATE_SIZE ] += B .T * edge .omega * B
153
148
154
- b [id1 :id1 + 3 , 0 ] += (A .T * edge .omega * edge .e )
155
- b [id2 :id2 + 3 , 0 ] += (B .T * edge .omega * edge .e )
149
+ b [id1 :id1 + STATE_SIZE , 0 ] += (A .T * edge .omega * edge .e )
150
+ b [id2 :id2 + STATE_SIZE , 0 ] += (B .T * edge .omega * edge .e )
156
151
157
152
return H , b
158
153
159
154
160
- def graph_based_slam (u , z , hxDR , hz ):
155
+ def graph_based_slam (x_init , hz ):
161
156
print ("start graph based slam" )
162
157
163
- x_opt = copy .deepcopy (hxDR )
164
- n = len (hz ) * 3
165
-
166
- # return x_opt
158
+ x_opt = copy .deepcopy (x_init )
159
+ n = len (hz ) * STATE_SIZE
167
160
168
161
for itr in range (MAX_ITR ):
169
162
edges = calc_edges (x_opt , hz )
@@ -175,10 +168,10 @@ def graph_based_slam(u, z, hxDR, hz):
175
168
for edge in edges :
176
169
H , b = fill_H_and_b (H , b , edge )
177
170
178
- H [0 :3 , 0 :3 ] += np .identity (3 ) * 10000 # to fix origin
171
+ # to fix origin
172
+ H [0 :STATE_SIZE , 0 :STATE_SIZE ] += np .identity (STATE_SIZE )
179
173
180
174
dx = - np .linalg .inv (H ).dot (b )
181
- # print(dx)
182
175
183
176
for i in range (len (hz )):
184
177
x_opt [0 :3 , i ] += dx [i * 3 :i * 3 + 3 , 0 ]
@@ -268,13 +261,14 @@ def main():
268
261
269
262
# State Vector [x y yaw v]'
270
263
xTrue = np .matrix (np .zeros ((STATE_SIZE , 1 )))
271
-
272
264
xDR = np .matrix (np .zeros ((STATE_SIZE , 1 ))) # Dead reckoning
273
265
274
266
# history
275
267
hxTrue = xTrue
276
268
hxDR = xTrue
277
- hz = []
269
+ hz = [np .matrix (np .zeros ((1 , 4 )))]
270
+ hz [0 ][0 , 3 ] = - 1
271
+ # hz = []
278
272
279
273
while SIM_TIME >= time :
280
274
time += DT
@@ -283,12 +277,10 @@ def main():
283
277
xTrue , z , xDR , ud = observation (xTrue , xDR , u , RFID )
284
278
285
279
hxDR = np .hstack ((hxDR , xDR ))
286
- hz .append (z )
287
-
288
- # store data history
289
280
hxTrue = np .hstack ((hxTrue , xTrue ))
281
+ hz .append (z )
290
282
291
- x_opt = graph_based_slam (ud , z , hxDR , hz )
283
+ x_opt = graph_based_slam (hxDR , hz )
292
284
293
285
if show_animation :
294
286
plt .cla ()
0 commit comments