我试图执行以下代码
p, c = [], []
for z in mes:
print (z)
print (c)
print (p)
p.append(kf.x)
c.append(kf.P)
kf.predict()
kf.update(z) #error on this line
我收到错误:
ValueError:尺寸不匹配:数组' cov'形状(1,1),但 '平均'是一个长度为2的向量。
这是屏幕上显示的输出
[512 102]
[array([[ 1000., 0., 0., 0.],
[ 0., 1000., 0., 0.],
[ 0., 0., 1000., 0.],
[ 0., 0., 0., 1000.]])]
[array([[ 396.],
[ 187.],
[ 0.],
[ 0.]])]
如果我只采用z
的第一个元素,它可以正常工作,但是,这并不是我想要的行为。
p, c = [], []
for z in mes:
print (z)
print (c)
print (p)
p.append(kf.x)
c.append(kf.P)
kf.predict()
kf.update(z[0])
更新其他信息
此错误来自multivariate.py
in scipy。我似乎无法从cov
更改(1,1)
的形状。我可以使用mean
更改z[0]
的长度,但是,这并不合适。我想原样使用z
。我还将整个代码发布为gist here。我也将filterpy library用于卡尔曼滤波器。有live python notebook使用此卡尔曼过滤器,但是,它并没有像我的场景中那样使用z
。
答案 0 :(得分:1)
使用filterpy库时,您自己负责设置卡尔曼滤波器的初始状态,并且各种矩阵的尺寸需要兼容。如果您查看KalmanFilter.update()
方法,您可以跟踪它所执行的计算,并在矩阵维度上提出以下一组约束:
R.shape == (dim_z, dim_z)
H.shape == (dim_z, dim_x)
P.shape == (dim_x, dim_x)
x.shape == (dim_x, 1...)
z.shape == (dim_z, 1...)
其中1...
可以表示大小为1的某些维度序列,两者的大小相同。例如,在您的情况下,dim_x == 4
和dim_z == 2
因此您可以拥有x.shape == (4, 1)
和z.shape == (2, 1)
,或者您可以拥有x.shape == (4,)
和z.shape == (2,)
,但你不能混搭。 (请注意,KalmanFilter.__init__()
文档似乎为H
提供了错误的必需维度。)
您的代码在两个位置设置了错误的尺寸:
H
设置为1x4矩阵,而不是2x4。 (我注意到你已经注释了有效的代码。)R
设置为标量值而不是2x2矩阵。可以说卡尔曼滤波器实现应该考虑到这一点,但只有当你将R
作为参数传递给update()
时才会这样做,而不是在你提前设置它时。 (但要小心:如果将R
设置为标量,代码仍将工作!它会做我认为错误的事情:为每个元素添加2矩阵而不是添加2倍的单位矩阵。)当您将z
传递给update()
方法时,您传递的是一个两元素列表,该列表将转换为2元素向量,而不是2x1矩阵,因为它应该是与x
(4x1)兼容。您可以通过在调用z = np.array([z]).T
之前在循环体中运行update()
来 来解决此问题。但我认为有更好的方法:保持z
不变,只需将x
设为4元素向量:
x = np.array([measurements[0][0],measurements[0][1],0.,0.])
我不确定这是否意味着作者的工作,但它确实(目前),它可能应该。我认为要求在传递之前将每个测量值转换为2x1矩阵是有点傻。
KalmanFilter
包含test_matrix_dimensions()
方法,您可以使用该方法检查设置中的错误。但是我对它有点矛盾,因为如果你将x
设置为4元素向量,正如我在上一段中所建议的那样,它会将其标记为不正确。