ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

卡尔曼滤波入门:从预测与修正看懂状态估计核心思想

卡尔曼滤波入门:从预测与修正看懂状态估计核心思想 先说个我见过很多次的场景你做了一个带轮子的小机器人想让它知道自己走了多远。轮子编码器说“走了1米”激光雷达测距说“前方1.2米”。两个传感器看着都挺像那么回事但到底信谁如果你直接选其中一个可能在某一瞬间被一个随机毛刺带偏如果你直接平均又会在机器人真正加速和减速的时候严重滞后。卡尔曼滤波Kalman Filter就是为了处理这种“每个数据源都不完全可信但都不能完全丢掉”的局面而存在的。这篇文章我会完全站在小白的角度把卡尔曼滤波拆成“预测”和“修正”两个动作来讲。全程不需要你具备微积分或者矩阵基础只需要你愿意跟着我做一个简单的思想实验。等这套直觉建立起来我再带你逐步走近卡尔曼滤波的数学思想、具体公式的含义以及调参时的常见坑。适合第一次接触状态估计、想搞懂原理而不是死记公式的读者也适合做机器人、自动驾驶、无人机飞控、传感器融合的入门者。1. 先忘掉公式一个盒子质量估算问题让你理解卡尔曼的本意1.1 两把“尺子”都有误差时怎么取最可靠的结果假设你面前有个箱子你想知道它到底有多重。你拉了三个朋友来帮忙第一个朋友拿弹簧秤掂了一下说“大概10公斤”。第二个朋友用电子秤读数“10.5公斤”。第三个朋友凭手感说“我觉得9.8公斤”。三个人都有误差。弹簧秤可能老化电子秤可能没校准手感就更不用说了。问题是真实重量只有一个你手上却有三个彼此不一致的估计。最原始的做法是求平均因为多个有误差的测量叠加在一起随机误差会互相抵消一部分。这个思路没问题但它没有考虑一个很关键的信息这三把“尺子”的可信度不一样。电子秤在正常情况下应该比手感靠谱得多。如果仅仅因为手感说9.8就把10.5往那边拉很可能把一个好数据污染了。反过来如果电子秤今天正好接触不良读数一直在10到11之间乱跳那它上次再靠谱这次也不能给它太高的权重。卡尔曼滤波解决的就是这个问题它不会傻乎乎地取平均而是根据每个信息来源的“信任程度”动态调整它们的话语权。越值得信赖的数据说话越有分量噪声越大的数据只能当个参考。1.2 卡尔曼的做法不是取平均而是动态加权在卡尔曼框架里一般有两个信息源。第一个叫预测值来自你自己对系统的理解。举个例子你知道箱子上一次称是10公斤而且这一周没人动过它那你就可以“预测”它现在还是10公斤左右。第二个叫测量值来自传感器的直接读数比如电子秤现在显示10.5公斤。真正的重量是谁谁都不知道。卡尔曼滤波给出的答案不是简单的50比50平均而是“按照误差大小分配权重”。如果测量设备非常准就多信测量值如果测量设备最近噪声很大就多信预测值。这个权重在卡尔曼滤波里有一个专门的名字叫卡尔曼增益。它在每一轮迭代中都会重新计算决定最终估计值到底站在预测和测量的哪一边。你不需要背公式只要记住一句话增益越大权重越偏向测量值增益越小权重越偏向预测值。2. 预测和修正卡尔曼滤波的全部家底2.1 预测用数学模型往前推一步卡尔曼滤波虽然名字听着吓人但它的主循环只有两个动作。第一个动作是预测英文叫 predict第二个动作是修正英文叫 update 或 correct。整篇算法做来做去就是这两个动作不断循环。预测的思维方式是这样的有一个系统比如一辆匀速直线运动的小车上一秒它在位置10米处速度是2米每秒时间过了1秒那下一秒它在哪小学知识就够位置等于原来的位置加上速度乘以时间也就是10 2×1 12米。这里没有任何玄学预测这一步就是在做“用物理规律往前推”。这个物理规律在卡尔曼滤波里叫状态转移模型。之所以要推这一步是因为测量往往不是连续的两次测量之间可能隔了一段时间我们总不能在中间那段空白里两眼一抹黑。预测的作用就是在这个空白期里给系统一个合理的估计方向。但预测有个致命弱点模型不可能完美。小车可能遇到斜坡轮子可能打滑风速可能变化。这些没被算进模型里的因素会让预测结果逐渐偏离真实状态。所以光有预测远远不够必须请出传感器。2.2 修正让传感器把我们的想象拉回现实传感器的测量值是现实世界最直接的反馈。激光雷达告诉你前方障碍物1.2米GPS告诉你现在坐标在某个经纬度上。测量值虽然也有噪声但它能把我们从“模型推算”的天马行空里拉回现实。修正动作的本质是把预测值和测量值做一个带权重的融合。你说你算出来小车应该在12米但传感器测出来是11.8米两者差0.2米。这个差异在卡尔曼滤波里叫残差或新息意思是“现实和想象的差了多少”。卡尔曼滤波会根据此刻预测和测量的信任度决定用这0.2米去修正多少如果测量噪声很大可能只用0.2的很小一部分比如最终修正到11.95米。如果测量很准可能几乎全部采纳比如最终变成11.82米。修正完就得到这一轮的最佳估计。这个最佳估计又作为下一轮预测的起点。如此循环滤波就运转起来了。2.3 一台沿直线滑行的小车把两步串成一个循环把预测和修正串起来看整个过程是这样的从上一轮的最终估计出发用运动模型算出小车现在应该在哪。算出这个预测和传感器实际读数之间的差距。根据预测和测量的可信度决定折中出一个新位置。把这个新位置当成新的起点回到第1步。如果你用程序实现这个循环就是一个while(1)里不断执行两个函数predict()和update()。非常简单。真正的复杂性不在流程而在“可信度”这三个字该怎么量化。3. 信任度从哪来状态误差和测量误差的博弈3.1 用方差理解“信心程度”要分配权杖先得有一把衡量“靠不靠谱”的尺子。卡尔曼滤波用来衡量“不靠谱程度”的东西叫方差和协方差。听起来吓人但你可以把方差理解为“猜数的发散程度”。假如你猜一个东西的位置一会儿猜10.0一会儿猜10.2一会儿猜9.9几次猜测之间波动很小说明你的答案很稳定方差小。如果你一会儿猜10一会儿猜15一会儿猜6数字之间像个蹦床一样弹来弹去方差就大。方差大意味着这一堆数据里任何一个单独数值的可信度都要打折扣。卡尔曼滤波里的状态不只是位置一个数往往还有速度、加速度等。比如小车状态包含位置和速度。位置和速度之间不是互相独立的位置猜得准不准跟速度猜得准不准是有关系的。所以除了每个量自己的方差还要描述它们之间的“协同关系”。这一堆数字放在一起就是协方差矩阵。小白不需要会算它只需要理解一件事情协方差矩阵就是卡尔曼滤波的“信心账本”每一轮都在更新它记录着我们对当前状态的信任度。3.2 卡尔曼增益公式的直觉解释卡尔曼增益是接近公式时最先遇到的东西它在教科书里长这样[ K \frac{P}{P R} ]如果你没有数学基础可以把 (P) 想象成“预测的不确定性”把 (R) 想象成“测量的不确定性”。那么卡尔曼增益 (K) 就表示“测量结果被采信的比例”。来套用极端情况如果 (R) 特别大说明测量几乎不可信。(K) 会趋近于0最终估计几乎完全采用预测值。如果 (R) 特别小说明测量超级准。(K) 会趋近于1最终估计几乎完全采用测量值。如果两者旗鼓相当(K) 就是0.5左右预测和测量各占一半。注意真实世界里 (P) 和 (R) 都不是一个数而是一个矩阵。因为系统里通常有位置、速度等多个变量每一个都有自己的不确定性和交叉关联。但矩阵版卡尔曼增益的物理含义没有变它在调节“模型推算”和“传感器实测”之间的信任比例。3.3 一轮更新之后为什么误差会越变越小你可能会有个疑问预测和测量都不可靠把两个不可靠的量融合一下凭什么就比原来更可靠直觉是这样的两个独立来源的误差往往不会同时往同一个方向偏。预测今天偏左测量明天偏右它们各自随机晃但真实状态是同一个。当两堆随机噪声做加权平均时随机成分会互相削掉一部分而被预测模型和传感器共同刻画的“真实成分”会被保留下来。这就和“三个人都说看见差不多的东西那这东西大概率是真的”是一个道理。每一轮融合之后卡尔曼滤波会更新协方差矩阵把不确定性进一步压缩。你如果在程序里打印这个数值会看到它随着时间总体呈下降趋势。这个下降并不是因为传感器突然变准了而是因为系统把历史信息、模型信息、测量信息不断滚雪球式地融合在一起对真实状态的把握越来越足。4. 一个脑子和多条腿从单变量扩展到位置与速度联合估计4.1 状态向量和协方差矩阵到底在表达什么真正用来做工程的卡尔曼滤波很少只估计一个量。最常见的是同时估计位置和速度。因为如果只知道位置不知道速度下一轮预测时你就没有依据去推系统会往哪儿走。于是我们把位置和速度放进一个“状态向量”里比如[ x \begin{bmatrix} p \ v \end{bmatrix} ]两个量同步更新。预测时系统模型会把位置和速度一起往前推位置增加 (v\Delta t)速度如果保持匀速就不变。修正时传感器可能只直接测量位置但因为这个位置和速度是关联在一起的位置被修正的同时速度也会被牵动修正。这就引出了卡尔曼滤波的一个隐藏能力它能把不同传感器的优点拼起来。比如GPS位置更新频率低但绝对漂移小速度计加速度计更新频率高但积分会飘。卡尔曼滤波让高频传感器负责提供连续变化让低频传感器负责定期校准最终得到一条又平滑又不容易偏移的估计曲线。这种“共享状态、分头测量”的结构就是多传感器融合的标准套路。卡尔曼滤波里的矩阵运算本质上就是帮你自动处理多个变量和多个测量源之间的相互影响。想明白这一点再看代码里那些矩阵相乘就不会被吓到。4.2 当系统不再线性EKF 线性化思路普通卡尔曼滤波有一个前提系统模型和测量模型都是线性的。什么叫线性小车匀速直线运动位置和速度是简单的加减乘除这就是线性。但现实里问题没这么客气。以无人机为例无人机想要知道自己的俯仰角、横滚角、偏航角还要把角度变化率和地理位置一起估计。这些角度之间的转换关系带三角函数比如 cos、sin这就不是线性了。如果还硬套普通卡尔曼滤波误差会越滚越大最终发散。于是有了扩展卡尔曼滤波英文叫 Extended Kalman Filter简称 EKF。思路很直白非线性不好处理那就把非线性函数在当前估计点附近“掰直”。就像你看地球表面是弧形但如果只看眼前一米的路面完全可以当成平的。这个“掰直”的过程叫线性化用数学语言说是求雅可比矩阵。你不需要手算但你要明白EKF 并不是换了套原理它还是在做预测和修正只是把非线性的模型在每一轮先做了一次局部近似再套用卡尔曼滤波的标准流程。这也解释了为什么 EKF 工作“足够好”但不完美它只是局部线性近似如果系统非线性特别强或者你当前估计偏离真实状态太远“掰直”就掰不准了滤波效果会打折扣。4.3 从玩具小车到 PX4 飞控里的卡尔曼家族很多第一次接触卡尔曼滤波的人是在玩PX4飞控或者ArduPilot时遇到的。打开地面站日志可能看到EKF1、EKF2、EKF3这些词。它们都是扩展卡尔曼滤波的工程实现不是玄学而是前面讲的这套预测修正思路在真实飞行器上的落地。在PX4里卡尔曼滤波要处理的信息源非常多IMU的加速度计、陀螺仪、磁力计、气压计、GPS、光学流量计等。IMU更新频率快适合做短期预测GPS更新频率慢误差不会随时间无限累积适合做长期修正。卡尔曼滤波把这两类传感器各自发挥优势输出一个统一的姿态和位置估计。你如果看过PX4的EKF日志会发现里面有state vector和covariance等概念这些正是我们前面说的状态向量和信心账本。所以对初学者而言不要在没理解预测/修正循环之前就去啃PX4的矩阵推导。先把小车模型跑明白再去看飞控源码会发现它只是把同样的思想放进了更复杂的模型里。5. 亲手算一遍带具体数字的完整迭代5.1 初始化与第一轮预测光讲概念会飘我陪你做一次手算。假设一辆小车在一维轨道上运动我们只估计位置。为了方便展示先假定速度一直为0.5米每秒真实位置随时间线性增加。我们给卡尔曼滤波估的位置初始值是0米初始方差很大比如 (P_010)代表我们对初始位置相当没底。假设时间步长是1秒。第一轮预测[ x_{\text{pred}} 0 0.5 \times 1 0.5 ]预测方差会加上模型噪声。我们随便设一个很小的过程噪声 (Q0.01)[ P_{\text{pred}} 10 0.01 10.01 ]这意味着做完预测之后我们虽然认为小车在0.5米处但信心并没有增加多少因为初始方差太大了。5.2 第一轮修正卡尔曼增益上场这时测量值来了假设传感器报出位置是0.9米。测量方差 (R0.1)表示传感器本身噪声不大。先算卡尔曼增益[ K \frac{P_{\text{pred}}}{P_{\text{pred}} R} \frac{10.01}{10.01 0.1} \approx 0.99 ]增益接近1说明我们对预测的信心远小于对传感器的信心于是最终估计基本向传感器靠拢[ x_{\text{new}} 0.5 0.99 \times (0.9 - 0.5) \approx 0.896 ]更新完协方差也被压缩[ P_{\text{new}} (1 - 0.99) \times 10.01 \approx 0.0999 ]你可以看到仅仅一轮修正系统的不确定性从10掉到了0.1左右。这是卡尔曼滤波第一次惊艳我的地方一个几乎没用的初始猜测只靠一个靠谱的测量就能迅速收敛。5.3 第二轮迭代看滤波结果如何稳定收敛第二轮继续预测。预测位置[ x_{\text{pred}} 0.896 0.5 1.396 ]预测方差[ P_{\text{pred}} 0.0999 0.01 0.1099 ]新的卡尔曼增益[ K \frac{0.1099}{0.1099 0.1} \approx 0.5236 ]注意增益已经从上一轮的0.99降下来了原因是经过第一轮修正我们的预测已经变得相当可靠不再需要把测量值当成救命的唯一依据。假设第二次测量值是1.4则[ x_{\text{new}} 1.396 0.5236 \times (1.4 - 1.396) \approx 1.398 ]方差[ P_{\text{new}} (1 - 0.5236) \times 0.1099 \approx 0.0523 ]第二轮下来估计位置1.398离真实值很接近了方差进一步缩小。5.4 数值背后揭示的三个结论从这个数字例子能提炼出三个对实际工程非常有用的结论。第一卡尔曼增益不是固定的它随着系统对状态的信心变化而变化。第一轮信心不足增益接近1把测量几乎全盘接受第二轮信心增强增益自动降到0.5左右开始“拿捏”预测和测量的平衡。这个自适应特性是普通低通滤波器完全比不上的。第二协方差下降速度很快但不会降到0。因为过程噪声 (Q) 每一轮都会往系统里注入新的不确定性传感器噪声 (R) 也在限制着估计精度下限。这很合理世界总有扰动测量总有噪声完美是不可能的。第三Q和R的大小关系决定了滤波器的“性格”。如果R设得很小增益常年偏高系统会更听传感器的话输出曲线会快速响应但对噪声更敏感如果R设得很大系统会更依赖模型曲线会很平滑但容易出现滞后。这个调节过程没有标准答案完全取决于你的系统更怕“噪声”还是更怕“延迟”。6. 参数调优与常见误区噪声矩阵不是随便填6.1 Q和R的直觉含义一个调动态一个调信任实际用卡尔曼滤波时最让人头疼的就是 (Q) 和 (R) 怎么设。很多人看到公式里写着“噪声协方差矩阵”就以为一定要用统计方法去精确测量噪声方差。理论上是应该但工程里往往是先给个经验值再根据效果反复调。我把它们用大白话翻译一下(R) 代表传感器噪声的“讨人厌程度”。这个值可以通过收集一段静止状态的传感器数据算标准差然后平方来得到初值。(Q) 代表模型没考虑到的“外部捣乱程度”。比如你没有建模风阻、地面摩擦、电机响应延迟这些不确定性都要塞进 (Q) 里。它很难直接测量通常靠试。一个常见误区是把 (Q) 设成很小的数字比如默认给0.001。这会让滤波系统对自己模型的预测过于自信实际系统一旦出现模型没覆盖的扰动比如小车撞到东西、无人机碰到阵风估计结果就会僵在那里迟迟不肯跟随测量值。反过来(Q) 设太大会导致滤波结果和传感器读数几乎一样滤波等于没干。6.2 调参口诀与起步值根据我的经验第一次调参会遵循这样一个流程适合绝大多数项目先固定 (R)拿传感器原地静置一段时间记录数据计算标准差然后平方。如果懒得算先把 (R) 设成传感器数据手册里的噪声密度的量级。再调 (Q)从 (Q0.001) 开始慢慢往上加观察滤波曲线。如果曲线太毛糙、跟随传感器毛刺明显就把 (R) 调大或者把 (Q) 调小如果曲线太平滑、在真实变化出现后半天跟不上就把 (Q) 调大或者把 (R) 调小。判断标准不要看单点误差而是看动态响应和稳态平滑度之间是否达到了你能接受的平衡。这个过程很像给设备调音高音太刺耳就压一压测量噪声的信任度低音太闷就给模型多一点自由变化空间。6.3 常见误区不是所有噪声都适合用高斯分布卡尔曼滤波背后有一个重要假设预测过程噪声和测量噪声都服从高斯分布也就是那种中间高、两边低的正态分布。现实里很多噪声确实接近高斯但也有一些是例外。比如GPS在多路径效应严重的城市峡谷中偶尔会冒出巨大的跳变值这是典型的“长尾分布”或者“野值”不符合高斯假设。遇到这种野值时卡尔曼滤波会吃大亏。因为它只懂高斯分布里的“小偏差收敛”当一个离谱的测量值进来卡尔曼增益可能正好很大于是估计值被瞬间拉飞。解决这个问题的方案通常有两个方向一个是在卡尔曼滤波之前加一个野值剔除判断比如测量值偏离预测值超过3倍标准差就直接丢弃另一个是用鲁棒卡尔曼滤波或者带卡方检验的扩展卡尔曼滤波。PX4的EKF里就有类似的新息检测机制当测量值跟预测值差得离谱时会降低该传感器权重。6.4 什么时候别硬上卡尔曼卡尔曼滤波不是万金油它适合的系统有一个共同特征系统状态演变规律相对清晰传感器噪声大致服从高斯分布。如果你的问题是数据完全随机、模型完全未知或者系统的非线性太强以至于局部线性化完全失效那卡尔曼滤波不一定是最佳选择。举个反例你想根据一段股票价格序列预测明天是涨是跌先不说金融市场的模型是不是“真实状态”光是把股票波动建模成可控的线性运动就非常牵强。这种情况下与其套卡尔曼滤波不如换粒子滤波或者干脆用统计学习方法。再比如系统存在严重的多模态分布一个估计值可能同时“又在这里又在那里”卡尔曼滤波只会憋出一个四不像的中间值。所以选择卡尔曼滤波之前先问自己三个问题我能不能写出系统的状态转移关系传感器噪声是不是基本服从高斯分布我的状态是不是单峰的也就是大体上在某个值附近波动三个答案都是肯定的才值得继续往深处写代码。7. 我自己的实践心得和给新手的进阶路线如果只是学习一个仿真轮子项目足够。网上有大把小车的二维卡尔曼滤波源码你拿过来改改测量噪声看看输出曲线怎么变比强行推导十页矩阵更有用。我自己的学习路线是先用一维位置估计跑通再扩展到位置速度的二维状态最后在四旋翼仿真里加入陀螺仪和加速度计数据做姿态估计。每走一步都回到“预测和修正”这套内核去理解。实际开发中我还没见过一个状态估计系统是跑一遍卡尔曼滤波就完事的。几乎都要配合传感器故障检测、初始化阶段的延迟处理、不同传感器时间戳对齐这些工程细节。卡尔曼滤波更像是一个骨架真正让它好用的是你对传感器和运动模型的理解。参数调多了之后你会慢慢形成一种直觉看到滤波曲线太过丝滑首先怀疑是不是Q太小看到曲线像没滤波一样在剧烈呼吸首先怀疑是不是R太大。另外一个容易被低估的细节是初始化。卡尔曼滤波的初始协方差矩阵千万别设成零矩阵因为零就代表“我啥都知道了”后面测量和预测都没有拉动空间。一般会设一个比较大的初始值让滤波器在头几轮快速收敛到真实状态附近。如果你发现滤波输出前端出现一段明显的爬坡和震荡多半就是初始化没做好或者时间步长与数据频率不对齐。最后再分享一个小技巧调参时把预测值、测量值、滤波输出值画在同一条时间轴上一眼就能看出谁在拖后腿。如果滤波输出明显比测量值慢半拍通常是模型权重给太多也就是Q太小或者R太大如果滤波输出被毛刺拉得到处乱跳就是测量权重给太多。肉眼判断永远比盯着一堆数值去“感觉”要高效。这套方法在我做小车定位和无人机姿态估计时都反复用屡试不爽。卡尔曼滤波的学习曲线确实有点陡但一旦你把“预测求期望、修正加权平均”这层窗户纸捅破后面再接触EKF、无迹卡尔曼滤波、粒子滤波就只是在不同的“信任度描述方式”上做文章罢了。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表