这个例子在 Simulink 中手搭了一个卡尔曼滤波器,不调用 Simulink 自带的
Kalman Filter 模块,也不把状态矩阵拆成标量。模型把对象和滤波器分别
封装为 Subsystem(被控对象)和 Subsystem1(卡尔曼滤波器),中间信号
全部保持 2x1 向量,处理过程全部使用矩阵增益 A、B、C、L。
顶层结构为:
HeaterStep ─┬─> Subsystem(被控对象)─┬─> x_log / x_out
│ ├─> z_log / Subsystem1
│ └─> Scope
└─> Subsystem1(卡尔曼滤波器)─> xhat_log / xhat_out / Scope
输入端口:
U:加热功率输入W1、W2:过程噪声输入
内部模块:
process_noise_mux:把W1、W2合成2x1过程噪声向量wplant_A_gain、plant_B_gain:对象矩阵增益,计算A*x、B*uplant_dx_sum:对象向量求和,计算A*x + B*u + wplant_x_integrator:向量积分器,输出对象状态xplant_C_gain:输出矩阵增益,计算C*x得到真实温度measurement_sum:把真实温度和测量噪声相加,得到带噪测量值v:测量噪声源y_log:记录理想观测值
输出端口:
x真实状态:真实状态向量xZ 带噪声测量值:带噪测量值zCX=Y 理想观测值:理想观测值C*x
输入端口:
z:带噪测量值U:加热功率输入xhat:估计状态反馈
内部模块:
KF_A_gain、KF_B_gain:滤波器动态矩阵增益,计算A*xhat、B*uKF_C_gain:预测测量值,计算C*xhatinnovation_sum:计算新息z - C*xhatKF_L_gain:卡尔曼增益,计算L*(z - C*xhat)KF_dx_sum:向量求和,计算dxhat/dtxhat_integrator:向量积分器,输出估计状态xhat
输出端口:
估计状态X:估计状态向量xhat
顶层反馈线 Subsystem1:1 -> Subsystem1:3 把估计状态送回滤波器的 xhat
输入,完成闭环。
对象方程:
dx/dt = A*x + B*u + w
z = C*x + v
滤波器方程:
dxhat/dt = A*xhat + B*u + L*(z - C*xhat)
参数:
tau1 = 4,tau2 = 1,K = 1.5A = [0 1; -0.25 -1.25]B = [0; 0.375]C = [1 0]Q = diag([1e-3, 1e-2])R = 1e-2- 稳态增益
L = [0.5859; 0.1216]
在 MATLAB 中运行:
build_kalman_temperature_model
run_kalman_temperature_model运行后会生成 kalman_temperature_results.png,展示真实温度、带噪测量、
卡尔曼估计值以及两个状态量的估计误差。
- 求解器:固定步长
ode4,步长0.01s - 仿真时间:
80s - 噪声采样周期:
Ts = 0.1s
面向实际硬件工程的离散卡尔曼滤波器位于同目录,包含 MATLAB 参数计算、 C 语言实现和离散仿真,详见 README_discrete_kalman.md。