Part5.2D_Kalman_Filter_Example

\(Key:\)

\[\begin{align*} &z_1 = 6.5 mm,\sigma_1 = 0.2 mm;z_2 = 7.3 mm,\sigma_2 = 0.4 mm & \\ &求最优估计: \hat{z} = ? \\ \hat{z} &= z_1 + \frac{\sigma_1^2}{\sigma_1^2 + \sigma_2^2} (z_2 - z_1) \\ &= 6.5 + \frac{0.2^2}{0.2^2 + 0.4^2} \cdot (7.3 - 6.5) \\ &= 6.66 \\ So:& \\ &The\ key\ is\ 6.66. \end{align*} \]


\(Example:\)

Example

\[\begin{align*} States&: \\ &x_1:位置;x_2:速度& \\ 匀速&: \\ &位置:x_{1,k} = x_{1,k-1} + \Delta T x_{2,k-1} = x_{1,k-1} + x_{2,k-1},{\color{red}{\Delta T = 1}} \\ &速度:x_{2,k} = x_{2,k-1} \\ &采样时间:\Delta T\ k时刻与k-1时刻的间隔 \\ 因为&具有不确定性:\\ &位置:x_{1,k} = x_{1,k-1} + x_{2,k-1} + w_{1,k-1} \\ &速度:x_{2,k} = x_{2,k-1} + w_{2,k-1} \\ &w为Process\ Noise(过程噪声),p(w) \sim N(0,Q) \\ 测量&: \\ &z_{1,k} = x_{1,k} \\ &z_{2,k} = x_{2,k} \\ 同样&因为具有不确定性:\\ &z_{1,k} = x_{1,k} + v_{1,k} \\ &z_{2,k} = x_{2,k} + v_{2,k} \\ &v为Measure\ Noise(过程噪声),p(v) \sim N(0,R) \\ \therefore\ & \begin{aligned} &\begin{bmatrix} x_{1,k} \\ x_{2,k} \\ \end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 0 & 1 \\ \end{bmatrix} \begin{bmatrix} x_{1,k-1} \\ x_{2,k-1} \\ \end{bmatrix} + \begin{bmatrix} w_{1,k-1} \\ w_{2,k-1} \\ \end{bmatrix} \Rightarrow {\color{red}{X_k = A X_{k-1} + w_{k-1}}} \\ &\begin{bmatrix} z_{1,k} \\ z_{2,k} \\ \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ \end{bmatrix} \begin{bmatrix} x_{1,k} \\ x_{2,k} \\ \end{bmatrix} + \begin{bmatrix} v_{1,k} \\ v_{2,k} \\ \end{bmatrix} \Rightarrow {\color{red}{Z_k = H X_k + v_k}} \\ \end{aligned} {\color{red}{\Rightarrow \hat{X}_k最优}} \end{align*} \]


\(预测\)

\[\begin{align*} &先验: \hat{X}_k^- = A \hat{X}_{k-1}^- + B u_{k-1}& \\ &先验误差协方差: P_k^- = A P_{k-1} A^T + Q,{\color{green}{P_{k-1} \rightarrow 上一次误差的协方差}} \\ \end{align*} \]

\(校正\)

\[\begin{align*} Kalman\ Gain:K_k &=\frac{P_k^- H^T}{H P_k^- H^T + R}& \\ 后验估计: \hat{X}_k &= \hat{X}_k^- + K_k (Z_k - H \hat{X}_k^-) \\ 更新误差协方差: P_k &= (I - K_k H) P_k^- \\ \end{align*} \]

参考文献

下面是在评论区中找到的同学分享的代码:

# https://zhuanlan.zhihu.com/p/48876718
# https://www.bilibili.com/video/BV1dV411B7ME?share_source=copy_web
# DR_CAN例子的python实现
import numpy as np
import matplotlib.pyplot as plt


def gaussian_distribution_generator(var):
    return np.random.normal(loc=0.0, scale=var, size=None)


# 状态转移矩阵,上一时刻的状态转移到当前时刻
A = np.array([[1, 1],
              [0, 1]])

# 过程噪声协方差矩阵Q,p(w)~N(0,Q),噪声来自真实世界中的不确定性
Q = np.array([[0.1, 0],
              [0, 0.1]])

# 观测噪声协方差矩阵R,p(v)~N(0,R)
R = np.array([[1, 0],
              [0, 1]])

# 状态观测矩阵
H = np.array([[1, 0],
              [0, 1]])

# 控制输入矩阵B
B = None
# 初始位置与速度
X0 = np.array([[0],
               [1]])

# 状态估计协方差矩阵P初始化
P = np.array([[1, 0],
              [0, 1]])

if __name__ == "__main__":
    # ---------------------------初始化-------------------------
    X_true = np.array(X0)  # 真实状态初始化
    X_posterior = np.array(X0)
    P_posterior = np.array(P)

    speed_true = []
    position_true = []

    speed_measure = []
    position_measure = []

    speed_prior_est = []
    position_prior_est = []

    speed_posterior_est = []
    position_posterior_est = []

    for i in range(30):
        # -----------------------生成真实值----------------------
        # 生成过程噪声
        w = np.array([[gaussian_distribution_generator(Q[0, 0])],
                      [gaussian_distribution_generator(Q[1, 1])]])
        X_true = np.dot(A, X_true) + w  # 得到当前时刻状态
        speed_true.append(X_true[1, 0])
        position_true.append(X_true[0, 0])
        # -----------------------生成观测值----------------------
        # 生成观测噪声
        v = np.array([[gaussian_distribution_generator(R[0, 0])],
                      [gaussian_distribution_generator(R[1, 1])]])

        Z_measure = np.dot(H, X_true) + v  # 生成观测值,H为单位阵E
        position_measure.append(Z_measure[0, 0])
        speed_measure.append(Z_measure[1, 0])
        # ----------------------进行先验估计---------------------
        X_prior = np.dot(A, X_posterior)
        position_prior_est.append(X_prior[0, 0])
        speed_prior_est.append(X_prior[1, 0])
        # 计算状态估计协方差矩阵P
        P_prior_1 = np.dot(A, P_posterior)
        P_prior = np.dot(P_prior_1, A.T) + Q
        # ----------------------计算卡尔曼增益,用numpy一步一步计算Prior and posterior
        k1 = np.dot(P_prior, H.T)
        k2 = np.dot(np.dot(H, P_prior), H.T) + R
        K = np.dot(k1, np.linalg.inv(k2))
        # ---------------------后验估计------------
        X_posterior_1 = Z_measure - np.dot(H, X_prior)
        X_posterior = X_prior + np.dot(K, X_posterior_1)
        position_posterior_est.append(X_posterior[0, 0])
        speed_posterior_est.append(X_posterior[1, 0])
        # 更新状态估计协方差矩阵P
        P_posterior_1 = np.eye(2) - np.dot(K, H)
        P_posterior = np.dot(P_posterior_1, P_prior)

       

    # 可视化显示
    if True:
        fig, axs = plt.subplots(1,2)
        axs[0].plot(speed_true, "-", label="speed_true", linewidth=1)  # Plot some data on the axes.
        axs[0].plot(speed_measure, "-", label="speed_measure", linewidth=1)  # Plot some data on the axes.
        axs[0].plot(speed_prior_est, "-", label="speed_prior_est", linewidth=1)  # Plot some data on the axes.
        axs[0].plot(speed_posterior_est, "-", label="speed_posterior_est", linewidth=1)  # Plot some data on the axes.
        axs[0].set_title("speed")
        axs[0].set_xlabel('k')  # Add an x-label to the axes.
        axs[0].legend()  # Add a legend.

        axs[1].plot(position_true, "-", label="position_true", linewidth=1)  # Plot some data on the axes.
        axs[1].plot(position_measure, "-", label="position_measure", linewidth=1)  # Plot some data on the axes.
        axs[1].plot(position_prior_est, "-", label="position_prior_est", linewidth=1)  # Plot some data on the axes.
        axs[1].plot(position_posterior_est, "-", label="position_posterior_est", linewidth=1)  # Plot some data on the axes.
        axs[1].set_title("position")
        axs[1].set_xlabel('k')  # Add an x-label to the axes.
        axs[1].legend()  # Add a legend.

        plt.show()
clc
clear all
%% 时间序列设定
delta_t=0.01;
t=0:delta_t:30;
N = length(t);
sz = [2,N];
X = zeros(sz);
Z = zeros(sz);
%% 矩阵的设定
A = [1 delta_t; 0 1];
H =[1 0; 0 1];
w1=1*randn(2,N);
w2=1*randn(2,N);
X(:,1)=[0; 1];
%% 实际信号和测量信号
for i=2:N
    X(:,i)=A*X(:,i-1)+w1(:,i-1);
    Z(:,i)=H*X(:,i)+w2(:,i);
end
plot(t,X(1,:),'g')
hold on
plot(t,Z(1,:),'r')
%% 噪声
Q=[0.1 0; 0 0.1];
R=[0.1 0; 0 0.1];
n=size(Q);
m=size(R);
%% 观测值数据初始化
xhat=zeros(sz);
xhatminus=zeros(sz);
P=zeros(n);
Pminus=zeros(n);
K=zeros(n(1),m(1));
I=eye(n(1));
xhat(:,1)=[2; 0];
P=eye(n(1));
%% 卡尔曼滤波
for k=2:N
    xhatminus(:,k)=A*xhat(:,k-1);
    Pminus=A*P*A'+Q;
    % 滤波
    K = Pminus*H'*inv(H*Pminus*H'+R);
    xhat(:,k)=xhatminus(:,k)+K*(Z(:,k)-H*xhatminus(:,k));
    P=(I-K*H)*Pminus;
end
figure
plot(t,X(1,:),'g')
hold on
plot(t,Z(1,:),'r')
hold on
plot(t,xhat(1,:),'b','linewidth',0.5)
figure
plot(t,X(2,:),'g')
hold on
plot(t,Z(2,:),'r')
hold on
plot(t,xhat(2,:),'b','linewidth',0.5)
posted @ 2025-12-29 13:02  Zhuye_inking  阅读(34)  评论(0)    收藏  举报