ARTICLE DETAIL

资讯详情

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

Matlab实现魔术公式轮胎模型:参数拟合与特性曲线仿真

Matlab实现魔术公式轮胎模型:参数拟合与特性曲线仿真 轮胎是整车与地面唯一的接触点这句话做车辆工程的人基本都听过但真正动手做仿真时才会发现轮胎模型选得不对后面ABS、ESP、自动驾驶路径规划全都跟着飘。魔术公式轮胎模型也就是常说的Pacejka模型是目前学术界和工业界最常用的半经验轮胎模型之一。我第一次用它做控制算法验证时被B、C、D、E这组参数折磨了整整一周后来把公式拆开逐项做Matlab仿真才算真正掌握。这篇博文就把我如何用Matlab实现魔术公式、拟合参数、绘制特性曲线的完整过程写下来适合理工科学生、车辆方向研究人员以及刚接触车辆动力学仿真的工程师。1. 先从“轮胎力决定整车动力学”说起魔术公式模型的价值在哪里1.1 轮胎力整车仿真的“地基”很多刚入门的同学会把注意力放在悬架模型、转向模型和车身姿态计算上结果仿真跑起来总觉得“车是飘的”。原因很简单所有底盘控制算法最终都要通过轮胎与地面之间的作用力来改变车辆运动状态轮胎力算不准上层模型再精细也是空转。轮胎能提供给整车的力主要分三部分纵向力F_x对应驱动和制动侧向力F_y对应转弯时的抓地力回正力矩M_z对应方向盘回正手感。这三条曲线都有明显的非线性特征——小输入时近似线性输入增大后逐渐饱和饱和后甚至会出现下降。用线性模型去近似只能在很小的工作范围内成立一旦把仿真工况推到极限比如急刹车、高速变道误差会被迅速放大。魔术公式轮胎模型最吸引人的地方就是能用一条带三角函数的解析式同时描述这种“线性段-饱和段-回落段”的完整非线性特征。它并不是从物理机理推导出来的第一性模型而是通过大量轮胎试验数据拟合出的半经验公式计算效率高精度在工程可接受范围内所以在车辆动力学仿真、控制算法验证和自动驾驶仿真领域几乎成了标配。1.2 魔术公式凭什么成为行业默认选择魔术公式最早由荷兰代尔夫特理工大学的Pacejka教授提出后来经过多次迭代衍生出Pacejka 89、Pacejka 94、PAC2002以及商业化版本的MF-Tyre/MF-Swift。能在几十年里一直被广泛采用核心原因是它抓住了“精度与效率的平衡点”。一个完整的轮胎模型如果纯靠物理机理去推导需要考虑橡胶粘弹性、胎压、温度、磨损、路面粗糙度等一大堆因素参数可能上百个而且很多参数在工程现场根本测不到。魔术公式把所有这些复杂因素压缩成B、C、D、E四个主参数外加水平偏移S_h和垂直偏移S_v最多再考虑载荷和侧偏角的修正项就能把主要力特性描述得相当准确。更重要的是这套公式形式统一纵向力、侧向力和回正力矩都共用同一个函数骨架只是参数不同写代码时可以大幅复用。对于做控制的人来说这个模型还有一个隐形优势它在一定范围内是可微的。ABS、ESP、四驱扭矩分配算法都需要对轮胎力求导或者做局部线性化魔术公式这种连续光滑的解析表达式比查表插值友好得多用它设计控制器、做稳定性分析都更顺手。1.3 看清边界什么工况适合用什么情况要换必须说清楚魔术公式不是万能的。它描述的是稳态工况下的轮胎力特性也就是假设滑移率、侧偏角基本恒定后轮胎力达到的稳定值。对于快速瞬态工况比如路面附着突变、高频转向输入轮胎力会存在滞后现象这时候需要引入松弛长度模型或者在魔术公式外面再接一个一阶惯性环节。另外魔术公式原始形式不直接考虑胎压、胎温的实时变化。如果你的仿真目标是研究热管理或者不同胎压对操纵性的影响就需要换用热-力学耦合的轮胎模型或者对参数做插值修正。还有一种情况也容易踩坑大侧偏角复合工况同时有纵向滑移和侧偏角单个公式算出来的纵向力和侧向力会互相矛盾必须用摩擦椭圆/摩擦圆的概念做耦合修正。我在实际项目里的经验是做整车操纵稳定性分析、底盘控制算法开发、自动驾驶轨迹跟踪仿真魔术公式完全够用做轮胎自身设计、耐久性预测、高频振动分析则应该换更精细的模型。2. Matlab实现前的准备工程目录、参数结构与函数接口2.1 把工程目录整理清楚后面少走弯路很多同学拿到代码就直接打开一个.m文件写到底等做到参数拟合、批量画图的时候才发现到处都是硬编码改一个参数要找半天。我建议在动手写第一行代码前先花十分钟把工程目录搭好。我常用的目录结构是这样的magic_formula_model/ |-- main_plot_Fx.m % 纵向力仿真主脚本 |-- main_plot_Fy.m % 侧向力仿真主脚本 |-- fit_parameters.m % 参数拟合脚本 |-- magic_formula.m % 模型核心函数 |-- get_tire_params.m % 轮胎参数库 |-- data/ | |-- tire_test_Fx.csv % 纵向力试验数据 | |-- tire_test_Fy.csv % 侧向力试验数据 |-- results/ | |-- Fx_curve.png | |-- Fy_curve.png好处很明显仿真脚本、模型函数、参数库、试验数据分离后续换一套轮胎参数只需要改data目录下的数据文件和get_tire_params.m里的参数表核心代码完全不碰。如果是在做课程作业或者临时验证目录可以简化但我仍然建议至少把“模型函数”和“主脚本”分开因为拟合和仿真都要反复调用模型函数。Matlab版本方面我这里用的语法和函数都是比较通用的R2018b以上版本基本都能直接运行。要用到lsqcurvefit做参数拟合的话需要安装Optimization Toolbox如果装的是精简版或者学生版没有这个工具箱后面我也会提到替代方案。2.2 用结构体组织轮胎参数B、C、D、E与偏移量魔术公式的标准形式为[ y(x) D \sin\left[C \arctan\left(Bx - E(Bx - \arctan(Bx))\right)\right] S_v ]其中 ( x X S_h )。这里的 ( X ) 是输入变量滑移率 ( \kappa ) 或侧偏角 ( \alpha )输出 ( y ) 对应纵向力或侧向力。每个参数的含义和影响我用表格整理如下参数名称物理含义对曲线的主要影响B刚度因子决定曲线原点附近的斜率B越大小输入时力增长越快代表轮胎刚度越高C形状因子决定曲线整体形态C影响曲线是“S形”还是“正弦形”通常纵向力取1.9、侧向力取1.3附近D峰值因子决定曲线峰值大小基本等于最大附着系数乘以垂直载荷E曲率因子影响峰值附近和末端的弯曲程度E越大峰值之后回落越明显S_h水平偏移输入零点偏移让曲线沿横轴平移用于处理由于帘布层转向引起的偏移S_v垂直偏移输出零点偏移让曲线沿纵轴平移用于处理残余力/力矩在Matlab里我倾向于用结构体保存参数字段名和公式一一对应看起来非常直观par_fx struct(... B, 10.0, ... C, 1.9, ... D, 8000, ... E, 0.97, ... Sh, 0.0, ... Sv, 0.0);这里给的是某型乘用车在干沥青路面上、垂直载荷约8000N时的纵向力参考参数D直接取了接近载荷的数值意味着最大附着系数接近1.0这在良好路面上是合理的。真正的轮胎参数来自试验数据拟合只是拿来教学演示时用一组物理上说得通的数值更让人容易理解。2.3 写一个所有工况共用的基础函数因为纵向力、侧向力、回正力矩都共用同一个公式骨架我把核心运算抽成一个通用函数主脚本里只管传不同的参数结构体这样代码复用性最好。function F magic_formula(X, par) % magic_formula 魔术公式轮胎模型基础计算 % X : 输入变量滑移率或侧偏角 % par : 参数结构体字段为 B/C/D/E/Sh/Sv % % F : 输出力或力矩 x X par.Sh; y par.D .* sin(par.C .* atan(par.B .* x - par.E .* (par.B .* x - atan(par.B .* x)))); F y par.Sv; end注意几个细节。第一我用的是逐元素运算运算符这样函数内部可以直接接收行向量或者列向量画图时避免写循环。第二arctan在Matlab里用atan函数对应数学上的反正切主值范围这个正好符合魔术公式定义。第三return之前不需要做额外的数据规整后续拟合时这个函数可以直接被优化器调用。写好这个基础函数后主脚本就变得非常清爽。下面进入正题纵向力和侧向力怎么计算、怎么画图。3. 核心公式的Matlab实现纵向力与侧向力仿真3.1 纵向力滑移率与驱/制动力的关系纵向力对应的输入是滑移率 ( \kappa )工程上常定义为[ \kappa \frac{V_x - \omega R_e}{V_x} ]其中 ( V_x ) 是车轮中心的纵向速度( \omega ) 是车轮旋转角速度( R_e ) 是轮胎有效滚动半径。车辆加速时 ( \omega R_e V_x )滑移率为正制动时 ( \omega R_e V_x )滑移率为负。为了画图好看且符合大多数论文的习惯我通常把横轴滑移率转换成百分比并且保持正负号。下面是一个完整的纵向力仿真与绘图脚本% main_plot_Fx.m clc; clear; close all; % 添加模型函数路径实际使用时确保magic_formula.m在当前路径或已加入路径 par_fx struct(... B, 10.0, ... C, 1.9, ... D, 8000, ... E, 0.97, ... Sh, 0.0, ... Sv, 0.0); % 生成滑移率序列范围 -30% 到 30% kappa -0.30 : 0.002 : 0.30; Fx magic_formula(kappa, par_fx); % 绘图 figure(Color, w, Position, [100 100 800 500]); plot(kappa * 100, Fx, b-, LineWidth, 2); grid on; xlabel(滑移率 \kappa (%)); ylabel(纵向力 F_x (N)); title(魔术公式轮胎模型——纵向力特性曲线); xlim([-30 30]); ylim([-8500 8500]);运行之后你会看到一条通过原点、关于原点近似中心对称的曲线。滑移率在±3%以内时曲线近似为一条直线斜率就是轮胎纵向刚度由B、C、D三者共同决定。继续增大滑移率曲线斜率逐渐变缓在滑移率10%到15%左右达到峰值对应轮胎最大附着力的工作点再往后曲线略微下降这是轮胎进入明显打滑区域的标志。做控制算法时这条曲线有两个关键点要记住峰值点对应的滑移率就是最佳滑移率ABS的控制目标通常就是让滑移率稳定在这个点附近原点附近的线性区是驱动防滑和常规制动控制的稳定区域曲线斜率为正。一旦越过了峰值点曲线斜率为负纵向力随滑移率增大反而减小这时如果不干预轮胎很容易被抱死。3.2 侧向力侧偏角决定了车辆的转向响应侧向力的输入是侧偏角 ( \alpha )单位是弧度。侧偏角本质上是轮胎行进方向与轮圈平面方向之间的夹角转弯时侧偏角增大轮胎会先呈现近似线性的侧偏特性再进入饱和区。依然用同一个magic_formula函数参数换成侧向力参数% main_plot_Fy.m par_fy struct(... B, 0.18, ... % 1/rad C, 1.3, ... D, 6000, ... E, -0.9, ... Sh, 0.0, ... Sv, 0.0); alpha linspace(-0.4, 0.4, 401); % 约 -23度 到 23度 Fy magic_formula(alpha, par_fy); figure(Color, w, Position, [100 100 800 500]); plot(alpha * 180 / pi, Fy, r-, LineWidth, 2); grid on; xlabel(侧偏角 \alpha (deg)); ylabel(侧向力 F_y (N)); title(魔术公式轮胎模型——侧向力特性曲线); xlim([-25 25]); ylim([-7000 7000]);注意我这里侧向力参数里的B只有0.18和纵向力的B差别很大这是因为输入单位不同侧偏角用弧度滑移率无量纲换算到相同的横轴尺度后原点斜率 ( B \times C \times D ) 会落在合理的范围内。E取负值在侧向力里很常见会让曲线在峰值之后出现更明显的回落反映轮胎在极限工况下侧偏刚度衰退、甚至侧滑的趋势。这条曲线的重要性体现在操纵稳定性上。侧偏角在±2度以内时曲线非常陡代表轮胎的侧偏刚度车辆高速变道时的横摆响应主要靠这个区间侧偏角增大到8到12度以后曲线接近饱和说明轮胎已经快到达附着极限再加大转角也不会产生更多侧向力超过极限后曲线下降车辆就会开始出现甩尾、推头等失稳现象。ESP系统在判断车辆是否失稳时核心依据之一就是当前侧偏角是否处在轮胎力的下降段。3.3 一张图看懂特性曲线与参数敏感性很多人在刚接触魔术公式时光是记住B、C、D、E分别叫“刚度因子、形状因子、峰值因子、曲率因子”还不够一定要在Matlab里调一次参数看看曲线怎么变才能真正建立直觉。我建议做三组对比实验。第一组只改变D。把D从6000改成9000你会发现整条曲线纵向拉伸峰值变高原点斜率也变大。道理很简单D决定了纵轴尺度相当于最大附着力上限。第二组只改变B。把B从0.18改成0.30曲线在原点附近变陡但峰值几乎不变或者需要配合其他参数微调。B是刚度因子直接影响线性段的斜率这正好对应测量车辆“侧偏刚度”这个核心参数。第三组只改变E。把E从-0.9改成0.5你会发现曲线峰值之后的变化趋势完全不同。E接近1时曲线平坦E偏负时曲线峰值后回落更快。E的辨识在所有参数里最容易出问题因为它和B存在较强的耦合。我强烈建议你在自己的环境里跑一遍这个参数敏感性实验连续画几条曲线叠加在同一张图上用不了十分钟但对B/C/D/E的理解会牢固很多。这比背十遍参数定义都管用。4. 从试验数据到模型参数Matlab拟合实战4.1 为什么说“手调参数不靠谱”初学阶段用现成参数画曲线没有问题但一旦要模拟自己手头那套轮胎就必须做参数拟合。有人会质疑就四个参数手动在脚本里改数值、看曲线贴合度多试几次不就行了吗我试过结论是不行。原因在于B和E的耦合关系特别强改变B会影响原点斜率改变E会影响峰值之后的弯曲程度但两者对中间区域的影响又相互叠加手调很容易陷入“调好左端、坏了右端调好右端、左端又偏”的循环。更麻烦的是如果还涉及S_h和S_v同时要匹配曲线位置和形状手工调整完全不可控而且没有任何精度评估依据写论文和做工程都无法交代。参数拟合本质上是求解一个非线性最小二乘问题找到一组参数使得模型输出和试验数据之间的误差平方和最小。Matlab的Optimization Toolbox里提供了现成的lsqcurvefit函数用来做这件事非常合适。4.2 用lsqcurvefit做参数拟合的完整流程假设我们用轮胎试验台测得了一组纵向力数据不同滑移率对应的纵向力存储在data/tire_test_Fx.csv中第一列是滑移率第二列是纵向力。拟合脚本的核心代码如下% fit_parameters.m clc; clear; close all; % 读取试验数据 data readmatrix(data/tire_test_Fx.csv); kappa_data data(:, 1); Fx_data data(:, 2); % 定义优化目标函数把参数向量p映射到模型输出 fun (p, x) p(4) .* sin(p(2) .* atan(p(1) .* x - p(3) .* (p(1) .* x - atan(p(1) .* x)))); % 初始值根据曲线特征估计 % D 取试验数据的峰值 D0 max(abs(Fx_data)); % 纵向力曲线C通常在1.6~2.0之间 C0 1.9; % 原点斜率大约为 B*C*D因此B0 原点斜率/(C0*D0) % 取原点附近两点计算斜率 idx_center find(abs(kappa_data) 0.02); slope0 (Fx_data(idx_center(end)) - Fx_data(idx_center(1))) / ... (kappa_data(idx_center(end)) - kappa_data(idx_center(1))); B0 slope0 / (C0 * D0); % E 先给一个经验值 E0 0.9; p0 [B0, C0, D0, E0]; % 上下界限制参数在物理合理范围内 lb [0.1, 1.0, 1000, -2.0]; ub [50, 2.5, 30000, 1.5]; % 执行拟合 options optimset(Display, iter, TolFun, 1e-10, TolX, 1e-10, MaxIter, 1000); pfit lsqcurvefit(fun, p0, kappa_data, Fx_data, lb, ub, options); % 输出拟合结果 par_fx_fitted struct(B, pfit(1), C, pfit(2), D, pfit(3), E, pfit(4), Sh, 0, Sv, 0); % 画对比图 kappa_plot linspace(min(kappa_data), max(kappa_data), 300); Fx_fit fun(pfit, kappa_plot); figure(Color, w, Position, [100 100 800 500]); plot(kappa_data * 100, Fx_data, o, MarkerSize, 5, LineWidth, 1.2); hold on; plot(kappa_plot * 100, Fx_fit, r-, LineWidth, 2); grid on; xlabel(滑移率 \kappa (%)); ylabel(纵向力 F_x (N)); legend(试验数据, 拟合结果, Location, northwest); title(魔术公式参数拟合结果对比);这里有几个关键点要展开说明。第一初值估计。非线性最小二乘对初值敏感如果初值离真值太远很容易陷入局部最优。我上面的估计方法很实用D0用试验数据的峰值因为峰值因子本来就决定曲线顶点高度C0根据经验取1.9附近纵向力的形状因子变化范围不大B0用原点附近斜率除以C0D0因为公式在原点的导数正好等于BC*DE0给一个中间值0.9。这套估计顺序保证了初值在合理区间内能大幅提高拟合收敛概率。第二边界约束。给参数设置物理合理的上下界不只是防止优化器跑到荒谬的值还能加速收敛。比如D不可能小于零C基本不会超过2.5B不会超过某个范围。这里我给的上下界只是示例实际要根据你的轮胎类型和试验数据范围调整。第三如果Sh和Sv也需要拟合可以把它们也加进参数向量但初值会更难给而且和B、E的耦合更复杂。我的建议是先固定Sh0、Sv0做一次拟合看残差是否有明显的系统偏移如果有再把Sh、Sv加入拟合这样逐步推进比一步到位稳定得多。4.3 拟合精度的评估与初值设置技巧拟合不是跑完lsqcurvefit就结束了还要评估结果质量。我最常用的指标有三个决定系数R²、均方根误差RMSE、最大绝对误差。R²越接近1越好RMSE和最大绝对误差则要结合力的量级判断。对于纵向力峰值8000N左右的情况RMSE在100N以内就算不错如果总在数百N以上说明模型结构或者数据本身有问题。另外千万别只盯着拟合误差看还要检查拟合出的参数是否物理合理。比如D拟合出15000N远超该轮胎在给定载荷下的峰值即使拟合误差不高这个结果也不能用于仿真因为外推能力会很差。遇到这种情况通常是C的取值偏离太多或者试验数据没有覆盖到饱和区导致D和C互相补偿。解决办法是压缩C的上下界范围甚至固定C1.9只拟合B、D、E三个参数。如果Matlab没有Optimization Toolbox可以用fminsearch替代但fminsearch不支持参数上下界而且性能不如lsqcurvefit。我的建议是优先检查工具箱情况实在没有也可以手写一个带惩罚项的目标函数配合fminsearch做边界约束就是代码会啰嗦一些适合应急。5. 实操中踩过的坑与排查经验5.1 常见问题速查表我在教学和项目里反复碰到下面这些问题整理成一个速查表遇到类似现象可以直接对照处理。问题现象可能原因解决办法曲线峰值和D参数明显不符曲线带垂直偏移Sv或试验数据有零位偏移先对数据做去零位处理或把Sv加入拟合拟合结果不收敛或卡在奇怪位置B和E初值不合适耦合太强按“D→C→B→E”顺序估计初值逐步拟合侧向力横轴用了角度曲线形状非常怪模型函数要求弧度主脚本却传了度数统一在模型内部或入口处转换单位制动滑移率曲线方向相反滑移率符号定义不一致ISO/SAE明确采用一种定义符号处理统一放在数据预处理阶段仿真过程轮胎力跳变、震荡查表插值数据点过稀或噪声太大用拟合后的连续模型代替查表或先对试验数据做平滑峰值后下降趋势拟合不上E参数范围太小或数据没覆盖到下降段放宽E的下界允许负值补充大滑移率/大侧偏角试验点同一套参数纵向力特别好侧向力完全不能用两种力的参数库混用或载荷修正缺失分别建立Fx、Fy参数表不要共用一套B/C/D/E5.2 参数整定的进阶技巧处理真实轮胎数据时有几个进阶操作能明显提升效果。第一个技巧是分段加权拟合。如果你最关心小滑移率区间比如做ABS控制重点工况在5%到15%滑移率可以在目标函数里给这个区间的误差乘以更高的权重让拟合结果优先贴合关键区段。实现起来并不复杂给误差数组乘一个权重向量即可。第二个技巧是分步拟合。先把不用管偏移量的简化模型拟合好固定B/C/D/E后再拟合S_h和S_v。这两个偏移参数在物理上往往有明确来源比如子午线轮胎的帘布层转向会产生侧向力偏移实际数据里它们的值通常不大如果拟合出来的偏移量非常大八成是主参数没拟合对而不是偏移真的那么大。第三个技巧是在拟合前后都做“参数归一化”。轮胎参数的数值范围差别很大B可能是0.18D可能是6000直接放在一个优化问题里数值尺度不一致会让优化器对B的更新步长不敏感。可以通过对参数做对数变换或者按上下界做缩放把各个参数调整到同一个数量级优化效率和稳定性都会提升。5.3 从单工况到整车仿真扩展思路单条纵向力曲线和侧向力曲线跑通之后很多人的下一步是把模型接到整车仿真里。这里有几个扩展方向按难度从低到高排列。第一载荷修正。上面例子里的参数都是在固定垂直载荷下测的真实的车上载荷会随加速、制动、转向而转移。常见做法是让D、B等参数随垂直载荷Fz做插值或线性变化。我建议先测三个载荷点空载、半载、满载然后对D和B做Fz的分段线性插值效果通常已经足够好。第二复合工况的耦合。车辆在制动的同时转向纵向力和侧向力会争夺同一个附着极限单纯把Fx和Fy分开算会导致总力超过摩擦圆边界。我采用的方法是用摩擦圆/椭圆修正先计算不考虑耦合的Fx0、Fy0再根据当前附着利用率整体缩放或者按滑移率和侧偏角联合查表。这部分写起来不难但需要对车辆动力学有个整体理解建议放在单工况模型完全验证通过后再做。第三回正力矩的实现。回正力矩M_z和Fx/Fy共用同一个魔术公式只需要更换输入、参数和输出单位把基础函数复制一份、参数换成回正力矩参数即可。回正力矩对转向手感仿真很重要尤其是做线控转向或者转向系统设计时这个模型不可或缺。最后再分享一点个人体会魔术公式参数库不管网上能找到多少版本真正到了自己项目里还是得花时间用试验数据标定。别指望套一套现成参数就能精确复现你手头的轮胎科学的态度是用它做趋势分析、控制算法验证和方案对比这些场景下它的精度完全够用。另一个经验是把建模脚本和数据文件分开管理每个参数调整都记录在数据文件里而不是散落在脚本各处项目后期维护会轻松很多。如果你正准备开始做整车动力学仿真建议先把纵向力和侧向力两条曲线跑通理解B、C、D、E对曲线形态的影响再把复合工况和整车模型加进来这个顺序能让你少走很多弯路。
返回列表