Skip to content

Commit b355215

Browse files
committed
first release histogram filter
1 parent 2917dc2 commit b355215

File tree

1 file changed

+69
-57
lines changed

1 file changed

+69
-57
lines changed

Localization/histogram_filter/histogram_filter.py

+69-57
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,25 @@
1919
from scipy.ndimage import gaussian_filter
2020

2121
# Parameters
22-
NOISE_RANGE = 2.0 # [m] 1σ range noise parameter
23-
NOISE_SPEED = 0.5 # [m/s] 1σ speed noise parameter
24-
2522
EXTEND_AREA = 10.0 # [m] grid map extention length
2623
SIM_TIME = 50.0 # simulation time [s]
2724
DT = 0.1 # time tick [s]
2825
MAX_RANGE = 10.0 # maximum observation range
29-
MOTION_STD = 1.0
30-
RANGE_STD = 3.0 # standard diviation for gaussian distribution
26+
MOTION_STD = 1.0 # standard deviation for motion gaussian distribution
27+
RANGE_STD = 3.0 # standard deviation for observation gaussian distribution
28+
29+
# grid map param
30+
XY_RESO = 0.5 # xy grid resolution
31+
MINX = -15.0
32+
MINY = -5.0
33+
MAXX = 15.0
34+
MAXY = 25.0
35+
36+
37+
# simulation paramters
38+
NOISE_RANGE = 2.0 # [m] 1σ range noise parameter
39+
NOISE_SPEED = 0.5 # [m/s] 1σ speed noise parameter
40+
3141

3242
show_animation = True
3343

@@ -41,34 +51,41 @@ def __init__(self):
4151
self.miny = None
4252
self.maxx = None
4353
self.maxx = None
54+
self.xw = None
55+
self.yw = None
56+
self.dx = 0.0 # movement distance
57+
self.dy = 0.0 # movement distance
4458

4559

46-
def histogram_filter_localization(gmap, u, z, yaw, dx, dy):
60+
def histogram_filter_localization(gmap, u, z, yaw):
4761

48-
gmap, dx, dy = motion_update(gmap, u, yaw, dx, dy)
62+
gmap = motion_update(gmap, u, yaw)
4963

5064
gmap = observation_update(gmap, z, RANGE_STD)
5165

52-
return gmap.data, dx, dy
66+
return gmap
5367

5468

55-
def observation_update(gmap, z, std):
69+
def calc_gaussian_observation_pdf(gmap, z, iz, ix, iy, std):
5670

57-
for iz in range(z.shape[0]):
58-
for ix in range(len(gmap.data)):
59-
for iy in range(len(gmap.data[ix])):
71+
# predicted range
72+
x = ix * gmap.xyreso + gmap.minx
73+
y = iy * gmap.xyreso + gmap.miny
74+
d = math.sqrt((x - z[iz, 1])**2 + (y - z[iz, 2])**2)
6075

61-
# observation range
62-
zr = z[iz, 0]
76+
# likelihood
77+
pdf = (1.0 - norm.cdf(abs(d - z[iz, 0]), 0.0, std))
6378

64-
# predicted range
65-
x = ix * gmap.xyreso + gmap.minx
66-
y = iy * gmap.xyreso + gmap.miny
67-
d = math.sqrt((x - z[iz, 1])**2 + (y - z[iz, 2])**2)
79+
return pdf
6880

69-
# likelihood
70-
pdf = (1.0 - norm.cdf(abs(d - zr), 0.0, std))
71-
gmap.data[ix][iy] *= pdf
81+
82+
def observation_update(gmap, z, std):
83+
84+
for iz in range(z.shape[0]):
85+
for ix in range(gmap.xw):
86+
for iy in range(gmap.yw):
87+
gmap.data[ix][iy] *= calc_gaussian_observation_pdf(
88+
gmap, z, iz, ix, iy, std)
7289

7390
gmap = normalize_probability(gmap)
7491

@@ -133,22 +150,22 @@ def normalize_probability(gmap):
133150

134151
sump = sum([sum(igmap) for igmap in gmap.data])
135152

136-
for i in range(len(gmap.data)):
137-
for ii in range(len(gmap.data[i])):
138-
gmap.data[i][ii] /= sump
153+
for ix in range(gmap.xw):
154+
for iy in range(gmap.yw):
155+
gmap.data[ix][iy] /= sump
139156

140157
return gmap
141158

142159

143-
def init_gmap(xyreso):
160+
def init_gmap(xyreso, minx, miny, maxx, maxy):
144161

145162
gmap = grid_map()
146163

147164
gmap.xyreso = xyreso
148-
gmap.minx = -15.0
149-
gmap.miny = -5.0
150-
gmap.maxx = 15.0
151-
gmap.maxy = 25.0
165+
gmap.minx = minx
166+
gmap.miny = miny
167+
gmap.maxx = maxx
168+
gmap.maxy = maxy
152169
gmap.xw = int(round((gmap.maxx - gmap.minx) / gmap.xyreso))
153170
gmap.yw = int(round((gmap.maxy - gmap.miny) / gmap.xyreso))
154171

@@ -162,43 +179,45 @@ def map_shift(gmap, xshift, yshift):
162179

163180
tgmap = copy.deepcopy(gmap.data)
164181

165-
lenx = len(gmap.data)
166-
leny = len(gmap.data[0])
167-
168-
for ix in range(lenx):
169-
for iy in range(leny):
182+
for ix in range(gmap.xw):
183+
for iy in range(gmap.yw):
170184
nix = ix + xshift
171185
niy = iy + yshift
172186

173-
if nix >= 0 and nix < lenx and niy >= 0 and niy < leny:
187+
if nix >= 0 and nix < gmap.xw and niy >= 0 and niy < gmap.yw:
174188
gmap.data[ix + xshift][iy + yshift] = tgmap[ix][iy]
175189

176190
return gmap
177191

178192

179-
def motion_update(gmap, u, yaw, dx, dy):
193+
def motion_update(gmap, u, yaw):
180194

181-
dx += DT * math.cos(yaw) * u[0]
182-
dy += DT * math.sin(yaw) * u[0]
195+
gmap.dx += DT * math.cos(yaw) * u[0]
196+
gmap.dy += DT * math.sin(yaw) * u[0]
183197

184-
xshift = dx // gmap.xyreso
185-
yshift = dy // gmap.xyreso
198+
xshift = gmap.dx // gmap.xyreso
199+
yshift = gmap.dy // gmap.xyreso
186200

187-
if abs(xshift) >= 1.0 or abs(yshift) >= 1.0:
201+
if abs(xshift) >= 1.0 or abs(yshift) >= 1.0: # map should be shifted
188202
gmap = map_shift(gmap, int(xshift), int(yshift))
189-
dx -= xshift * gmap.xyreso
190-
dy -= yshift * gmap.xyreso
203+
gmap.dx -= xshift * gmap.xyreso
204+
gmap.dy -= yshift * gmap.xyreso
191205

192206
gmap.data = gaussian_filter(gmap.data, sigma=MOTION_STD)
193207

194-
return gmap, dx, dy
208+
return gmap
209+
210+
211+
def calc_grid_index(gmap):
212+
mx, my = np.mgrid[slice(gmap.minx - gmap.xyreso / 2.0, gmap.maxx + gmap.xyreso / 2.0, gmap.xyreso),
213+
slice(gmap.miny - gmap.xyreso / 2.0, gmap.maxy + gmap.xyreso / 2.0, gmap.xyreso)]
214+
215+
return mx, my
195216

196217

197218
def main():
198219
print(__file__ + " start!!")
199220

200-
xyreso = 0.5 # xy grid resolution
201-
202221
# RFID positions [x, y]
203222
RFID = np.array([[10.0, 0.0],
204223
[10.0, 10.0],
@@ -208,25 +227,18 @@ def main():
208227
time = 0.0
209228

210229
xTrue = np.matrix(np.zeros((4, 1)))
211-
212-
gmap = init_gmap(xyreso)
213-
214-
dx, dy = 0.0, 0.0
215-
216-
mx, my = np.mgrid[slice(gmap.minx - gmap.xyreso / 2.0, gmap.maxx + gmap.xyreso / 2.0, gmap.xyreso),
217-
slice(gmap.miny - gmap.xyreso / 2.0, gmap.maxy + gmap.xyreso / 2.0, gmap.xyreso)]
230+
gmap = init_gmap(XY_RESO, MINX, MINY, MAXX, MAXY)
231+
mx, my = calc_grid_index(gmap) # for grid map visualization
218232

219233
while SIM_TIME >= time:
220234
time += DT
221235

222236
u = calc_input()
223237

224-
# Orientation is known in this simulation
225-
yaw = xTrue[2, 0]
238+
yaw = xTrue[2, 0] # Orientation is known
226239
xTrue, z, ud = observation(xTrue, u, RFID)
227240

228-
gmap.data, dx, dy = histogram_filter_localization(
229-
gmap, u, z, yaw, dx, dy)
241+
gmap = histogram_filter_localization(gmap, u, z, yaw)
230242

231243
if show_animation:
232244
plt.cla()

0 commit comments

Comments
 (0)