简介:面向FANUC工业机器人操作与编程人员的一份技术文档,系统讲解码垛堆积功能中的示教编程环节,从指令选择(B、BX、E、EX)到初期资料设定、堆上式样示教均有详细说明,适用于正在学习或优化码垛程序、需要理解码垛寄存器与排列方法的工程现场人员。包体为单份docx文件,大小仅1.34MB,便于下载后在离线环境随时查阅;内容围绕实际示教操作展开,重点覆盖堆上/堆下选择、增加数设定、码垛寄存器号码、行列层排列方式、辅助点及姿势控制等参数,并提示中断会导致已设定资料重置等功能键使用注意事项。文档还结合操作界面,对无辅助点/有辅助点下的顶点示教、直线/自由/间隔三种排列方法及层式样数设定进行了梳理,能帮助读者建立完整的码垛示教逻辑。已有984人学习下载,适合需要快速掌握FANUC码垛堆积示教编程要点的机器人工程师、集成商与院校师生。
1. 码垛堆积不是把点示教一遍:FANUC 选项与 TP 的边界
FANUC 机器人的码垛堆积功能,表面上是“Palletizing”,但真正在产线上长时间跑得稳的,往往是示教器上那几行 TP 循环程序。原因很简单:码垛不是把托盘上几百个位置点挨个示教一遍,而是让同一个基准点加上行、列、层偏移后的结果。每次换品种都要重示教点位的话,节拍和停机时间都扛不住;正确做法是把“堆成什么样”抽象成行数、列数、层数和间距,用寄存器和位置寄存器驱动程序去计算目标位置。这就是标题里“示教编程”要解决的事:用示教器完成少数基准点示教,剩下的位置交给参数和循环算出来。适合谁?适合手里有一台 R-30iB 或 R-30iB Plus 控制器,要做集成项目又要给现场留调整余地的电气工程师和机器人调试工程师。需要说明的是,FANUC 系统选项里有 Palletizing 支持,但许多现场并不直接依赖系统宏,而是用 TP 自写循环处理;下文给的是我在项目里常用的不依赖额外选项的写法。
2. FANUC 码垛堆积建模:用 R 寄存器和位置寄存器定义堆位
2.1 先分清“码垛选项”和“码垛程序”
FANUC 的码垛堆积功能在系统选项中表现为一组 Palletizing 支持。装了这个选项后,示教器上会多出码垛设置界面,可以在里面填行列数、层高、花纹,然后由系统生成点位数据。这个选项适合品种固定、容错要求高的产线;但它的示教数据往往存在系统内部,现场想临时改间距或者加一层,不如直接改寄存器来得快。我一般会先看控制器选项,但不把宝全押在选项上。启动后按MENU - SYSTEM - VERSION查看系统版本和选项清单,能看到 Palletizing 相关字眼;看不到也不影响下面的实现。我们要做的是把码垛堆积当成三维数组来建模:行、列、层分别用寄存器和位置寄存器表示,后续改动只改数值,不重新示教。
| 数据对象 | 推荐寄存器 | 含义 | 典型初始值 |
|---|---|---|---|
| 当前件号 | R[1] | 已经放置到托盘上的工件数 | 0 |
| 每层件数 | R[2] | 行数乘列数,例如 2 行乘 3 列 | 6 |
| 当前层号 | R[3] | 从第 1 层开始计数 | 1 |
| 目标行 | R[4] | 程序计算得到 | 1 |
| 目标列 | R[5] | 程序计算得到 | 1 |
| 基准放置点 | PR[100] | 第 1 层第 1 行第 1 列位置 | 示教值 |
| X 方向间距 | PR[101] | 行方向工件中心距 | 0.0 |
| Y 方向间距 | PR[102] | 列方向工件中心距 | 0.0 |
| 层高 | PR[103] | 每一层的 Z 向升高量 | 0.0 |
这个表的价值在于:现场改垛型时,你不需要进程序,只需要翻到位置寄存器页,把PR[101,1]改成新间距,把R[2]改成新每层件数。PR[101,1]是位置寄存器 101 的 X 分量,PR[102,2]是 Y 分量,PR[103,3]是 Z 分量。FANUC 的位置寄存器分量访问就是PR[编号,轴序号],轴序 1 到 3 对应 XYZ,4 到 6 对应 WPR。码垛只用 XYZ 的情况最多,姿态全部由基准点决定。
2.2 行列层的换算:先算位置再算层
假设托盘每层放 6 件,排列为 2 行乘 3 列。第 13 件应该落在第 3 层第 1 行第 1 列。换算逻辑是:先用总件号算出层号和层内序号,再用层内序号算出行号和列号。公式如下:
R[1] = 13 R[2] = 6 R[3] = (R[1] - 1) DIV R[2] + 1 ! 层号 = 3 R[4] = (R[1] - 1) MOD R[2] + 1 ! 层内序号 = 1 R[5] = 3 ! 每行列数 R[6] = (R[4] - 1) DIV R[5] + 1 ! 行号 = 1 R[7] = (R[4] - 1) MOD R[5] + 1 ! 列号 = 1DIV是整除取商,MOD是取余数。你可能会遇到示教器报ILLEGAL INSTRUCTION,这是因为部分 FANUC TP 版本对DIV和MOD的支持受系统变量影响。遇到这种情况不要纠结,直接换成减法循环,或者用IF分支把每层的件号映射到行列。我一般会在项目启动时先写一小段块验证寄存器指令,再放进完整码垛程序里。算出行列后,目标位置就变成了:
PR[10,1] = PR[100,1] + (R[6] - 1) * PR[101,1] PR[10,2] = PR[100,2] + (R[7] - 1) * PR[102,2] PR[10,3] = PR[100,3] + (R[3] - 1) * PR[103,3]这是把基准点PR[100]的 XYZ 分别加上行偏移、列偏移和层高偏移,算出来的PR[10]就是当前工件要放的位置。注意这里只改了 XYZ,WPR 姿态完全继承基准点。如果现场要求每一层转 180 度,需要单独处理 WPR,而不是把姿态硬写在每个目标点里。
2.3 交错堆叠时不能只用一套间距
如果只是普通矩阵堆叠,上面一套间距就够了。交错堆叠或者砖墙式马赛克,第奇数层和第偶数层的 X 偏移不一样,这时候 R 寄存器要再加一个“层奇偶”判断。常见做法是把第二套偏移放在另一个位置寄存器里,比如PR[104],在算出层号后判断:
IF R[3] DIV 2 * 2 = R[3] THEN PR[10,1] = PR[100,1] + (R[6] - 1) * PR[101,1] + PR[104,1] ELSE PR[10,1] = PR[100,1] + (R[6] - 1) * PR[101,1] ENDIF这里的判断逻辑是:R[3] DIV 2 * 2如果等于R[3],说明层号能被 2 整除,是偶数层,就多加一个PR[104,1]的偏置。交错堆叠最容易出错的地方是:只改了偶数的 X 偏移,忘记 Y 方向也要交替,最后码出来像阶梯一样错位。所以我在做交错花纹时,习惯把每层的行、列、偏移写成一张参数表,在示教器上逐层检查,而不是只写满第一个循环就交付。
3. 码垛堆积示教编程的第一步:基准点与 UFrame 标定
3.1 示教基准点:姿态先别自由旋转
码垛的基准点就是第 1 层第 1 行第 1 列的放置位置。示教时很多人直接用手动模式把机器人调到大概位置,然后自由转一下姿态,觉得“差不多能放进去”就行。这样往往给后续埋雷。基准点的姿态不只是为了让工件放正,它还决定了整托盘所有点的姿态。如果基准点的 WPR 和托盘平面不平行,越往远处偏移,工件歪得越明显。
我示教基准点时会先把机器人的姿态调成“TCP 的 Z 轴垂直于托盘表面”,然后用单轴移动微调,最后用FINE定位示教。为什么要用FINE?因为码垛放置动作要求机器人完全到位后再松开工件,FINE让机器人停稳并且完成到位确认,避免因为CNT还在飞就被同步信号打断。基准点示教完成后,把该点写入P[100],同时在位置寄存器页确认PR[100]的 UF 和 UT 编号与当前激活的坐标系一致。
3.2 把 UFrame 建在托盘上,而不是用 World 坐标
码垛偏移的本质是在托盘坐标系里做 XY 移动。如果你用 World 坐标做偏移,托盘在现场只要偏 1 度,整个垛型就会从中心往外发散,越靠边越偏。正确做法是把 UFrame 建在托盘上。一般用三点法:先示教托盘角点作为原点,再示教 X 方向点,再示教 Y 方向点。UFrame 的 Z 向由前两个点自动计算,通常不需要额外设。
建好之后,你的基准点P[100]和偏移量PR[101]、PR[102]就全是 UFrame 坐标系下的值。这样现场如果叉车把托盘碰歪了,只需要重新标定 UFrame,程序一行都不用改。这也是 FANUC 码垛编程里最划算的一个动作。很多集成商为了省时间,直接用系统默认的 World 坐标系做偏移,调试时看着没问题,跑几小时后托盘位置固定不住,错位概率明显升高。
3.3 安全高度和过渡点:空跑时从 T1 开始
码垛程序不能只有一个放置点。取料点到码垛点之间必须有过渡点,防止机器人带着工件从托盘侧板或旁边工件上方扫过去。我会单独示教一个安全高度点P[90],Z 值高于托盘最高一层加工件高度的 50 毫米左右。每次放置前先到P[90],再垂直下降到目标点;放完后抬升回P[90],再回取料点。
现场初次跑程序,一定要把控制器切到T1,速度倍率调到 10%,然后单步执行。重点看三件事:第一,从过渡点下降到目标位置的过程中,会不会碰旁边已经放好的工件;第二,夹具张开时会不会和相邻工件干涉;第三,抬升时有没有撞上下层。这些如果直接开自动跑,轻则托盘翻了,重则手腕撞碎。切到 T1 不是怕程序写错,是怕工艺上有些干涉只有在真实轨迹上才能看出来。
4. 用 TP 循环和 OFFSET 指令写一个可运行的码垛程序
4.1 OFFSET 指令是码垛循环的基底
FANUC 的 TP 程序里有一个很实用的功能:OFFSET。它的作用是让后面紧接着的运动指令在执行时,在示教点的坐标基础上叠加一个位置寄存器的偏移值。这个机制非常适合码垛:你只示教一个P[100]基准点,程序里每次往PR[10]里写不同的偏移,然后执行L P[100],机器人实际到达的位置就是P[100] + PR[10]。
写法如下:
1: OFFSET PR[10] 2: L P[100] 500mm/sec FINE 3: OFFSET第一行是打开偏移,第三行是关闭偏移。中间运动指令的目标点P[100]永远不变,变的只是PR[10]里存的偏移量。这样比直接示教几十个位置点干净得多,而且现场改垛型时只需要改寄存器的值,不需要重新示教。使用OFFSET时要注意,它默认偏移的是 XYZ,WPR 要不要偏移取决于系统设置。如果你只想要位置偏移而不想改变姿态,保持基准点姿态不变即可;如果某些码垛工艺要求每层旋转 180 度,那需要在PR[10]的第四到第六元素里写入对应姿态,并确认OFFSET配置允许姿态偏移。
4.2 完整的码垛放置循环程序
下面是一个最小可执行的 TP 程序骨架。假设CALL PICK是已经写好的取料子程序,取料完成后机器人回到安全点;R[1]存当前件号,R[2]存每层件数,R[12]存总件数,R[8]存每行列数,PR[100]是基准点,PR[101]、PR[102]、PR[103]分别是行距、列距、层高。
1: ! 码垛主循环 2: LBL[1] 3: CALL PICK 4: R[1] = R[1] + 1 5: ! 算层号和层内序号 6: R[3] = (R[1] - 1) DIV R[2] + 1 7: R[4] = (R[1] - 1) MOD R[2] + 1 8: ! 算行号和列号 9: R[6] = (R[4] - 1) DIV R[8] + 1 10: R[7] = (R[4] - 1) MOD R[8] + 1 11: ! 目标偏移量 12: PR[10,1] = PR[100,1] + (R[6] - 1) * PR[101,1] 13: PR[10,2] = PR[100,2] + (R[7] - 1) * PR[102,2] 14: PR[10,3] = PR[100,3] + (R[3] - 1) * PR[103,3] 15: ! 先到托盘上方安全高度 16: L P[90] 1200mm/sec CNT50 17: ! 打开偏移并放置 18: OFFSET PR[10] 19: L P[100] 500mm/sec FINE 20: OFFSET 21: ! 松开工件,等待夹具完成 22: CALL RELEASE 23: ! 抬升到安全高度 24: L P[90] 1000mm/sec CNT50 25: ! 判断是否满盘 26: IF R[1] >= R[12] JMP LBL[9] 27: JMP LBL[1] 28: ! 满盘处理 29: LBL[9] 30: CALL PALLET_FULL第 4 行先累加当前件号;第 6 到 10 行完成层号、行号、列号的换算。第 12 到 14 行把基准点坐标加上偏移后写入PR[10],注意这里写的是PR[100,1]这样的分量,不是把整个 PR 做向量加法。第 16 行先到安全高度P[90],然后第 19 行打开OFFSET去基准点。看起来目标点还是P[100],但实际落点已经在PR[10]的偏移位置上。第 26 行判断当前件数是否达到总件数,如果满了就跳转满盘处理程序,否则回到循环。
这段程序里最容易被忽略的是第 16 行的CNT50。过渡点用CNT50,机器人不用完全到位就转向下一步,节省节拍;但是第 19 行放置点必须用FINE,否则机器人可能还没稳定,夹具就打开了,工件会轻微滑移。很多现场码垛看着位置对,但每层都歪一点,最后越叠越矮,问题往往就是放置点用了CNT。
4.3 满盘判断与报警输出
满盘判断不要只依赖当前件号等于总件数,还要考虑“当前层是否已经放满”和“是否有空位”。如果中途有人手动拿掉一件,程序按原计数走,就可能少放一件。我一般会在程序里加一个辅助计数器R[11],每放一件加 1,满盘条件用R[11] >= R[12]判断,同时把当前件号写入R[1]。这样即使中途停机,重新启动后也能从上一次位置继续。
满盘处理程序可以做两件事:第一,给 PLC 或上位机发一个完成信号;第二,把计数寄存器清零,等托盘更换后自动进入下一垛。注意清零动作要放在 PLC 确认换盘完成之后,不能程序一跑到就清零。如果不清零,程序会立刻开始码下一盘,而现场可能还没换盘,工件会直接掉到地上。
5. 码垛程序调试:异常报警、错位与节拍参数修正
5.1 报警代码分级排查:INTP、MOTN、SRVO 的处理顺序
FANUC 机器人的报警大体分三类:程序类、运动类、伺服类。码垛程序调试时,遇到报警先看报警代码前缀,再决定从哪下手,不要一上来就怀疑程序逻辑。
| 报警前缀 | 常见原因 | 排查方向 |
|---|---|---|
| INTP | 程序语法、寄存器下标越界、参数类型不匹配 | 检查 TP 程序行号,重点看 DIV/MOD 表达式和 PR 分量访问 |
| MOTN | 路径规划失败、目标点超出行程、奇异点 | 单步走一遍轨迹,确认目标点有没有跑到机器人臂展外 |
| SRVO | 伺服报警、碰撞、急停、安全信号丢失 | 先恢复安全回路,再检查机械和工装,最后看程序 |
我遇到过很多次INTP报警其实是位置寄存器下标被算成了负数。比如R[1]从 0 开始,第一件时R[1] - 1等于 0,如果程序里写了PR[100 + R[1] - 1],第一件访问的是PR[99],可能不是你想用的基准寄存器。解决方法是先做一个计数器初始化,确保第一件时R[1]已经是 1,或者把所有下标计算收敛到明确的R寄存器上,不要直接写在PR方括号里。现场“发那科机器人进不去系统怎么办”这类问题,多半是后台宏程序死循环或者系统文件异常,先把控制柜断电重启,停在启动菜单后用备份恢复,不要在没有备份的情况下清 SRAM。
5.2 错位排查表:先看基准还是先看间距
码垛出现错位时,很多人第一反应是改程序里的偏移值,结果越改越乱。正确的排查顺序是从“基准”到“方向”再到“间距”。先用单步模式走到第一件放置点,把实际位置和托盘上的第一格对齐;不对的话重示教PR[100],不要动后面的间距。第一件对得上、后面的偏,再看间距和 UFrame 方向。
| 症状 | 可能原因 | 处理方式 |
|---|---|---|
| 所有点整体向 X 方向偏同一个值 | 基准点偏离或 UFrame 原点偏 | 重示教 PR[100],或重新标定 UFrame |
| 离基准点越远,X 方向偏差越大 | 托盘坐标系偏转,或 PR[101] 只改了 X 没改 Y | 用三点法重新建 UFrame |
| 每一层压到上一层的工件 | 层高 PR[103] 设成工件高度,没加托盘压缩余量 | 实测两层间高度,加上 1-2mm 余量 |
| 同一层里行和列交叉错位 | 行列公式反了,或者每行列数设置错误 | 单步打印 R[6] 和 R[7],对比实际位置 |
检查 UFrame 方向有一点要和电气工程师反复确认:Y 的正方向是朝向机器人还是背对机器人。方向上错,整个托盘的花纹会呈镜像,而且很难看出来,因为程序本身不报错。我一般会在空托盘上用记号笔画出第 1 件、第 2 件、第 3 件的位置,单步跑三件,直接对照标记检查。
5.3 节拍与轨迹:拐弯角速度对码垛精度的影响
码垛的节拍瓶颈往往不在直线速度,而在转弯和加减速。FANUC 的轨迹规划里,CNT值越大,路径越圆滑,机器人拐弯时不会完全减速到零,看起来节拍很快,但代价是实际轨迹会切弯。码垛过渡段切弯没问题,但放置段切弯就会导致工件位置不稳定。我的经验是:取料后到托盘前的移动,用CNT50或CNT100;从安全高度下降到放置点,必须FINE;放置完成抬升回安全高度,可以再用CNT50。这样既保证了节拍,又不会牺牲最后几毫米的定位精度。
提到“机器人拐弯角速度”,很多调试员只调OVERRIDE倍率,忽略了ACC加速度设定。FANUC TP 程序可以给运动指令单独指定加速度百分比,例如在程序开头用ACC 80把整体加速度降下来。如果放的工件是易碎品或细长件,我一般会把放置段的加速度降到 60% 以下,而不是只降速度。速度降下来但加速度很高,机器人到位瞬间还是有冲击,工件照样会位移。
6. 用宏程序和持久寄存器实现断电恢复与动态排布
6.1 TP 里的“#1-1 GE 0”:FANUC 宏程序思路怎么搬过来
用过 FANUC 数控宏程序的人,很熟悉#1-1 GE 0这种条件判断。到了机器人 TP 里,没有这套以#开头的公共变量,但有对应的R寄存器和IF分支。FANUC 机器人宏程序一般指 KAREL 程序,它可以在后台计算排布花纹,然后把结果写到寄存器里,TP 程序再去读。比如 KAREL 程序算好当前工件的行和列,写入R[20]和R[21],TP 端直接读:
IF R[20] > 0 THEN R[6] = R[20] R[7] = R[21] ENDIF这样做的价值是:复杂的交错排布、动态变层、按订单切换花纹,都可以放到 KAREL 里处理,TP 端只保留运动逻辑。如果不想碰 KAREL,纯 TP 也可以做,只是代码会多一点。需要注意,TP 里的GE写作>=,不要照搬数控宏程序的GE。语义一样是“大于等于”,但示教器上按出来的键位完全不同。
6.2 把当前件数写到持久寄存器,上电接着码
产线最怕突然断电,机器人程序停在托盘码到一半的位置,重新上电后不知道从哪一层开始。FANUC 的R寄存器和位置寄存器在正常断电后会保持,但长期断电电池耗尽或系统重启异常时可能丢。可靠做法是把关键计数写到项目早期就规划好的持久寄存器区域,比如R[60]存当前件号,R[61]存当前层号,R[62]存当前托盘编号。程序启动时先判断这些寄存器是否大于 0,大于 0 说明是中断恢复,跳转到对应层数继续码:
IF R[62] > 0 THEN R[1] = R[60] R[3] = R[61] JMP LBL[1] ENDIF这里R[60]到R[62]是现场约定的掉电保持区,任何人工复位操作不能把这块清掉。我把这个逻辑放在主程序最前面,配合PALLET_FULL子程序里的清零动作。这样每次换托盘的清零由流程触发,而不是程序开头无脑清零。实际执行时,还必须把当前件号同步给 PLC 一份,因为机器人侧显示不了完整托盘状态,操作员需要知道已经码了多少件。把计数放到持久寄存器,再在 HMI 上显示当前件号,就是一套不依赖昂贵选项的断电恢复方案。
本文还有配套的精品资源,点击获取