CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download
Project: test
Views: 91872
1
from filterpy.monte_carlo import stratified_resample
2
import matplotlib as mpl
3
import matplotlib.pyplot as plt
4
5
import numpy as np
6
from numpy.random import randn, random, uniform, multivariate_normal, seed
7
#from nonlinear_plots import plot_monte_carlo_mean
8
import pylab as plt
9
import scipy.stats
10
from RobotLocalizationParticleFilter import *
11
12
13
14
class ParticleFilter(object):
15
16
def __init__(self, N, x_dim, y_dim):
17
self.particles = np.empty((N, 3)) # x, y, heading
18
self.N = N
19
self.x_dim = x_dim
20
self.y_dim = y_dim
21
22
# distribute particles randomly with uniform weight
23
self.weights = np.empty(N)
24
self.weights.fill(1./N)
25
self.particles[:, 0] = uniform(0, x_dim, size=N)
26
self.particles[:, 1] = uniform(0, y_dim, size=N)
27
self.particles[:, 2] = uniform(0, 2*np.pi, size=N)
28
29
30
def predict(self, u, std):
31
""" move according to control input u with noise std"""
32
33
self.particles[:, 2] += u[0] + randn(self.N) * std[0]
34
self.particles[:, 2] %= 2 * np.pi
35
36
d = u[1] + randn(self.N)
37
self.particles[:, 0] += np.cos(self.particles[:, 2]) * d
38
self.particles[:, 1] += np.sin(self.particles[:, 2]) * d
39
40
self.particles[:, 0:2] += u + randn(self.N, 2) * std
41
42
43
def weight(self, z, var):
44
dist = np.sqrt((self.particles[:, 0] - z[0])**2 +
45
(self.particles[:, 1] - z[1])**2)
46
47
# simplification assumes variance is invariant to world projection
48
n = scipy.stats.norm(0, np.sqrt(var))
49
prob = n.pdf(dist)
50
51
# particles far from a measurement will give us 0.0 for a probability
52
# due to floating point limits. Once we hit zero we can never recover,
53
# so add some small nonzero value to all points.
54
prob += 1.e-12
55
self.weights += prob
56
self.weights /= sum(self.weights) # normalize
57
58
59
def neff(self):
60
return 1. / np.sum(np.square(self.weights))
61
62
63
def resample(self):
64
p = np.zeros((self.N, 3))
65
w = np.zeros(self.N)
66
67
cumsum = np.cumsum(self.weights)
68
for i in range(self.N):
69
index = np.searchsorted(cumsum, random())
70
p[i] = self.particles[index]
71
w[i] = self.weights[index]
72
73
self.particles = p
74
self.weights = w / np.sum(w)
75
76
77
def estimate(self):
78
""" returns mean and variance """
79
pos = self.particles[:, 0:2]
80
mu = np.average(pos, weights=self.weights, axis=0)
81
var = np.average((pos - mu)**2, weights=self.weights, axis=0)
82
83
return mu, var
84
85
86
def plot_random_pd():
87
def norm(x, x0, sigma):
88
return np.exp(-0.5 * (x - x0) ** 2 / sigma ** 2)
89
90
91
def sigmoid(x, x0, alpha):
92
return 1. / (1. + np.exp(- (x - x0) / alpha))
93
94
x = np.linspace(0, 1, 100)
95
y2 = (0.1 * np.sin(norm(x, 0.2, 0.05)) + 0.25 * norm(x, 0.6, 0.05) +
96
.5*norm(x, .5, .08) +
97
np.sqrt(norm(x, 0.8, 0.06)) +0.1 * (1 - sigmoid(x, 0.45, 0.15)))
98
with plt.xkcd():
99
#plt.setp(plt.gca().get_xticklabels(), visible=False)
100
#plt.setp(plt.gca().get_yticklabels(), visible=False)
101
plt.axes(xticks=[], yticks=[], frameon=False)
102
plt.plot(x, y2)
103
104
105
def plot_monte_carlo_ukf():
106
107
def f(x,y):
108
return x+y, .1*x**2 + y*y
109
110
mean = (0, 0)
111
p = np.array([[32, 15], [15., 40.]])
112
113
# Compute linearized mean
114
mean_fx = f(*mean)
115
116
#generate random points
117
xs, ys = multivariate_normal(mean=mean, cov=p, size=3000).T
118
fxs, fys = f(xs, ys)
119
120
plt.subplot(121)
121
plt.gca().grid(b=False)
122
123
plt.scatter(xs, ys, marker='.', alpha=.2, color='k')
124
plt.xlim(-25, 25)
125
plt.ylim(-25, 25)
126
127
plt.subplot(122)
128
plt.gca().grid(b=False)
129
130
plt.scatter(fxs, fys, marker='.', alpha=0.2, color='k')
131
132
plt.ylim([-10, 200])
133
plt.xlim([-100, 100])
134
plt.show()
135
136
137
def plot_pf(pf, xlim=100, ylim=100, weights=True):
138
139
if weights:
140
a = plt.subplot(221)
141
a.cla()
142
143
plt.xlim(0, ylim)
144
#plt.ylim(0, 1)
145
a.set_yticklabels('')
146
plt.scatter(pf.particles[:, 0], pf.weights, marker='.', s=1, color='k')
147
a.set_ylim(bottom=0)
148
149
a = plt.subplot(224)
150
a.cla()
151
a.set_xticklabels('')
152
plt.scatter(pf.weights, pf.particles[:, 1], marker='.', s=1, color='k')
153
plt.ylim(0, xlim)
154
a.set_xlim(left=0)
155
#plt.xlim(0, 1)
156
157
a = plt.subplot(223)
158
a.cla()
159
160
else:
161
plt.cla()
162
plt.scatter(pf.particles[:, 0], pf.particles[:, 1], marker='.', s=1, color='k')
163
plt.xlim(0, xlim)
164
plt.ylim(0, ylim)
165
166
167
def Gaussian(mu, sigma, x):
168
169
# calculates the probability of x for 1-dim Gaussian with mean mu and var. sigma
170
g = (np.exp(-((mu - x) ** 2) / (sigma ** 2) / 2.0) /
171
np.sqrt(2.0 * np.pi * (sigma ** 2)))
172
for i in range(len(g)):
173
g[i] = max(g[i], 1.e-29)
174
175
return g
176
177
178
def test_gaussian(N):
179
for i in range(N):
180
mean, std, x = randn(3)
181
std = abs(std)
182
183
d = Gaussian(mean, std, x) - scipy.stats.norm(mean, std).pdf(x)
184
assert abs(d) < 1.e-8, "{}, {}, {}, {}, {}, {}".format(d, mean, std, x, Gaussian(mean, std, x), scipy.stats.norm(mean, std).pdf(x))
185
186
187
def show_two_pf_plots():
188
""" Displays results of PF after 1 and 10 iterations for the book.
189
Note the book says this solves the full robot localization problem.
190
It doesn't bother simulating landmarks as this is just an illustration.
191
"""
192
193
seed(1234)
194
N = 3000
195
pf = ParticleFilter(N, 20, 20)
196
z = np.array([20, 20])
197
198
#plot(pf, weights=False)
199
200
for x in range(10):
201
202
z[0] = x+1 + randn()*0.3
203
z[1] = x+1 + randn()*0.3
204
205
pf.predict((1,1), (0.2, 0.2))
206
pf.weight(z=z, var=.8)
207
pf.resample()
208
209
if x == 0:
210
plt.subplot(121)
211
elif x == 9:
212
plt.subplot(122)
213
214
if x == 0 or x == 9:
215
mu, var = pf.estimate()
216
plot_pf(pf, 20, 20, weights=False)
217
if x == 0:
218
plt.scatter(mu[0], mu[1], color='g', s=100)
219
plt.scatter(x+1, x+1, marker='x', color='r', s=180, lw=3)
220
else:
221
plt.scatter(mu[0], mu[1], color='g', s=100, label="PF")
222
plt.scatter([x+1], [x+1], marker='x', color='r', s=180, label="True", lw=3)
223
plt.legend(scatterpoints=1)
224
plt.tight_layout()
225
226
227
def test_pf():
228
229
#seed(1234)
230
N = 10000
231
R = .2
232
landmarks = [[-1, 2], [20,4], [10,30], [18,25]]
233
#landmarks = [[-1, 2], [2,4]]
234
235
pf = RobotLocalizationParticleFilter(N, 20, 20, landmarks, R)
236
237
plot_pf(pf, 20, 20, weights=False)
238
239
dt = .01
240
plt.pause(dt)
241
242
for x in range(18):
243
244
zs = []
245
pos=(x+3, x+3)
246
247
for landmark in landmarks:
248
d = np.sqrt((landmark[0]-pos[0])**2 + (landmark[1]-pos[1])**2)
249
zs.append(d + randn()*R)
250
251
pf.predict((0.01, 1.414), (.2, .05))
252
pf.update(z=zs)
253
pf.resample()
254
#print(x, np.array(list(zip(pf.particles, pf.weights))))
255
256
mu, var = pf.estimate()
257
plot_pf(pf, 20, 20, weights=False)
258
plt.plot(pos[0], pos[1], marker='*', color='r', ms=10)
259
plt.scatter(mu[0], mu[1], color='g', s=100)
260
plt.tight_layout()
261
plt.pause(dt)
262
263
264
def test_pf2():
265
N = 1000
266
sensor_std_err = .2
267
landmarks = [[-1, 2], [20,4], [-20,6], [18,25]]
268
269
pf = RobotLocalizationParticleFilter(N, 20, 20, landmarks, sensor_std_err)
270
271
xs = []
272
for x in range(18):
273
zs = []
274
pos=(x+1, x+1)
275
276
for landmark in landmarks:
277
d = np.sqrt((landmark[0]-pos[0])**2 + (landmark[1]-pos[1])**2)
278
zs.append(d + randn()*sensor_std_err)
279
280
# move diagonally forward to (x+1, x+1)
281
pf.predict((0.00, 1.414), (.2, .05))
282
pf.update(z=zs)
283
pf.resample()
284
285
mu, var = pf.estimate()
286
xs.append(mu)
287
288
xs = np.array(xs)
289
plt.plot(xs[:, 0], xs[:, 1])
290
plt.show()
291
292
293
def plot_cumsum(a):
294
295
N = len(a)
296
297
cmap = mpl.colors.ListedColormap([[0., .4, 1.],
298
[0., .8, 1.],
299
[1., .8, 0.],
300
[1., .4, 0.]]*(int(N/4) + 1))
301
cumsum = np.cumsum(np.asarray(a) / np.sum(a))
302
cumsum = np.insert(cumsum, 0, 0)
303
304
fig = plt.figure(figsize=(6,3))
305
ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
306
norm = mpl.colors.BoundaryNorm(cumsum, cmap.N)
307
bar = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
308
norm=norm,
309
drawedges=False,
310
spacing='proportional',
311
orientation='horizontal')
312
if N > 10:
313
bar.set_ticks([])
314
plt.show()
315
316
317
def plot_stratified_resample(a):
318
N = len(a)
319
320
cmap = mpl.colors.ListedColormap([[0., .4, 1.],
321
[0., .8, 1.],
322
[1., .8, 0.],
323
[1., .4, 0.]]*(int(N/4) + 1))
324
cumsum = np.cumsum(np.asarray(a) / np.sum(a))
325
cumsum = np.insert(cumsum, 0, 0)
326
327
fig = plt.figure(figsize=(6,3))
328
ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
329
norm = mpl.colors.BoundaryNorm(cumsum, cmap.N)
330
bar = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
331
norm=norm,
332
drawedges=False,
333
spacing='proportional',
334
orientation='horizontal')
335
xs = np.linspace(0., 1.-1./N, N)
336
ax.vlines(xs, 0, 1, lw=2)
337
338
# make N subdivisions, and chose a random position within each one
339
b = (random(N) + range(N)) / N
340
plt.scatter(b, [.5]*len(b), s=60, facecolor='k', edgecolor='k')
341
bar.set_ticks([])
342
plt.title('stratified resampling')
343
plt.show()
344
345
346
def plot_systematic_resample(a):
347
N = len(a)
348
349
cmap = mpl.colors.ListedColormap([[0., .4, 1.],
350
[0., .8, 1.],
351
[1., .8, 0.],
352
[1., .4, 0.]]*(int(N/4) + 1))
353
cumsum = np.cumsum(np.asarray(a) / np.sum(a))
354
cumsum = np.insert(cumsum, 0, 0)
355
356
fig = plt.figure(figsize=(6,3))
357
ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
358
norm = mpl.colors.BoundaryNorm(cumsum, cmap.N)
359
bar = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
360
norm=norm,
361
drawedges=False,
362
spacing='proportional',
363
orientation='horizontal')
364
xs = np.linspace(0., 1.-1./N, N)
365
ax.vlines(xs, 0, 1, lw=2)
366
367
# make N subdivisions, and chose a random position within each one
368
b = (random() + np.array(range(N))) / N
369
plt.scatter(b, [.5]*len(b), s=60, facecolor='k', edgecolor='k')
370
bar.set_ticks([])
371
plt.title('systematic resampling')
372
plt.show()
373
374
375
def plot_multinomial_resample(a):
376
N = len(a)
377
378
cmap = mpl.colors.ListedColormap([[0., .4, 1.],
379
[0., .8, 1.],
380
[1., .8, 0.],
381
[1., .4, 0.]]*(int(N/4) + 1))
382
cumsum = np.cumsum(np.asarray(a) / np.sum(a))
383
cumsum = np.insert(cumsum, 0, 0)
384
385
fig = plt.figure(figsize=(6,3))
386
ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
387
norm = mpl.colors.BoundaryNorm(cumsum, cmap.N)
388
bar = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
389
norm=norm,
390
drawedges=False,
391
spacing='proportional',
392
orientation='horizontal')
393
394
# make N subdivisions, and chose a random position within each one
395
b = random(N)
396
plt.scatter(b, [.5]*len(b), s=60, facecolor='k', edgecolor='k')
397
bar.set_ticks([])
398
plt.title('multinomial resampling')
399
plt.show()
400
401
402
def plot_residual_resample(a):
403
N = len(a)
404
405
a_norm = np.asarray(a) / np.sum(a)
406
cumsum = np.cumsum(a_norm)
407
cumsum = np.insert(cumsum, 0, 0)
408
409
cmap = mpl.colors.ListedColormap([[0., .4, 1.],
410
[0., .8, 1.],
411
[1., .8, 0.],
412
[1., .4, 0.]]*(int(N/4) + 1))
413
414
fig = plt.figure(figsize=(6,3))
415
ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
416
norm = mpl.colors.BoundaryNorm(cumsum, cmap.N)
417
bar = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
418
norm=norm,
419
drawedges=False,
420
spacing='proportional',
421
orientation='horizontal')
422
423
indexes = residual_resample(a_norm)
424
bins = np.bincount(indexes)
425
for i in range(1, N):
426
n = bins[i-1] # number particles in this sample
427
if n > 0:
428
b = np.linspace(cumsum[i-1], cumsum[i], n+2)[1:-1]
429
plt.scatter(b, [.5]*len(b), s=60, facecolor='k', edgecolor='k')
430
bar.set_ticks([])
431
plt.title('residual resampling')
432
plt.show()
433
434
435
if __name__ == '__main__':
436
plot_residual_resample([.1, .2, .3, .4, .2, .3, .1])
437
438
#example()
439
#show_two_pf_plots()
440
441
a = [.1, .2, .1, .6]
442
#plot_cumsum(a)
443
#test_pf()
444
445