公司动态
两连杆机械臂柔顺控制:DSC+自适应+SEA变阻抗仿真实践
简介机械臂柔顺控制是机器人实现安全物理交互的关键技术其核心在于通过阻抗控制调节末端刚度和阻尼使机械臂在接触外力时表现出可变的柔顺特性。然而刚性机械臂在高频动态、参数不确定性和交互稳定性方面存在固有缺陷。串联弹性驱动器SEA通过引入弹性元件解耦电机与负载惯量为力控提供天然力矩测量通道并提升稳定裕度。动态面控制DSC利用一阶低通滤波器替代虚拟控制量的复杂求导抑制了高阶系统微分爆炸自适应参数估计则在线补偿负载变化和模型误差。将二者与一阶变阻抗策略融合可构建兼顾跟踪精度与接触柔顺性的主动柔顺方案。该方案适用于两连杆机械臂的力位混合控制、阻抗控制和SEA驱动器研究已在Simulink仿真中验证其稳定性与鲁棒性为实际机器人交互控制提供参考。 最近一直在调两连杆机械臂的柔顺控制实验把动态面控制DSC、自适应参数估计和串联弹性驱动器SEA的变阻抗方案强行塞进了同一个仿真框架里。折腾了三周从理论推导到Simulink实现踩了不少坑但也把整套东西的脾气摸清楚了。这套方案的目标很直接让两杆机械臂在末端受力时表现出“可变柔顺”的响应而不是硬碰硬地扛住所有外力。它解决的核心问题是刚性机器人交互时的稳定性脆、力控冲击大、参数不确定性难处理这三件事。适合正在做机器人阻抗控制、力位混合控制、SEA驱动器相关课题的研究生和工程师。下面这些内容是我从实际调试中记录下来的理论推导和仿真代码的思路都会提到你可以直接照着搭建。1. 整体设计思路为什么把DSC、自适应和SEA凑在一起1.1 刚性机械臂做柔顺控制的三个痛点如果你直接用刚性机械臂做力控或者阻抗控制第一道坎就是关节减速器和结构刚度带来的高频动态。控制周期稍微没跟上末端微小振动就会在力传感器上放大成噪声然后闭环又把噪声循环回去整个系统开始嗡嗡响。这类问题在工业机器人上表现为末端抖动在协作机器人上表现为安全停机。第二个痛点是参数不确定性。两杆臂只要换个末端负载或者抓取物体的重心变了惯量矩阵和重力项全部变掉。传统基于精确模型的阻抗控制几乎立刻失效——理论设计好的阻尼特性实际跑起来不对劲末端该柔的时候不够柔该稳的时候又过冲。第三个痛点是“微分爆炸”。基于反步法的控制器在高阶系统里需要对虚拟控制量反复求导一旦系统阶数上到四阶以上表达式就长到没法手推即使强行求导出来放仿真里也会因为符号计算误差导致控制量跳变。这是推动我用动态面控制替换传统反步法的直接原因。1.2 串联弹性驱动器用弹簧换来的稳定裕度SEA的结构不复杂电机输出端经过一个弹簧常见的有扭转弹簧、螺旋弹簧、盘簧再连接到连杆。相比刚性直驱弹簧把电机侧惯量和负载侧惯量解耦了。从力控制的角度看你不再需要靠电流环硬憋出力矩而是通过控制弹簧变形量间接控制输出力矩相当于给系统增加了一个天然的力传感器——弹簧本身就是一个测量单元。代价是系统多了一个弹性自由度状态变量翻倍动力学方程从二阶变四阶。高增益的刚性力控制器直接用在这类系统上极易失稳但阻抗控制本身是低增益的交互控制反而和SEA的柔性特性很搭配。在这个方案里SEA的价值不是助力而是提供物理柔顺性和力矩测量通道让阻抗控制的稳定裕度大幅提升。1.3 动态面控制与自适应各解决什么问题动态面控制解决的是微分爆炸在设计虚拟控制量之后不直接对这个虚拟量求导而是让它通过一个一阶低通滤波器用滤波器的输出去替代原函数作为下一级参考输入。代价是引入了一个时间常数很小的滤波器动态理论分析时把它当作扰动项处理并用Lyapunov方法证明系统的最终一致有界性。自适应控制解决的是参数未知把机械臂的惯性参数、连杆质量、质心位置甚至负载变化都放进回归矩阵设计在线参数更新律让控制器自动适应负载变化。整套方案里动态面负责稳定自适应负责补偿不确定性SEA负责物理柔顺和力矩感知一阶变阻抗则负责目标行为的在线调整。2. 核心原理SEA机械臂动力学与一阶变阻抗设计2.1 两杆SEA系统的完整动力学方程两杆SEA系统需要同时建立电机转子、弹性元件和连杆三个层次的状态。电机侧方程可以写成[ J_m(\theta) \ddot{\theta} \tau_f(\dot{\theta}) \tau_s \tau_m ]其中(\theta)是电机侧转角(\tau_s)是弹簧力矩(\tau_m)是电机力矩。每个关节配一个SEA所以(\theta)、(\tau_s)、(\tau_m)都是二维向量。连杆侧是常规的两杆机械臂动力学[ M(q) \ddot{q} C(q,\dot{q}) \dot{q} G(q) \tau_s \tau_{ext} ]这里面(q)是连杆侧位置(\tau_{ext})是末端受到的外力映射到关节的等效力矩。弹簧力矩按线性弹簧建模就够了[ \tau_s K_s (\theta - q) ](K_s)是关节处SEA的刚度矩阵。值得注意的是两杆臂的惯性矩阵(M(q))不再是对角阵耦合项很影响控制律设计自适应的时候也要把这些耦合项一起处理不能只估计对角元素。2.2 一阶变阻抗模型的物理含义常规阻抗控制的目标方程是[ M_d (\ddot{q} - \ddot{q}_r) B_d (\dot{q} - \dot{q}r) K_d (q - q_r) \tau{ext} ]这个方程的本质是让机械臂在接触外力下表现出二阶弹簧-阻尼系统的响应。固定刚度和阻尼的时候系统行为是定死的无法根据接触状态切换柔顺程度。一阶变阻抗的意思是阻抗参数主要是刚度和阻尼不再固定而是依据系统状态以“一阶动态”方式变化——参数本身不会突跳而是经过一个惯性环节过渡到目标值。具体实现时我给每个关节设计了这样的参数动态[ \varsigma \dot{K}d(t) K_d(t) K{base} \Delta K \cdot \sigma(q - q_r) ][ \varsigma \dot{B}d(t) B_d(t) B{base} \Delta B \cdot \varsigma \dot{K}_d(t) ](\varsigma)是变化速率常数(\sigma(q - q_r))是随位置偏差变化的整形函数。这样设计的好处是机械臂在自由空间跟踪时刚度较高保证传统跟踪精度接触瞬间偏差变大时刚度自动回落阻尼自动增强末端变得柔顺而不反弹。2.3 阻抗参数约束与稳定性边界一阶变阻抗不是从(B_d)和(K_d)选什么值都行的。如果参数变化范围太激进即便理论上的自适应控制器能保证有界性实际仿真中也会出现末端震颤。我给参数做约束的几个原则如下刚度下限必须大于零这是物理可实现的硬约束。(K_d)降到接近零时末端会出现“飘移感”跟踪误差漂移很典型。阻尼比映射关系沿用二阶系统概念(\zeta B_d / (2\sqrt{M_d K_d}))设计时让(\zeta)的取值范围落在[0.7, 1.5]之间避免欠阻尼振荡。参数变化速率(\varsigma)取值至少比机械臂最低结构频率慢5倍否则参数变化本身会激发结构模态。目标惯量(M_d)在整段仿真中保持不变只变阻尼和刚度。这个约束非常关键否则加速度反馈通道的参数变化会直接破坏系统的物理一致性。按照这些约束整定出来的参数系统既保留了自由运动时的跟踪能力又能在接触瞬间显现出柔顺性而且参数切换的过程是连续的、可微的这为Lyapunov证明提供了极大的便利。3. 控制律推导与Simulink仿真实现3.1 动态面阻抗控制律的推导流程动态面控制的设计流程分四步每一步对应一层状态面。第一步定义第一个误差面[ z_1 q - q_r ]这个面反映的是连杆位置相对于期望轨迹的偏差。第二步设计虚拟控制量(\alpha_1)让误差面收敛到阻抗模型指定的动态[ \alpha_1 \dot{q}_r - \Lambda_1 z_1 ]这里的(\Lambda_1)是正定的增益矩阵。传统反步法会直接对(\alpha_1)求导来计算(\dot{q})的期望而动态面控制的做法是把(\alpha_1)喂给一阶低通滤波器[ \varsigma_1 \dot{\alpha}{1f} \alpha{1f} \alpha_1 ](\alpha_{1f})是滤波后的虚拟控制量用它替代(\alpha_1)参与后续计算因为(\dot{\alpha}_{1f})是有限且可用的。这样的处理直接绕开了对复杂非线性函数求导的问题表达式简化了一大截。第二层状态面定义为连杆速度与滤波虚拟量的偏差[ z_2 \dot{q} - \alpha_{1f} ]对(z_2)求导后就会引入动力学模型。把上一节的两杆SEA连杆侧方程代入加上阻抗目标方程整理之后就能解出控制量表达式。控制量的结构包括三部分(\tau_{ff})前馈补偿项、(\tau_{imp})阻抗项、(\tau_{adp})自适应补偿项。表达式中需要用到回归矩阵(Y(q,\dot{q},t))把所有已知函数和状态量放进去未知参数提炼成待估计向量(\hat{\Theta})。这也是自适应控制器设计的标准做法麻烦但在工程上很成熟。3.2 自适应律与参数估计设计这一步是整个方案里最需要细心调的部分。两杆臂的自适应参数向量可以取为[ \Theta [m_1, m_2, I_1, I_2, l_{c1}, l_{c2}, K_{s1}, K_{s2}, f_{v1}, f_{v2}]^T ]既包含连杆惯性参数也包含SEA刚度不确定性和关节粘滞摩擦系数。自适应律的经典形式是梯度法配合σ修正[ \dot{\hat{\Theta}} \Gamma Y^T z_2 - \sigma_\Theta \Gamma \hat{\Theta} ](\Gamma)是自适应增益矩阵(\sigma_\Theta)是一个很小的正数用来防止参数漂移。这里特别注意(\Gamma)不能取太大不然参数估计值会高频震荡也不能取太小否则负载变化后跟上不。我试过好几组值最后(\Gamma)的对角元素落在0.1到1.0这个区间是最稳定的。参数估计初值不必精确甚至可以设成零因为自适应律会在线收敛。但如果你的仿真里机械臂初始状态远离平衡点建议至少把重力相关参数给个粗略值否则控制器刚起来的零点几秒里会有较大的力矩冲击。3.3 Simulink模型架构与关键配置我用的是Simulink标准库M语言S-Function配合Simscape Multibody的方式搭建。整个模型分三个子系统被控对象子系统、控制律子系统、参数估计子系统。被控对象子系统用Simscape Multibody建立两杆SEA模型。这里有个小技巧不要在Simscape里用带摩擦的关节模块来模拟SEA弹簧否则后续参数估计会对不准。我用的方式是直接建模两个转动惯量块加一个弹簧-阻尼模块串联在关节中电机侧输入力矩指令连杆侧输出角度和角速度。控制律子系统用S-Function写核心控制律输入是期望轨迹、反馈角度、反馈角速度、估计参数输出是电机力矩指令。采样时间固定设为1kHz即0.001秒步长。这个采样频率要和SEA弹簧固有频率匹配经验法则是采样频率至少是弹簧-负载系统固有频率的20倍。参数估计子系统独立运行同样1kHz读取(z_2)等状态量计算自适应律并把估计值正反馈给控制律子系统。仿真器配置上我用固定步长ode4求解器步长0.001秒仿真时长10秒。这里不要用ode45变步长在SEA系统的刚性方程上会频繁降低步长跑得很慢而且结果不连续。4. 调试实录与高频问题排查4.1 问题一自适应估计值漂移第一版仿真里自适应参数(\hat{\Theta})跑了2秒后就出现明显漂移(m_2)的估计值一路涨到真实值的3倍连杆末端轨迹也开始偏离。检查下来发现根因是激励不够充分机械臂自由运动时回归矩阵中的某些列始终接近零这些列所对应的参数根本不会被激励起来但更新律还在算只是基于噪声在算自然就漂了。解决的组合拳是加入σ修正项把不带物理意义的参数缓慢拉回零同时在仿真中给机械臂输入一个持续激励的轨迹例如小幅度正弦叠加在梯形轨迹上确保回归矩阵满秩激发。两者缺一不可。只做激励不修正噪声还是会让参数漂只修正不激励真实参数估计不出来控制器适应性就差。4.2 问题二状态面抖动与高频噪声为了凑响应速度一开始把(\Lambda_1)增益调得比较高结果(z_2)状态面在接触瞬间出现抖振。分析数据发现不是数值发散而是位置差分到速度之后高频噪声被控制器放大反馈又通过变阻抗参数形成第二路径最后振起来了。处理办法分两步。第一把速度信号换成二阶低通滤波器输出截止频率设到50Hz左右既能滤掉齿轮和弹簧的高频分量又不会明显影响低频跟踪。第二重新调整(\Lambda_1)和动态面滤波器(\varsigma_1)的关系让两者满足(\varsigma_1 \Lambda_1 0.2)。这个经验约束是我反复试出来的能保证虚拟控制量滤波后的相位滞后不至于破坏稳定性。4.3 问题三变阻抗参数突变导致力矩跳变一阶变阻抗参数动态理论上保证连续性但我在初版实现时直接把(\sigma(q - q_r))写成了一个切换函数——偏差超过阈值就切到低刚度模式结果切换瞬间力矩信号出现了尖峰。这是因为切换函数本身不连续而(K_d)的变化速率虽然被滤波器限制但阻尼(B_d)没跟着同步调整系统的自然频率突然跳变。修正方法把切换函数改成连续可微的S形函数并让阻尼变化和刚度变化捆绑在一起刚度下降的同时阻尼按比例上升。修正后力矩尖峰从幅值约30Nm直接降到4Nm以内接触响应也更符合直觉。4.4 问题四SEA刚度选型与采样时间冲突SEA的弹簧刚度(K_s)选大了仿真步长必须缩小否则弹簧变形量的数值积分误差会累积成真实偏差。选小了力控带宽不够系统响应粗糙。我的做法是先用线性化模型算一下弹簧-负载系统的固有频率[ f_{SEA} \frac{1}{2\pi} \sqrt{\frac{K_s}{J_{eq}}} ]然后匹配三个仿真参数固定步长至少比周期小20倍传感器采样频率至少比(f_{SEA})高10倍控制律更新频率至少比(f_{SEA})高20倍。在(K_s 200)Nm/rad、负载等效惯量(J_{eq} 0.05)kg·m²时(f_{SEA})大约是10Hz控制频率100Hz起步基本够用但实际我放到1kHz仿真结果明显更平滑。5. 常见问题速查表现象根因排查方向末端持续振荡变阻抗阻尼不足或采样频率过低增大(B_d)下限检查仿真步长是否匹配SEA固有频率跟踪误差不收敛自适应激励不足检查回归矩阵是否满秩给轨迹叠加持续激励信号力矩指令跳变参数切换函数不连续把切换函数改成S形阻尼和刚度变化捆绑设计参数估计值发散缺少σ修正或自适应增益过大加入σ修正项降低(\Gamma)数值并检查激励信号接触瞬间反弹刚度切换过快且阻尼配合不够增大(\varsigma)值让刚度变化更平缓同时提升阻尼下限仿真速度极慢变步长求解器遇到刚性问题改固定步长ode4检查弹簧刚度和惯量比的量级如果一个现象对应多个可能原因不要同时改多个参数。每一步只动一个变量记录曲线变化再决定下一步这是我调试了三周后最深刻的体会。另外还有一个容易忽略的细节动态面滤波器的初始值必须同步到虚拟控制量的初始值。如果滤波器初始值是零而虚拟控制量初始不是零第一个控制周期就会产生瞬态冲击从被控对象的响应曲线上看就是起始时刻的毛刺。解决方式是在初始化回调里把滤波器状态赋为(\alpha_1(0))而不是设零。6. 个人经验补充与后续扩展建议我这套方案目前是在纯仿真环境里验证的还没上真实硬件。从仿真到实物的过程中有几个地方需要提前做准备SEA弹簧刚度的实际误差、电机驱动器的力矩响应延迟、传感器噪声特征。如果你后面要接真实硬件建议先在仿真里把力矩指令加一个10到20毫秒的一阶延迟模拟驱动器特性再看看控制器的表现这个预实验能省好多现场调试时间。变阻抗参数方面我现在用的是基于位置偏差的整形函数如果你们有末端六维力传感器数据可以直接把外力向量引入参数整形函数会得到更好的接触响应。另外本文提到的基于全模型参数的自适应估计框架也可以扩展到包含负载质量估计、质心位置估计后续做轨迹规划或者抓取任务时会有帮助。我个人在实际操作中最满意的一个改进是把变阻抗参数动态与自适应律共用一个时间常数让参数变化节奏保持一致。这个改动让整套系统在负载突变时不需要重新整定阻抗参数控制器自适应加上变阻抗配合形成一个更完整的主动柔顺方案鲁棒性和灵活性都比固定参数版本好很多。本文还有配套的精品资源点击获取