简介:这份资源面向学习卡尔曼滤波算法及MATLAB实现的学生、工程师与科研人员,提供从基础到进阶的完整例程。压缩包共4个文件,以3个m脚本和1份pdf文档为主,整体约165KB,脚本可直接在MATLAB中运行,pdf则补充自适应滤波的理论方法。内容覆盖标准卡尔曼滤波的预测与更新迭代流程,以及自适应卡尔曼滤波在线调整增益与噪声协方差、应对系统参数时变或不确定性的策略,可帮助读者理解状态估计、传感器融合与动态系统跟踪等场景下的滤波思路。已有5382人学习下载,适合希望借助可运行代码快速上手、对照理论文档深入掌握算法细节的读者。
1. 卡尔曼滤波与自适应卡尔曼滤波 matlab 例程:从调参崩溃到收敛的实战路径
很多做状态估计的工程师都有过这种经历:照着教材把卡尔曼滤波的五个方程敲进 MATLAB,跑出来的曲线却像喝醉了酒,要么发散,要么滞后得让人怀疑人生。问题往往不在公式,而在 Q 和 R 这两个协方差矩阵的取值——它们决定了滤波器是信任模型还是信任观测。卡尔曼滤波与自适应卡尔曼滤波 matlab 例程这个方向,本质上解决的就是「模型不准时怎么办」和「噪声统计特性未知时怎么调」这两个落地痛点。它适合做导航、目标跟踪、传感器融合、电池 SOC 估计的从业者,也适合刚学完理论想找可复现代码练手的学生。下面我按自己踩过的坑,把标准 KF 到自适应 KF 的完整实现路径拆开讲。
2. 标准卡尔曼滤波的 MATLAB 骨架:五个方程怎么落成可跑代码
2.1 先定状态空间模型,再谈滤波
卡尔曼滤波不是拿来就套的万能公式,它要求你先把系统写成状态空间形式。常见的一维匀速运动模型,状态向量取位置和速度:
% 一维匀速运动模型:状态 [位置; 速度] T = 0.1; % 采样周期,单位秒 A = [1 T; 0 1]; % 状态转移矩阵 H = [1 0]; % 观测矩阵,只观测位置这里 A 的物理含义是:下一时刻位置 = 当前位置 + 速度×周期,速度保持不变。H 表示传感器只测位置,不测速度。很多人一上来就把 A 写成单位阵,结果滤波器完全跟不上运动,这是最基础的翻车点。状态维数 n=2,观测维数 m=1,后面所有矩阵维度都要和这个对齐。
2.2 五个核心方程的 MATLAB 实现
标准 KF 的预测和更新两步,写成函数形式最清晰:
function [x_est, P] = kf_step(x_est, P, z, A, H, Q, R) % 预测步 x_pred = A * x_est; % 状态预测 P_pred = A * P * A' + Q; % 协方差预测 % 更新步 K = P_pred * H' / (H * P_pred * H' + R); % 卡尔曼增益 x_est = x_pred + K * (z - H * x_pred); % 状态更新 P = (eye(size(P_pred)) - K * H) * P_pred; % 协方差更新 end逻辑说明:预测步用模型往前推,协方差 P 加上过程噪声 Q 表示不确定性增大;更新步用观测残差 z - H*x_pred 修正状态,增益 K 决定修正多少。参数说明:Q 越大表示越不信任模型,滤波器越依赖观测;R 越大表示观测噪声越大,滤波器越依赖模型预测。这两个矩阵的比值才是关键,绝对数值反而次要。
2.3 用循环跑通完整例程并画图
把单步函数放进时间循环,生成带噪声的观测数据验证:
N = 200; x_true = zeros(2, N); x_true(:,1) = [0; 1]; z = zeros(1, N); for k = 2:N x_true(:,k) = A * x_true(:,k-1) + [0; 0.01*randn]; % 真实轨迹带微小扰动 z(k) = H * x_true(:,k) + 0.5*randn; % 观测噪声 end x_est = [0; 0]; P = eye(2); Q = diag([0.01, 0.1]); % 过程噪声协方差 R = 0.25; % 观测噪声方差 x_hist = zeros(2, N); for k = 1:N [x_est, P] = kf_step(x_est, P, z(k), A, H, Q, R); x_hist(:,k) = x_est; end plot(1:N, x_true(1,:), 'k', 1:N, z, '.', 1:N, x_hist(1,:), 'r'); legend('真实位置','观测','滤波估计');跑完这张图,如果红线在观测点之间平滑穿过,说明参数基本合理。如果红线剧烈抖动贴着观测走,说明 R 设小了;如果红线严重滞后,说明 Q 设小了。这是最直观的调参反馈。
3. 自适应卡尔曼滤波:当 Q 和 R 未知时怎么让滤波器自己学
3.1 为什么标准 KF 在真实场景会失效
标准 KF 假设 Q 和 R 是已知常数,但真实系统里噪声统计特性往往随工况变化。比如目标机动时过程噪声突然增大,传感器温度漂移时观测噪声变化。固定 Q、R 的滤波器要么响应慢,要么发散。自适应 KF 的核心思路是:用观测残差序列在线估计噪声协方差,让滤波器自己调整信任权重。常见做法有 Sage-Husa 自适应估计和新息序列协方差匹配两类,前者实现简单,适合入门。
3.2 Sage-Husa 自适应估计的 MATLAB 实现
Sage-Husa 方法用残差递推估计 R 和 Q,核心代码如下:
function [x_est, P, R_hat, Q_hat] = akf_step(x_est, P, z, A, H, R_hat, Q_hat, b) % b 为遗忘因子,通常取 0.95~0.99 x_pred = A * x_est; P_pred = A * P * A' + Q_hat; residual = z - H * x_pred; % 新息 S = H * P_pred * H' + R_hat; K = P_pred * H' / S; x_est = x_pred + K * residual; P = (eye(size(P_pred)) - K * H) * P_pred; % 自适应更新 R 和 Q R_hat = (1-b)*R_hat + b*(residual*residual' - H*P_pred*H'); Q_hat = (1-b)*Q_hat + b*(K*residual*residual'*K'); R_hat = max(R_hat, 1e-6); % 防止负定 Q_hat = max(Q_hat, 1e-6); end逻辑说明:遗忘因子 b 控制历史信息的权重,b 越大越信任新数据,适应越快但抖动也越大。R_hat 的更新用新息平方减去预测协方差贡献,Q_hat 用增益加权的新息平方。参数说明:b 一般从 0.95 起调,观测噪声变化快就调小到 0.9,变化慢就调到 0.99。max 保护是必须的,否则数值误差会让协方差变负导致崩溃。
3.3 自适应 KF 与标准 KF 的对比验证
用同一组数据跑两种滤波器,观察跟踪误差:
% 在观测噪声中途突变时对比 R_true = 0.25 * ones(1,N); R_true(100:end) = 2.0; % 第100步后观测噪声变大 % 标准KF用固定R=0.25,自适应KF用R_hat在线估计 err_std = zeros(1,N); err_adp = zeros(1,N); % ... 循环调用 kf_step 和 akf_step,记录位置误差对比结果通常显示:噪声突变前两者接近,突变后标准 KF 误差明显上升,自适应 KF 在几十步内重新收敛。这个实验是判断自适应算法是否值得引入的直接依据。如果工况稳定,标准 KF 反而更省算力、更平滑。
4. 避坑与排查:调参时最容易翻车的五个地方
4.1 滤波器发散,估计值越跑越偏
现象:估计曲线逐渐偏离真实值,协方差 P 持续增大。原因:Q 设得过小,滤波器过度信任模型,而模型和真实系统不匹配。解决:先把 Q 调大一个数量级观察是否收敛,再逐步回调。也可以用新息序列的统计量判断——如果新息均值不为零且持续偏大,说明模型有问题。
4.2 估计曲线抖动剧烈,完全跟着观测跑
现象:滤波输出和观测几乎重合,失去平滑效果。原因:R 设得过小,卡尔曼增益接近 1,滤波器几乎不信任模型。解决:把 R 调大,或者检查观测噪声方差是否被低估。实际传感器手册给的噪声方差往往偏乐观,建议在静态条件下实测观测标准差再平方作为 R 初值。
4.3 协方差矩阵失去对称正定性
现象:运行若干步后 P 出现负特征值,MATLAB 报错或结果异常。原因:数值累积误差,尤其在自适应 KF 中 R_hat 或 Q_hat 更新时出现负值。解决:每步更新后做对称化 P = (P + P')/2,并对 R_hat、Q_hat 加下限保护。Joseph 形式协方差更新比简单形式数值稳定性更好,值得改用。
4.4 自适应 KF 的遗忘因子选错导致震荡
现象:自适应估计的 R_hat 来回大幅波动,滤波输出震荡。原因:遗忘因子 b 太小,新息噪声被过度放大。解决:b 不低于 0.9,工况变化不快时用 0.98 以上。也可以对 R_hat 再做一次低通滤波,牺牲一点适应速度换平稳性。
4.5 观测矩阵 H 维度写错导致静默错误
现象:代码能跑但结果完全不对,没有报错。原因:H 的列数应等于状态维数,行数等于观测维数,写反了 MATLAB 广播机制可能不报错但计算错误。解决:在函数入口加断言 assert(size(H,2)==length(x_est)),把维度检查前置。这个习惯能省下大量调试时间。
5. 进阶技巧:用新息白度检验判断滤波器是否真的收敛
新息序列(残差)是卡尔曼滤波的黑匣子,它应该近似白噪声。如果新息还有相关性,说明滤波器没榨干观测信息。实操中用自相关函数检验:
residuals = zeros(1,N); for k = 1:N % ... 滤波循环中记录 residual = z(k) - H*x_pred residuals(k) = z(k) - H*x_pred; end [acf, lags] = xcorr(residuals - mean(residuals), 50, 'coeff'); stem(lags, acf); hold on; plot([-50 50], [0.2 0.2], 'r--'); plot([-50 50], [-0.2 -0.2], 'r--');判断标准:95% 的滞后阶自相关应落在 ±0.2 以内(对应 N=200 的近似置信带)。如果超出,说明 Q 或 R 没调好,或者模型结构有缺失。这个检验比肉眼看曲线靠谱得多,我一般把它作为调参的最后一关。
另一个实用技巧是 NIS(归一化新息平方)检验,统计量 residual' * inv(S) * residual 应服从卡方分布,自由度等于观测维数。连续多步超出阈值就说明滤波器一致性被破坏。这两个检验配合使用,基本能定位 90% 的调参问题。
最后说个血泪教训:别一上来就写自适应 KF。先用标准 KF 把模型和量纲理清楚,确认新息白度合格,再引入自适应机制。我见过太多人直接上 Sage-Husa,结果 Q_hat 和 R_hat 互相耦合,调了一周还不如固定参数。先把标准版跑稳,自适应才有意义。希望帮到你。
本文还有配套的精品资源,点击获取