ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于Simulink/Simscape的工业机器人阻抗控制轨迹跟踪仿真

基于Simulink/Simscape的工业机器人阻抗控制轨迹跟踪仿真 在调试机械臂的过程中我遇到过一件比较头疼的事一台六轴工业机器人在纯位置控制模式下走直线轨迹空载时重复定位精度可以到0.1mm以内但只要末端一接触工件表面哪怕只是轻轻碰一下电流瞬间拉高、安全保护频繁触发整个产线节奏都被打乱。后来换到阻抗控制思路在Simulink/Simscape里把整套系统跑通之后我才彻底弄清楚问题不在伺服本身而在于位置控制回路那套“不允许被外力推开”的逻辑根本不适应接触类作业。这篇文章就用我实际搭建的一套基于阻抗控制的工业机器人轨迹跟踪仿真系统来讲。内容会覆盖阻抗控制为什么能解决接触难题、Simscape里怎么建立六轴机械臂多体模型、控制器在Simulink中怎么一步步搭出来以及参数整定和调试踩坑的经验。适合正在做机器人控制算法验证、准备把力控策略落地到仿真平台上的工程师和研究生参考代码和模块配置思路可以直接搬到自己的模型里。1. 为什么位置控制不够用刚性伺服背后的接触难题1.1 位置伺服系统默认的“不允许被推开”传统工业机器人最核心的底层就是位置伺服。每个关节内部有一个高增益的位置环通常以PD或PID形式存在目标只有一个让关节实际角度精确复现指令角度。这意味着只要控制器还在运行机器人末端在外力作用下的位置偏差会被极力抑制表现出来就是“硬”。在搬运、焊接、涂胶这类非接触作业中这种刚性是非常理想的属性。机械臂走一条直线不管末端是空载还是带负载位置轨迹都能保持得很好轨迹跟踪精度就是普通产线最看重的指标。这也是为什么大多数工业机器人出厂默认就是位置控制模式。但问题恰好出在“不允许被推开”这句话上。一旦末端与外部环境发生接触比如装配时轴孔配合、打磨时砂轮与工件表面贴合外力会被位置环全部“硬扛”下来。如果接触力超过结构承载极限轻则触发碰撞保护停机重则损坏工件或机器人本体。1.2 位置精度与接触力之间的死结在接触类任务里位置控制面对一个根本性的矛盾末端执行器与工件的相对位置存在不可避免的误差可能是来料公差、夹具定位偏差或者机器人自身重复精度的波动。如果机器人坚持把末端推到指令位置而实际工件表面比指令位置高了几毫米结果是机器人“硬挤”进去表现在末端就是接触力陡增。我在仿真里复现过这个现象让末端以1mm/s的速度沿法线方向靠近一面刚性墙位置控制模式下的接触力会在触碰瞬间冲到接近400N仿真步长稍微大一点数值直接发散。原因很简单——位置环把期望位置直接丢给伺服系统期望位置在墙里面墙不让进力就只能一路涨。这时候大家自然会想到用力传感器做反馈让机器人“感知”接触力再调整动作。但直接做力闭环也有问题力传感器噪声大、带宽低跟位置环带宽相差太远直接串在一起很容易震荡。而且力控制对接触环境刚度极其敏感换个工件材质控制器可能就要重新调。1.3 从“力控制”转向“力与位置的关系控制”阻抗控制解决这个问题的思路很巧妙不直接控制力也不直接控制位置而是控制“当外力作用时机器人末端应该表现出多大的位移”以及“当位置偏离目标时机器人会产生多大的力”。这种外力与位移之间的动态关系在物理上就是一种阻抗。用一句话概括位置控制把机器人变成一根顶天立地的刚性柱子阻抗控制把机器人变成一根有刚度参数、阻尼参数的弹簧。柱子碰到东西就硬顶弹簧碰到东西会退让退多少取决于弹簧劲度系数退得快不快取决于阻尼大小。这样带来的好处是接触力不再是一个失控量而是可以通过阻抗参数预先设计。想让机器人“软一点”就降低刚度想让机器人“回得快”就加大阻尼。而且整套逻辑可以构建在已有位置伺服基础上不需要底层大改非常适合工程项目。2. 阻抗控制的原理先理解“力与位移的关系”再谈仿真2.1 目标阻抗方程与机械阻抗的物理直觉阻抗这个名词在机器人领域常把人绕晕因为大家更熟悉的是电学里的阻抗。但机械阻抗的概念其实更直观给末端施加一个外力末端会产生速度/位移响应力与速度或位移之间的动态比值就是机械阻抗。理想的目标阻抗通常写成二阶系统的形式M_d * (x_ddot_d - x_ddot_e) B_d * (x_dot_d - x_dot_e) K_d * (x_d - x_e) F_ext其中x_d是期望末端位置x_e是实际末端位置F_ext是外部接触力。M_d、B_d、K_d分别对应于期望惯量、期望阻尼、期望刚度。这个方程本质上就是一个弹簧-质量-阻尼系统。想象你推一扇带液压闭门器的门门有质量所以推起来有惯性感液压缸提供阻尼所以推快了会有阻力门轴弹簧提供刚度所以放手后门会自己关回去。阻抗控制就是让机器人末端“变成”这样一套可以用参数任意配置的机械系统。2.2 阻抗控制与导纳控制一个问题的两个视角阻抗控制在实际工程里其实有两条实现路线。阻抗控制真正意义上的阻抗控制控制器感知末端位移误差通过目标阻抗方程计算所需要的力然后用力去驱动环境。这种实现需要精确的机器人与环境动力学模型对模型误差特别敏感实际工程项目中用得相对少。导纳控制也叫位置基阻抗控制控制器感知末端与环境的接触力通过目标阻抗方程把它换算成位置修正量再把修正后的位置作为底层位置伺服的指令。这种实现方式可以直接叠在现有位置控制器上对模型误差没那么敏感更适合“让现有机器人具备力控能力”的改造场景。我这里选择的是位置基导纳控制路线。原因很简单一方面我想复用现成的关节位置伺服另一方面打磨、装配这类接触作业中机器人运动速度不快末端速度、加速度都不高导纳控制完全够用。如果你做的是高速抛磨或者需要极高动态响应的场景那还是要回到真正意义上的阻抗控制做好动力学补偿。2.3 为什么底层位置环仍然重要很多初学者会把阻抗控制和“直接给关节力矩指令”画等号实际不是这样。在位置基导纳控制架构里底层依然保留位置/速度伺服环阻抗控制器只是在外层不断修正位置指令。这样做的好处很实际底层位置环把机器人的非线性动力学做了大部分补偿外层阻抗控制器看到的是一个线性化程度较好的被控对象。仿真结果也验证了这一点——同样的阻抗参数有底层位置环的系统和没有底层位置环的系统前者在自由空间里的轨迹跟踪精度要高出近一个数量级。3. Simscape多体机械臂建模关节、刚体、接触力与传感器配置3.1 从机构简图到多体模型的搭建思路Simscape Multibody的建模逻辑和SolidWorks这类机械设计软件很像用刚体表示机械臂的各个连杆用关节模块表示连杆之间的运动副用坐标系变换定义刚体之间的连接关系。我使用的是6自由度串联工业机器人构型也就是常见的六轴垂直关节结构。基座固定在全球坐标系原点从基座到末端依次是腰关节J1、肩关节J2、肘关节J3、前三个腕关节J4-J6。每个连杆用一个Solid模块表示Solid里需要设置质量、质心位置和惯性张量。初学者最容易在这步出问题刚体只要设置了外形尺寸和密度Simscape会自动计算质量与惯性张量很多人就直接用了。但对一个控制仿真来说这个自动计算只适合可视化展示用真实参数才靠谱。我是把实际机器人每个连杆的质量和质心坐标查出来填进去的惯性张量也尽量用三维软件里的测量值模型与真实机器人的匹配度会高很多。3.2 关节模块设置与力矩输入模式每个旋转关节使用Revolute Joint模块。关键设置有两个。一是Mode下拉框默认是No Actuator要把它改成Provided by Input并把输入信号连接到关节的力矩输入端口。二是传感器输出端把关节位置和各关节速度引出到Simulink侧作为底层位置环的反馈信号。这里有个细节阻抗控制层的输出是关节力矩但底层同时又有位置环两个力矩如何分配实践中是把阻抗控制器的输出作为力矩叠加到关节上底层位置环的PD输出也叠加到同一个关节力矩指令。整体结构是“底层位置环承担轨迹跟踪外层导纳环做位置修正两者合流后通过力矩接口驱动Simscape模型”。如果你只想先跑通自由空间轨迹跟踪不加接触约束可以不接阻抗外环只保留底层PD加重力补偿先把模型和轨迹跟踪调顺再逐步加入阻抗层。3.3 末端工具坐标系与接触力建模末端执行器我加了一个小球体作为“指尖”通过Rigid Transform模块固定在第六轴末端法兰中心。Simscape里所有的力/运动测量都是围绕坐标系做的所以在末端装一个坐标变换是必须的。接触建模用了Simscape的Spatial Contact Force模块让末端小球和一个固定平面刚体产生接触。这个模块的作用是当两个刚体表面穿透距离大于0时根据接触刚度计算法向接触力并根据相对速度计算摩擦力。它比直接用Bushing Joint加等效弹簧阻尼来模拟接触要直观得多而且能反映接触发生的瞬间动态。接触刚度的取值特别重要我前几次仿真一直发散后来发现是接触刚度设置太大数值积分器步长被迫缩得极小。经验值接触刚度可以先取1e4 N/m量级能把末端压入平面的穿透量控制在0.1mm以下就够用。3.4 传感器测量与单位一致性检查Simscape里测量末端位姿和速度常用Transform Sensor模块可以接在一个坐标系和全局坐标系之间直接输出位移、速度、旋转矩阵等信号。注意Simscape默认输出的方位角单位是度deg而控制算法里雅可比矩阵、目标阻抗方程都要求弧度rad单位不一致会让结果非常奇怪而且很难排查。我习惯是在每个进入Simulink控制端的Simscape信号后面显式加上一个增益模块来完成deg到rad的转换而不是在某个角落偷偷改。这样整个信号的单位链路是透明的看模型就能明白每个信号物理上是什么量、单位是什么。4. 阻抗控制器在Simulink中的搭建从参考轨迹到关节力矩4.1 控制器架构与离散化设置在Simulink里搭建控制系统第一件事想清楚哪些模块连续、哪些模块离散。我的方案是整个控制算法全部用离散模块搭建采样周期1ms即控制频率1kHzSimscape多体模型作为连续被控对象。为什么这么设计因为阻抗控制最终要下放到真实控制器里执行真实控制器就是离散系统强位置伺服周期通常就是1kHz或更低。在仿真里先按离散方式搭后面做代码生成、硬件在环时可以直接复用。如果从一开始就用连续积分器搭转到离散时会多出很多麻烦。实现方法是把Simulink控制部分放到一个采样时间设为0.001的触发子系统里或者用离散PID、离散传递函数模块。单位延迟模块在这里不仅用于信号时序控制还承担了切断代数环的任务后面会专门讲到。4.2 参考轨迹生成与逆运动学解算轨迹方面我用的是一条笛卡尔空间直线轨迹起点0.65, 0, 0.35终点0.65, 0.1, 0.45单位都是米末端姿态保持竖直向下不变。轨迹规划采用梯形速度曲线加速段0.5s、匀速段1.0s、减速段0.5s总时长2s。Simulink里用Clock模块接一个MATLAB Function写出五次多项式或梯形速度插补函数即可。逆运动学是这套仿真里最容易拖慢速度的环节。Robotics System Toolbox里有现成的ik函数可以直接在MATLAB Function里调用但问题是它每次仿真步都要执行迭代优化速度非常慢一个2秒的轨迹仿真跑完要好几分钟。我换成了解析逆解对6自由度垂直关节机器人利用腕部解耦特性先用末端位姿求前三个关节角再根据手腕偏置求后三个关节角。虽然推导过程要花点时间但仿真速度提升非常明显。如果你只想先验证阻抗控制逻辑也可以用平面3自由度机械臂做演示逆解甚至可以用几何法手算出来。4.3 目标阻抗计算模块的实现目标阻抗方程在Simulink里搭起来不复杂关键在于想清楚算出来的量到底是什么。我采用的是导纳控制实现由接触外力F_ext算出末端的位置修正量dx。具体做法是把目标阻抗方程两边做拉普拉斯变换得到接触力到位移修正量的传递函数dx / F_ext 1 / (M_d * s^2 B_d * s K_d)在Simulink里可以分别搭三个通道F_ext除以M_d后经过两次积分得到位移修正量B_d项作为速度阻尼、K_d项作为位置刚度一起反馈回积分之前。更简洁的做法是直接用一个传递函数模块1/(M_ds^2B_dsK_d)但传递函数模块默认是连续域后面想生成C代码还得手动改成离散传递函数不如全程用离散积分器搭。接触力F_ext从哪里来Simscape的Spatial Contact Force模块输出的是一个力矢量Fx,Fy,Fz直接引出到Simulink即可。注意在自由空间里末端没有接触接触力为0此时导纳环输出修正量为0控制器退化为纯位置轨迹跟踪。4.4 笛卡尔空间力到关节力矩的变换导纳修正得到的是末端期望位置修正量dx叠加上参考轨迹得到修正后的末端期望位置经逆解得到修正后的关节期望角度送入底层位置环。但层次上还有一个重要环节目标阻抗方程里的F_ext是笛卡尔空间的力如果要做力矩级阻抗控制需要用雅可比矩阵转置把笛卡尔空间的期望力映射到关节空间。tau_imp J^T * F_imp其中F_imp是通过阻抗方程算出来的期望接触力J是当前位姿下的雅可比矩阵。为什么是转置而不是逆矩阵因为力的映射和速度的映射是“对偶”的速度从关节空间映射到笛卡尔空间用的是J力从笛卡尔空间映射到关节空间用的就是J^T。这一点理解透了看相关代码和论文就不容易晕。雅可比矩阵的计算我用MATLAB Function根据当前关节角实时算出来。具体可以按标准DH参数求几何雅可比也可以调用Robotics System Toolbox里的geometricJacobian函数。注意geometricJacobian输出矩阵维度是6xn包含线速度雅可比和角速度雅可比两部分我只需要前三维线速度部分参与位置力映射别把维度搞混。在奇异位置附近雅可比矩阵会出现病态直接算J^T * F_imp不会发散但如果你做的是速度级逆解比如J的伪逆就要加阻尼最小二乘处理我后面在踩坑部分细说。4.5 底层补偿重力项与关节PD纯粹的阻抗控制器输出关节力矩在仿真里会遇到一个大问题如果不做重力补偿末端会在重力作用下明显下沉位置跟踪误差会大得离谱。因此我在关节力矩指令里加入了重力项和科氏力项补偿tau_cmd tau_imp tau_grav tau_coriolis K_p * e K_d * de/dt这里的重力补偿项我是在模型初始化时用Robotics System Toolbox的gravitationalTorque函数预计算好存成关于各关节角的查找表仿真过程中按当前关节角插值查表。如果直接用MATLAB Function实时调这个函数又会拖慢仿真速度。底层PD增益的整定参考了临界阻尼原则先加大K_p让关节响应变快再按照阻尼比接近1来定K_d。由于Simscape里的被控对象包含了完整的多体动力学PD增益不需要像仿真作业里那样随便给个几百就完事一定要结合实际模型的自然频率来调。5. 轨迹跟踪仿真实验与参数整定5.1 仿真场景设计自由空间与接触约束我设计了两个场景来验证系统场景一是自由空间直线轨迹跟踪末端不接触任何物体目标是评估阻抗控制对轨迹跟踪精度的影响。理论上阻抗控制会增加一些跟踪误差因为外层导纳环毕竟是在“干扰”原始位置环的期望轨迹但好的参数配置下这个影响可以控制在很小范围。场景二是末端接触固定平面让末端在追踪直线轨迹的同时在某个时刻开始与一个倾斜平面产生接触目标是在保证一定轨迹跟踪性能的前提下把接触力峰值限制在可接受范围。两个场景共用同一套控制器和阻抗参数方便对比控制策略在不同工况下的差异。5.2 阻抗参数整定的顺序与经验阻抗控制器的参数有三个刚度K_d、阻尼B_d、惯性M_d。我的整定顺序是先定刚度再加阻尼最后调惯性。刚度K_d决定了末端在与环境接触时的“柔软程度”。K_d越大同样的接触力产生的位移偏差越小表现为末端越硬但接触力也越大。可以这样理解目标把期望位置视为弹簧的原长实际末端位置偏离期望位置越远产生的力越大。阻尼B_d决定了接触过程的过渡特性。阻尼太小接触瞬间会有明显的来回振荡阻尼太大接触动态变得迟钝调整时间拖得很长。用二阶系统类比阻尼比zeta B_d / (2sqrt(K_dM_d))一般取0.7到1.2之间比较合理。惯性M_d在导纳控制里的作用容易被低估。M_d在数值上取得越大接触力变化引起的加速度响应越小系统表现得越“迟钝”有利于过滤高频力冲击。但M_d太大会让系统对接触环境的动态响应变差有时还会导致数值积分不稳定。实际调试时M_d是从10开始试效果不满意再逐步加大。5.3 典型参数与实验结果对照下面这组参数是我在仿真里实际测出来的一组典型结果注意数值是通用示例具体项目中需要根据机器人型号和负载重新标定阻抗参数配置自由空间轨迹RMSE (mm)接触力峰值 (N)接触瞬态振荡纯位置控制无阻抗层0.8410持续振荡K_d2000, B_d80, M_d102.5320有轻微过冲K_d1500, B_d60, M_d154.1240基本收敛K_d800, B_d60, M_d1511.2165收敛良好可以看到刚度从2000降到800轨迹误差从2.5mm增加到11.2mm换来的是接触力峰值从320N降到165N。这就是阻抗控制在轨迹精度和接触力之间做的“交易”实际项目里就是根据工艺要求来选折中点。5.4 如何判断参数是否“调好了”我判断阻抗参数是否合理的标准有三个第一自由空间轨迹误差不能比纯位置控制差太多。如果加了阻抗层后自由空间误差增加超过一个数量级说明阻抗参数给得太软需要把刚度往大调或检查底层PD增益。第二接触瞬间力峰值与稳态接触力的比值最好小于2。如果接触瞬间力峰值过高说明阻尼太小或刚度太大系统来不及“退让”。第三接触发生后末端位置修正量不能出现持续振荡。振荡超过3个周期还没衰减就要考虑加大阻尼或减小惯性。6. 调试过程中踩过的坑与解决思路6.1 代数环导致联合仿真不收敛Simulink与Simscape联合仿真中最常见的问题是代数环。现象是仿真一开始报错“Algebraic loop detected”或者不报错但仿真速度极慢、结果发散。代数环产生的原因阻抗控制器里末端接触力F_ext是Simscape的计算结果而Simscape的关节力矩输入又依赖F_ext两者形成闭环在同一个仿真步内需要联立求解。解决方案是在反馈回路中插入一个Memory模块或Unit Delay模块把前一步的接触力值用于当前控制周期也就是让控制器比被控对象落后一个采样周期。对于1kHz控制周期来说这一步延迟对整体性能影响很小完全可接受。这也是我前面强调控制部分全部用离散模块的原因——离散模块本身就有天然的时序滞后可以避免代数环。6.2 Simscape仿真速度如何优化刚开始我把Simscape求解器设为默认的变步长ode45一个2秒轨迹仿真跑下来要将近5分钟非常痛苦。后来做了三个改动仿真速度提升明显一是把Simscape Mechanics部分的局部求解器Local Solver打开只对多体部分用变步长精确求解控制算法部分仍然是固定步长离散执行。二是把Spatial Contact Force模块里的接触刚度适当调低同时把Contact stiffness参数从“精确接触”模式换成“软接触”模式减少高频数值振荡对积分步长的压缩。三是把机械臂刚体模型里那些对动力学基本没影响的小特征简化掉比如倒角、螺纹孔等几何细节在Simscape里以不能简化的Solid属性为准。每个刚体只要外形确保干涉关系正确质量/惯量保持准确即可。6.3 逆解与雅可比在奇异位置附近的数值爆炸轨迹中如果有直线段经过机械臂的奇异位置即使阻抗控制器本身不直接求逆解底层位置环的逆解模块也会在奇异点附近产生巨大的速度指令关节力矩随即饱和仿真直接发散。我的处理办法是给雅可比伪逆加阻尼最小二乘项J_damped_inv J^T * inverse(J * J^T lambda^2 * eye(6))lambda取0.01到0.1之间的小值。在奇异位置附近这个阻尼项能有效限制逆解速度指令的幅值同时不影响正常位置处的精度。如果你不涉及速度级逆解只是用解析逆解也要注意在奇异构型附近限制关节速度指令的变化率我是加了一个饱和模块在关节角速度指令后面。6.4 单位、角度制与信号维度的隐蔽问题这类问题看起来低级但真出bug时极难排查。有一次我仿真结果里末端轨迹出现了周期性的锯齿波动查了半天发现是Simscape的Transform Sensor输出的旋转量单位是度而控制器里雅可比矩阵按弧度计算导致每走一步就有一个微小的角度累积误差反馈回来又参与计算形成了一种高频振荡。另一个常见问题是信号维度不匹配。Simulink里很多模块是支持广播运算的比如你给一个6x1的向量和一个标量做加减标量会被自动广播到6x1结果看起来正常其实不是你想要的意思。排查方法是打开信号维度显示Format - Signal Dimensions把每个关键信号线旁边显示的维度标出来逐一核对。还有一个细节是单位前缀。我在Simscape里用的是SI单位制即米、千克、秒但参考轨迹生成模块里如果用毫米或厘米定义坐标点入口处必须做换算不能偷懒直接接进去。我习惯把所有输入信号在进入Simscape端口之前统一做一个“/1000”或“*1000”的增益并在信号线上标注单位防止后期改模型时忘记。6.5 接触模块参数的选择刚度与穿透量的权衡Spatial Contact Force模块提供了很多接触参数最关键的是法向接触刚度。如果取1e6 N/m以上模型能保持很好的几何精度但仿真步长会被压缩到微秒级仿真时间不可接受。如果取1e3 N/m仿真快了但末端会“陷进”接触面好几个毫米接触力波形严重失真。我最后用的折中方案是取2e4 N/m配合接触阻尼保证最大穿透量在0.2mm以下仿真步长可以维持在毫秒量级。结构刚度远大于接触刚度时这个穿透量对结果影响可忽略如果接触对象本身是软材料就需要把接触刚度降得更低同时允许更大的穿透量。从模型到实机一点个人的经验和延伸整套系统在Simulink/Simscape里跑通之后给我最大的感触是仿真模型的价值不完全取决于控制算法有多高级更大程度上取决于被控对象模型的可靠程度。仿真里各种参数可以随意覆盖但一个惯性张量设错的模型会把所有上层调试工作带偏得到的结论在实机上完全无法复现。所以我会建议每个做机器人控制仿真的朋友第一步都先去核实自己的机器人模型参数来源而不是急着调控制器。控制器实现上也有一个值得留意的方向模型搭好后可以先把控制算法部分通过Embedded Coder生成C代码再放到Simulink外部模式或像DSPACE RT这样的实时平台上去做硬件在环验证。因为整个阻抗控制器的数据流已经是离散化的、按固定周期执行的与真实控制器代码几乎可以直接对接。如果你现在还在纠结从哪里入手我的建议是先别急着建复杂六轴模型用平面三连杆机器人在Simscape里跑通阻抗控制逻辑理解了力到位移修正、修正量到逆解、逆解到底层位置环这条链路之后再升级到工业六轴模型。这个思路比我当初直接上六轴要省力很多调试时定位问题也会快得多。
返回列表