Matlab学习卡尔曼滤波以及状态观测器的各种实例代码和模型 讲解,各种卡尔曼滤波的m代码,可以一行一行讲(KF,EKF,UKF,SRUKF,CKF,SRCKF等) KF,EKF,UKF,SRUKF,CKF,SRCKF,滑模观测器,PID观测器等 本人硕士写的,有简单版本的纯m代码,也有进阶学习的Sfunction代码,以及simulink模型代码,代码附有详细的注释,提供卡尔曼滤波理论方面的。
% KF基础版(线性系统) function [x_est, P] = kalman_filter(z, x_prev, P_prev, A, H, Q, R) % 预测阶段 x_pred = A * x_prev; % 状态预测 (式1) P_pred = A * P_prev * A' + Q;% 协方差预测 (式2) % 更新阶段 K = P_pred * H' / (H*P_pred*H' + R); % 卡尔曼增益 (式3) x_est = x_pred + K*(z - H*x_pred); % 状态修正 P = (eye(size(P_prev)) - K*H)*P_pred; % 协方差更新 end式1到式3直接对应卡尔曼五公式里的前三步。重点注意K的计算用了矩阵右除代替逆运算,数值稳定性更好。实际调试时盯着协方差矩阵P会不会爆炸,很多时候问题出在系统噪声Q和观测噪声R的取值不合适。
遇到非线性系统怎么办?EKF出场。看这段扩展卡尔曼滤波的雅可比矩阵处理:
%EKF关键片段(非线性系统) F = jacobian_state(x_prev); % 状态转移雅可比 H_jac = jacobian_measure(x_pred); % 观测雅可比 % 预测协方差时改用雅可比矩阵线性化 P_pred = F * P_prev * F' + Q; K = P_pred * H_jac' / (H_jac*P_pred*H_jac' + R);这里jacobianstate和jacobianmeasure需要自己写函数计算当前状态的偏导。新手常踩的坑是雅可比矩阵更新频率——要么每个步长都重新计算(计算量大),要么固定间隔更新(可能发散),具体要看系统非线性强度。
再来个UKF的Sigma点采样,感受下无迹变换的暴力美学:
% UKF的Sigma点生成 function [X] = sigma_points(x, P, alpha, beta, kappa) n = length(x); lambda = alpha^2*(n + kappa) - n; sqrt_P = chol((n + lambda)*P)'; % Cholesky分解 X(:,1) = x; for i = 1:n X(:,i+1) = x + sqrt_P(:,i); X(:,i+n+1) = x - sqrt_P(:,i); end end参数alpha控制Sigma点分布范围,通常取1e-3。注意Cholesky分解可能失败,实操时要加正则化处理。SRUKF(Square-Root UKF)用QR分解代替协方差直接计算,数值稳定性更好,适合长期运行的嵌入式系统。
滑模观测器代码更有意思,这种鲁棒性强的设计适合存在建模误差的场景:
% 滑模观测器核心更新律 s = C*x_hat - y; % 滑模面 v = -rho * sign(s); % 控制量 dx_hat = A*x_hat + B*u + L*(y - C*x_hat) + v;这里的rho是切换增益,决定了收敛速度和抖振强度的trade-off。实际工程中常用饱和函数sat(s/φ)代替sign函数,用边界层厚度φ来抑制高频抖振。
进阶玩家可以玩Sfunction,把算法封装成Simulink模块。看这个S-function的伪代码结构:
function sys=mdlDerivatives(t,x,u) % 获取输入 z = u(1); u_ctrl = u(2); % 调用KF算法 [x_est, ~] = ekf_core(z, x, P, u_ctrl); % 导数计算 sys = A*x_est + B*u_ctrl; end重点在离散-连续系统的混合仿真设置,需要处理好采样时间和过零检测。Simulink模型里记得用Memory模块保持状态同步,否则会出现代数环问题。
代码仓库里有个双摆系统的CKF仿真案例,用了球面径向规则采样,比UKF的Sigma点数量少一半。关键在这段容积点计算:
% CKF容积点生成 for i=1:n Xi(:,i) = x_est + sqrt_P(:,i); Xi(:,n+i) = x_est - sqrt_P(:,i); end weights = ones(2*n,1)/(2*n); % 等权重CKF在计算效率上有优势,但要求系统维度不能太高。SRCKF版本用平方根滤波替代协方差矩阵传递,适合低精度微控制器实现。
调参经验:先通过蒙特卡洛仿真确定噪声统计特性,再现场微调。有个暴力但有效的方法——把Q和R的对角元素设为估计误差的方差,运行时用移动平均在线自适应。