ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于扩展卡尔曼滤波的车辆质量在线估算及Simulink仿真实践

基于扩展卡尔曼滤波的车辆质量在线估算及Simulink仿真实践 1. 为什么车辆质量估算值得折腾——一个容易被低估的参数在车辆纵向动力学里整车质量大概是所有参数里最现实的一个。你翻任何一本控制理论的教材里面的车辆模型几乎都把质量当成已知常数可实际工况根本不是这么回事——空载和满载的乘用车质量能差出三四百公斤商用车空重和满载更是差出好几吨换一个驾驶员上车整车质心位置和惯量也跟着变。ABS制动控制、ESP车身稳定、坡道辅助起步、纯电车的续航里程预估、自动挡换挡策略这些系统全都要拿质量参数去算控制量质量给错了控制效果直接打折。用卡尔曼滤波去估算车辆质量本质上是把质量当作一个慢变状态放进状态向量里依托整车纵向动力学模型从带噪声的车速、加速度或驱动力信号中把质量实时滤出来。这个思路的好处是它不需要额外加装称重传感器纯软件就能实现而且天然具备抗噪声能力可以在车辆正常行驶过程中持续在线更新。我自己在Matlab Simulink里搭了一套完整的仿真模型跑了空载、满载、中载好几组工况确认这套方案从原理到实现都站得住脚。这篇文章把我踩过的坑、调过的参数、写过的代码原原本本记录下来适合正在做车辆状态估计、纵向控制或者刚接触卡尔曼滤波的工程师和研究生参考。先说清楚这篇文章的范围我会从整车纵向力平衡模型讲起推导出适合扩展卡尔曼滤波的状态方程和雅可比矩阵然后落到Simulink上的模块搭建与EKF算法实现最后重点讲Q、R矩阵的整定逻辑以及为什么质量估算在某些工况下死活不收敛这类实际工程里最容易撞上的问题。2. 纵向动力学模型与状态方程搭建——估算的底子2.1 从牛顿第二定律出发的整车纵向力平衡车辆在平直路面上行驶时纵向方向上作用的力量大致是这么几类驱动轮上的驱动力、空气阻力、滚动阻力以及坡度阻力。整车的纵向加速度由这四者的合力决定写出来就是标准的牛顿第二定律m * a Ft - Fw - Ff - Fi其中m是整车质量单位kga是纵向加速度单位m/s²Ft是驱动力单位N由发动机/电动机输出扭矩经过变速器、主减速器放大后作用到轮胎接地面上Fw是空气阻力Fw 0.5 * ρ * Cd * A * v²ρ取1.2258 kg/m³Cd是空气阻力系数A是迎风面积Ff是滚动阻力水平路面上Ff m * g * ff是滚动阻力系数Fi是坡度阻力Fi m * g * sin(θ)θ是道路坡度角驱动力Ft的计算也有一条经典链路。设发动机输出扭矩为Tq变速器当前挡位传动比ig主减速比i0传动效率η轮胎滚动半径r那么Ft Tq * ig * i0 * η / r这条公式在Simulink里就是几个增益模块串起来的事但要注意单位。扭矩是N·m传动比无量纲半径是m出来的才是N。很多初学者在Simulink里仿真结果数量级不对多半是这里某个参数写错或者速度单位没有从km/h换成m/s。下面是我仿真时用的一组基准参数后面所有代码和调试记录都基于这张表参数符号数值单位空载质量m_empty1800kg满载质量m_full2500kg空气阻力系数Cd0.4-迎风面积A2.3m²滚动阻力系数f0.012-传动效率η0.92-主减速比i04.3-3挡传动比ig2.5-轮胎滚动半径r0.326m重力加速度g9.81m/s²用这组参数很快可以算一笔账当发动机输出200 N·m扭矩、车辆挂在3挡时驱动力大约是6067 N空载1800 kg时加速度约3.1 m/s²满载2500 kg时加速度约2.2 m/s²。质量差近四成加速度差异非常明显这正说明车速信号里携带了质量信息卡尔曼滤波才有东西可滤。2.2 状态向量选什么为什么这里必须上EKF而不是标准KF要做卡尔曼滤波首先要写状态方程。质量估计里状态向量最常见的选择是x [v, m]ᵀ也就是把纵向车速v和整车质量m同时作为状态量。为什么把质量放进状态方程而不是直接当参数这里有个考虑虽然质量本身是常数但在实际行驶过程中它是慢变的比如乘客上下车、货物装卸这些变化是离散事件你不可能精确预知它何时发生。把质量当作一个缓变状态让滤波器自己去跟踪就不需要外部事件触发也不需要额外的传感器。于是连续时间状态方程可以写成dv/dt (Ft - 0.5 * ρ * Cd * A * v² - m * g * f) / m dm/dt 0第二个式子表达的就是质量是慢变量在单个滤波周期内近似常数。这个假设在绝大多数工况下成立除非你在几秒内把整车载荷彻底换掉。那么问题来了标准卡尔曼滤波要求系统是线性的即状态方程可写成x_dot Ax Bu w。现在你观察dv/dt的表达式里面出现了v²/m和1/m项——v和m在同一项里耦合而且是对状态的乘积关系这就是典型的非线性。所以不能用标准KF得用扩展卡尔曼滤波EKF在每个采样周期把非线性方程在当前估计值附近做一阶泰勒展开得到线性近似后再套卡尔曼的预测-更新框架。如果你图省事直接把dv/dt的表达式里v取上一次值、m取上一次值当成已知量那也能跑但那已经不是严格的卡尔曼结构滤波增益的计算会有偏差实际表现是估计值容易漂移。我建议该推导雅可比矩阵就老老实实推导后面代码里也就是几个表达式的事。2.3 雅可比矩阵推导这一步最容易出错EKF的预测步里需要求状态方程对状态的偏导数矩阵也就是雅可比矩阵F。f1 (Ft - 0.5 * ρ * Cd * A * v² - m * g * f) / m分别对v和m求偏导∂f1/∂v -(ρ * Cd * A * v) / m这个式子来自v²项的导数v前面的系数2被0.5约掉了很干净。注意这里的负号不能丢——空气阻力随速度增大而增大所以速度越快的车速度导数的增量越小这是物理上自洽的。∂f1/∂m -(Ft - 0.5 * ρ * Cd * A * v²) / m²这里要特别小心一个陷阱滚动阻力项m * g * f除以m之后变成了g * f对m的偏导是0。很多人看到滚动阻力里含m就直接把m²项写成撇开结果雅可比矩阵多了一项滤波器更新时质量估计会莫名其妙向错误方向修正。我第一次推这个偏导时也在这里卡了二十分钟后来干脆在草稿纸上把f1拆成含质量项和不含质量项逐一求导才把问题理清。f2 0所以∂f2/∂v 0∂f2/∂m 0。整理成矩阵就是F [∂f1/∂v, ∂f1/∂m; 0, 0]离散化时用一阶欧拉近似F_d I F * Ts其中Ts是滤波采样周期。对于车辆质量估计这种慢动态系统这种离散化精度完全够用。量测方程就简单了把车速传感器的输出当作量测H [1, 0]量测噪声假设为高斯白噪声方差为R。3. Simulink仿真模型搭建实操3.1 整体架构车辆模型、滤波器、量测注入三块Simulink模型我拆成三块来看这样不管是排查问题还是换算法都比较清晰。第一块是被辨识对象说白了就是用一个Simulink模型模拟真车。这个模型按照上面那套纵向动力学方程搭建内部把真实质量设成一个常数比如2500 kg。输入是发动机扭矩Tq输出是真实车速v_true。搭建方法不复杂用一个Integrator把加速度积成速度加速度由驱动力减阻力再除以质量得到。需要注意的细节是Integrator的初始条件要设成车辆起始车速比如10 m/s不然仿真从0开始加速前面几秒的速度过低阻力小EKF的激励特性跟正常行驶差别很大。第二块是传感器模块。用Band-Limited White Noise模块产生高斯白噪声叠加到v_true上模拟实际车速传感器轮速传感器或GPS速度信号的测量噪声。噪声方差这里取0.25对应标准差0.5 m/s这个量级对轮速传感器来说比较保守但也符合实际。第三块就是EKF滤波器本体。它接收两个输入驱动力Ft和带噪声的速度量测v_meas输出质量估计m_hat。在后面我会把EKF算法的完整MATLAB Function代码放出来直接复制到Simulink的MATLAB Function模块里就能用。3.2 EKF在Simulink里的三种实现方式EKF的实现我试过三种路子分别说一下优缺点。第一种是纯MATLAB Function块。这也是我最推荐起步的方式。直接在Simulink里拖一个MATLAB Function模块把EKF算法写成MATLAB函数persistent变量保存状态和协方差矩阵。优点是代码直观、调试容易可以在代码里打断点也可以把中间变量通过额外的输出端口接出来看。缺点是仿真速度稍慢而且后续想要代码生成上实车还得改写成C语言S-Function。第二种是S-Function。用Level-2 S-Function把EKF编写成C MEX适合要跑硬件在环或者C代码生成的场景。开发效率上慢一些但运行速度快和嵌入式代码风格一致。第三种是把滤波算法用Simulink原生模块搭出来。用Add、Gain、Product、Divide等模块把预测步、更新步逐级拼出来。这种做法的好处是可视化程度极高矩阵运算是怎么一步步算的一目了然坏处是模型规模大模块连线多稍不留神就出现代数环排查起来很闹心。我一般只在演示算法原理时用这种做实际项目还是MATLAB Function。不管你选哪种我都建议先跑通纯MATLAB Function版本算法行为确认无误后再往S-Function迁移不要一上来就搞C代码连Q、R都还没调明白迁过去只会两头抓瞎。3.3 仿真参数设置与输入信号设计Simulink的求解器设置里我推荐用固定步长求解器选ode4四阶龙格-库塔步长设0.001 s。为什么不用变步长因为EKF里的persistent变量逻辑本质上是按离散步数运行的变步长会让步长Ts不确定你还要费劲去改离散化系数没必要。固定步长0.001 s对车辆动力学来说计算量可以接受精度也足够。如果你把步长拉到0.1 s欧拉离散误差会明显增大质量估计值会高频抖动这个我在调试时确实遇到过。输入激励信号是质量辨识成败的关键。卡尔曼滤波想从量测中提取某个状态的估计前提是该状态在系统中被充分激励。对质量m来说激励就是加速度变化。如果你让车辆一直匀速跑那车速没有变化量测里几乎没有携带质量信息滤波器自然什么都估不出来。我用的输入信号是扭矩阶跃组合前10 s给100 N·m稳定扭矩让车辆加速10 s处阶跃到260 N·m持续8 s18 s再跳回150 N·m整个60 s仿真里穿插加速、接近匀速、再次加速等工况段。这个信号设计的好处是加速度覆盖多个区间质量对驱动力的反作用在不同工况下都有体现EKF能持续获得信息。为了观察收敛性还可以多跑几组对比试验同一时刻扭矩跳变幅度分别设为200、260、320 N·m看质量估计收敛速度如何变化。加速越猛收敛越快这从物理上很好理解——大油门时驱动力占主导质量的推力效应越明显辨识信噪比越高。EKF核心的MATLAB Function代码如下这是我实际调试过的版本参数里已经包含完整的空气阻力和滚动阻力公式function [m_hat, v_hat] ekf_mass(v_meas, Ft, Ts) persistent x P if isempty(x) x [v_meas; 1800]; % 状态初值 [车速, 质量] P diag([1e4, 2.5e5]); % 初始协方差质量标准差约500 kg end % 常量定义 rho 1.2258; % 空气密度 Cd 0.4; % 风阻系数 A 2.3; % 迎风面积 f 0.012; % 滚动阻力系数 g 9.81; % 重力加速度 v x(1); m x(2); % 状态方程 f1 (Ft - 0.5 * rho * Cd * A * v^2 - m * g * f) / m; f2 0; x_pred x [f1; f2] * Ts; % 雅可比矩阵 F [ -(rho * Cd * A * v) / m, ... -(Ft - 0.5 * rho * Cd * A * v^2) / m^2; 0, 0]; Fd eye(2) F * Ts; % 过程噪声协方差核心整定对象 Q diag([0.05, 0.5]); % 预测协方差 P Fd * P * Fd Q * Ts; % 量测更新量测为车速 H [1, 0]; R 0.25; % 量测噪声方差 K P * H / (H * P * H R); x x_pred K * (v_meas - H * x_pred); P (eye(2) - K * H) * P; m_hat x(2); v_hat x(1); end这段代码里有几个参数后面在整定环节会反复提到初始协方差P中的质量项2.5e5过程噪声Q(2,2)等于0.5量测噪声R等于0.25。这几个数字不是随便拍的后面细说。4. Q、R矩阵整定滤波器的性格调节旋钮4.1 过程噪声协方差Q的含义与初值选取卡尔曼滤波里的Q矩阵描述的是你对状态方程本身信任程度的折扣。Q越小意味着你认为模型越准状态预测的过程越可靠Q越大意味着你认为模型内部存在较多不确定性滤波器会给量测修正更大的权重。在质量估计这个场景里Q是个二维对角阵Q(1,1)对应速度状态Q(2,2)对应质量状态。Q(1,1)反映的是车辆纵向动力学模型中未建模因素对车速影响的强度比如坡度突变、风阻变化、路面附着系数变化。我一般取0.01~0.1这个范围。取太小滤波器对速度量测过度信任容易把量测噪声透传进状态取太大又会让速度估计变得过于平滑丢失高频信息。Q(2,2)对应质量本身的慢变假设的不确定性。理论上质量是常数Q(2,2)应该取0但如果取0滤波器一旦收敛到一个错误的质量值就永远无法靠后续量测把偏差拉回来——因为协方差已经趋于0增益也趋于0。所以工程上会保留一个小的非零值让它有醒来的可能。我调试下来Q(2,2)取0.1~1之间比较合适这个值越大质量估计收敛越快但对量测噪声的敏感度也会提高估计曲线会明显变糙。想要兼顾收敛速度和稳态平滑性可以试试分阶段调Q仿真前10 s用较大Q(2,2)让质量从初始猜测快速拉近真实值后面把Q(2,2)调小细修稳态精度。在Simulink里可以用Signal/Crossing模块或者手动切换仿真段来实现但初学阶段建议先用固定Q把行为看明白再说。4.2 量测噪声协方差R的依据R描述的是车速传感器的噪声方差这一项相对最客观。如果你用的是轮速传感器在正常路面上的车速量测噪声标准差大约在0.1~0.5 m/s取方差就是0.01~0.25。如果是GPS速度低速时误差略大高速时会好一些也可以用0.5~1 m/s的标准差。R的实际意义是滤波器认为速度量测有多可信。R越小滤波器越相信速度读数增益K的第一行越大速度估计紧跟量测但第二行质量修正的权重也会跟着被拉高噪声会被放大了灌进质量通道。所以你会发现一个很反直觉的现象R设置得太小质量估计反而剧烈抖动不是因为算法错了而是因为量测噪声被算法当成真实速度变化去反推质量了。反过来R设得太大滤波器对所有量测都爱信不信质量估计可能长时间徘徊在初始值附近不动收敛非常慢。调试时可以先用量测数据离线统计一下残差方差再作为R的参考基准。下面这张表是我多次试错后整理的整定参考区间贴出来供参考参数推荐范围太小太大Q(1,1) 速度过程噪声0.01 ~ 0.1估计过度平滑响应变慢速度估计抖动明显Q(2,2) 质量过程噪声0.1 ~ 1收敛后卡死无法纠正质量估计噪声大R 量测噪声方差0.01 ~ 1质量通道被噪声污染收敛极慢不贴近真实值P(2,2) 初始协方差1e4 ~ 1e6收敛慢初始偏差持续很久前几步修正幅度过大可能振荡4.3 调参实操中的典型案例收敛慢与发散调试阶段我遇到过两个特别典型的失灵场景直接说出来可能帮你省掉不少排查时间。第一个是质量估计全程躺平从初始值1800 kg几乎不动。排查下来发现是初始协方差P(2,2)设得太小了只有1。这个数字的含义是滤波器认为自己一开始就知道真实质量在±1 kg范围内根本不需要量测给什么修正意见于是增益K的第二个分量接近0后面的量测自然无法推动质量状态。解决方法是把P(2,2)调回2.5e5相当于告诉滤波器我一开始对质量一无所知误差可能大到500 kg它才会认真听量测信号的意见。这个教训告诉我初始协方差的意义不是对初值的信息量而是对初值的诚实程度。第二个是质量估计在中途突然跳出一大截随后又慢慢回落像受到一次大幅干扰。这个我最终定位到是仿真中输入激励切换导致的。当扭矩从260 N·m瞬间掉到150 N·m时加速度突减滤波器的预测步里ff1表达式在短时间内剧烈变化雅可比F也跳变协方差P被短暂放大增益K跟着冲高质量估计就被带偏了一块。这种阶跃激励下的瞬态偏离其实在物理上可以理解——驱动力突变时模型来不及完全解释掉速度变化率余量就被推给了质量状态。想要抑制这种现象最有效的手段是适度增大Q(1,1)让速度状态吸收更多模型不确定性而不是把锅甩给质量。5. 仿真结果分析三种载荷下的估算表现5.1 空载/满载/中载工况对照我分别把模型里的真实质量设为1800 kg、2200 kg、2500 kg跑了三组仿真其余参数完全一致初始质量猜测统一设成1800 kg。这个初始猜测本身就已经等于空载工况的真实值所以空载那组从一开始就是准的而满载那组初始偏差达到了700 kg最能检验滤波器的纠错能力。仿真结果整体上是符合预期的加速段内质量估计快速向真实值靠拢前5 s内就能逼近到真实值附近之后进入慢速收敛阶段60 s仿真结束时满载组的稳态误差大约在±3%以内也就是2500 kg的估计值稳定在2425~2575 kg区间。空载组的稳态误差更小在±1.5%左右。中载组的收敛速度介于两者之间这跟驱动力相同时加速度随质量增大而减小的物理规律是完全一致的——质量越大系统的加速度信噪比越低实际上反而是质量越大相同驱动力下加速度越小如果量测噪声不变那么信噪比是降低的所以大质量工况下辨识难度略大。这一点在工程上是需要注意的空载和满载的质量估计精度天然不一样。如果把质量估计曲线和真实质量曲线叠在一起看会发现一个很不错的特性滤波输出的质量曲线不会反复穿越真实值而是呈指数样逼近。这是卡尔曼滤波协方差收缩的自然效果说明滤波器内部的信心在逐步建立后面的量测逐渐变成对已有估计的微调。5.2 收敛速度与稳态精度的平衡这里的核心矛盾是参数设置让收敛快一点稳态的曲线就会糙一点想让稳态曲线平滑收敛又会拖沓。我在多次实验中找到的一个相对好用的平衡点就是代码里那组数Q diag([0.05, 0.5])R 0.25P0(2,2) 2.5e5。在这个参数下满载工况大约4~6 s收敛到真实值±100 kg范围稳态时质量估计曲线上的峰峰抖动大约在±80 kg左右整体表现可用于实际工程逻辑。如果你追求更平滑的稳态曲线可以把Q(2,2)从0.5降到0.05代价是满载组收敛时间可能拉长到15 s以上对于某些需要快速响应的控制策略来说就太慢了。反之如果你想要更快的收敛速度比如在线起步阶段就要知道大概载荷可以把Q(2,2)提到2稳态抖动会随之明显变大。这个矛盾没有标准答案主要看下游控制需求。我的经验是质量估计这类慢变量宁可选略保守的收敛速度也不要让稳态抖动太大因为控制模块用到一个带着±3%抖动的质量值平顺性感受很差。很多控制策略不求实时质量曲线跟皱眉头似的精确更在意它稳定不跳变。5.3 激励不足时的可观测性问题我在后面补了一组匀速巡航工况的仿真直接把扭矩设为恒定值车速稳定在20 m/s附近加速度趋近于0让质量在流逝的时间里几乎收不到新信息。结果很有意思质量估计不像大家想象的那样维持在原处不动而是缓慢地向一个偏离真实值的方向漂移——这是因为Q(2,2)的非零项在持续向协方差里注入不确定性卡尔曼增益把这个不确定性转化为对质量的修正但由于量测中缺乏与质量相关的激励这个修正在噪声驱动下变成了随机游走。这个现象很真实它指向一个深层次问题在匀速工况下质量在系统方程里不具备可观测性卡尔曼滤波无法从量测中提取质量信息。这不是算法的问题是系统本身的物理信息不足。工程上处理这个问题的通用办法是设置激励检测器只有当加速度绝对值超过某个阈值比如0.2 m/s²才允许质量估计结果对外发布或被控制模块采用否则保持此前已收敛质量值避免把游走结果递给下游模块。我在Simulink里实现这个逻辑很简单在EKF输出后面接一个Switch判断加速度阈值即可。这个细节往往是仿真模型跟实车逻辑差异的关键一环恰恰是它决定了整套算法在不同工况下是否可靠。6. 踩坑记录与工程化建议6.1 仿真结果看起来完美还远远不够最开始跑通模型时我盯着Scope里几乎完全重合的速度曲线和质量逼近曲线一度以为问题解决了。后来仔细做残差分析才发现速度估计残差的实际统计方差远大于我设置的R。这说明我的模型里可能存在未建模的动态偏差比如阻力系数不准、传动效率被当成常数处理这些偏差被EKF的模型不确定性项吸收了但反映在残差上就变成了超额噪声。如果你发现滤波后的v_hat曲线和v_meas曲线贴合得很漂亮但残差方差明显大于R的上限就要停下来想一下模型本身是否还有漏项而不是继续压参数。另一个容易自我欺骗的是只看一条仿真工况。我建议至少设计三组覆盖不同加速度区间的工况低速大扭矩加速、高速稳定巡航、带坡度的爬坡如果用坡度信号只有在这几类工况下质量估计都保持收敛且稳态不跳变才敢说模型可用。6.2 从Simulink到实车的距离仿真里各个环节都是理想的阻力系数恒定、坡度已知、传动效率固定。实车上的情况要复杂很多——坡度是个未知量默认0会让上坡工况下质量估计天然偏大因为坡度阻力被质量项吸收了转弯工况下轮胎滑移率变化会引入额外的力风阻在强侧风时也会偏离标称值。所以如果要做实车验证我建议优先考虑两个方案。第一个是坡度补偿方案如果车上能拿到纵向加速度计的读数可以把加速度计读数 - 车速导数粗略估计出坡度分量再把坡度项补偿进阻力公式里这样质量估计才不会被坡度污染。第二个是联合仿真方案用Carsim提供高保真车辆动力学信号Simulink里的EKF直接消费Carsim输出的驱动力矩和车速形成闭环验证。Carsim的好处是它的轮胎、悬架、空气阻力模型比Simulink里的简化模型精细得多能帮助你提前发现算法在理想模型上成立、在精细模型上尴尬的落差。代码生成方面MATLAB Function块在Simulink Coder下可以生成C代码但要注意persistent变量的初始化逻辑在嵌入式环境里要保证全局静态变量被正确清零浮点运算尽量统一成double或者根据ECU能力降成float避免精度不一致导致协方差矩阵更新异常。6.3 后续扩展坡度联合估计、UKF对比、RLS对照如果你把质量估算这条路走通了可以顺手往几个方向扩展。第一是坡度联合估计。把坡度θ也放进状态向量状态方程里加上θ的慢变假设x [v, m, θ]ᵀ量测仍然只有车速。这个系统有三个状态、一个量测可观测性会变差不少但依然可以跑。实测中坡度质量和加速度计的配合能显著改善坡道工况的辨识精度代价是雅可比矩阵推导工作量又上了一个台阶。第二是UKF对比。EKF靠一阶泰勒展开做线性近似UKF则通过Sigma点集来传播分布的均值和协方差对强非线性系统更稳健。车辆质量估算这种非线性程度中等的系统两者的估计精度差异其实不大但UKF无需推导雅可比矩阵代码维护成本低只是计算量更大。如果你是做研究生课题这组对比可以作为算法深度分析部分的内容。第三是递归最小二乘RLS对照。RLS的线性回归结构天然适合输入是驱动力、输出是加速度这种形式的质量辨识而且在某些简单场景下收敛比EKF还快。但RLS对噪声协方差和遗忘因子的组合非常敏感也不像EKF那样天然处理量测噪声分布所以两者的适用场景有微妙差别。把EKF、UKF、RLS在相同工况下做一次横评是我觉得对这个题目最有价值的工程化收尾。就个人体会而言卡尔曼滤波估算车辆质量这个项目最大的收获不是跑通了一个Simulink模型而是让我明白状态估计算法的效果上限实际上是由系统物理模型的可观测性和激励条件决定的。调Q、调R只是在给定的信息条件下做最优权衡永远无法凭空挤出模型里不存在的信息。真把模型和工况理解透了滤波器的表现自然会上去。
返回列表