做四轮转向(4WS)控制,绕不开的第一步就是给被控对象搭一个能跑得起来的 Simulink 模型。很多人一上来就想用 CarSim 这种高精度车辆模型,结果控制算法还没验证,先被一堆非线性轮胎模型参数折腾到怀疑人生。我的建议是:先用二自由度线性模型把控制思路跑通,再考虑整车级联合仿真。这篇文章从一个可复现的最小角度出发,把四轮转向汽车二自由度线性模型在 Simulink 里的搭建过程、状态方程推导、参数标定和踩过的坑完整过一遍,适合车辆工程专业学生、底盘控制入门工程师,以及所有要做车辆横向运动控制但不想被非线性细节淹没的人。
1. 四轮转向汽车二自由度线性模型,到底在仿真什么
1.1 为什么偏偏是“二自由度”
在车辆动力学里,完整描述一辆车可以有十几个自由度:纵向、侧向、垂向、横摆、侧倾、俯仰,再加上四个车轮的转动和位移。但对于转向控制研究,最关键的其实是两个量:一个是横摆角速度 γ,也就是车绕垂直轴转得有多快;另一个是质心侧偏角 β,也就是车身实际行驶方向跟车头指向之间的夹角。这两个量直接决定了车辆是不是“听话”,也直接关联到驾驶员对转向的感知。
二自由度线性模型,圈子里也常叫“自行车模型”,它把左右两侧车轮合并成前后两个车轮,只保留侧向运动和横摆运动这两个自由度。它会忽略纵向车速变化、悬架变形、侧倾、俯仰,同时假设轮胎始终工作在线性区。听起来牺牲了很多精度,但换来的是极简的数学表达:整个系统只有两个状态变量、一阶线性常系数微分方程,非常有利于做控制器的设计和稳定性分析。
做四轮转向控制的研究,前期最关心的不是“这辆车在某条异形试车场里详细动作如何”,而是“我引入后轮转角之后,质心侧偏角有没有被压下去,横摆角速度跟随性有没有变好”。这些问题用二自由度模型就能定性、甚至半定量地回答。等你把控制策略在这些线性模型上验证得差不多,再换CarSim去跑更真实的路况,省时省力,逻辑上也站得住。
1.2 四轮转向给模型带来什么变化
传统前轮转向车型的输入只有一个前轮转角 δf,汽车只能依靠前轮“牵着鼻子走”。四轮转向多了一个后轮转角 δr,等于给车尾也加了一把转向伞,控制手段自然更丰富。业界一般分两段用这个能力:低速时让后轮与前轮反相转动,等效缩短轴距,减小最小转弯半径,泊车、掉头时特别明显;高速时让后轮与前轮同相转动,让车尾跟上车头的意图,减小质心侧偏角,提高变道和弯道中的稳定性。
在二自由度模型里,这个变化非常直观:状态方程从单输入变成双输入,B矩阵多了一列,仅此而已。你可以在 Simulink 模型里给后轮转角单独加一个信号源,也可以把它接到前轮转角乘以某个增益,仿真同相和反相的效果。由于模型是线性的,后轮转角对横摆和侧偏的贡献可以单独叠加,理解起来比非线性模型清爽得多。
当然,线性模型有它的适用范围:一般建议在侧向加速度不超过 0.4g、附着良好、车速基本恒定、转向输入不猛烈的工况下使用。超过这个范围,轮胎侧偏角进入非线性区,侧偏刚度不再是常数,“线性”这个前提就不成立了,跑出来的结果会偏乐观。后面所有推导和模块搭建,都默认在这个适用范围内。
2. 建模前的准备:从受力分析到状态方程
2.1 坐标约定与轮胎线性假设
动手建模前,先把坐标系和符号统一好,这一步做不好,后面所有 Simulink 结果都是自欺欺人。我习惯用车辆动力学教材里的标准约定:x 轴沿车纵向向前,y 轴指向驾驶员左侧,z 轴垂直向上。纵向车速 v 恒定;质心侧偏角 β 是速度矢量与车辆纵轴的夹角,逆时针为正;横摆角速度 γ 绕 z 轴,逆时针为正;前轮转角 δf 和后轮转角 δr 都以前左/后左轮相对车辆纵轴逆时针偏转为正。
轮胎侧向力在二自由度模型里被简化成线性关系:Fy = -C·α。注意这里的 C 取正数,称为侧偏刚度,单位是 N/rad;α 是侧偏角,也就是轮胎接地印迹处速度方向与车轮平面之间的夹角。负号表示侧向力总是阻碍侧偏发生,车轮往左偏,力就往右拉。
很多初学者在这里被符号整晕。有些教材把侧偏刚度定义为负值,写成 Fy = Cα,C 本身是负的。两种约定最后算出来的状态方程完全一样,但如果你照着一份用负刚度推导的资料去填另一个用正刚度推导的 Simulink 矩阵,稳稳态结果能差出一个正负号来。我的建议是:本文统一使用“正刚度+负号力”的约定,在模型参数脚本里也明确写 C_f_pos 这样带后缀的变量,避免自己把自己坑了。
2.2 二自由度运动方程推导
把整车等效成“前轮+后轮”的自行车模型后,侧向应用牛顿第二定律,横摆方向应用动量矩定理:
$$m v \left(\dot{\beta} + \gamma\right) = F_{yf} + F_{yr}$$
$$I_z \dot{\gamma} = a F_{yf} - b F_{yr}$$
其中 m 是整车质量,Iz 是绕 z 轴的转动惯量,a 是前轴到质心的距离,b 是后轴到质心的距离。前、后轮的侧偏角写成:
$$\alpha_f = \beta + \frac{a \gamma}{v} - \delta_f$$
$$\alpha_r = \beta - \frac{b \gamma}{v} - \delta_r$$
第一式的意思是:前轮实际速度方向由质心侧偏角、横摆运动带来的侧向速度分量共同决定,再减去前轮转角。后轮同理,只是横摆分量方向相反。把侧偏角代入线性轮胎力公式,再代回运动方程,整理成状态空间就是:
$$\begin{bmatrix} \dot{\beta} \ \dot{\gamma} \end{bmatrix} = A \begin{bmatrix} \beta \ \gamma \end{bmatrix} + B \begin{bmatrix} \delta_f \ \delta_r \end{bmatrix}$$
其中:
$$A = \begin{bmatrix} -\dfrac{C_f+C_r}{m v} & \dfrac{b C_r - a C_f}{m v^2} - 1 \ \dfrac{b C_r - a C_f}{I_z} & -\dfrac{a^2 C_f + b^2 C_r}{I_z v} \end{bmatrix}$$
$$B = \begin{bmatrix} \dfrac{C_f}{m v} & \dfrac{C_r}{m v} \ \dfrac{a C_f}{I_z} & -\dfrac{b C_r}{I_z} \end{bmatrix}$$
注意 A11 的负号代表车辆本身的侧向阻尼:速度越低,这个阻尼效应越强,车越“稳当”;A12 里那个 "-1" 来自向心加速度项,车速越高,它对侧偏角演化的影响越大;A21 和 A22 则对应横摆方向上的“恢复力矩”和“横摆阻尼”。
对于四轮转向,只需要把 δr 当作第二个输入即可。如果暂时不接后轮转角,令 δr = 0,方程组就退化成经典的前轮转向二自由度模型,这也是后面验证模型正确性的重要手段。
2.3 参数怎么定:一套可复现的车辆数据
理论推导只是第一步,Simulink 模型里填什么参数,直接决定仿真结果像不像一辆车。我一般会准备一组典型中型轿车的等效参数,方便快速跑通:
| 参数 | 数值 | 说明 |
|---|---|---|
| m | 1298.9 kg | 整车质量 |
| Iz | 1627 kg·m² | 绕 z 轴转动惯量 |
| a | 1.05 m | 前轴到质心距离 |
| b | 1.57 m | 后轴到质心距离 |
| Cf | 65000 N/rad | 前轴等效侧偏刚度 |
| Cr | 80000 N/rad | 后轴等效侧偏刚度 |
| v | 25 m/s | 仿真车速,90 km/h 左右 |
参数里最容易出问题的是侧偏刚度。这里的 Cf、Cr 必须是前轴和后轴的“等效总刚度”,也就是把同一轴上的两个轮胎合并成一条虚拟轮胎后的刚度,不是你从轮胎单体实验报告上看到的单轮刚度。单轮刚度大约在 30000~50000 N/rad,同轴两轮合并后通常可以达到 60000~100000 N/rad。如果直接用单轮刚度填进二自由度模型,仿真出来的车辆会显得异常迟钝,跟实际操稳数据对不上。
在没有实测数据的时候,还有一种反推方法:先确定车辆希望呈现的不足转向梯度 K,再用公式 K = (m/L²)(b/Cf - a/Cr) 来反算刚度组合。这样做出来的模型至少“手感”是对的。本文参数计算出的 K 约为 0.0021,表现为不足转向,符合绝大多数民用车设定。
3. Simulink建模实操:从空白模型到跑通仿真
3.1 建模思路选择:State-Space模块还是积分器加增益
Simulink 里实现二自由度模型有两条常见路线。第一条是用现成的 State-Space 模块,直接把 A、B、C、D 四个矩阵填进去,干净利落,适合对控制算法做快速验证;第二条是用积分器+增益模块把微分方程拆开搭,直观但模块多,适合以后想扩展成非线性轮胎、加入限幅或查表的场景。
如果你就是想要一个“被控对象”,后面马上接状态反馈控制器、LQR、PID 之类的算法,我强烈建议用第一条路线。State-Space 模块输入是 [δf, δr]ᵀ,输出是 [β, γ]ᵀ,端口清晰,代码生成也好处理。如果你做的是研究项目,后面大概率要把模型从 Simulink 生成 C 代码丢到快速原型里跑,State-Space 这种结构化表达比一堆积分器块更容易被 Embedded Coder 优化。
反过来,如果你以后想模拟轮胎侧偏刚度随载荷变化、加入悬架侧倾对侧偏刚度的影响,那积分器方案更灵活,因为你可以随时往积分路径里插环节。我这次以 State-Space 方案为主线讲解,但会说明每个操作对应的物理含义,理解之后再换积分器方案很容易。
3.2 一步步搭建带后轮转向输入的模型
打开 Simulink,新建一个空模型,保存成 4WS_2DOF.slx。先在 MATLAB 工作区把参数跑一遍,或者在模型的 Model Properties -> Callbacks -> InitFcn 回调里写好参数脚本。我习惯写在 InitFcn 里,这样每次打开模型都会自动重新赋值,防止模型和数据脚本失配。
在 Simulink 库浏览器的 Continuous 目录里找到 State-Space 模块,拖进来。双击模块,把 A、B、C、D 四个矩阵填写为工作区变量 A、B、Cmat、Dmat。C 建议用 Cmat=eye(2),这样输出就是两个状态本身;Dmat=zeros(2,2),因为二自由度模型中没有输入的直通项。注意这里先不要直接在模块里写矩阵数字,用变量可以方便后面做参数扫描。
然后添加两个 Step 模块。第一个 Step 设置 Step Time=0,Final Value=10*pi/180,作为前轮阶跃转角;第二个 Step 初始设为 0,作为后轮转角输入。两个 Step 信号经过一个 Mux(2输入)合成 2×1 向量,接到 State-Space 的输入端。
在模型里用 Gain 模块做“度转弧度”其实更规范:Step 里就填 10,后面接一个 Gain=pi/180。这样模型里的信号含义一目了然,也不会因为某个常量算错而让整个仿真结果差一个量级。
State-Space 模块的输出接一个 Demux,拆成 beta 和 gamma 两路,分别接 Scope。为了后面做控制策略对比,我习惯再加一个 To Workspace 模块,把 beta、gamma 连同时间 t 一起导出到 MATLAB 工作区,方便脚本绘制多工况对比曲线。到这里,一个能跑的最小模型就算搭完了。点一下 Run,如果没报错,Scope 里应该能看到一条向上的横摆角速度阶跃响应曲线和一条向下的质心侧偏角曲线。
3.3 输入信号、仿真步长与初始化脚本
很多第一次跑这个模型的同学会遇到“波形根本不动”或“爆成一片”的问题,九成是仿真配置没设好。我建议:仿真停止时间先设 5 秒;求解器选固定步长的 ode4(四阶龙格-库塔),步长设 1e-3。原因是线性模型本身刚度不大,固定步长完全够用,而且后续转到代码生成、硬件在环时,定步长是必须条件。
初始条件 x0 保持 [0;0],也就是一开始车辆处于直线行驶状态,Step 信号在 t=0 时突然给一个前轮转角,观察车辆如何从稳态过渡到新稳态。如果你用状态空间模块,x0 在模块参数里设置,别写成行向量 [0 0],语法上它勉强能过,但矩阵维度不对会让你检查半天。
初始化脚本里还要注意一件事:别在脚本里直接给 A 矩阵赋值后又被后面某段代码覆盖。我曾经在一份项目里同时存在两个同名脚本,一个算 A 矩阵,一个算控制器增益,后者不小心用了相同的变量名,结果模型里的 A 矩阵被控制器变量“污染”,阶跃响应完全不正常。从那以后,我的习惯是凡是被控对象参数一律加后缀 _veh,比如 A_veh、Cf_veh,控制器变量加 _ctl,从命名上杜绝这类冲突。
4. 仿真结果验证与策略对比
4.1 先用两轮转向工况校模型:稳态增益对不对
模型搭出来后,第一件事不是急着加后轮转向控制,而是把 δr 设成 0,用传统的两轮转向工况验证模型是否正确。这个步骤能过滤掉大部分低级错误,也是我一直坚持的“先退化,再扩展”的调试顺序。
二自由度前轮转向模型有一个很经典的稳态增益公式,横摆角速度稳态值 γss 与输入前轮转角 δf 的比值满足:
$$\frac{\gamma_{ss}}{\delta_f} = \frac{v}{L \left(1 + K v^2\right)}$$
其中 L=a+b=2.62 m,K 就是前面说的不足转向梯度。用上面那组参数计算,v=25 m/s 时,K v² 约为 1.31,于是稳态增益约等于 4.14 1/s。给一个 10° 的阶跃前轮转角(0.1745 rad),理论稳态横摆角速度约为:
γss ≈ 4.14 × 0.1745 ≈ 0.72 rad/s
再看质心侧偏角,从力矩平衡反推得到的稳态值大约 -0.072 rad,也就是 -4.1° 左右。跑完仿真,Scope 上横摆角速度如果能稳定在 0.72 rad/s 附近,质心侧偏角稳定在 -4° 左右,就可以基本认定模型搭建正确。
只看稳态还不够,还要看动态过程。二自由度车辆的横摆响应是典型的欠阻尼二阶系统,γ 会先冲过头一点,再衰减到稳态值。用上面的参数算出的闭环极点大约在 -5.5 ± 5.6i,这意味着响应周期 1 秒多一点,超调量不会太大。如果仿真曲线一来就直挺挺冲上去然后猛烈振荡几十秒,多半是矩阵符号或刚度量级出了问题。
4.2 加入后轮转向:同相控制和反相控制的效果
验证完基础模型,就可以把第二个输入端用起来。最简单的四轮转向控制策略就是比例控制:δr = k·δf。k 为正就是高速同相转向,k 为负就是低速反相转向。
在 Simulink 里,你只需要从第一个 Step 的前轮转角信号上引出一条线,经过一个 Gain 模块(增益为 k),接到原来第二个 Step 的位置。这里也可以保留一个 Step 作为叠加项,用来模拟后轮转角中有外部干扰或主动修正的情况。
以 k=0.2 同相为例,后轮跟随前轮转一个小角度。这时候你会看到质心侧偏角的稳态绝对值明显变小,从原来的 -4° 往 0° 靠拢;横摆角速度的稳态绝对值会比纯前轮转向略小一点,但响应过程更平滑。这正是四轮转向在高速公路上变道时的核心价值:车身姿态更“正”,驾驶员体感更稳。
反过来,k=-0.2 反相时,后轮往相反方向转,等效于把车辆转向半径缩短,横摆角速度稳态值会比前轮转向工况大,车明显更“活”。这就是低速泊车时想要的效果。为了直观对比,我喜欢用 MATLAB 的 quickplot 统一画三条曲线:纯前轮转向、k=0.2、k=-0.2,分别看 β 和 γ 的时间历程。表格里可以这样总结:
| 工况 | 后轮转角 | 质心侧偏角稳态 | 横摆角速度稳态 | 典型场景 |
|---|---|---|---|---|
| 传统前轮转向 | 0 | 较大(绝对值) | 标准值 | 作为基准 |
| 高速同相 | +0.2δf | 明显减小 | 略减小 | 高速变道、稳定性控制 |
| 低速反相 | -0.2δf | 随车速变化 | 增大 | 泊车、掉头、灵活性控制 |
注意这里的“同相/反相”效果是在固定车速下仿真的,真实四轮转向系统往往根据车速在两种策略之间连续切换,中间还伴随过渡区。线性模型非常适合研究这种切换逻辑的初步设计,但切线车速附近的瞬态行为还是要留到更精细模型里去验证。
4.3 车速变化下的动态特性
二自由度模型里,车速 v 藏在 A、B 矩阵的多个分母项内,因此车速对系统动态特性的影响很值得单独跑一组实验。我的做法是用 for 循环在 MATLAB 里对 v = [5, 15, 25, 40] m/s 分别求解 A 矩阵特征值,然后观察极点分布变化。
结果很有意思:低速 5 m/s 时,两个极点都在实轴上,且离虚轴很远,系统反应快、没有振荡;25 m/s 时极点变成共轭复数,阻尼开始变小,响应出现清楚的振荡;到 40 m/s 时振荡频率更高,阻尼进一步降低。直观地看,就是车速越快,转向响应越“神经质”,给一点转角车头摆动越频繁。这解释了为什么高速时驾驶员对方向盘的微小动作都很敏感,也说明在设计高速四轮转向控制时,尤其要注意对 γ 变化率的阻尼。
如果你把后轴侧偏刚度 Cr 调小,模拟一种过度转向倾向强的车,会发现在某个车速下 A 矩阵出现正实部特征值,Simulink 里的状态直接发散。这时候模型不是出 bug,而是在提醒你:这辆车在物理上已经失稳了。对控制工程师来说,这是一件好事,因为你可以直接在模型里制造失稳边界,再验证控制器能不能把系统拉回来。
5. 常见问题与排查技巧实录
5.1 先怀疑:单位、符号和习惯约定
如果有人拿着仿真结果来问我“为什么我的横摆角速度是理论值的 57.3 倍”,我闭着眼都能猜到:角度用了度,但公式里要求弧度。57.3 就是角度和弧度转换的比例。在车辆动力学仿真里,角度单位问题几乎是最常见、也最隐蔽的错误之一。
同理,侧偏刚度单位如果写成了 N/deg,那结果也会成倍出错。我的习惯是:所有角度信号在 Simulink 里一律以 rad 为单位流动,只在需要给人看的曲线标签上转换成 deg。模型内部所有增益、矩阵、控制系数全部按 rad 设计。时间长了你会发现,这套约定能帮你在整个底盘域模型里省掉大量不必要的单位换算。
符号方向是第二个重灾区。前面说过,不同资料对侧偏刚度的正负定义不一致。如果在推导时用的是正刚度定义,但参数脚本里填的是一个负值,A 矩阵正反馈项会瞬间把系统搞爆。还有后轮转角的方向:很多同学在为四轮转向模型写控制律时,后轮转角符号和前轮取成相反,结果低速反相控制变成了表面同相,实际效果与预期完全相反。建议在模型里增加一个 subsystem 或者注释块,把 δf、δr 的正方向定义用文字钉死,方便后来接手的人。
5.2 典型症状速查表
下面这表格里的问题,都是我在实际带项目时经常排查的,整理成速查表方便按图索骥:
| 症状 | 可能原因 | 快速处理办法 |
|---|---|---|
| 状态输出一步一步发散到 NaN | A 矩阵出现正实部极点;或车速设置过高;或步长过大 | 检查特征值;降低 v;把定步长改为 1e-4 试跑 |
| 横摆角速度稳定值是理论值几十倍 | 角度单位混用(度/弧度) | 检查 Step、Gain 的 rad 转换 |
| 质心侧偏角方向反了 | 侧偏刚度符号约定不一致 | 统一用“正刚度+负号力”的公式 |
| 输出完全没动静 | δf 或 δr 的 Final Value 为 0;Mux 输入接反 | 查 Step 参数和接线顺序 |
| 模型报初始条件尺寸不匹配 | x0 用了 1×2 行向量或写错维度 | x0=[0;0] 用 2×1 列向量 |
| 加入后轮控制后出现代数环警告 | δr 与控制律直通形成代数闭环 | 在反馈支路插入 Memory 或离散单位延迟 |
| 仿真结果对步长极敏感,改小步长后波形变化很大 | 用了变步长或模型刚度不合适 | 固定步长 ode4,步长 1e-3 或更小 |
| 控制律在仿真里很好,生成代码后对不上 | 连续/离散混合、求解器不一致 | 从仿真开始就用定步长离散求解器 |
出现发散问题时,我的第一反应是把仿真时间缩短到 0.1 秒,先看曲线在爆炸前是什么趋势。如果前几个毫秒内状态就开始指数增长,那基本是建模问题而不是数值问题;如果在某个临界点之后才发散,才考虑步长和求解器。
5.3 调试中的几个心得
最后说几条在调试过程中真正管用的体会。
第一,验证线性模型时,永远从“零后轮转角”开始。四轮转向控制器写得再复杂,它首先得是一个正确的二自由度车辆模型。先把 δr 强制置零,让模型退化成大家都能验证的前轮转向模型,稳态增益和理论公式对上之后,再碰后轮控制。这个顺序能让你把“模型问题”和“控制问题”彻底分开。
第二,State-Space 模块里不要写裸数字,一定用工作区变量名。这不是编码洁癖,是为了参数扫描。你在 MATLAB 里定义一个 v_list = [5:5:40],循环给 v_veh 赋值,再调用 sim('4WS_2DOF'),一个批量工况矩阵就出来了。要是矩阵里填的是数字,每次换参数都得去翻模块界面,效率低还容易漏。
第三,四轮转向模型的价值不只是仿真轨迹,更在于给你一个“可求导”的被控对象。线性模型可以非常方便地算李雅普诺夫方程、算 LQR 增益、画根轨迹,这些是非线性模型很难直接给到你的。所以哪怕你后续打算用 CarSim 做最终验证,Simulink 里的这个二自由度线性模型也不要删,它完全可以作为控制器设计的参考基准和快速迭代工具。
我自己现在搭一遍这个模型只需要十分钟左右,但第一次做的时候为了一个符号问题折腾了半个下午。归根结底,二自由度四轮转向模型不复杂,复杂的是各种约定和矩阵符号背后的物理含义。把坐标系、刚度符号、单位这些习惯统一好,剩下的就是拉线连模块了。线性模型验证通过之后,再上 CarSim 做联合仿真,你会发现自己对车辆行为的理解远比一开始直接硬怼整车模型时要深刻得多。