尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

滑模控制在机器人位置控制中的应用:从PID到鲁棒控制

滑模控制在机器人位置控制中的应用:从PID到鲁棒控制 简介面向机器人控制方向本科生与入门工程师这份资源围绕位置控制、机器人控制与滑膜控制展开以MATLAB/Simulink实现为落脚点可用于理解机械臂精确运动、速度与力矩协调以及非线性系统下的鲁棒控制设计。包体共4个文件包含2个.m脚本、1个.mdl模型和1个.asv备份文件覆盖PID位置跟踪、滑膜控制仿真及Simulink可视化建模等典型环节整体仅11KB轻量易读适合对照源码快速验证算法效果。目前已有274人学习下载对于刚接触机器人运动控制或需要课程设计参考的学习者可通过这些脚本和模型梳理位置-速度-力矩控制流程理解滑膜控制相比传统线性控制在参数摄动和外部扰动下的优势同时借助备份文件了解开发过程中的迭代痕迹。由于文件结构简单、内容聚焦可作为MATLAB机器人仿真入门或本科控制实验的辅助素材帮助缩短从理论公式到仿真调参的路径。1. 位置控制里的滑模控制什么时候你该换掉 PID在一个负载经常变化的位置控制回路里PID 参数往往是最先失去效用的东西换一个末端执行器原来的增益就开始超调或者回弹。这类场景下很多人会翻到“滑模控制”这个词但标题里的“滑膜”其实是音误行业里的标准写法是滑模控制Sliding Mode Control。它的核心不是造一套比 PID 更复杂的公式而是把位置误差和速度误差压到一条“滑模面”上让误差自己沿着这条线走到零。下面按“模型 → 控制律 → 仿真 → ROS2 落地”这条线展开想直接抄仿真代码的可以先跳到第 3 章。2. 机器人位置控制先建模滑模控制面对的误差动态2.1 位置控制在机器人里的任务边界机器人位置控制的目标很直接把当前状态位置、速度收敛到期望轨迹上。但“机器人”三个字覆盖的范围太宽移动机器人控制的是底盘位姿和轮速六轴机械臂控制的是关节角度和力矩两者的模型形态完全不同。滑模控制在工业机械臂、协作臂的关节空间里效果最明显原因在于这部分系统有明确的惯量、摩擦和重力项且这些项很难精确建模。所以先限定在关节空间讨论再给出通用的模型形式。机械臂 n 自由度关节空间动力学方程一般写作τ M(q)q̈ C(q, q̇)q̇ G(q) τ_d其中 M(q) 是 n×n 惯量矩阵C(q,q̇) 是科氏力和离心力项G(q) 是重力项τ_d 是摩擦、负载扰动等未建模量的集合。位置控制的任务是给定期望关节角 q_d算出控制力矩 τ让 q→q_d。滑模控制对这个模型的依赖比较宽松不需要各项精确但需要知道 M 的数量级和模型误差的上界这决定了切换项的幅值。因此建模这一步做的不是“精确求逆”而是把误差动态写清楚。import numpy as np # 从编码器读到的当前关节角 q、速度 qd以及任务层给的期望轨迹 q_d、qd_d def error_state(q, qd, q_d, qd_d, lam2.0): e q_d - q # 位置误差单位 rad de qd_d - qd # 速度误差单位 rad/s s de lam * e # 一阶滑模面单位 rad/s return e, de, s # 示例调用 q, qd 0.1, 0.05 q_d, qd_d 0.3, 0.0 e, de, s error_state(q, qd, q_d, qd_d, lam2.0)这段代码先不涉及控制量它只是把位置控制问题转换成误差状态。lambda 越大位置误差在滑模面里的权重越高取 2.0 意味着速度误差和位置误差按 2:1 的关系混合。s 的单位是 rad/s后面所有控制器参数都要对应这个量纲否则调参会混乱。2.2 误差状态方程把目标变成“让 s 收敛到 0”2.2.1 一阶滑模面为什么能同时管住位置和速度定义误差 eq_d−q 之后二阶系统变成 ë q̈_d−q̈。直接控制二阶误差动态需要同时处理位置误差和速度误差两个通道控制器设计的自由度多参数也多。滑模面的引入把这个问题降了一阶令 sėλe当 s0 时误差满足 ė−λe。这是一个一阶线性微分方程意味着误差从任意初始值指数衰减到零且衰减速率只由 λ 决定。所以滑模控制把“位置和速度都要收敛”变成了“把 s 压到 0”。这是一个关键转换控制器不再分别跟踪位置误差和速度误差而是盯住一个标量或一个向量。在相平面上看s0 是一条过原点的直线状态一旦落在这条线上就会被这条线的动力学“吸”到原点。这也是“滑模面”名称的来历——误差状态在相平面里是“滑”过去的而不是直接弹过去的。2.2.2 “滑”的直观理解把误差相平面画出来横轴是位置误差 e纵轴是速度误差 ė。初始误差落在平面某个位置控制器先把它往 s0 这条直线上推这段叫到达阶段到达之后状态只能沿直线滑向原点这段叫滑动阶段。滑动阶段的行为完全由 λ 决定与系统模型关系不大。滑模控制的鲁棒性就体现在这里只要切换项能把状态按在直线附近内部模型不准、外部负载变化这些影响都会被“滑模面动力学”覆盖掉。2.3 什么时候该用滑模控制和 PID 先对个坐标滑模控制不是用来全面替代 PID 的。点位运动、负载固定、轨迹平滑的场合PID 加前馈仍然是最省事的方案。滑模的收益体现在模型误差有界但不可精确建模、负载经常变化、轨迹跟踪持续进行的场景。选型不能拍脑袋先看误差来源和模型掌握程度。位置控制场景典型扰动来源保守方案值得上滑模的动机机械臂示教点位移动重力、摩擦PID重力前馈末端负载频繁更换不想反复调增益高速轨迹插补科氏力、离心力耦合逆动力学前馈模型已有但残余误差仍明显需要硬性拉回移动机器人位姿跟踪地面打滑、轮径误差速度环 PID位置误差会持续积累需要鲁棒项力位混合控制接触瞬间突跳阻抗导纳控制误差突跳时切换项能快速作出反应这张表不是穷举而是提供一个判断方法模型大致了解但不够精确、扰动有界却持续变化这两个条件同时满足时滑模才值得上。若系统模型完全未知滑模的切换幅值没法设硬调出来的增益会比 PID 还难收敛。3. 滑模位置控制器设计趋近律、参数表和单关节仿真3.1 控制律从哪来等效项配合切换项从 sėλe 出发对其求导得到 ṡëλė。把单关节动力学 Jq̈bq̇d(t)τ 代进去模型参数 J、b、d 在控制器里是估计值真实系统的下标省略。期望滑模面动态设为指数趋近律ṡ −Q·s − ε·sign(s)其中 Qs 让 s 指数收敛到 0ε·sign(s) 负责抵抗模型估计误差和外部扰动。把代进去并解出 ττ J_hat·(q̈_d λ·ė Q·s ε·sign(s)) b_hat·q̇ d_hat这个式子分两块看前一项是等效控制让理想系统沿滑模面收敛后一项是切换项用来吸收 J_hat、b_hat 和真实值之间的误差。如果真实误差上界超过 εs 就压不到 0位置跟踪会出现一个残余偏差。所以 ε 的设定不能只看仿真要反推模型误差的幅值。3.2 单关节位置跟踪的 Python 仿真代码把上面的控制律落到一个完整可运行的仿真里。被控对象是单关节真实参数和控制器估计参数故意设成不同看看滑模能不能压住误差。import numpy as np import matplotlib.pyplot as plt # 真实被控对象参数转动惯量 0.5粘性摩擦 0.8 J_true, b_true 0.5, 0.8 # 控制器里的估计参数故意偏差 10%~25% J_hat, b_hat 0.45, 0.6 d_hat 0.0 # 时间轴 dt 0.001 t_end 6.0 steps int(t_end / dt) t_arr np.linspace(0.0, t_end, steps) # 外部扰动幅度 0.2 的正弦力矩 d_ext 0.2 * np.sin(2.0 * t_arr) def trajectory(t): # 2 秒内从 0 匀速转到 45 度之后保持 if t 2.0: q_d np.deg2rad(45) * t / 2.0 dq_d np.deg2rad(45) / 2.0 else: q_d np.deg2rad(45) dq_d 0.0 return q_d, dq_d, 0.0 q, dq 0.0, 0.0 lam, Q, eps 3.0, 2.0, 0.35 tau_list, s_list, e_list [], [], [] for i in range(steps): q_d, dq_d, ddq_d trajectory(t_arr[i]) e q_d - q de dq_d - dq s de lam * e # 滑模控制律模型估计值 切换项 tau (J_hat * (ddq_d lam * de Q * s eps * np.sign(s)) b_hat * dq d_hat) # 真实系统积分 ddq (tau - b_true * dq - d_ext[i]) / J_true dq ddq * dt q dq * dt tau_list.append(tau) s_list.append(s) e_list.append(e) plt.figure(figsize(10, 4)) plt.subplot(1, 2, 1) plt.plot(t_arr, np.rad2deg(e_list)) plt.title(position error (deg)) plt.xlabel(t (s)) plt.subplot(1, 2, 2) plt.plot(t_arr, tau_list, lw0.5) plt.title(control torque) plt.xlabel(t (s)) plt.tight_layout() plt.show()控制律里用的是 J_hat、b_hat而被控对象用的是 J_true、b_true两者的偏差就是切换项要消化的模型不确定性。仿真中的外部扰动 d_ext 是正弦信号控制器完全不知道它的存在。运行后可以看到位置误差在到达滑模面之后被压到零点附近但控制力矩曲线会出现明显的高频切换这就是 sign(s) 带来的抖振。把 eps 从 0.35 改成 0.05 再跑一次误差会变大说明切换项幅值太小压不住扰动把 lam 从 3.0 改成 6.0误差收敛变快但力矩噪声也会被放大。3.3 增益调节表与 sat 函数的第一层防抖参数含义常见范围调大后果调小后果λ滑模面斜率1~10 rad/s位置误差衰减快速度噪声被放大收敛变慢扰动影响时间变长Q指数趋近系数0~5到达滑模面更快到达段变慢ε切换幅值0.1~1鲁棒性增强抖振加剧鲁棒性下降可能丢收敛δsat 边界层宽度0.005~0.05 rad/s抖振变小稳态误差变大抖振变大精度更高把 sign(s) 换成 sat(s) 是抑制抖振的第一步也是最常用的一步。sat 在 s 绝对值小于 δ 时输出 s/δ相当于在切换边界附近做了一个线性过渡s 绝对值大于 δ 时输出 ±1行为与 sign 相同。边界层 δ 越宽控制力矩越平滑但滑模“硬拉”的效果越弱。后续第 5 章会给出一个动态调整 δ 的做法这里先把静态的 sat 版本在仿真里替换掉观察切换频率的变化。观察收敛是否达标的快捷方式不是只看位置误差曲线而是看 s 曲线如果 s 在初始阶段后稳定在零点附近说明到达条件成立如果 s 围绕零点振荡不消多半是 ε 取小了。仿真阶段先用 s 曲线判断再回到位置误差看精度比直接调位置误差环路更直观。4. 从仿真到 ROS2 机器人位置控制多关节滑模落地的坑4.1 多关节模型耦合项进控制律还是进扰动把单关节推广到 n 自由度动力学变成前文的多关节形式。滑模面写成向量形式 s ė ΛeΛ 是对角矩阵每个关节可以设不同的 λ。控制律对应变成τ M_hat(q)(q̈_d Λė Qs ε·sign(s)) C_hat(q,q̇)q̇ G_hat(q)其中 M_hat、C_hat、G_hat 都是估计量。实际工程中很少有人把 M、C、G 全部算准更常见的做法是关节级独立滑模把其他关节的耦合项当作扰动每个关节单独算一套 τ。低速点位运动时这种简化没问题高速轨迹插补中耦合项可能变成主要误差来源那个场景下集中式滑模才有优势。工业机器人控制器里的位置环ABB、库卡这类六轴机械臂在示教点位移动时直接用高增益 PID 加前馈就能工作得很好滑模多出现在负载变化明显、结构刚度较弱的原型系统上。ROS2 机器人开发资料里常见的做法也是先把单关节滑模仿真跑通再映射到多关节节点上这样排错范围小很多。4.2 在 ROS2 的位置控制环里放一路滑模在 ROS2 里实现滑模位置控制常见做法是写一个独立节点订阅 /joint_states计算力矩后发布给 effort controller。代码骨架如下。import rclpy import numpy as np from rclpy.node import Node from sensor_msgs.msg import JointState from std_msgs.msg import Float64MultiArray class SlidingPositionController(Node): def __init__(self, joint_names): super().__init__(sliding_position_controller) self.joint_names joint_names self.lam 3.0 self.Q 1.0 self.eps 0.35 self.state None self.sub self.create_subscription( JointState, /joint_states, self.on_state, 10) self.pub self.create_publisher( Float64MultiArray, /effort_controller/commands, 10) # 500 Hz 控制频率对应 2ms 周期 self.timer self.create_timer(0.002, self.control_loop) def on_state(self, msg): self.state msg def control_loop(self): if self.state is None: return cmd Float64MultiArray() q_d, dq_d 0.5, 0.0 for joint in self.joint_names: idx list(self.state.name).index(joint) q_m self.state.position[idx] dq_m self.state.velocity[idx] e q_d - q_m de dq_d - dq_m s de self.lam * e tau (self.eps * np.sign(s) self.Q * s self.lam * de) cmd.data.append(tau) self.pub.publish(cmd) def main(): rclpy.init() node SlidingPositionController([joint1, joint2]) rclpy.spin(node) rclpy.shutdown()这个节点省掉了动力学前馈项适合先验证滑模闭环是否能稳定。真正接机械臂时需要把 M、C、G 前馈加上否则 ε 要设得很大才能压住重力抖振会明显加剧。JointState 里的 velocity 如果是编码器差分信号λ 会给噪声乘以一个放大系数下一步就要处理速度信号质量问题。4.3 实物端的三个坑执行器饱和、速度噪声和弹性模态4.3.1 执行器饱和与“算出来却发不出去”滑模控制律算出的力矩一旦超过驱动器限制真实力矩曲线会撞在限幅上s 可能始终停不到零点。处理顺序是先给控制输出加饱和限制再观测 s 是否还能收敛如果收敛不了说明 ε 相对模型误差不够或者期望轨迹太激进需要降速。这一块比 PID 好处理因为滑模没有积分状态硬截断不会引发积分饱和问题。4.3.2 速度反馈噪声被 λ 放大编码器差分速度信号在低速段噪声明显λ 越大s 里的噪声越大sign(s) 可能在零点附近高频翻转。常见做法是对 s 做一阶低通再进切换项s_f(k) 0.95·s_f(k−1) 0.05·s(k)这个滤波系数对应约 500 Hz 控制周期下几十 Hz 的低通截止频率能显著降低高频翻转但也会让滑模面反应变慢。若机器人本身有编码器状态估计器直接用估计速度替代差分速度效果更好。实物端现象可能来源处理顺序位置误差不大但关节高频颤ε 过大或 sign 太硬换成 satε 降到最小可行值轨迹末端来回超调λ 过大λ 减半再试大误差跟得上、小误差进不去边界层过宽缩小 δ控制指令带明显高频噪声速度差分噪声给 s 加低通或换观测器输出4.3.3 弹性模态与耦合共振减速机的弹性会让真实系统比刚性仿真多出高频模态。ε 大时切换项会激励这些模态机器人发出高频啸叫力矩日志里也能看到几百 Hz 的反复翻转。仿真完全看不出这个问题因为刚性模型里没有这些模态。应对思路明确降低切换频率而不是继续加 ε。sat 边界层、s 低通、降低 λ三者依次尝试直到高频成分明显下降。5. 把抖振压下去又不丢鲁棒性变边界层滑模的实现与验证5.1 用误差幅值动态调整 sat 的边界层宽度固定边界层有个矛盾δ 太大稳态误差被放宽δ 太小切换器在零点附近依然会激发抖振。变边界层把 δ 绑到位置误差的幅值上误差大时放宽边界层让控制力矩平缓推进误差接近零时收紧边界层保住稳态精度。常见实现如下。def sat_with_schedule(s, e, delta_min0.005, delta_max0.05, k20.0): delta delta_min (delta_max - delta_min) * np.exp(-k * abs(e)) return np.clip(s / delta, -1.0, 1.0), delta这里 delta 的单位和 s 一致是 rad/s不是角度。k 控制边界层从宽变窄的速度k 越大误差稍大一点就切换到窄边界层模式实际效果接近固定小边界层k 太小误差大时也长时间处于宽边界层稳态精度受影响。直接把这段替换掉第 3 章仿真里的 sat(s)其他参数不变能同时看到误差曲线基本不变和力矩曲线高频成分明显减少。5.2 验证改进是否有效看切换频率而不是只看误差位置误差变小可能是增益换来的不一定是抖振被抑制。验证变边界层有没有起作用统计 sign 或 sat 进入饱和后正负方向的切换次数更直接。可以沿用仿真中的 s 序列在控制循环外统计符号翻转频率prev_sign None switch_count 0 for s_val in s_list: cur 1 if s_val 0 else -1 if prev_sign is not None and cur ! prev_sign: switch_count 1 prev_sign cur print(fswitch_rate{switch_count / (steps * dt):.1f} Hz)切换频率从几百赫兹降到几十赫兹以下说明不连续切换确实被磨平了如果误差变小但切换频率反而更高说明是靠增益堆出来的精度机械结构迟早出问题。联调时把这个统计放进 ROS2 节点的日志里观察变边界层的 δ_min、δ_max 和 k 三个参数优先固定 λ在 ε 与 δ_min 之间找平衡是滑模位置控制从仿真走通到实物最快的一条路。本文还有配套的精品资源点击获取
返回列表