两轮差速小车滑模控制实战:从动力学到Simulink落地
2026/9/11 14:16:12 网站建设 项目流程

简介:本资源是一套面向自动化、控制工程与机器人方向本科生及初阶研究者的滑模控制实践教学材料,聚焦移动小车这一典型非线性被控对象,解决动力学建模与鲁棒控制器设计的实际问题。压缩包共5个文件(4个MATLAB脚本.m + 1个Simulink仿真模型.mdl),涵盖系统建模(chap1_4plant.m)、滑模控制器设计(chap1_4ctrl.m)、模糊补偿模块(chap1_4mf.m)、结果可视化(chap1_4plot.m)及完整仿真环境(chap1_4sim.mdl),总大小仅13KB,轻量易读、结构清晰,便于逐模块理解滑模面构造、切换律实现与抖振抑制策略。已有801人学习下载,读者可直接运行复现小车位置/速度/姿态的跟踪响应,观察抗干扰性能,并基于代码快速修改参数、拓展边界层设计或替换动力学模型,是掌握滑模控制从理论到MATLAB仿真实操的关键入门范例。

1. 滑模控制不是“抖得越猛越准”,而是用数学边界把小车动力学误差锁进收敛带

你调过差速小车的PID,发现负载一变、坡度一陡,轨迹就飘;你试过LQR,但模型稍有偏差,控制力矩就发散;而滑模控制(Sliding Mode Control, SMC)在Matlab里跑通后,哪怕轮子打滑、电池压降、地面摩擦突变,小车仍能以确定性方式强行回到期望轨迹——这不是靠参数微调,而是靠构造一个“滑模面”,让系统状态一旦抵达该面,就再也出不去。本篇聚焦两轮差速移动小车这一最典型平台,用Matlab/Simulink完整复现从动力学建模→滑模面设计→等效控制律推导→抖振抑制→实时仿真验证的全链路。不讲泛泛而谈的“鲁棒性强”,只说清楚:为什么必须用非线性动力学方程推导滑模面?为什么切换增益不能凭经验乱设?为什么simulink中用Saturation模块比Sign函数更接近真实执行器?适合已掌握Matlab基础建模、想落地机器人运动控制的工程师,也适合工创赛/课程设计中需交出可运行、可解释、可答辩的控制方案的学生。

2. 从牛顿-欧拉出发:推导两轮差速小车的完整动力学模型与误差动力学

滑模控制的根基不在控制律本身,而在对被控对象物理本质的精确刻画。对移动小车而言,“小车”不是黑箱,而是由质量、转动惯量、轮距、轮半径、电机扭矩-转速特性共同定义的刚体系统。若直接套用简化的一阶运动学模型(如 $\dot{x} = v\cos\theta$),滑模面将失去物理约束力,导致控制量在现实中无法实现或引发剧烈抖振。因此,必须从第一性原理出发,建立包含驱动轮动力学的二阶完整模型。

2.1 坐标系定义与变量约定

我们采用标准移动机器人坐标系:

  • 全局坐标系 $O_{XY}$:固定于地面,原点为初始位置
  • 车体坐标系 $O_{xy}$:原点位于小车质心,$x$轴指向前进方向,$y$轴向左,$\theta$为车体朝向角(逆时针为正)
  • 关键物理参数(以典型工创赛小车为例):
    • 总质量 $m = 2.8,\text{kg}$
    • 绕质心转动惯量 $I_z = 0.045,\text{kg}\cdot\text{m}^2$
    • 轮距(左右轮中心距)$L = 0.26,\text{m}$
    • 轮半径 $r = 0.035,\text{m}$
    • 电机电枢电阻 $R_a = 2.1,\Omega$,电枢电感 $L_a = 0.0015,\text{H}$,反电动势常数 $K_e = 0.012,\text{V}\cdot\text{s}/\text{rad}$,转矩常数 $K_t = 0.012,\text{N}\cdot\text{m}/\text{A}$

提示:这些参数必须实测或查电机手册获取。用“典型值”代入会导致后续滑模面设计失效。例如,若实际 $I_z$ 比设定值大30%,则计算出的所需转向力矩将系统性偏低,滑模控制器会持续“欠补偿”,表现为轨迹持续右偏。

2.2 完整动力学方程推导(含电机电气动态)

对两轮差速小车,需同时描述机械运动与电机电气过程。设左、右轮电机输入电压为 $u_l, u_r$,对应轮端输出转矩为 $\tau_l, \tau_r$,轮角速度为 $\omega_l, \omega_r$,则:

电机电气方程(每轮独立):
$$ u_i = R_a i_i + L_a \frac{di_i}{dt} + K_e \omega_i \quad (i=l,r) $$
其中 $i_i$ 为电枢电流。

电机-轮传动关系(忽略齿轮间隙与弹性):
$$ \tau_i = K_t i_i $$

轮-车体运动学关系(纯滚动无滑移假设):
$$ v = \frac{r}{2}(\omega_l + \omega_r), \quad \omega = \frac{r}{L}(\omega_r - \omega_l) $$
其中 $v$ 为质心线速度,$\omega$ 为车体角速度。

车体质心动力学(牛顿第二定律 + 转动定律):
$$ \begin{cases} m\dot{v} = \frac{1}{2}(\tau_l + \tau_r)\cos\theta - \frac{1}{2}(\tau_l - \tau_r)\sin\theta - F_{dx} \ m v\dot{\theta} = \frac{1}{2}(\tau_l + \tau_r)\sin\theta + \frac{1}{2}(\tau_l - \tau_r)\cos\theta - F_{dy} \ I_z \dot{\omega} = \frac{L}{2}(\tau_r - \tau_l) - T_{dz} \end{cases} $$
其中 $F_{dx}, F_{dy}, T_{dz}$ 为地面摩擦、空气阻力等不确定扰动,是滑模控制要鲁棒处理的对象。

将上述方程联立消去中间变量 $i_i, \omega_i, \tau_i$,最终得到以 $[x, y, \theta, v, \omega]$ 为状态、$[u_l, u_r]$ 为输入的五阶非线性状态空间模型。此模型在Matlab中需用ode45或Simulink的S-Function实现,不可简化为三阶运动学模型。

2.3 误差动力学模型构建:从跟踪目标到滑模面设计的桥梁

滑模控制的目标是让小车跟踪给定参考轨迹$(x_d(t), y_d(t), \theta_d(t))$。定义跟踪误差: $$ e_x = x_d - x, \quad e_y = y_d - y, \quad e_\theta = \theta_d - \theta $$

但直接对 $e_x, e_y, e_\theta$ 设计滑模面会因坐标耦合导致控制律奇异(例如当 $e_\theta$ 很大时,$e_x$ 和 $e_y$ 的修正方向难以解耦)。工程上通用做法是:先将误差变换到车体坐标系下,再构造二阶误差动力学。

定义车体坐标系下的横向与纵向误差: $$ \begin{bmatrix} e_{\parallel} \ e_{\perp} \ e_\theta \end{bmatrix} = \begin{bmatrix} \cos\theta & \sin\theta & 0 \ -\sin\theta & \cos\theta & 0 \ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} e_x \ e_y \ e_\theta \end{bmatrix} $$

令 $e_1 = e_{\parallel},; e_2 = e_{\perp},; e_3 = e_\theta$,对其求导并代入动力学方程,可得误差动力学: $$ \begin{cases} \dot{e}_1 = -v + \dot{x}_d\cos\theta + \dot{y}_d\sin\theta \ \dot{e}_2 = -v e_3 + (-\dot{x}_d\sin\theta + \dot{y}_d\cos\theta) \ \dot{e}_3 = -\omega + \dot{\theta}_d \end{cases} $$

再对 $e_1, e_2, e_3$ 求二阶导,引入控制输入 $v, \omega$ 及其导数,最终得到形如: $$ \ddot{e}_i = f_i(e, \dot{e}, v, \omega, \dot{v}, \dot{\omega}) + d_i(t) $$ 的二阶误差系统,其中 $d_i(t)$ 包含所有建模不确定性与外部扰动。这正是滑模面 $s_i = \dot{e}_i + \lambda_i e_i$ 的设计依据——只有基于此二阶误差动力学,才能保证 $s_i=0$ 时误差指数收敛。

3. 在Matlab/Simulink中实现滑模控制器:从符号推导到可运行仿真

理论模型有了,下一步是将其转化为Matlab中可调试、可可视化的控制代码。关键在于:滑模控制律必须显式包含对不确定扰动 $d_i(t)$ 的上界估计,且切换增益需与该上界严格匹配。否则,要么抖振无法抑制,要么系统无法收敛。

3.1 符号计算辅助滑模面与控制律生成(避免手算错误)

手动推导 $\ddot{e}_1, \ddot{e}_2, \ddot{e}_3$ 极易出错。Matlab Symbolic Math Toolbox 是必备工具。以下代码生成 $s_1 = \dot{e}_1 + \lambda_1 e_1$ 对应的等效控制律核心项:

% 定义符号变量 syms ex ey etheta x y theta xd yd thd v omega vl vr r L m Iz Ra La Ke Kt g syms lambda1 lambda2 lambda3 % 滑模面系数 syms d1 d2 d3 % 扰动上界(待设定) % 车体坐标系误差 e_parallel = ex*cos(theta) + ey*sin(theta); e_perp = -ex*sin(theta) + ey*cos(theta); % 一阶误差导数(已知运动学关系) de_parallel = -v + diff(xd)*cos(theta) + diff(yd)*sin(theta); de_perp = -v*etheta + (-diff(xd)*sin(theta) + diff(yd)*cos(theta)); de_theta = -omega + diff(thd); % 构造滑模面 s1 = de_parallel + lambda1*e_parallel; s2 = de_perp + lambda2*e_perp; s3 = de_theta + lambda3*etheta; % 对s1求导,代入动力学(此处以v的动力学为例,需补全完整表达式) % 实际项目中需用前面推导的完整五阶模型代入 ds1 = diff(s1, 't'); % 将ds1表示为 v_dot, omega_dot, d1 的函数... % 然后解出使 ds1 + eta1*s1 = 0 的 v_dot_ref(即等效控制部分) % 此处省略冗长代数,重点是:结果必须是 v_dot_ref = f(v, omega, e, de, xd_ddot, ...)

参数说明lambda1, lambda2, lambda3是滑模面趋近率参数,决定误差收敛速度。典型取值范围:$\lambda_i \in [5, 20]$。过大则初始超调剧烈;过小则收敛慢。eta1是趋近律增益,与lambda1配合使用,通常取eta1 = lambda1 * 1.2

3.2 Simulink中搭建可调参滑模控制闭环(含抖振抑制)

在Simulink中,我们构建如下核心模块:

  • Plant(被控对象):用S-Function封装前述五阶动力学模型,输入为[ul, ur],输出为[x, y, theta, v, omega]
  • Reference Generator:生成参考轨迹,如直线 $x_d = 2t, y_d = 0, \theta_d = 0$ 或圆形 $x_d = \cos(0.5t), y_d = \sin(0.5t), \theta_d = 0.5t$
  • Error & Sliding Surface Calculation:计算 $e_{\parallel}, e_{\perp}, e_\theta$ 及 $s_1, s_2, s_3$
  • SMC Controller:核心模块,实现: $$ u_{\text{eq}} = \text{Equivalent Control} \quad (\text{连续部分}) \ u_{\text{sw}} = -k_i \cdot \text{sat}(s_i/\phi_i) \quad (\text{切换部分,用Saturation替代Sign}) $$ 其中sat(z)是饱和函数:z绝对值小于边界 $\phi_i$ 时输出z,否则输出sign(z)
3.2.1 关键参数表:抖振抑制与鲁棒性的平衡点
参数物理意义典型取值(工创赛小车)调试原则
$\lambda_i$滑模面趋近速率$\lambda_1=12, \lambda_2=15, \lambda_3=18$先设中值,观察收敛速度;增大则响应快但超调大
$k_i$切换增益(抗扰能力)$k_1=80, k_2=100, k_3=120$必须大于扰动上界估计值;过大会加剧抖振
$\phi_i$边界层厚度(抖振抑制)$\phi_1=0.05, \phi_2=0.08, \phi_3=0.1$增大可平滑控制量,但会引入稳态误差;需在示波器中观察 $s_i$ 波形,确保其在 $[-\phi_i, \phi_i]$ 内小幅震荡

注意k_i的设定绝非“越大越好”。若 $k_1=200$,而实际轮面摩擦扰动仅约 $30,\text{N}$,则控制器会持续高频切换,导致电机发热、编码器信号噪声放大、甚至驱动芯片过载。务必用Scope观察s1,s2,s3的实际轨迹——理想状态是它们快速抵达边界层 $\phi_i$ 后,在其内做小幅、低频震荡,而非剧烈穿越零点。

3.3 Matlab脚本一键启动仿真与参数扫描

为加速调试,编写主脚本run_smc_simulation.m,支持批量修改参数并自动保存结果:

% === 参数配置区 === params.lambda1 = 12; params.lambda2 = 15; params.lambda3 = 18; params.k1 = 80; params.k2 = 100; params.k3 = 120; params.phi1 = 0.05; params.phi2 = 0.08; params.phi3 = 0.1; % === 启动Simulink仿真 === set_param('smc_mobile_robot','StopTime','30'); % 仿真30秒 set_param('smc_mobile_robot/Controller/lambda1','Value',num2str(params.lambda1)); set_param('smc_mobile_robot/Controller/k1','Value',num2str(params.k1)); set_param('smc_mobile_robot/Controller/phi1','Value',num2str(params.phi1)); sim('smc_mobile_robot'); % === 提取并绘图 === t = tout; x = xout(:,1); y = xout(:,2); theta = xout(:,3); plot(t, x, 'b', t, xd_ref, 'r--'); xlabel('Time (s)'); ylabel('X Position (m)'); legend('Actual', 'Reference'); grid on; title(sprintf('SMC Tracking: lambda1=%d, k1=%d, phi1=%.2f', params.lambda1, params.k1, params.phi1));

此脚本可嵌入for循环,对k1[60, 100, 140]间扫描,自动生成三组对比图,直观判断抖振与跟踪精度的trade-off。

4. 工创赛/课程设计落地要点:从Simulink到实物的三道硬门槛

Simulink仿真跑通只是第一步。真正交付一个“能上台演示、能现场调试、能答辩讲清”的滑模小车系统,必须跨过以下三个工程化门槛。跳过任一环节,都会在答辩时被问住:“你这个抖振,在实物上怎么解决的?”

4.1 编码器信号预处理:消除数字噪声对滑模面的致命干扰

Simulink中编码器输出是理想方波,但实物STM32/ESP32读取的AB相脉冲含开关噪声、接触抖动、电磁干扰。若直接将原始计数值送入滑模控制器,s_i会因微小噪声频繁穿越零点,导致控制量疯狂抖动,电机发出刺耳啸叫。

正确做法是:在MCU端对编码器进行硬件+软件两级滤波

  • 硬件:在编码器输出线(A/B)与地之间各加一个10nF陶瓷电容,滤除高频毛刺
  • 软件(以STM32 HAL库为例):
    // 使用TIM的编码器接口,并开启数字滤波器 htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.RepetitionCounter = 0; if (HAL_TIM_Encoder_Init(&htim2, &sConfig, &sICConfig) != HAL_OK) { /* Error */ } // 关键:设置数字滤波器,采样窗口为8个时钟周期 __HAL_TIM_SET_ICPRESCALER(&htim2, TIM_ICPSC_DIV8); __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE);

提示:滤波后,编码器分辨率会下降(如原本每转2000脉冲,滤波后等效为2000/8=250),但换来的是干净的速度信号。在Matlab中仿真时,必须在Plant模块后加入First-Order HoldZero-Order Hold,并添加Band-Limited White Noise(功率设为1e-6)模拟真实编码器噪声,否则仿真结果无法指导实物调试。

4.2 电机驱动的非线性补偿:PWM死区与电流饱和的在线补偿

滑模控制器输出的是理想电压 $u_l^, u_r^$,但H桥驱动存在:

  • 死区时间(Dead Time):上下管不能同时导通,导致低压段输出失真
  • 电流饱和:电机堵转时,即使指令电压高,实际电流也受限于电源与MOSFET

若忽略这两点,控制器会持续“误判”执行器能力,不断加大指令,最终失控。

解决方案是在控制律后增加补偿模块:

  • 死区补偿:查表法。预先测量不同占空比下的实际输出电压,建立Duty -> Vout映射表,在控制器输出后查表校正
  • 电流前馈:在MCU中实时读取电机电流(用INA219等电流传感器),若检测到电流已达限幅值 $I_{\max}$,则主动将电压指令钳位为 $u_{\text{lim}} = I_{\max} \cdot R_a + K_e \cdot \omega$,避免积分饱和

此补偿逻辑必须写入MCU固件,不能只在Simulink中仿真。工创赛评审专家会现场用万用表测电机端电压,验证你是否真的处理了死区。

4.3 实物滑模参数整定口诀:三步走,不碰公式

面对一台焊好、装好、通电的小车,如何快速调出可用的SMC参数?记住这个现场口诀:

  1. 先调 $\phi_i$(边界层):将k_i设为最小值(如20),缓慢增大 $\phi_i$,直到小车运动时电机声音从“嘶嘶”高频变为“嗡嗡”低频,且轨迹无肉眼可见抖动。此时记录 $\phi_i$。
  2. 再调 $k_i$(抗扰增益):保持 $\phi_i$ 不变,逐步增大 $k_i$,同时用手轻推小车制造扰动。当小车受扰后能在1秒内回到轨迹,且无明显过冲时,停止增大。此时 $k_i$ 即为最优。
  3. 最后微调 $\lambda_i$(收敛速度):若小车启动慢,略微增大 $\lambda_i$;若启动猛甩头,略微减小 $\lambda_i$。调整幅度不超过±2。

注意:此口诀基于大量实物调试经验,绕开了复杂的扰动上界估计。它有效,是因为 $\phi_i$ 直接决定了抖振感知,$k_i$ 决定了抗扰临界点,而 $\lambda_i$ 仅影响暂态,对稳态无影响。答辩时,你可以指着正在运行的小车说:“我调参不看公式,看电机声音、看轨迹抖动、看手推响应——因为滑模控制的本质,是让系统在物理约束下,用最‘粗暴’的方式达成最‘确定’的结果。”

5. 验证滑模控制是否真正生效:三类必做实验与数据判据

仿真波形漂亮不等于控制有效。必须通过三类实验,用可量化、可复现的数据证明:你的滑模控制器确实发挥了鲁棒性、收敛性与抗扰性。每一类实验都有明确的Matlab数据判据,答辩时可直接展示。

5.1 收敛性验证:绘制滑模面轨迹 $s_i(t)$ 并计算收敛时间

在Simulink中,用To Workspace模块导出s1,s2,s3的时间序列。在Matlab中运行:

% 加载数据 load('sliding_surfaces.mat'); % 包含 s1, s2, s3, t % 计算收敛时间:s_i 进入 [-0.01, 0.01] 并持续保持的时间点 tol = 0.01; idx1 = find(abs(s1) <= tol, 1, 'first'); T_conv1 = t(idx1); % s1收敛时间 % 同理计算 T_conv2, T_conv3 fprintf('s1收敛时间: %.3f s, s2: %.3f s, s3: %.3f s\n', T_conv1, T_conv2, T_conv3);

判据:若 $T_{\text{conv}i} < 2.0,\text{s}$(对30秒仿真),且 $s_i$ 在收敛后始终在 $[-\phi_i, \phi_i]$ 内震荡,则收敛性达标。若 $s_i$ 持续在零附近大幅摆动(如±0.5),说明 $k_i$ 过小或 $\phi_i$ 过大。

5.2 抗扰性验证:注入阶跃扰动并分析最大偏差

在Simulink Plant模块中,人为注入扰动:

  • 在 $x$ 方向动力学中加入Step模块,$t=10,\text{s}$ 时施加 $F_{\text{dist}} = 5,\text{N}$ 的阶跃力
  • 记录扰动前后小车横向误差 $e_{\perp}$ 的峰值
% 找出扰动注入时刻(t=10s)附近的 e_perp 最大值 idx_dist = find(t >= 10 & t <= 12, 1, 'first'); e_perp_dist = e_perp(idx_dist:idx_dist+200); max_dev = max(abs(e_perp_dist)); fprintf('阶跃扰动下最大横向偏差: %.3f m\n', max_dev);

判据:工创赛小车要求 $max_dev < 0.08,\text{m}$。若超标,说明 $k_2$(对应 $e_{\perp}$ 的切换增益)不足,需增大。

5.3 鲁棒性验证:改变小车质量后重跑,对比跟踪误差积分(IAE)

这是最硬核的验证。在Simulink中,将质量 $m$ 从2.8改为3.5(增加25%),重新仿真同一轨迹。计算两种质量下的跟踪误差绝对值积分:

% 加载正常质量与加重质量的 e_parallel 数据 load('e_para_normal.mat'); load('e_para_heavy.mat'); IAE_normal = trapz(t, abs(e_para_normal)); IAE_heavy = trapz(t, abs(e_para_heavy)); robust_ratio = IAE_heavy / IAE_normal; fprintf('质量变化25%%,IAE变化倍数: %.2f\n', robust_ratio);

判据:若robust_ratio < 1.3,说明控制器对参数摄动鲁棒;若> 1.8,则滑模面设计未充分考虑质量不确定性,需检查动力学模型中是否遗漏了 $m$ 的显式依赖。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询