news 2026/10/7 4:29:58

四轮转向汽车二自由度线性模型Simulink搭建全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
四轮转向汽车二自由度线性模型Simulink搭建全攻略

前几天有个做车辆控制的朋友问我,四轮转向汽车的线性模型在Simulink里到底该怎么搭。他说网上能找到的模型几乎都是封装好的黑盒子,想改个参数、把后轮转角输入引出来,根本无从下手。这其实是很典型的需求——不管是做毕设、写论文,还是刚入行的底盘控制工程师,第一步几乎都是先有一个可靠、可调、看得懂的二自由度车辆模型。这篇文章就把“四轮转向汽车二自由度线性模型”从数学推导到Simulink实现完整过一遍,包括三种不同的搭建思路、仿真结果怎么解读,以及我在调参和仿真过程中踩过的那些坑。

这个模型能做的东西其实不少:验证后轮转向控制律、设计状态观测器、做前馈比例控制、给CarSim联合仿真当参考模型,都是用它打底。适合的读者是已经有一点车辆动力学基础、想亲手把这个模型搭出来而不是直接抄文件的同学。

1. 四轮转向在解决什么问题,二自由度模型凭什么够用

1.1 从“自行车模型”到四轮转向

车辆动力学里最经典的降维方式,就是把汽车简化成一辆“自行车”。前轴两个轮子合并成一个轮,后轴两个轮子也合并成一个轮,车身看作一根有质量的杆子。这样一来,车辆在水平面内的运动就只剩下两个自由度:质心侧偏角和横摆角速度。

质心侧偏角就是车头指向和车辆实际速度方向之间的夹角,横摆角速度就是车身绕垂直轴旋转的快慢。这两个量基本决定了车辆的操纵稳定性感受。ESP、ABS、主动转向这类系统,核心控制目标说白了都是在管这两个量。

二自由度模型之所以够用,是因为在研究转向响应、操纵稳定性、稳态转向特性这些问题时,俯仰、侧倾、垂向载荷转移这些因素对车辆横向运动的影响不是主导因素。把问题压缩成“侧向+横摆”两个自由度,既能保留核心物理规律,又能让模型足够简单,适合做控制律推导和快速仿真验证。

四轮转向则是普通前轮转向的扩展:前轮转角作为主输入,后轮转角作为附加输入或控制量。这个额外的输入自由度,给了控制器很大的发挥空间。

1.2 低速反相位、高速同相位

说到四轮转向,很多人会想到低速时后轮反向转,高速时后轮同向转。这个说法没错,但背后的物理逻辑值得说清楚。

低速场景下,比如泊车、掉头,车辆希望转弯半径尽量小。后轮相对前轮反向偏转,相当于把车辆“两头同时转向”,等效转向角变大,原地机动性明显提升。这个工况下二自由度模型里的轮胎侧偏刚度变化不大,线性化假设依然成立。

高速场景下,前轮突然施加一个转角,车身会先出现一个较大的质心侧偏角瞬态响应,然后再稳定下来。如果让后轮和前轮同方向偏转,相当于给后轴也侧向“推”了一把,车辆横摆角速度和侧偏角的超调量都会显著降低,体感就是车辆更“稳”。

二自由度线性模型在四轮转向研究中的角色,就是提供一个能解析表达、能快速迭代的被控对象模型。你可以在这个模型上先用线性控制理论设计出后轮转角控制律,再拿到CarSim或者实车上细调。

2. 数学模型推导:从牛顿定律到状态空间方程

2.1 动力学方程是怎么来的

先约定坐标系和符号。把车辆坐标系固定在车身上,x轴指向车头,y轴指向车身左侧,z轴垂直向上。横摆角速度r逆时针为正。前轮转角δ_f逆时针为正,后轮转角δ_r也按同样的正方向定义。这个约定非常重要,后面搭模型时一旦方向搞反,仿真结果全错。

任意时刻,车辆质心处的侧向加速度可以写成:

$$ a_y = v_x(\dot{\beta} + r) $$

根据牛顿第二定律和绕质心的力矩平衡,可以得到:

$$ m v_x(\dot{\beta} + r) = F_{yf} + F_{yr} $$

$$ I_z \dot{r} = a F_{yf} - b F_{yr} $$

其中a是质心到前轴的距离,b是质心到后轴的距离,F_yf和F_yr分别是前轴和后轴受到的等效侧向力。

轮胎侧向力在小侧偏角范围内可以线性化为:

$$ F_{yf} = -C_f \alpha_f, \quad F_{yr} = -C_r \alpha_r $$

C_f、C_r是前、后轴的等效侧偏刚度,注意它是正数,侧向力方向由侧偏角符号决定。

前后轮的侧偏角表达式是:

$$ \alpha_f = \beta + \frac{a r}{v_x} - \delta_f $$

$$ \alpha_r = \beta - \frac{b r}{v_x} - \delta_r $$

把侧向力代入直线动力学方程,整理后可以得到两个一阶微分方程:

$$ \dot{\beta} = -\frac{C_f+C_r}{m v_x}\beta - \left(\frac{a C_f - b C_r}{m v_x^2} + 1\right)r + \frac{C_f}{m v_x}\delta_f + \frac{C_r}{m v_x}\delta_r $$

$$ \dot{r} = -\frac{a C_f - b C_r}{I_z}\beta - \frac{a^2 C_f + b^2 C_r}{I_z v_x}r + \frac{a C_f}{I_z}\delta_f - \frac{b C_r}{I_z}\delta_r $$

写成状态空间形式就是:

$$ \dot{x} = A x + B u $$

取状态向量$x=[\beta, r]^T$,输入向量$u=[\delta_f, \delta_r]^T$,则:

$$ A = \begin{bmatrix} -\frac{C_f+C_r}{m v_x} & -\frac{a C_f - b C_r}{m v_x^2} - 1 \ -\frac{a C_f - b C_r}{I_z} & -\frac{a^2 C_f + b^2 C_r}{I_z v_x} \end{bmatrix} $$

$$ B = \begin{bmatrix} \frac{C_f}{m v_x} & \frac{C_r}{m v_x} \ \frac{a C_f}{I_z} & -\frac{b C_r}{I_z} \end{bmatrix} $$

这个状态空间方程就是后面Simulink模型的核心。

2.2 参数选取与量纲陷阱

模型搭建本身不难,参数选错才是大多数仿真翻车的根源。我常用的样例参数如下,适合一辆中型轿车:

参数符号数值单位
整车质量m1500kg
横摆转动惯量I_z2500kg·m²
质心到前轴距离a1.2m
质心到后轴距离b1.4m
前轴等效侧偏刚度C_f55000N/rad
后轴等效侧偏刚度C_r60000N/rad
纵向车速v_x30m/s

两个特别容易踩的坑:

第一,侧偏刚度单位。轮胎厂商给的侧偏刚度时常是N/deg,而公式里用的是N/rad,两者差了57.3倍。直接拿N/deg带入模型,A矩阵数值会小两个数量级,仿真出来的横摆角速度会大到离谱。换算很简单:乘以57.3。

第二,车速单位。公式里v_x是m/s,不是km/h。如果把72km/h直接填成72,模型也会直接发散。建议在参数初始化脚本里统一单位,或者干脆在Simulink里用Constant模块写清楚单位。

另外,车速不能为0,因为A矩阵和B矩阵里都有除以v_x的项。车静止时根本不存在侧偏角和横摆角速度的定义,所以仿真的起始车速至少要取1m/s以上,低速工况再低也要保留一个非零值。

3. Simulink模型三种搭建方式

3.1 方式一:State-Space模块,十分钟搞定

如果你只是想做仿真验证,不打算深入研究内部结构,直接用Simulink Continuous库里的State-Space模块最省事。

操作步骤:

新建一个Simulink模型,从库浏览器里把State-Space模块拖进画布。双击模块,参数A填A,参数B填B,C填eye(2),D填zeros(2,2)。跑仿真之前,先运行参数初始化脚本,把这些矩阵变量载入工作区。

参数初始化脚本很简单:

%% 四轮转向汽车二自由度模型参数初始化 m = 1500; % 整车质量 kg Iz = 2500; % 绕z轴转动惯量 kg*m^2 a = 1.2; % 质心到前轴距离 m b = 1.4; % 质心到后轴距离 m Cf = 55000; % 前轴等效侧偏刚度 N/rad Cr = 60000; % 后轴等效侧偏刚度 N/rad vx = 30; % 纵向车速 m/s A = [-(Cf+Cr)/(m*vx), -(a*Cf - b*Cr)/(m*vx^2) - 1; -(a*Cf - b*Cr)/Iz, -(a^2*Cf + b^2*Cr)/(Iz*vx)]; B = [Cf/(m*vx), Cr/(m*vx); a*Cf/Iz, -b*Cr/Iz]; C = eye(2); D = zeros(2,2);

输入端需要把前轮转角信号和后轮转角信号拼成一个二维向量。老版本用Mux模块,新版本推荐用Vector Concatenate。两个输入信号,一个来自前轮转角Step模块,一个来自后轮转角控制律模块。

输出端直接用Demux拆开,或者干脆把输出向量接进Scope,Scope里设置多端口显示。

这个方案最大的问题就是“黑盒”。如果后轮转角要接控制器、状态要反馈给控制律,虽然也能做,但你对中间物理过程没有直观感受。

如果需要输出侧向加速度,可以把C和D改成三输出版本:

C = [1, 0; 0, 1; -(Cf+Cr)/m, -(a*Cf - b*Cr)/(m*vx)]; D = [0, 0; 0, 0; Cf/m, Cr/m];

这样输出依次是β、r、a_y。

3.2 方式二:手搭积分反馈图,看清每个系数

我自己的习惯是手搭一遍,因为这样每个增益系数对应哪个物理项,心里一清二楚。

搭建思路是把两个微分方程分别用积分器表示。比如β的导数β̇,是四个信号的加权和:

信号增益说明
δ_fCf/(m*vx)前轮转角对β̇的贡献
δ_rCr/(m*vx)后轮转角对β̇的贡献
β-(Cf+Cr)/(m*vx)侧偏角反馈
r-(aCf-bCr)/(m*vx^2)-1横摆角速度交叉反馈

r的导数ṙ同理:

信号增益说明
δ_fa*Cf/Iz前轮转角对ṙ的贡献
δ_r-b*Cr/Iz后轮转角对ṙ的贡献
β-(aCf-bCr)/Iz侧偏角交叉反馈
r-(a^2Cf+b^2Cr)/(Iz*vx)横摆角速度反馈

在Simulink里的连接方式:

拖入两个输入端口,命名为delta_f和delta_r。分别接Gain模块,增益值直接填表达式,比如Cf/(m*vx),Simulink会解析工作区变量。

拖入两个Integrator模块,第一个积分器的输入是β̇,输出是β;第二个积分器的输入是ṙ,输出是r。

把β接到第一条反馈支路,经过Gain模块-(Cf+Cr)/(m*vx)进入β̇的Sum模块。把r接到另一条反馈支路,经过Gain模块-(a*Cf-b*Cr)/(m*vx^2)-1也进入同一个Sum模块。

对第二个积分器做同样处理:β经过Gain模块-(a*Cf-b*Cr)/Iz,r经过Gain模块-(a^2*Cf+b^2*Cr)/(Iz*vx),连同两个输入经增益后的信号,一起加到ṙ的Sum模块。

一个非常实用的小技巧:Gain模块的增益值允许填带变量的表达式。所以你完全可以在模块里写-(Cf+Cr)/(m*vx),而不是手动算出一个数字填进去。这样以后改参数只需要改初始化脚本,不需要动模型。

还有一个细节:为了让Sum模块默认的“+”号全部适用,所有Gain模块的增益值都填“带符号”的最终值,包括负值。这样Sum模块四个输入都是正号相加,逻辑清楚,不容易乱。

整个手搭模型只有十几个模块,麻雀虽小,五脏俱全。做完之后,你可以把β和r分别接Out1和Out2,方便被上层测试脚本引用。

3.3 方式三:MATLAB Function块的正确用法

经常有人问能不能用MATLAB Function块直接把状态方程写出来。当然可以,但要注意,连续积分状态必须放在积分器里,MATLAB Function块只适合计算“导数”或者“控制律”。

如果你想在被控对象里用MATLAB Function,建议写成这样的导数计算函数:

function [beta_dot, r_dot] = vehicle_dynamics(beta, r, delta_f, delta_r, p) % p是一个结构体参数,包含m, Iz, a, b, Cf, Cr, vx beta_dot = -(p.Cf+p.Cr)/(p.m*p.vx)*beta ... - (p.a*p.Cf-p.b*p.Cr)/(p.m*p.vx^2)*r - r ... + p.Cf/(p.m*p.vx)*delta_f + p.Cr/(p.m*p.vx)*delta_r; r_dot = -(p.a*p.Cf-p.b*p.Cr)/p.Iz*beta ... - (p.a^2*p.Cf+p.b^2*p.Cr)/(p.Iz*p.vx)*r ... + p.a*p.Cf/p.Iz*delta_f - p.b*p.Cr/p.Iz*delta_r; end

然后把函数的两个输出接到两个Integrator,积分器输出β和r再接回输入端,形成闭环。

不过更常见的用法是把被控对象保留为积分反馈图,把MATLAB Function块用在控制律侧,用来计算后轮转角。比如写一个比例前馈控制律:

function delta_r = four_ws_control(delta_f, vx) % 一个简单的前馈比例控制:低速反相位,高速同相位 k = 0.6 - 0.7*vx/30; delta_r = k * delta_f; end

这样可以随时修改控制算法,而不需要动被控对象的底层模型。

4. 仿真工况设置与结果解读

4.1 阶跃工况怎么设置

仿真参数建议:定步长求解器ode4,步长1ms,仿真时长5s。车速取30m/s,前轮转角在第0.1秒从0阶跃到1度,也就是0.01745rad。

后轮转角分三种情况对比:第一种,后轮转角恒为0,等效于传统前轮转向;第二种,后轮转角按前轮转角的0.5倍同相位输入;第三种,按零质心侧偏角控制律输入,这个比例系数需要用稳态分析标定。

零侧偏角控制律的公式不复杂,思路是令稳态时β=0,反解出δ_r和δ_f的比例关系:

$$ \frac{\delta_r}{\delta_f} = -\frac{C_f\left[b C_r (a+b) - a m v_x^2\right]}{C_r\left[a C_f (a+b) + b m v_x^2\right]} $$

用第二节的参数,不同车速下的比例系数如下:

车速比例系数k转向特性
10 m/s-0.09反相位
20 m/s+0.45同相位
30 m/s+0.62同相位

可以看到,大约12m/s以下后轮反相位,12m/s以上后轮同相位,而且车速越高比例越大。这和实车四轮转向的标定规律是一致的。

4.2 稳态响应对比

仿真结束后,读取Scope里β和r的稳态值。按照第二节参数计算的理论稳态结果如下:

控制策略稳态质心侧偏角β(deg)稳态横摆角速度r(deg/s)
传统前轮转向-1.655.52
后轮同相位0.5-0.332.76
零侧偏角控制02.08

这个结果很直观:传统前轮转向在1度前轮转角下,稳态质心侧偏角有负的1.65度,车辆明显带着一个侧滑角在跑。加上后轮同相位转向之后,β明显减小。零侧偏角控制策略更是把稳态β压到接近0。

横摆角速度的变化更值得玩味。后轮同相位转向会把稳态横摆角速度增益拉低,也就是说同样打1度方向,车辆实际横摆角速度变小了。这既有好处也有代价:瞬态冲击小、稳定性好,但驾驶员会感觉转向响应变迟钝。所以实际四轮转向系统通常还会配合可变传动比或者横摆角速度反馈控制,把稳态增益补偿回来。

4.3 前馈控制改的是响应形态,不是系统阻尼

这里要纠正一个在不少文章里看到的说法:认为四轮转向前馈控制提升了系统阻尼。从线性系统角度看,前馈比例控制只改变了B矩阵,A矩阵完全没变,因此系统极点不变,自然阻尼比也不变。

那为什么仿真曲线上看起来超调量变了?

因为输入矩阵B改变了系统的零点,而零点会影响阶跃响应中的瞬态分量形态。后轮同相位转向相当于引入了一个“前置”的激励,抵消掉了前轮输入在初始阶段的相位冲击,所以质心侧偏角的超调明显减小。但这和“阻尼变大”是两回事。如果真想改变阻尼比,需要引入状态反馈,比如根据当前β和r实时计算后轮转角,而不是只做δ_r=kδ_f。

这一点在论文里尤其要注意,别把前馈控制宣传成改变极点的方案,审稿人看到会抓。

5. 常见问题、排查技巧与扩展玩法

5.1 模型直接发散,不知从何查起

这是被问得最多的问题。模型跑出来曲线直接冲到几百上千,基本可以锁定三个方向:单位错、符号错、车速给错。

单位问题前面提过,快速排查方法是看参数数量级是否合理。C_f如果是60000,v_x在用m/s单位下是30,乘积一百万量级,除以质量1500,出来的β̇系数最多几十,不会上千。如果Gain模块里出现好几万的量级,先怀疑单位换算。

符号问题重点检查后轮转角方向。你要非常清楚自己的正方向约定:如果整车坐标y轴向左为正,后轮转角δ_r正方向也是左转为正。但在很多实际控制器的输出里,转向方向定义可能相反。一个常见的验证方法:低速车速下给一个很小的前轮转角,后轮反相位输入,看横摆角速度是否比纯前轮转向更大。如果反了,横摆角速度反而变小,那就是符号反了。

还有一个必须检查的点是A矩阵特征值。在MATLAB里执行eig(A),所有特征值实部必须小于0,模型才是稳定系统。如果出现正实部,基本是参数或者符号错误,不用急着去调Simulink。

5.2 代数环报警怎么处理

手搭模型在连续域里通常不会出现代数环,因为状态反馈经过积分器,已经断开了瞬时代数依赖。但如果你在控制律里用当前时刻的β、r直接计算δ_r,并且立刻作用到被控对象,而你的被控对象又被你写成了一个隐式求解结构,就有可能出现代数环。

Simulink检测到代数环后,求解器会尝试解析它,但解析很慢,而且仿真结果可能不准。最简单的处理方法是:在控制律输出到被控对象输入之间加一个Memory模块或者Unit Delay模块,把当前时刻的值变成上一时刻的值。代价是引入一拍延迟,在1ms采样周期下影响可以忽略。

如果你打算做C代码生成,更推荐直接离散化整个模型,从根本上避免代数环问题。

5.3 模型要生成C代码,怎么处理连续积分器

热词里有一条“simulink模型C代码生成”,这确实是个高频需求。二自由度线性模型本身结构简单,但直接用于Embedded Coder生成C代码时,连续积分器不能直接映射到离散嵌入式系统。

建议的做法:把Integrator模块换成Discrete-Time Integrator,采样时间设置为1ms或者2ms。求解器类型选离散求解器,固定步长,然后配置Model Settings里的代码生成目标。这样生成的C代码可以直接部署到快速控制原型或者硬件在环平台。

采样时间的选择有个经验准则:二自由度车辆的横摆模态频率通常不超过3Hz,采样时间至少要小于系统带宽的1/10,所以1ms~5ms都是合理的。太粗的采样时间会在离散化时引入明显相位滞后,导致控制效果和连续仿真对不上。

5.4 扩展玩法:当参考模型、做联合仿真

二自由度线性模型的用处远不止开环仿真。我用的比较多的场景是做参考模型。在四轮转向控制或者稳定性控制里,控制器需要知道“理想状态下车辆应该产生多大的横摆角速度”,这个理想值一般就用二自由度线性模型在线计算。

做法是:把实际车速v_x作为模型输入,把驾驶员前轮转角作为模型输入,模型输出的r和β作为参考值。控制器再去跟踪这个参考值,偏差就是需要额外修正的量。

如果跟着CarSim联合仿真,思路也是这样。CarSim提供高精度的车辆动力学状态,Simulink里的二自由度模型只负责生成参考轨迹和控制律计算。CarSim的接口块输出车速、横摆角速度、路面附着,Simulink把后轮转角、附加横摆力矩等控制量送回CarSim。要注意的是,二自由度模型里的侧偏刚度参数在低附着路面需要打折扣,否则参考模型太“激进”,控制器会对每个小扰动都做大幅修正,实车体验会很差。

我个人实际调模型的时候有个习惯:把v_x单独做成一个Constant模块或者从外部输入,而不是写死在初始化脚本里。这样一来,扫不同车速工况不需要反复改脚本,直接把Constant的值拉一下就能重跑,配合MATLAB的sim函数做批量参数扫描也方便。希望这篇内容能帮你少走弯路,把四轮转向二自由度模型真正变成自己手里的工具。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 4:29:16

SpringBoot项目本地运行实战:环境配置到高效调试全指南

1. 跑通前的三件事:JDK、构建工具与IDEA的选择先聊点实在的。我在本地帮同事排查过很多次“为什么别人电脑上能跑起来的SpringBoot项目,到你这就起不来”的问题,十次里有八次都是环境不对付。SpringBoot项目本地运行这件事,表面上…

作者头像 李华
网站建设 2026/10/7 4:28:49

坚果色选机实战:从原理到选型、调试与维护全指南

1. 色选机到底在坚果加工里扮演什么角色干坚果加工这行超过十年的人应该都记得,早年挑异色粒全靠人工,一条生产线配几十个阿姨,夏天车间热,仁果又小又滑,眼睛盯一天下来基本是花的。现在你再去看中型以上的加工厂&…

作者头像 李华
网站建设 2026/10/7 4:28:34

基于BP神经网络的高大平房仓温度场预测实战指南

简介:《基于BP神经网络方法的高大平房仓温度场预测研究》是一份学术论文PDF,内容围绕国家粮食储备仓型——高大平房仓的温度场预测展开,面向粮油仓储安全监测、机器学习算法应用以及数据建模方向的科研人员、工程师与学生。该研究以BP神经网络…

作者头像 李华
网站建设 2026/10/7 4:28:33

从档案到故障处理:16页PPT讲透风电场运行维护要点

简介:这是一份关于风电场运行维护与管理的PPT教学课件,面向风电运维人员、相关专业学生及需要系统学习风电场运行知识的从业者。课件共16页,围绕风电场运行、风力发电机组运行、风电场维护三大模块展开,涵盖运行前准备工作、运行巡…

作者头像 李华
网站建设 2026/10/7 4:27:17

MinerU 4.0 Windows本地部署:彻底解决RAG中PDF解析难题

搞 RAG 这么多年,我发现一个很反直觉的真相:大家焦虑的向量检索、召回率、重排模型,其实都不是最容易翻车的地方。真正让项目流产的,往往是第一关——手里那几百个 PDF 根本没办法干净地转换成纯文本。我见过太多人拿 PyPDF2 抽出…

作者头像 李华
网站建设 2026/10/7 4:26:57

LeetCode 32 最长有效括号:三种解法详解与边界陷阱

1. 题目拆解:Hard题里的"最长连续"到底在考什么LeetCode 32 最长有效括号(Longest Valid Parentheses),我在刷题列表里见过它太多次了。题目本身一句话就能说完:给定一个只包含 ( 和 ) 的字符串,…

作者头像 李华