如何为卡尔曼滤波器定义状态转移矩阵?

3
我将翻译以下内容,涉及IT技术相关。"Original Answer"的翻译为"最初的回答"。请注意保留HTML标签,并尽可能使内容更加通俗易懂。

我正在尝试理解卡尔曼滤波器,但有些术语我无法理解。

我在阅读关于动态模型转移矩阵(4x4)的内容。它说这个矩阵将把下面的方程映射到状态组件上。这些方程是简单的物理方程:

xt = x(t-1) + vx(dt)
yt = y(t-1) + vy(dt)
dt = 1

这个代码的表示如下:

最初的回答

dt = 0.1
DT = np.matrix([[1.,0.,dt,0],[0.,1.,0.,dt],[0.,0.,1.,0.],[0.,0.,0.,1.]])

有人可以帮我理解这个吗?这到底是什么意思?

最初的回答:

3个回答

2
状态转移矩阵描述了在给定初始状态的情况下,状态如何随时间变化。对于线性时不变系统(LTI),这是一个常数矩阵。
例如,假设我有一个2维离散时间LTI模型,如下所示:
x(k+1) = x(k) ---- (1)
y(k+1) = y(k) + 2x(k) ----- (2)
通过查看每个方程中状态的系数,可以将其写成矩阵形式,如下所示:
[x(k+1), y(k+1)] = [[1.0, 0.0],[2.0, 1.0]]* [x(k),y(k)]
矩阵[[1.0, 0.0],[2.0, 1.0]]称为状态转移矩阵。请注意,这类似于以矩阵形式编写线性方程组,以使用Cramer法则或矩阵求逆同时解决它们。
正如您所看到的,只有x(k)出现在(1)中,系数为1,因此转移矩阵的第一行为[1.0, 0.0]。同样,第二行是[2.0, 1.0]。
看一下你的矩阵结构:
DT = np.matrix([[1.,0.,dt,0],[0.,1.,0.,dt],[0.,0.,1.,0.],[0.,0.,0.,1.]])
我可以告诉你有4个变量[x(t-1),y(t-1),vx,vy]。你只展示了两个状态方程(x(t)和y(t)),你矩阵的前两行与方程中的变量系数相对应。
从你的矩阵中,我可以推断出最后两个方程是:
vx(t)= vx(t-1)和vy(t)= vy(t-1)。
我建议你阅读更多关于状态空间模型的内容(LTI应该足够)。https://en.wikipedia.org/wiki/State-space_representation 注意:对于连续时间模型,获得状态转移矩阵将需要找到矩阵指数。

1
因此,转移矩阵描述了从一个时间点 i 到下一个i + 1的自发转移。比如说,你有一个小机器人在你家里行驶。然后有时它会在地板上滑动一点,因为它并不总是有很好的牵引力。转移矩阵试图对其进行建模。
然后,在卡尔曼滤波器的几个部分中使用转移模型。首先,用于描述时间点i处机器人的方差和位置。并且它是构建传感器模型的预测误差(卡尔曼增益)的一部分,以最小化下一个测量的方差。
基本上,这是卡尔曼滤波器的一个重要组成部分,但也是一个微不足道的部分。它只试图对随时间的自发转移进行建模(例如滑动、滑动、被风吹动...)
如果这没有帮助,请再问。

如何定义这个矩阵?你能展示一个小的代码例子吗? - Sophia
我正在查看位于https://dev59.com/0GYr5IYBdhLWcg3wKHIp的代码。它是否定义了转移矩阵? - Sophia
1
嗯,就我理解,矩阵描述了你的位置变化和速度变化从一步到另一步的行为。所以如果你有一个包含x位置、y位置、x速度、y速度的四元组,那么这个矩阵描述了你当前位置和当前速度对这个随机转换的影响程度。1表示完全影响其中一个属性。0.1表示10%的影响程度。这是我对它的理解。 - Auss
不确定我是否理解了这个问题。假设第三行第二列等于0,那么这对状态转换有什么影响?同样地,如果第一行第一列等于1,那意味着什么? - Sophia
@Sophia 因为通常情况下,这是一个单位矩阵(对角线上的元素为1),所以第三列和第二行不应该有任何值。只有第二行、第二列或第三行、第三列等等。我会坚持我的假设,即在所有这些公式中,矩阵描述了当前位置或速度对代理的自发转变负责的程度。它用于简单的矩阵乘法运算。至于为什么你的矩阵在对角线之外包含了那些0.1,超出了我的理解范围。非常抱歉! - Auss
显示剩余4条评论

0

方程的数量等于状态变量的数量

你的方程描述了如何从时间 t-1 的值计算出时间 t 的变量 xy(我稍作修正):

x(t) = x(t-1) + vx*dt
y(t) = y(t-1) + vy*dt

dt是“时期”t-1t之间的时间(后者是时间指数,而不是实际时间)

我们可以看到计算涉及到不仅xy还有vxvy,根据牛顿运动方程(p = p0 + v*t)。所以你的系统有4个变量,其中2个是被观察到的(通过对xy的测量),另外2个是隐藏的(它们没有测量但是由滤波器计算得出)。这些变量构成了系统的“状态”X

X = [x, y, vx, vy]

您提供了两个方程,还有两个缺失的方程,这些方程与速度有关。但是在这里假设的预测模型是一个恒定速度运动,因此状态中的速度不会改变,例如vy的预测方程只是:
vy = vy

注意:

  • 状态变量的顺序并不重要,但滤波矩阵必须根据选定的状态向量顺序进行一致设计。

  • 不要混淆无关的名称:状态向量 X(一个向量)和变量 x(该向量的一部分,由于巧合而有相似的名称)。

预测和校正阶段

滤波器工作分为两个阶段:预测阶段,然后是校正阶段,名称可能有所不同。您的问题与预测相关。

预测是基于您提供给滤波器的模型来预测时刻t的状态,该模型以方程的形式表示,每个变量对应一个方程。每个方程都是涉及所有变量的项的总和(原始卡尔曼滤波器的线性方程)。
校正(更新)是通过使用输入中提供的实际测量z,按比例调整预测结果,这个比例系数K由滤波器在每个预测/校正周期中计算和更新。K(0到1)表示滤波器对自己的预测(K=0)或测量(K=1),或两者的信任程度,比例为1-K和K。这里的信任程度由相关的高斯方差来量化。
构建预测(转移)矩阵F
如果我们看一下预测阶段,例如对于y,我们必须提供以下类型的方程:
y(t) = f1.x(t-1) + f2.y(t-1) + f3.vx(t-1) + f4.vy(t-1)

现在这个带有指数的方程是数学家用于证明的方程,但对于一个IT工程师来说,由于t和t-1总是隐含的,分别位于等号左边和右边,所以可以简化为:
y = f1.x + f2.y + f3.vx + f4.vy

根据你的方程式 y
y  = y + vy*dt
   = 0.x + 1.y + 0.vx + dt.vy

一种可能的简化方法是使用矩阵同时执行多个操作。
[y] = [f1, f2, f3, f4] . ⎡x ⎤
                         ⎢y ⎥
                         ⎢vx⎥
                         ⎣vy⎦

你将最后的矩阵识别为垂直编写的状态向量,而中间的矩阵是所谓的"过渡矩阵"F。如前所述,过渡矩阵中的系数顺序必须与您选择的状态顺序相匹配。

对于那些忘记了矩阵相乘(点乘)的人,可以在这里查看。

Kalman滤波器不一定要使用矩阵,它们也可以使用单独的方程。但是,在短时间的熟悉后,使用矩阵会更简单,因为它们可以同时处理多个变量,并具有巨大的优势:基于矩阵运算的公式在变量数量发生变化时仍然有效。

在这里可以看到这一点:我们为y所做的操作也可以用来计算其他3个变量。同样的过渡矩阵F可以使用,每个方程占据一行,结果将是一个包含4个变量的状态向量(在时间t):

⎡x ⎤ = ⎡?,  ?,  ?,  ? ⎤ . ⎡x ⎤
⎢y ⎥   ⎢f1, f2, f3, f4⎥   ⎢y ⎥
⎢vx⎥   ⎢?,  ?,  ?,  ? ⎥   ⎢vx⎥
⎣vy⎦   ⎣?,  ?,  ?,  ? ⎦   ⎣vy⎦

所以让我们用从这四个方程中所知的所有系数来写出矩阵 F:

⎡x ⎤ = ⎡1, 0, dt, 0 ⎤ . ⎡x ⎤
⎢y ⎥   ⎢0, 1, 0,  dt⎥   ⎢y ⎥
⎢vx⎥   ⎢0, 0, 1,  0 ⎥   ⎢vx⎥
⎣vy⎦   ⎣0, 0, 0,  1 ⎦   ⎣vy⎦

要清楚地阅读这个问题:xt时刻(左侧状态向量的第一个变量)等于系数为1, 0, dt, 0(F矩阵的第一行)的项之和,而变量分别是在t-1时刻(右侧向量)的状态向量中的x, y, vx, vy

重要注意事项

用于预测的模型是一个恒定速度运动模型。通常不需要使用滤波器,因为位置可以准确地表示为p = p0 + v * 常数,在绘图时呈直线。我们使用滤波器是因为我们知道系统与该模型有些出入。但如果模型不准确,那么为什么要使用它呢?

滤波器能够处理具有恒定速度模型的缓慢变化的速度情况,但在预测和修正阶段都需要引入不确定性阈值。

这种不确定性实际上是一个方差/协方差矩阵。方差和协方差告诉滤波器使用系数K来调整其校正阶段,以便在自身预测(矩阵Q)和测量值(矩阵R)方面不要过于自信。提供这些矩阵意味着您有一些方法来预估方差,否则我们将需要通过一些测试来调整这些矩阵,这可能会很繁琐。

示例

您会注意到我在代码中没有使用矩阵,而是使用了简单的Numpy数组。原因是这样更好,矩阵没有额外的优势,反而带来了不便之处(参见deprecation)。Numpy中的点积运算使用语法糖数组操作符@进行简化。

# Prediction function
def predict(x, P):
    x = F @ x
    P = F @ P @ F.T + Q
    return x, P

# Correction/update function
def update(x, P, z):
    S = H @ P @ H.T + R
    K = P @ H.T @ np.linalg.inv(S)
    y = z - H @ x

    x = x + K @ y
    P = P - K @ H @ P
    return x, P

dt = 1
Q_std = 0.04
R_std = 0.35

# Transition
# NOTE: order of state variables is x, dx, y, dy   
F = np.array([[1, dt, 0, 0],
              [0, 1, 0, 0],
              [0, 0, 1, dt],
              [0, 0, 0, 1]])

# Process noise
q = np.array([[0.0004, 0.0008], 
              [0.0008, 0.0016]])
Q = la.block_diag(q, q)

# Measurement matrix H
# NOTE: order of state variables is x, dx, y, dy   
H = np.array([[1, 0, 0, 0],
              [0, 0, 1, 0]])

# Measurement noise matrix R
R = np.eye(2) * R_std**2

# Unknown initial positions and velocities.
# We assume no x/y or p/v correlation.
x = np.array([[0, 0, 0, 0]]).T
P = np.eye(4) * 500

for z in zs:
    x, P = update(*predict(x, P), z)
    # do something with estimated x and P

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接