3. UR机器人编程与节拍关系

在UR机器人的节拍优化中,程序本身往往比硬件参数更容易被忽视。同一台UR5e、同一段轨迹,换一种指令类型或程序结构,单循环时间可能相差30%以上。理解URScript、Polyscope程序结构与运动指令对节拍的影响,是把节拍从“能跑”压到“跑得快且稳”的核心能力。

一、Polyscope程序结构与节拍的关系

Polyscope程序由主程序(Main Program)和若干子程序(SubProgram)组成,结构上分为“主序列”和“子序列”。主序列负责流程调度,子序列封装具体动作。节拍影响主要体现在三处:

  • 程序扫描与解释开销:Polyscope是解释执行,每个节点都有解析时间。主序列中节点越多,循环周期内非运动时间越长。经验上,一个空节点约0.5~2 ms,100个节点的程序每循环可能多出50~200 ms。
  • 子程序调用层级:每层调用增加栈操作与上下文切换。建议子程序层级不超过3层,高频循环内的动作尽量内联。
  • 线程与事件:Polyscope支持多线程(Thread)和事件(Event)。把等待IO、等待信号放在独立线程,可避免主序列阻塞,但线程切换本身有开销,不宜滥用。

实际优化中,常见做法是把“取件—移动—放件”这类固定动作封装为子程序,主序列只保留流程判断和调用。这样既减少主序列节点数,又便于复用和调试。

二、URScript对节拍的底层影响

URScript是UR的脚本语言,Polyscope的每个节点最终都会翻译成URScript执行。直接写URScript可以绕过部分图形化节点的解释开销,但更重要的是它能精确控制运动参数和时序。

# 示例:URScript中设置运动参数
set_speed(0.8)          # 全局速度比例
set_acceleration(1.2)   # 全局加速度比例
movel(p[0.3,0.2,0.4,0,3.14,0], a=1.2, v=0.8, t=0, r=0)

关键点:set_speed和set_acceleration是全局比例,会影响后续所有运动指令。若在循环内频繁修改,会增加解释开销。建议在程序初始化时设定,循环内不再改动。

URScript中sleep()、wait()、sync()等时序函数对节拍影响极大。sleep(0.1)意味着每循环固定增加100 ms,若循环时间目标为2 s,这100 ms就是5%的节拍损失。能用信号同步替代固定等待的,尽量用wait_digital_input()。

三、MoveJ、MoveL、MoveP的节拍特性对比

三种运动指令的底层规划方式不同,节拍表现差异明显:

指令运动方式节拍特点适用场景
MoveJ关节空间插补最快,路径不可控大范围转移、无路径要求
MoveL笛卡尔直线插补较慢,路径精确直线焊接、涂胶、插入
MoveP笛卡尔过程运动可恒速,适合连续轨迹圆弧、连续曲线、打磨

MoveJ在关节空间做插补,各关节同时以最大能力运动,通常比MoveL快20%~40%。但MoveJ的末端路径是曲线,可能碰撞。因此“能MoveJ就MoveJ”是节拍优化的第一原则。

MoveL在笛卡尔空间做直线插补,需要不断做逆解,且受奇异点、关节限速影响,速度往往被压低。若直线段较长,可在中间插入MoveJ过渡点,形成“MoveJ—MoveL—MoveJ”组合,既保证关键段精度,又提升整体节拍。

MoveP是过程运动,允许在路径上保持恒定速度,适合连续轨迹。它的节拍优势在于“不停顿”:MoveL在拐角处通常要减速到接近零再转向,而MoveP可以以设定速度平滑通过。对于由多段小直线组成的曲线,MoveP的节拍可提升30%以上。

UR运动指令节拍特性与路径对比 MoveJ 关节空间 曲线路径 · 最快 路径不可控 节拍基准 100% 起点 终点 MoveL 笛卡尔直线 直线路径 · 精确 拐角需减速 节拍约 120%~140% 起点 终点 MoveP 过程运动 平滑曲线 · 恒速 拐角不停顿 节拍约 90%~110% 起点 终点 同一轨迹不同指令组合的节拍对比(示例) MoveJ + MoveL + MoveJ 2.4 s 全 MoveL 3.0 s MoveP 连续轨迹 2.1 s 注:以上为示例数据,实际节拍需根据负载、速度、加速度和路径实测

四、程序结构优化对节拍的实操影响

把上述知识落到实际程序,可以从四个层面入手:

  1. 指令选型:先判断路径是否必须精确。非精确段全部用MoveJ;精确段用MoveL;连续曲线用MoveP。一个典型取放循环,若把“回安全点”从MoveL改为MoveJ,单循环可省0.3~0.6 s。
  2. 速度与加速度设置:UR的set_speed和set_acceleration是全局比例。建议在程序开头设为0.8~1.0,循环内不再改动。若某段需要慢速,用指令级参数v=和a=单独指定,避免全局修改带来的解释开销。
  3. 减少等待:把固定sleep改为信号等待。例如等待夹爪到位,用wait_digital_input(1, True)替代sleep(0.5),既准确又省时。
  4. 合并小段:多个短MoveL可合并为MoveP,或插入过渡点用MoveJ连接。每减少一个运动指令节点,就减少一次规划与解释开销。
实操建议:用Polyscope的“程序时间”显示功能,逐段测量每个运动指令的实际耗时。优先优化耗时最长的3个节点,通常能获得80%的节拍收益。

五、一个可参考的节拍优化检查表

检查项判断标准优化动作
非精确路径是否用MoveJ路径无碰撞要求改为MoveJ
连续小直线段段数≥3且方向渐变改用MoveP
固定sleep等待时间≥0.1 s改为信号等待
全局速度修改循环内出现set_speed移到程序开头
子程序层级层级>3层内联高频动作
主序列节点数节点数>80封装为子程序

需要强调的是,节拍优化不是单纯追求最快,而是在满足路径精度、安全性和稳定性的前提下压缩循环时间。MoveJ虽快,但若导致碰撞或奇异点,反而会因停机、重试而拖慢整体节拍。因此,每次修改后都应在低速下验证路径,再逐步提速。