ARTICLE DETAIL

资讯详情

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

机械臂零力拖动示教从入门到实战:六维力传感器与导纳控制完整指南

机械臂零力拖动示教从入门到实战:六维力传感器与导纳控制完整指南 机械臂装上六维力传感器满怀期待地准备做零力拖动示教结果一松手机械臂直接砸下去或者轻轻一推就疯狂震荡这种情况我见过太多次了。很多刚接触这个方向的朋友以为零力拖动就是读力、发指令这么简单真正上手才发现处处是坑。这篇文章从六维力传感器的选型标定、导纳控制的核心逻辑、代码落地到调参流程把整个链路完整梳理一遍希望能帮你少走弯路。1. 零力拖动为什么处处是坑从重力、摩擦到惯量先把问题定义清楚。零力拖动示教的本质是让操作者握住机械臂末端以很小的力就能把机械臂拉到任意期望位置同时机械臂要表现出顺从的柔顺特性一松手就稳稳停住不漂移、不反弹。市面上很多协作机械臂自带拖动示教功能但对于自研机械臂、实验室平台或者改装的老旧设备自己实现一套基于六维力传感器的导纳控制依然是主流方案。1.1 一个反直觉的结论零力拖动不是把力控到零很多人第一次做这个项目时会陷入一个误区以为零力拖动就是让机械臂控制器把外力抵消掉让力传感器读数趋近于零。听起来很合理但实际做起来会发现两个致命的逻辑问题。第一个问题是机械臂本身的物理属性决定了它不可能凭空消失。一台几十公斤的机械臂在重力、关节摩擦和惯性共同作用下你想要让末端悬停在某个位置关节电机本来就需要输出很大的力矩来维持。当你试图把这个维持力矩抵消到零机械臂会直接因为重力作用崩下去这是物理定律决定的不是控制器的问题。第二个问题是力传感器的读数里包含的不仅是操作者施加的力还包含机械臂自身结构产生的惯性力和重力分量。当机械臂运动时连杆的加速度会反映到传感器读数上形成一个虚假外力。如果控制器把这个虚假外力也当成操作者意图去响应系统就会陷入正反馈震荡——越动越晃越晃越大力。理解这个问题零力拖动的本质就很清楚了它不是力的闭环而是位置的柔顺整形。我们要做的不是让力为零而是让「操作者施加的力」经过一个虚拟质量-弹簧-阻尼系统的整形映射成末端的期望位移或速度再交给机械臂的位置/速度控制器去执行。1.2 机械臂本体的干扰源重力补偿是第一道门槛在所有干扰源里重力是最大的敌人。一台常见的六轴协作机械臂负载加上末端执行器可能有几公斤重在某个姿态下重力在传感器上产生的力分量可能高达几十牛顿。相比之下操作者拖动时施加的力通常只有几牛顿。如果重力补偿做不好你施加的拖动力完全被淹没在重力分量里机械臂根本不会按你的意图运动。重力补偿的关键不只是算一个简单的mg而是要对机械臂各连杆和负载的质心位置做准确建模。因为机械臂姿态变化时每一根连杆的重力在传感器坐标系下的投影都在变这个变化是非线性的。以六维力传感器安装在腕部为例重力补偿的数学模型大致是f_sensor f_operator f_load_gravity τ_sensor τ_operator p_com × f_load_gravity其中f_load_gravity是末端负载包括法兰、工具、被抓物体的重力在传感器坐标系下的矢量p_com是负载质心在传感器坐标系下的位置。实际工程中f_load_gravity可以通过机械臂当前姿态矩阵和负载的质量、质心参数实时计算出来。很多初学者的做法是拿一个水平仪把机械臂调到某个固定姿态然后测一组力数据做零点这种做法只对固定姿态有效机械臂一换姿态补偿就失效了。正确做法是建立负载的质量和质心参数辨识流程在机械臂运动到多个不同姿态时记录力和力矩数据用最小二乘法拟合出负载质量和质心位置。这个过程很像给机械臂做一次称重体检。1.3 摩擦力和惯量的影响为什么拖起来总有顿挫感重力补偿做好之后第二道坎是摩擦力。机械臂关节里的减速器、轴承、密封圈都会产生摩擦力这个力方向总是与运动方向相反。低速拖动时静摩擦和库仑摩擦占了主导你会明显感觉到一种黏滞感——推一下动一下一停就卡住。摩擦力很难通过力传感器前馈完全补偿因为摩擦模型本身就不精确而且温度、润滑状态都会影响摩擦系数。比较务实的做法是在导纳控制器里加入一个适当的速度阻尼项配合很小的加速度前馈让机械臂在低速段表现得丝滑一些。另外机械臂运动时各连杆的惯性耦合也会让末端表现出沉重感这需要对机械臂的惯量矩阵做补偿但在零力拖动场景下导纳控制器的虚拟惯量选择得当可以在一定程度上掩盖真实惯量的影响。2. 六维力传感器的选型、标定与读数的脏数据问题导纳控制的效果上限很大程度上取决于六维力传感器数据的质量。这里说的质量不只是精度更重要的是信噪比、更新率和噪声水平。传感器数据不给力后端的导纳控制器再花哨也白搭。2.1 选型时容易被忽略的三个参数六维力传感器的核心参数不同厂家宣传的侧重点不太一样但实际落地时我优先关注这三个量程和过载保护量程不能只看额定负载要看冲击载荷。拖动示教过程中操作者可能会突然用力或者不小心磕碰传感器的瞬间受力可能是正常工况的几倍。选购时至少要留出1.5到2倍的过载余量而且要确认传感器本身有机械限位保护否则一次意外就能让几万块的传感器报废。串扰和精度等级六维力传感器内部是应变片桥路理想情况下六个通道相互独立实际会有串扰。便宜的传感器串扰可能达到2%到5%满量程高端产品能做到0.1%以下。导纳控制对力的准确性要求不像精密测量那么苛刻串扰在1%以内一般够用不必盲目追求实验室级别的高精度。采样率和实时性力控系统至少要100Hz以上的控制频率才能跟手如果传感器采样率只有几十赫兹控制环路延时会非常明显。现在的以太网或CAN接口传感器普遍能到500Hz到1000Hz基本够用。需要注意的是传感器驱动要有稳定的实时通信保障否则数据掉包会直接导致控制抖动。2.2 标定不只是去皮还要处理偏心载荷六维力传感器的标定包含两个层面一个是由传感器厂家完成的出厂标定建立了应变信号到六维力/力矩的映射关系另一个是你自己需要做的负载标定也就是把法兰、末端工具等附加结构的重力特性标定出来。实际调试中很多人只做了去皮——在某个姿态下把传感器读数清零然后就直接开始调导纳控制。这样做在机械臂位置固定时勉强能用一旦机械臂改变姿态重力在传感器坐标系的投影方向变了零点就飘了。正确的负载标定流程是这样的机械臂处于水平零位记录传感器读数作为初始基准让机械臂依次运动到至少5到10个不同的姿态每个姿态停留记录力传感器读数和对应的机械臂末端齐次变换矩阵利用最小二乘法求解负载质量和质心位置参数目标是让所有姿态下补偿后的残差最小验证标定结果——让机械臂走几个标定时没用过的姿态检查补偿后传感器读数是否接近零。标定之后还涉及一个动态补偿的问题。末端负载在快速加减速时传感器会读数惯性力虽然导纳控制器本身对这部分有一定的容忍度但如果加速过猛惯性力造成的假拖动方向会让人感觉怪怪的。工程上的折中方案是控制末端拖动的期望加速度上限让机械臂的响应尽量平滑。2.3 滤波处理如何平衡平滑和灵敏六维力传感器的原始数据噪声一般都不小尤其是在电磁环境复杂的车间里读数上叠加的噪声可能有正负0.5N甚至更多。导纳控制本质上是一个积分过程噪声会导致末端位置持续漂移所以滤波是必须的。常用的滤波手段有三种滑动窗口均值滤波、低通滤波一阶RC或二阶巴特沃斯、以及基于模型的状态估计。我个人的经验是滑动窗口均值滤波最简单但会引入与窗口长度成正比的时间延迟一阶低通滤波参数好调但相位滞后会影响跟手感二阶巴特沃斯滤波在平坦度和截止特性上更均衡适合做中等性能的系统。滤波截止频率的选择很考验经验。截止频率设得太低噪声是被滤掉了但操作者给的力信号也被延迟拖动感觉像隔着手套摸东西设得太高噪声穿透到控制环机械臂末端会高频微抖。对于典型的协作机械臂拖动示教场景2到10Hz的低通截止频率是一个合理区间具体数值要根据机械臂的刚度和重量来调。另外滤波一定要放在重力补偿之后否则补偿量的高频抖动会被滤波器放大到位置指令里。3. 导纳控制的核心逻辑它不是力闭环而是受力—位移整形器导纳控制被讨论的频率很高但真正理解它的人其实不多。从控制理论的角度看导纳控制的本质是定义了外力和期望运动之间的动态关系——把机械臂末端等效成一个由质量、阻尼、弹簧组成的虚拟二阶系统。操作者施加的力是输入末端位移修正是输出。3.1 质量问题为什么导纳模型里有虚拟质量导纳控制的标准方程是Md × (d²x_e/dt²) Dd × (dx_e/dt) Kd × x_e F_ext其中x_e是末端期望位移修正量F_ext是操作者施加的外力Md、Dd、Kd分别是虚拟质量、虚拟阻尼和虚拟刚度。这个方程描述的关系是外力作用在虚拟系统上产生了多少位移修正。虚拟质量Md的作用是抑制高频力的影响。如果Md取得太小操作者施加一个冲击力时加速度修正量会瞬间变得非常大机械臂末端会猛冲一下非常危险。如果Md取得太大机械臂反应又会变得迟钝拖起来感觉笨重。严格来说Md应该尽可能匹配机械臂末端的真实等效惯量这样外力做功的效率最高拖动最自然。实际工程里常见做法是先测一次机械臂末端的等效质量然后以这个值为基础上下调整。3.2 为什么刚度不能设为零零力拖动不是零刚度虚拟刚度Kd是导纳控制器里最微妙的一个参数。从直觉上看零力拖动应该把Kd设成0让外力完全决定位置不受任何弹簧回拉效果的影响。但仔细想就会发现一旦Kd0系统的稳态特性就变成了只要有外力就持续产生位移外力消失时位移停在当前位置。这听起来似乎正是我们想要的但在工程上根本做不到。首先绝对零刚度意味着系统没有位置恢复性任何微小的偏置力比如重力补偿残差、传感器零漂都会让末端持续漂移根本稳稳不住。更关键的是Kd0时系统变成一个纯积分结构外力的微小波动会被不断积分放大末端位置会出现肉眼可见的低频晃动。所以实际导纳控制里Kd设的是一个很小的非零值它的作用不是回拉而是给位置修正量提供一个微弱的锚定。在稳定状态下位置修正量满足x_e F_ext / Kd对于小阻尼、低刚度配置这个修正量对于几牛顿的外力来说只有几毫米操作者几乎感知不到不会觉得有弹簧拉着。但正是这微小的刚度让系统拥有了抵抗漂移的能力。3.3 阻尼比的物理意义从发抖到跟手的密钥虚拟阻尼Dd决定了系统的能量耗散快慢它的选取比前两个参数更需要手感调试。用控制理论的话说导纳控制器的特征方程为s² (Dd/Md)s (Kd/Md) 0阻尼比ζ Dd / (2√(Md×Kd))是一个无量纲参数它直接决定了机械臂对外力的响应模式。ζ 远小于1系统欠阻尼操作者给一个阶跃力末端会围绕目标位置来回振荡好几次拖动的感觉就是机械臂在发抖非常廉价。ζ 约等于1临界阻尼末端快速平滑地到达目标位置不回弹、不振荡这是拖动示教最理想的状态。ζ 远大于1过阻尼末端运动变得缓慢拖不动的感觉明显操作者需要用更大的力气才能推动。调参的一个实用技巧是先把Kd固定在一个较小的值根据期望的拖动响应速度推算Md然后按照Dd 2ζ√(Md×Kd)计算Dd的初值ζ从1.0往上调。我实测下来ζ取1到1.5之间时机械臂的柔顺感和启停响应最接近人手对顺滑的直觉感知。4. 代码落地从力读数到末端期望位移的完整链路理论讲了一堆最终要落到代码里。我以ROS环境 C为主讲一下完整链路因为这是机器人领域最常用的组合。控制框架上机械臂底层最好是位置控制模式频率越高越好力控频率建议至少500Hz以上1kHz会舒服很多。4.1 控制框架的选型为什么建议用位置接口做力控有些机械臂支持力矩接口比如直接给关节力矩指令但大多数商用机械臂的力矩接口要么带宽不够要么有保护机制限制直接用起来很别扭。位置接口反而是最通用、最稳定的方式——你给控制器发一个末端位姿或关节位置的增量指令底层伺服自己去处理动力学问题。用位置接口做力控的核心思路是把导纳控制器的输出当作位置的修正量叠加到当前的期望位置上形成新的期望位置指令。位置控制器的跟踪带宽如果是几十赫兹导纳控制器的带宽就不能超过这个范围否则会发生指令追不上的情况。这也是为什么前文强调滤波截止频率不能太高的原因——整个控制链路的带宽是层层受限的。4.2 力信号处理和控制器的核心代码下面是一段典型的零力拖动控制主循环伪代码实际工程里还要加通信超时保护、安全监视等逻辑// 控制主循环频率1kHz void controlLoop() { // 1. 读取六维力传感器数据 Force6D f_raw ft_sensor.read(); // 2. 重力补偿利用当前机械臂末端位姿计算负载重力分量 Eigen::Matrix4d T_base_tool robot.getToolPose(); Force6D f_compensated f_raw - computeGravityCompensation(T_base_tool); // 3. 滤波低通滤波器截止频率5Hz Force6D f_filtered lowpassFilter(f_compensated, cutoff_freq); // 4. 静区处理小于阈值(如1.5N)的力视为0防止零漂和噪声导致漂移 if (f_filtered.force.norm() DEADZONE_FORCE) { f_filtered.setZero(); } // 5. 导纳控制律受力 - 期望位移增量 static double dt 0.001; static Eigen::Vector3d vel Eigen::Vector3d::Zero(); static Eigen::Vector3d pos_offset Eigen::Vector3d::Zero(); Eigen::Vector3d acc (f_filtered.force - Dd * vel - Kd * pos_offset) / Md; vel acc * dt; pos_offset vel * dt; // 6. 限制修正速度防止冲击 clamp(vel, MAX_TRANSLATION_VEL); clamp(pos_offset, MAX_DRAG_RANGE); // 7. 计算期望末端位姿并发送给机械臂 Eigen::Matrix4d T_target T_base_tool; T_target.translation() pos_offset; robot.setToolPose(T_target); }这段代码在力和位移的映射上只展示了平移部分完整实现还要处理旋转。旋转方向的导纳控制和平移方向本质相同但力的映射变成了力矩到位姿增量的转换通常使用旋转向量axis-angle来表达避免欧拉角的万向锁问题。姿态部分的虚拟惯性、虚拟阻尼参数一般和平移部分独立调节因为末端对于旋转方向的手感往往比平移动更敏感。4.3 静区、限幅和安全监控看不见但保命的细节代码里的静区处理非常关键但它常常被初学者忽略。传感器的零漂和噪声会让经过滤波的力信号也存在零点附近的微小波动如果没有静区机械臂会在静止状态下慢慢溜走——有时候是每分钟几毫米看起来不明显但会给拖动手感带来一种没停稳的印象。静区阈值取1到2N比较合适低于这个值的读数一律置零。代价是操作者需要用大于静区阈值的力才能让机械臂动起来这在实际使用中几乎感知不到。限幅是对导纳控制器输出做速度限制和位移限制。速度限制防止操作者用力过猛导致机械臂高速撞击位移限制本质上是一个工作空间限制防止机械臂被拉到奇异点或者超出关节行程。我在实际项目中至少会设置三层安全保护软件限幅、控制器缓冲区的紧急停止指令、以及急停硬件回路。任何一层触发系统都要立即停止。4.4 基于ROS的模块划分如果项目基于ROS我建议把整个系统拆成三个独立节点ft_sensor_node负责读传感器、做重力补偿、发布滤波后的力/力矩数据。这个节点只做数据处理不参与控制决策保证传感器的采集频率稳定。admittance_control_node订阅处理后数据运行导纳控制律输出末端期望位姿增量。核心控制逻辑全在这个节点里方便单独调试参数。robot_driver_node与机械臂底层通信执行期望位姿指令同时反馈当前位姿状态。模块化的好处是调导纳参数的时候不用反复编译整套代码用动态调参工具实时修改Md、Dd、Kd效率高很多。我自己常用的流程是拉起三个终端一个跑传感器节点一个跑控制节点另一个开可视化工具观察末端位姿轨迹和力曲线一边看曲线一边调参数。5. 调参流程如何从发抖调到跟手以及示教轨迹的记录与回放参数调到什么程度算好主观标准是跟手——你想让机械臂往哪走它就往哪走速度适中没有反弹和延迟松开手它稳稳停在当前位置。客观标准可以用阶跃响应来看给一个恒定的拖动力观察末端位移曲线应该平滑上升并稳定没有超调和振荡。5.1 一套可复现的调参顺序调参的顺序和策略比我刚做这个项目时想象得更重要。我总结了一套从平庸调到顺手的固定顺序先把基础控制频率跑稳。确认力传感器、控制节点、机械臂驱动的通信都在1kHz左右稳定运行没有周期抖动。调大虚拟质量到真实惯量水平。可以先不滤波或者滤波很浅用手推机械臂感受起步是否自然。从高刚度、高阻尼的僵硬状态开始。把Kd设到相对较大的值Dd也设大一些确认机械臂不会自己飘然后逐步降低Kd。降低刚度到柔顺但有韧性的状态。这个阶段操作者应该感觉要用力才能拖得动但拖起来很稳此时加入力传感器滤波把截止频率从10Hz往下调。最后调阻尼。固定Kd和Md逐步降低Dd观察末端是否出现抖动如果出现持续振荡马上升高Dd找到临界不抖的位置再往回留20%到30%的余量。拉力的维度也可以参考但最终要以实际手感为准。控制理论和手感出现冲突时信手感。5.2 调参中常见的异常现象和根因整理几个高频问题的排查思路很多都是实战中踩过的坑表现可能原因排查方向末端持续低频漂移重力补偿残差偏大或力传感器存在热漂移重新做负载标定检查传感器温升推一下末端来回振荡阻尼比太小系统欠阻尼增加Dd或适当减小Md拖起来一顿一顿滤波延迟太大或控制频率不足提高控制频率降低滤波滞后轻推不动用力突然猛冲静区阈值过大或摩擦补偿过大减小静区阈值重新评估摩擦补偿松手后末端回弹一段距离虚拟刚度偏大手出于回中趋势降低Kd同时补充一个停止状态触发的阻尼项松手回弹问题值得单独说一句。导纳控制器在恒力作用下会有稳态位置修正量x_e F_ext/Kd当操作者突然松手外力消失位置会以指数形式回到原始参考点这就是回弹的来源。要消除回弹常用的做法是记录手离开瞬间的末端位姿把这个位姿更新为导纳控制器的新的参考点。换句话说每次松手都清零参考点下次再拖就以当前位置为基准。5.3 从拖得动到示教产线可用录制、回放与轨迹平滑零力拖动的最终目的是示教也就是说操作者拖出来的轨迹要被系统记录下来然后机械臂可以自动复现。这个环节看起来只是加一个路径录制功能实际工程里还要处理不少细节。轨迹录制的核心是时间同步。力传感器数据、机械臂位姿数据和控制器指令各自有不同的时间戳回放时必须要用统一的时间轴对齐否则轨迹会发生错位。录制时我会同时记录末端位置和姿态姿态用四元数存储避免欧拉角的表示奇异。录制频率不需要跟控制频率一样高能到100Hz到200Hz就够了因为回放前还会做轨迹压缩和插值。回放阶段有两个常见问题。一是回放速度不均匀——因为操作者拖动时速度有快有慢如果直接按采集时间戳回放机械臂运动会像卡带一样忽快忽慢。我的做法是录制时对轨迹做等时间间隔重采样回放时再进行轨迹平滑具体可以用样条插值或者简单的低通滤波。二是回放轨迹必须经过机械臂逆运动学的校验确保所有路径点在关节空间和笛卡尔空间都可达不会碰到奇异点。这些工作在Gazebo仿真环境里可以提前验证——把实际录制的轨迹放到仿真的机械臂模型上跑一遍发现问题改参数比在实物上反复试错安全得多。6. 写在最后零力拖动的魂不在算法在工程细节这套方案做下来最深刻的体会是零力拖动本身的技术难度并不算高导纳控制的方法在五十年前就被提出并研究透了但把它做成一个让操作者觉得自然顺手的工程系统需要对每个细节都足够较真——重力补偿的残差、传感器的噪声、滤波器引入的延迟、控制频率的稳定性、安全保护的回退逻辑每一项都能单独毁掉整个手感。如果让我给正准备做这个方向的朋友一个建议那就是不要一上来就追求复杂的算法。先把重力补偿做到位让机械臂在任何姿态下悬停都不漂再谈力反馈的跟手性。基础不牢导纳参数再精细也只是在劣质地基上盖楼。另外有条件一定先在仿真环境里把整套逻辑跑通再上实物这能省下大量的调试时间。个人实际测试中还有一个提升监控效率的做法把力传感器原始信号、滤波后信号和导纳控制器输出信号同时录下来拖动的时候回放这几条曲线可以非常直观地看出信号链路里每一级带来的延迟和畸变。参数问题是出在传感器端、滤波端还是控制端一眼就能定位比盲调参数效率高得多。
返回列表