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%以上。
四、程序结构优化对节拍的实操影响
把上述知识落到实际程序,可以从四个层面入手:
- 指令选型:先判断路径是否必须精确。非精确段全部用MoveJ;精确段用MoveL;连续曲线用MoveP。一个典型取放循环,若把“回安全点”从MoveL改为MoveJ,单循环可省0.3~0.6 s。
- 速度与加速度设置:UR的
set_speed和set_acceleration是全局比例。建议在程序开头设为0.8~1.0,循环内不再改动。若某段需要慢速,用指令级参数v=和a=单独指定,避免全局修改带来的解释开销。 - 减少等待:把固定
sleep改为信号等待。例如等待夹爪到位,用wait_digital_input(1, True)替代sleep(0.5),既准确又省时。 - 合并小段:多个短MoveL可合并为MoveP,或插入过渡点用MoveJ连接。每减少一个运动指令节点,就减少一次规划与解释开销。
五、一个可参考的节拍优化检查表
| 检查项 | 判断标准 | 优化动作 |
|---|---|---|
| 非精确路径是否用MoveJ | 路径无碰撞要求 | 改为MoveJ |
| 连续小直线段 | 段数≥3且方向渐变 | 改用MoveP |
| 固定sleep | 等待时间≥0.1 s | 改为信号等待 |
| 全局速度修改 | 循环内出现set_speed | 移到程序开头 |
| 子程序层级 | 层级>3层 | 内联高频动作 |
| 主序列节点数 | 节点数>80 | 封装为子程序 |
需要强调的是,节拍优化不是单纯追求最快,而是在满足路径精度、安全性和稳定性的前提下压缩循环时间。MoveJ虽快,但若导致碰撞或奇异点,反而会因停机、重试而拖慢整体节拍。因此,每次修改后都应在低速下验证路径,再逐步提速。