简介:这份资源面向惯性导航、姿态解算方向的学习者与工程人员,聚焦陀螺仪与加速度计数据融合中的卡尔曼滤波实现,适合已具备一定MATLAB基础、希望从理论走向仿真验证的中级读者。压缩包共2个文件,以1个m脚本和1个txt说明为主,包体约1KB,脚本可直接运行观察滤波前后对比,说明文件辅助理解参数与流程。内容围绕状态模型、测量模型、系统噪声、预测与更新步骤、卡尔曼增益等关键环节展开,通过可视化输出呈现未滤波与滤波后数据的差异,帮助读者直观理解滤波器对噪声的抑制作用。已有1112人学习下载,可作为传感器数据处理与惯性导航系统入门实践的参考脚本,便于快速复现并在此基础上调整参数、评估性能。
1. 陀螺仪与加速度计卡尔曼滤波:从 MPU6050 原始数据到可用姿态角
MPU6050 这类六轴传感器便宜、好买、资料多,但真正把它用起来的人都会遇到同一个问题:陀螺仪积分几秒钟就飘得没法看,加速度计静态还行、一震动就全是噪声。单独用哪个都不够,于是卡尔曼滤波成了绕不开的一步。这个标题讲的正是这件事——用 MATLAB 把陀螺仪和加速度计的数据融合起来,输出稳定的姿态角。它适合正在做平衡车、云台、四轴飞控、行人航位推算(PDR)的嵌入式工程师,也适合想先把算法在 MATLAB 里跑通、再移植到单片机上的学生。核心不是调库,而是搞清楚状态方程怎么列、噪声参数怎么给、仿真结果怎么验证。下面按「先立住理论、再动手复现、最后踩坑收尾」的顺序讲透。
2. 卡尔曼滤波凭什么是陀螺仪加加速度计的最优解
2.1 两个传感器各自的死穴
先看陀螺仪。它输出的是角速度,单位 °/s,要得到角度必须对时间积分。积分本身没错,问题出在零偏(bias)。任何 MEMS 陀螺仪上电后都有一个不为零的静态输出,哪怕你一动不动,它也在缓慢累积误差。典型 MPU6050 的零偏在 ±20 °/s 量级,就算标定后压到 0.5 °/s,积分 60 秒也会漂 30°。这就是为什么纯陀螺仪方案撑不过一分钟。
再看加速度计。它测的是比力,静止时输出重力分量,通过 atan2 就能反解出俯仰角和横滚角,长期不漂。但加速度计对线性加速度和振动极其敏感——电机一转、轮子一颠,解算出来的角度就跳。所以加速度计适合做长期参考,不适合做短期输出。
两者恰好互补:陀螺仪短期准、长期漂;加速度计长期稳、短期噪。卡尔曼滤波就是干这个的——用陀螺仪做预测,用加速度计做观测更新,把两者的优势拼起来。
2.2 状态方程与观测方程怎么列
姿态融合里最常用的是一维卡尔曼,对俯仰角和横滚角分别处理。状态量取两个:角度 angle 和陀螺仪零偏 bias。
状态转移写成离散形式:
angle(k) = angle(k-1) + (gyro - bias(k-1)) * dt bias(k) = bias(k-1)写成矩阵就是:
x(k) = F * x(k-1) + B * u(k) F = [1 -dt] [0 1 ] B = [dt] [0 ] u = gyro观测方程用加速度计解算的角度作为观测量:
z(k) = H * x(k) + v H = [1 0]这里 z 就是加速度计算出来的角度,v 是观测噪声。状态量里把 bias 也估出来,好处是能在线补偿陀螺仪零偏,不用每次上电都手动标定。
2.3 过程噪声 Q 和观测噪声 R 到底怎么给
这是最多人卡住的地方。Q 是过程噪声协方差,反映你对状态方程的信任程度;R 是观测噪声协方差,反映你对加速度计的信任程度。
我一般这么起步:
| 参数 | 含义 | 典型初值 | 调整方向 |
|---|---|---|---|
| Q_angle | 角度过程噪声 | 0.001 | 越大越信陀螺仪 |
| Q_bias | 零偏过程噪声 | 0.003 | 越大零偏收敛越快但越抖 |
| R_measure | 观测噪声 | 0.03 | 越大越信陀螺仪 |
Q_angle 给太小,滤波器反应迟钝,角度跟不上真实变化;给太大,输出会抖。R_measure 给太小,加速度计的噪声全被吸进来;给太大,等于没用加速度计,又退化成纯积分。实操中先按上表跑一遍,看曲线再微调,别一上来就追求理论最优。
提示:Q 和 R 的绝对值不重要,重要的是它们的比值。调参时固定一个、动另一个,比同时改两个容易找到方向。
3. 在 MATLAB 里把卡尔曼姿态融合跑起来
3.1 仿真数据从哪来
没有硬件也能做。两种方式:一是用 MATLAB 自己造一段带噪声的陀螺仪和加速度计数据,二是导入真实 MPU6050 的串口日志。造数据的好处是真实角度已知,能直接算误差;真实数据的好处是能验证算法在振动下的表现。我建议先用造数据跑通流程,再换真实数据。
造数据的思路:设定一个真实角度轨迹(比如正弦摆动),对它求导得到真实角速度,加上零偏和高斯噪声当陀螺仪输出;对真实角度加上更大的高斯噪声当加速度计解算角度。
% 生成仿真数据:真实角度、陀螺仪输出、加速度计解算角度 fs = 100; % 采样率 100Hz T = 10; % 仿真 10 秒 t = (0:1/fs:T-1/fs)'; dt = 1/fs; true_angle = 30 * sin(2*pi*0.5*t); % 真实角度,0.5Hz 正弦 true_gyro = 30 * 2*pi*0.5 * cos(2*pi*0.5*t); % 真实角速度 gyro_bias = 0.8; % 陀螺仪零偏 °/s gyro_noise = 0.3; % 陀螺仪噪声标准差 acc_noise = 2.0; % 加速度计噪声标准差 gyro_meas = true_gyro + gyro_bias + gyro_noise*randn(size(t)); acc_angle = true_angle + acc_noise*randn(size(t));这段代码里 fs 决定仿真步长,true_angle 是已知真值,后面算 RMSE 全靠它。gyro_bias 故意设成 0.8,就是为了看卡尔曼能不能把零偏估出来。acc_noise 给 2.0 度,比陀螺仪噪声大一个量级,符合真实传感器特性。
3.2 一维卡尔曼滤波的完整实现
下面这段是核心,逐行都能对应到 2.2 的方程。
% 一维卡尔曼滤波:状态 [angle; bias] Q_angle = 0.001; Q_bias = 0.003; R_measure = 0.03; angle = 0; % 角度估计初值 bias = 0; % 零偏估计初值 P = [1 0; 0 1]; % 协方差矩阵初值 angle_est = zeros(size(t)); for k = 1:length(t) % --- 预测 --- gyro = gyro_meas(k) - bias; % 扣除当前零偏估计 angle = angle + dt * gyro; % 状态预测 P = P + [Q_angle 0; 0 Q_bias]*dt; % 协方差预测 % --- 更新 --- S = P(1,1) + R_measure; % 创新协方差 K = [P(1,1); P(2,1)] / S; % 卡尔曼增益 y = acc_angle(k) - angle; % 创新 angle = angle + K(1) * y; % 更新角度 bias = bias + K(2) * y; % 更新零偏 P = (eye(2) - K*[1 0]) * P; % 协方差更新 angle_est(k) = angle; end预测步里gyro = gyro_meas(k) - bias是关键,它把零偏估计实时扣掉,这是纯积分做不到的。协方差预测用P + Q*dt,Q 越小表示越信任模型。更新步里 S 是创新协方差,K 是增益,y 是加速度计和预测角度的差。K(1) 决定角度修正多少,K(2) 决定零偏修正多少。最后P = (I - K*H)*P是标准协方差更新。
跑完这段,把 angle_est 和 true_angle 画在一起,再画一条纯陀螺仪积分的曲线对比,差别一眼就能看出来。
3.3 结果怎么验证才算数
光看图不够,要算指标。三个必看:
% 纯积分对比 pure_integral = cumsum(gyro_meas)*dt; % 误差指标 rmse_kalman = sqrt(mean((angle_est - true_angle).^2)); rmse_pure = sqrt(mean((pure_integral - true_angle).^2)); fprintf('卡尔曼 RMSE: %.3f 度\n', rmse_kalman); fprintf('纯积分 RMSE: %.3f 度\n', rmse_pure); fprintf('零偏估计终值: %.3f °/s (真值 %.3f)\n', bias, gyro_bias);正常情况下卡尔曼 RMSE 应该在 0.5 度以内,纯积分会随着时间越来越大。零偏估计终值应该收敛到 0.8 附近,如果差很远,说明 Q_bias 或 R_measure 给得不合理。这一步是判断滤波器有没有真正工作的硬标准,别跳过。
注意:cumsum 积分会累积初值误差,纯积分曲线起点要对齐,否则对比不公平。
4. 从 MATLAB 仿真到嵌入式移植的避坑清单
4.1 采样周期 dt 不稳定导致滤波发散
现象:MATLAB 里跑得好好的,烧到板子上角度开始周期性抖动,严重时直接发散。
原因:仿真里 dt 固定 0.01,实际单片机用延时或定时器,dt 在 0.009 到 0.012 之间跳。卡尔曼对 dt 敏感,尤其是预测步angle = angle + dt*gyro,dt 波动直接变成角度误差。
解决:用硬件定时器触发采样,把真实 dt 传进滤波函数,别用固定值。如果做不到,至少用滑动平均把 dt 平滑一下。我一般会在滤波入口加一句 dt 合法性检查,超过 2 倍标称值就丢弃这一帧。
4.2 加速度计解算角度在剧烈运动时完全不可信
现象:小车急加速或转弯时,卡尔曼输出角度突然跳十几度,松开后又慢慢回来。
原因:加速度计测的是比力,不是纯重力。线性加速度混进来后,atan2 解出的角度是错的,而滤波器把它当观测真值用了。
解决:加一个加速度模值判断。静止或匀速时模值接近 1g,剧烈运动时偏离。模值超出 0.8g 到 1.2g 范围就临时调大 R_measure,让滤波器少信加速度计。这招在平衡车和四轴上很常用。
acc_mag = sqrt(ax^2 + ay^2 + az^2); if abs(acc_mag - 1) > 0.2 R_measure = 10; % 运动剧烈,几乎不信任加速度计 else R_measure = 0.03; % 正常状态 end4.3 零偏估计初值给 0 导致前几秒角度不准
现象:上电后前 3 到 5 秒角度明显偏,之后才慢慢正常。
原因:bias 初值设 0,但实际零偏可能有 1 到 2 °/s,滤波器需要时间收敛。这段时间角度是错的。
解决:上电时先静止采样 200 帧陀螺仪数据,取平均作为 bias 初值。这一步叫静态标定,花不了 2 秒,能省掉后面好几秒的收敛过程。标定时确保传感器真的静止,桌子晃一下都会污染初值。
4.4 用欧拉角分别做卡尔曼忽略了两轴耦合
现象:俯仰角大角度倾斜时,横滚角跟着出现误差,单独调哪个轴都调不好。
原因:一维卡尔曼把俯仰和横滚当独立处理,但实际姿态是耦合的,尤其俯仰接近 ±90° 时横滚解算会退化。
解决:如果应用场景倾斜不超过 ±60°,一维卡尔曼够用。超过这个范围,要么上四元数卡尔曼,要么用 Mahony 互补滤波先顶着。别硬用一维卡尔曼去跑全姿态,那是给自己找麻烦。
4.5 把 Q 和 R 当固定值一劳永逸
现象:实验室调好的参数,换个电机、换个机架就不好使了。
原因:Q 和 R 反映的是噪声统计特性,振动环境变了,噪声就变了。固定参数只在特定条件下最优。
解决:至少留一个运行时调参接口,通过串口能改 Q_angle 和 R_measure。我习惯在调试阶段把这两个值做成全局变量,用上位机实时改,找到合适值后再固化。别在代码里写死。
5. 用 Allan 方差标定噪声参数,让 Q 和 R 不再靠猜
前面调 Q 和 R 基本靠试,其实有更硬的办法——Allan 方差。它能从静态陀螺仪数据里直接读出角度随机游走和零偏不稳定性,这两个量正好对应卡尔曼里的 Q_angle 和 Q_bias。花十分钟做一次,比瞎调半天靠谱。
做法很简单:传感器静止采集至少 1 小时数据,采样率 100Hz 就够。用 MATLAB 算 Allan 方差,画双对数曲线。曲线在斜率 -1/2 段对应角度随机游走 N,在最低点对应零偏不稳定性 B。Q_angle 约等于 N²,Q_bias 约等于 B²。R_measure 则用加速度计静态数据的方差直接给。
% Allan 方差简化计算(分段聚类) data = gyro_static; % 静态陀螺仪数据,单位 °/s fs = 100; max_cluster = floor(length(data)/10); tau = zeros(max_cluster,1); adev = zeros(max_cluster,1); for m = 1:max_cluster n = floor(length(data)/m); cluster_means = mean(reshape(data(1:n*m), m, n))'; tau(m) = m/fs; adev(m) = sqrt(0.5*mean(diff(cluster_means).^2)); end loglog(tau, adev); xlabel('聚类时间 \tau (s)'); ylabel('Allan 偏差 (°/s)'); grid on;这段代码里 m 是聚类长度,cluster_means 是每段均值,diff 求相邻段差。斜率 -1/2 区域取一个点算 N,曲线最低点算 B。注意数据必须连续无断点,中间丢帧会让曲线尾部翘起来,误判成零偏不稳定。
标定完之后,把 N² 和 B² 填进 Q_angle 和 Q_bias,再跑 3.3 的验证,通常 RMSE 能再降 20% 到 30%。如果手头没有一小时静态数据,至少采 10 分钟,低频段虽然不准,但比拍脑袋强。
我自己的习惯是:每换一款传感器,先跑一次 Allan 方差存档,参数直接查表用。这样换硬件时不用重新试参数,省下来的时间够调好几版控制逻辑了。希望帮到你。
本文还有配套的精品资源,点击获取