资讯详情

资讯详情

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

做完这个基于阻抗控制的工业机器人轨迹跟踪仿真我有种“心里一块石头落地”的感觉。断断续续折腾了两周中间踩了无数坑从Simscape里机械结构动不动就“爆炸”发散到阻抗参数调得机器人一碰就抖最后总算是把一套能稳定跑完、轨迹跟踪误差在合理范围的仿真系统搭出来了。我觉得这套东西对做机器人控制、力控、人机协作的朋友非常有参考价值尤其是那些想先在仿真里验证算法又不想一上来就在真机上“拆家”的人这篇就是我整个搭建过程、原理思考、参数整定和排坑记录。先说结论用Simulink/Simscape做阻抗控制仿真核心优势就是能把机械本体、关节执行器、控制律放到同一个环境里联调。模型出了问题改起来快不用等机器人空转、不用怕电机过流效率高很多。本文适合机器人方向的学生、刚入行的控制工程师以及对力控和柔顺控制有兴趣的仿真爱好者。1. 整体设计思路与技术选型拆解1.1 为什么选了Simulink/Simscape而不是纯数值仿真刚开始我其实纠结过一阵子阻抗控制的核心是一个质量-阻尼-弹簧的动态关系我直接用MATLAB脚本写常微分方程然后Runge-Kutta积分不就行了吗为什么非要Simulink和Simscape后来我压着性子想明白了这件事。纯脚本仿真有一个很大的问题你把机器人当成一个理想的多刚体动力学方程来解关节全是理想的转动副没有摩擦、没有电机响应延迟、没有执行器饱和。这种环境下调好的阻抗参数到了真机上大概率废掉因为真实系统到处都是延迟和非线性。而Simscape里的机器人模型关节自带惯量、摩擦、执行器动态甚至接触刚度把这些物理效应都带进来了仿真结果更接近真实情况同时比真机验证便宜得多也没有把机器人撞坏的风险。另外Simulink/Simscape天生分两个域。Simulink的信号流非常适合搭控制算法比如轨迹规划、PID环、阻抗外环、力矩映射这些都是“信号进、信号出”的运算。Simscape则是物理域建模管的是执行器怎么发力、机械结构怎么动、末端碰到东西会产生多少接触力。两边通过Simscape内部的物理信号接口和Simulink的标准信号接口做转换这个分工特别顺手一个模型同时照顾了控制工程师和机械工程师的视角。1.2 阻抗控制与导纳控制的取舍在实际选型时还有个绕不开的问题同样是实现柔顺到底是做阻抗控制还是导纳控制这两个词经常被混用但思路有本质区别。阻抗控制Impedance Control的核心是机器人末端位置有偏差的时候它对环境施加一个“可控的力”这个力的大小和位置偏差、速度偏差呈弹簧-阻尼关系。它面向的是“机器人作为力源”的这种场景外环接收位置误差内环输出力/力矩。导纳控制Admittance Control恰好反过来机器人末端受外力的时候它主动让出位置也就是感受到力之后去调整运动轨迹让机器人感觉上“很软”。它面向的是“机器人作为运动源”的场景外环接收力信号内环跟踪调整后的位置。我最后选了阻抗控制这个方案主要原因是这次的核心目标是轨迹跟踪末端要按期望轨迹走同时遇到接触的时候具备一定柔顺性。阻抗控制把轨迹跟踪和柔顺性统一在一个框架里参数物理意义直观调起来好解释。导纳控制在纯位置控制基础上套了一层力-位置转换会多一个内环延迟参数不当时更容易振荡对初学者不太友好。当然如果你做的是人机协作那种“人被外力推开”的场景导纳控制其实是更自然的选法两种方法没有绝对优劣。1.3 先澄清一个搜索时容易踩的概念混淆我在找资料的时候发现一个有意思的现象搜“阻抗控制”会蹦出来一堆完全不相干的结果比如FPC软板阻抗控制、PCIe阻抗控制多少欧姆这类电子硬件的话题。这里的“阻抗”指的是电路板信号线路的特性阻抗是为了保证高速信号完整性控制走线宽度、层间距、介质常数这些参数。机器人领域的阻抗控制是Hogan在上世纪80年代提出的力控制理论讲的是机械系统末端力和运动之间的动态关系。这俩完全是同名的不同概念你在搜索参考文献的时候要留意一下别把PCB阻抗控制的文章下下来硬啃我真见过有人抱着一本高速数字设计教材找机器人阻抗控制公式找了一晚上。2. 阻抗控制原理与参数设计的实操要点2.1 质量-弹簧-阻尼模型的物理意义阻抗控制的基本想法特别朴素你希望机器人末端表现出来的行为不像是刚性位置源而像是一个“虚拟的”质量-弹簧-阻尼系统。什么意思呢想象你用手推一个悬挂在弹簧上的重球推它的时候它会顺着你的力挪一点撤掉力之后它会回弹到原来的位置。阻抗控制就是让机器人末端在受到外部力F_ext的时候体现出类似的响应。数学上末端目标行为可以写成一个二阶微分方程[ M_d(\ddot{x}_d - \ddot{x}_e) B_d(\dot{x}_d - \dot{x}e) K_d(x_d - x_e) F{ext} ]这里M_d是目标惯量B_d是目标阻尼K_d是目标刚度x_d是期望位置x_e是实际位置。F_ext是作用在末端的外力/接触力。这个方程表达的实际意思是外力F_ext会被“分配”到惯量项、阻尼项和刚度项上去导致末端偏离期望轨迹的程度是可以人为设计的。如果你把这个方程做一下变形把等号左边展开控制目标就是找一个控制力F_cmd使得机器人实际运动满足这个动态关系。在笛卡尔空间里这个控制力一般取成[ F_{cmd} M_d \ddot{x}_d B_d(\dot{x}_d - \dot{x}_e) K_d(x_d - x_e) ]然后通过雅可比矩阵J^T映射到关节力矩[ \tau_{imp} J^T F_{cmd} ]这个映射至关重要因为机器人的执行器在关节空间而阻抗控制定义在任务空间笛卡尔空间两者之间必须用运动学关系搭桥。这也就是为什么Simulink仿真里要单独搭一个从末端六维力/力矩到关节力矩的转换环节。2.2 目标刚度、阻尼、惯量的整定方法与计算过程这次做到一半我发现阻抗控制算法本身不难难的是参数。参数调不好机器人要么硬邦邦像根铁棍要么软绵绵碰到一点力就“飘”出去老远。以我这次在六轴机器人模型上整定的经验来说最典型的调参路径是这样的先定目标刚度K_d。刚度决定了位置跟踪和外力扰动之间的权衡。刚度越大机器人末端越“硬”跟踪误差越小但对外力的容让越小碰到硬物时冲击力也大。刚度越小机器人越“软”但纯轨迹跟踪的误差会变大。我先按任务需求估算末端允许的最大位置偏差e_max和允许的最大静态接触力F_max那么刚度初值可以取K_d F_max / e_max。比如允许接触力50N允许末端偏差5mm刚度就取10000 N/m。这个值可以先粗设后面微调。再定阻尼B_d。有了刚度之后阻尼直接决定系统的动态响应。按照二阶系统最优响应的思路临界阻尼比ζ1时是最快的无超调状态阻尼取[ B_d 2\zeta\sqrt{M_d K_d} ]如果目标惯量M_d取0.5kg刚度10000 N/m临界阻尼下的B_d就是2×1×sqrt(0.5×10000)≈141 N·s/m。实际中取0.7~1.0的阻尼比比较均衡既能压制振荡又不至于响应太慢。最后说目标惯量M_d。这个参数很多人忽略但它在接触瞬间影响很大。M_d越小受外力时加速度变化越剧烈接触响应越“尖锐”M_d越大动态越平缓但系统感受到的“虚拟质量”大会产生额外的惯性力。M_d一般取机器人末端等效质量的一半左右我的模型里取0.5~2kg之间做对比趋势非常明显M_d从0.5升到2.0同样的100N冲击力末端位移从3mm变成了11mm明显变“懒”了。2.3 为什么不建议把刚度无限调大有个很容易掉进去的坑为了让轨迹跟踪误差更小直接把K_d拉到十万甚至百万级别。表面上看误差是变小了但这时候阻抗控制其实已经退化成了纯位置控制柔顺性完全丢失。接触的时候会产生非常大的冲击力齿轮、谐波减速器、末端执行器都会受到冲击。更麻烦的是刚度大了之后整个系统进入高增益状态对模型误差、摩擦、测量噪声都特别敏感在Simscape里非常容易激励起高频振荡仿真步长会被迫压得非常小最后仿真慢到让人抓狂。我的经验是K_d的调整范围要看接触任务来定纯轨迹跟踪可以适当高一些但一旦有接触刚度就要往下降一个数量级。一个实用的做法是做“分阶段阻抗”自由空间用高刚度保证跟踪检测到接触力超过阈值之后切换成低刚度高柔顺这个在Simulink里用状态机或条件逻辑很容易实现。3. Simscape模型搭建与核心环节实现3.1 机器人模型的导入与关节配置我这次用的是Simscape Multibody的六轴机器人模型。有两种入手方式第一种是直接在MATLAB里用伪代码建一个刚体树指定每个连杆的质量、惯性张量、质心位置、关节类型这种方式灵活但麻烦第二种是导入URDF文件很多开源机器人型号都有现成的URDF直接导入之后Simscape会自动生成对应的刚体、关节和坐标系。我用的第二种方式。导入之后在Simscape中会生成一整套Multibody模型包括World坐标系、各连杆的Solid模块、关节的Revolute Joint模块。需要特别注意的就是关节类型要和实际机器人一致比如六轴机器人一般是六组Revolute Joint每个关节要设置一个初始角度否则仿真一开始的姿态不是你想要的。关节上面还要加传感器和执行器。Simscape里Joint块本身带有运动输入/力矩输入的接口选项如果你用的是Simscape库里的关节块可以直接在关节参数里勾选“Actuator”和“Sensor”分别把力矩输入口和角度/角速度测量口引出来。我做的时候把每个关节都开放了力矩输入口然后用一个Joint Actuator模块把Simulink侧算好的关节力矩喂进去再用Joint Sensor测量实际关节角度和角速度。这里我最开始栽了个跟头就是传感器信号默认是物理信号Physical Signal必须经过PS-Simulink Converter转成标准Simulink信号才能进控制律反过来控制律输出的力矩信号也要经过Simulink-PS Converter才能接入物理模型。每漏一个转换器仿真就直接报错。3.2 末端力测量的两种方式阻抗控制离不开末端力的反馈而Simscape里测末端力有好几种方式选对了省很多事。第一种方式是在末端法兰处加一个力/力矩传感器。Simscape Multibody里有一个Transform Sensor可以测量两个坐标系之间的相对力和力矩。在这个传感器两端分别连接末端连杆和工具/接触体就能实时读出六维力/力矩信号。这个方法最直观测量点就是你关心的真实接触界面阻抗控制中的F_ext直接用它。第二种方式是间接估算通过关节力矩传感器和动力学模型反向计算末端受力。这需要可靠的动力学参数仿真里可以用但精度受摩擦参数影响真机上一般也都是靠这种方式做力估算。仿真里建议直接用第一种方式数据干净还不用做状态估计。不过要注意加传感器本身不会改变机械动力学特性但传感器的测量坐标系有朝向问题。Simscape的Transform Sensor返回的力/力矩是在传感器坐标系下描述的转到基座坐标系还得乘一个旋转矩阵弄反了会让阻抗控制“越想往回拉越往外推”整个系统发散这个坑一定得避。3.3 接触环境建模的三种方式有了柔顺控制还得有个“环境”让机器人去碰。接触环境建模我试了三种方式。第一种是虚拟平面接触用一个刚度很高的弹簧-阻尼组合来模拟地面或者工件表面。末端接近到平面之后法向力按F_n k_contact * penetration c_contact * penetration_rate来计算。这种方式的优点是简单可控缺点是接触发生瞬间如果k_contact取得太大数值容易蹦需要配合小步长和刚性求解器。第二种是Simscape自带的Spatial Contact Force模块在两个刚体之间直接建立接触力关系。这个模块支持定义接触刚度、阻尼、摩擦系数。好处是物理真实感强碰撞检测由Simscape自动做坏处是参数多、计算量大仿真速度明显变慢。我用它模拟了末端执行器抓取一个方块的场景摩擦系数设到0.5左右滑块能稳定被推动这个效果是虚拟弹簧很难做出来的。第三种是把接触力做成外部输入通过一个Bus Creator或者Constant模块直接给末端一个时间变化的力信号作为阻抗控制的外部扰动输入。这种方式最适合做算法验证因为你完全知道外力是多少方便把阻抗参数调准了再去上真实接触模型。我的建议是先把第三种方式跑通确认阻抗控制算法本身没有bug然后升级成第一种方式验证接触稳定性最后有时间再上真实接触模型。一步一步来排查问题的成本最低。3.4 轨迹跟踪与阻抗控制的嵌套结构实现控制结构上我采用的是“内环位置/速度跟踪 外环阻抗柔顺”的经典嵌套架构整个控制律在Simulink模型里分三个层次实现第一层是轨迹规划层。给定起点和终点用五次多项式插值生成期望位置、速度、加速度轨迹。这个我直接在Simulink里写了个MATLAB Function模块输入起点、终点、时间输出t时刻的期望位置、期望速度、期望加速度。之所以用五次多项式而不是梯形速度规划是因为五次多项式的加速度是连续的不会产生加速度突变对阻抗控制这种带惯量项的控制器来说会更平稳。第二层是阻抗决策层。根据末端期望位姿和实际位姿之间的偏差结合当前接触力按前面提到的阻抗控制律计算出期望的笛卡尔空间力F_cmd。这一步在Simulink里用几个Gain模块和向量加法器就能搭起来每个轴独立算非常清晰。第三层是关节力矩映射层。把F_cmd通过雅可比矩阵转成关节力矩。这一步在Simulink里可以用MATLAB Function直接调取机器人模型对象的几何雅可比矩阵也可以先提前算好每个位形下的雅可比矩阵存成查找表。我用的是前者代码大概长这样function tau impedanceTorque(F_cmd, q) % 输入F_cmd为6x1笛卡尔空间广义力 % q为6x1关节角度 % 输出tau为6x1关节力矩 % 这里用的是MATLAB Robotics System Toolbox的刚性树模型 robot getRobotModel(); % 获取刚体树对象 J geometricJacobian(robot, q); % 6x6几何雅可比 tau J * F_cmd; % 力矩映射 end实际控制律里我还在内环加了一个简单的PD项和一个重力补偿项。阻抗控制给出的是“柔顺修正力”如果不加重力补偿机器人在外力为零的时候也会因为自重产生偏差尤其大臂关节的重力矩特别明显。重力补偿项在Simulink里用一个查表模块按关节角度查对应的重力矩就行。这里我踩了个坑一开始没加重力补偿模型静止状态下末端就往下沉了好几毫米我一度以为是阻抗参数不对折腾了半天才发现是重力的事。完整的Simulink模型大概是轨迹规划模块输出期望轨迹和机器人实际反馈的位置做差分进阻抗控制模块算出修正力同时力传感器测出来的F_ext也进阻抗控制模块修正力经雅可比映射成关节力矩叠加重力补偿后再发给Simscape中的关节执行器。整体信号流非常干净每一级都能单独用Scope盯数据。4. 仿真调试、常见问题与扩展玩法4.1 求解器选择与步长设置对数值稳定性的影响Simulink/Simscape仿真跑起来最让人崩溃的问题就是“发散”——上一秒还好好的下一秒仿真直接变NaN。我在这个项目里确认过绝大多数发散问题都出在求解器设置上。Simscape Multibody是物理域模型本质上是一堆微分代数方程关节约束、接触力都有很强的刚性。默认的变步长ode45跑了不到两秒就报错原因是ode45不适合刚性问题步长会被自动压到10^-6量级仿真慢得像PPT。后来我换成ode15s也就是可变阶刚性求解器情况才好转。Simscape官方其实推荐用ode15s或ode23t我实测下来ode15s稳定性最好跑3秒仿真大约需要几十秒到一两分钟可以接受。步长的设置也有讲究。如果接触刚度很大接触力的作用时间极短需要把“最小步长”设得足够小否则接触力采样在时间上不均匀就会给控制环引入高频噪声。我遇到过接触的时候阻抗控制明明参数没问题但末端力一直在抖最后发现是接触力离散化太粗糙把最小步长调到1e-5之后抖动就消失了。另外Simulink里如果用到MATLAB Function模块里面如果有符号计算或者工具箱函数编译阶段会慢很多能在外部把雅可比矩阵算好存成变量就尽量别在Function里实时调仿真效率会翻倍。4.2 常见崩溃与振荡问题排查速查表我把这次调试中遇到的主要问题整理成了一张表供同样在Debug的朋友快速定位问题现象可能原因排查思路与解决办法模型运行几秒就报“Simulink cannot solve”求解器不适合或步长过小换成ode15s/ode23t适当放宽最小步长上限关节角度变成NaN或Inf雅可比矩阵奇异或力矩过大检查是否经过奇异点限制控制力矩上限末端力持续高频振荡接触刚度太大/采样步长太粗降低接触刚度调小最小仿真步长自由空间轨迹跟踪误差大缺失重力补偿在力矩输出端叠加基于关节角度的重力补偿阻抗参数相同但响应时快时慢末端等效惯量随位形变化引入自适应惯量调节或按位形切换阻抗参数接触瞬间机器人“弹开”阻尼过小、刚度突变增大阻尼B_d检查接触模型是否有穿透补偿仿真速度极慢模型太复杂或步长被约束简化接触模型或先用虚拟力替代真实接触模型表格之外我想重点说一条经验当控制环和机械结构放在同一个模型里的时候优先检查信号方向和数据单位。Simscape里角速度单位是rad/s力矩单位是N·m但Simulink里PID模块输出默认可能是无量纲的中间Gain少了某个比例系数控制量差了两三个数量级这种问题最隐蔽不是发散就是跟踪失败。我建议在每个信号线上标注单位仿真前先用Constant代替控制器输出做开环测试确认关节能按照预期方向转动再接闭环。4.3 热词延伸FMU导出、外部模式、代码生成在仿真验证里的用法项目做到后期我开始琢磨一个问题仿真模型最后怎么变成能在真机上跑的东西顺着这条路摸到了几个特别有用的功能跟最近搜到的几个热词都能对上。第一个是FMU导出。Simulink可以把整个模型导出成FMUFunctional Mock-up UnitFMU是功能样机接口标准它可以实现不同仿真工具之间的无缝集成相当于把模型“打包”成标准格式给其他软件比如Dymola、OpenModelica或者工业仿真平台去调用。我在做联合仿真协同验证时试过导FMU很顺畅模型里所有的输入输出接口会在导出配置里列出来你只需要选好哪些端口作为对外接口。这个功能特别适合做系统级联调比如机器人控制模型和产线虚拟调试平台对接。第二个是外部模式External Mode。Simulink的外部模式可以把模型编译之后跑在真实的嵌入式设备/xPC目标机上同时通过TCP/IP或串口和上位机实时通信相当于硬件在环的入门玩法。虽然这次我没真正接到真机控制器上但在仿真阶段提前把模型按外部模式的要求梳理了一遍输入输出后面真机部署的坑就会少很多。第三个是C代码生成和静态代码检查。用Simulink Coder生成C代码之后可以做静态代码检查检查代码中有没有未定义行为、死代码、数据越界之类的问题。做嵌入式控制器开发的朋友应该很熟悉过程大致是在Simulink模型里配置好代码生成选项生成的代码丢到静态检查工具里跑一遍。仿真和代码生成之间的鸿沟其实非常大仿真里浮点随便算嵌入式环境下很多要改成定点或者做溢出保护所以模型设计的早期就要考虑代码生成的可行性变量类型尽量提前设置成目标平台的类型函数尽量用代码生成支持的模块。另一个热词是“Carsim与Simulink联合仿真”我虽然没有直接做车辆底盘的仿真但方法论上是相通的Carsim负责车辆动力学Simulink负责控制策略两者之间通过标准接口交换数据。这和我们做机器人Simscape与控制律拆分是一个思路先把物理域交给专业工具再把控制域留在Simulink跨领域协同就是当前工业仿真最实用的范式。5. 最后的扩展想法与个人体会经过这一轮蹲坑我最大的感受是阻抗控制调试的本质是找到一个机器人和环境之间的“默契值”。参数整定没有一个放之四海而皆准的数值必须结合任务需求、机械刚度和接触环境来整体权衡。顺序很重要一定是先单轴再整机、先自由空间再接触空间、先虚拟力再真实接触模型。别想着一步到位仿真平台解决的就是“低成本试错”的问题多跑几组参数对比曲线比在真机上拆一次手臂划算得多。后面我还打算做两个方向的扩展一个是把阻抗控制和力/位混合控制放在同一个框架下做对比另一个是把摩擦辨识加进去看看能在多大程度上提高接触力跟踪的精度。仿真模型搭到这个程度剩下的事情就是持续去丰富物理细节了。希望这篇笔记能帮你少走几步弯路尤其是那些被Simscape接触模型折腾到怀疑人生的朋友相信我调好步长和接触参数之后一切都会顺畅起来。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →