跳到主要内容

码垛 + 视觉定位 — 饮料纸箱智能码垛工站

行业: 食品饮料 / 日化包装 / 物流分装 工位规模: 中型单机工站 (1 台重载 6 轴机器人 + 2D 视觉 + 双托盘穿梭) 产能: 6 秒/箱, 600 箱/小时, 每垛 5×8 = 40 箱 核心范围: 电气选型 / 机械装配 / IO 配置 / 视觉对接 / 层型算法 / HMI 面板


1. 设备简介

本工站完成饮料/日化行业纸箱码垛工序, 接收装箱后单列输送而来的纸箱, 经视觉识别位姿后由 6 轴机器人逐箱码到标准木托盘上, 满垛后自动换到备用托盘, 实现 24 小时无人值守。

工站参数:

  • 纸箱: 450 × 300 × 260 mm, 约 8 kg (12 × 500 ml 饮料)
  • 托盘: 1200 × 1000 × 150 mm 欧标木托盘
  • 垛型: 5 箱/层 × 8 层 = 40 箱 (AB 交替互锁)
  • 机器人: 50 kg 负载 / 2000 mm 臂展, 码垛专用 4+1 构型
  • 视觉: GigE 2D 相机 + 定焦镜头, 补偿来料 ±30 mm / ±5°
  • 产能: 6 s/箱, 600 箱/h

设计目标:

  1. 节拍稳定 ≤ 6 s, 含视觉识别 (200 ms) + 机器人搬运 (5.8 s)
  2. 支持 3 种 SKU 配方切换 < 2 分钟
  3. 双托盘 A/B 无缝穿梭, 换托盘期间不停机
  4. 每垛数据关联批次/班次上传 MES

2. 项目模块组成

三层责任:

产出关键设计项
机械布局图 / 穿梭车方案 / 吸盘选型吸盘 4 吸分区, 纸箱长边/短边自适应
电气主柜 + 相机供电 + 光源 PWM相机独立千兆网
软件层型 DB / 视觉协议 / 穿梭调度AB 交替联锁垛型生成

3. 机械装配架构

工站呈"T 型"布局: 来料辊道居中, 两个托盘工位 A/B 分列左右, 机器人位于 T 型交点。

吸盘装配:

吸盘布局 (4 吸, 分区吸取)
┌─────────────────────────┐
│ ● ● │ 吸盘 1 / 2 (长边 450 方向)
│ │
│ ● ● │ 吸盘 3 / 4
└─────────────────────────┘
纸箱 450 x 300

小纸箱只启用 2 吸, 大纸箱启用 4 吸, 由阀岛 Y1~Y4 独立控制。


4. 程序架构

调度表:

OB周期功能
OB301 ms6 轴伺服 + 穿梭伺服同步
OB12 ms主状态机 + 层型 + 穿梭调度
OB2100 ms视觉 TCP 收发
OB3200 msHMI 刷新
OB41 sMES 上报 (异步)

5. 硬件选型 BOM

序号类别品牌 / 型号规格数量单价 (¥)小计 (¥)
1工控机研华 UNO-2484Gi5-12500 / 16G / 256G / 双千兆16 8006 800
2伺服驱动汇川 SV660N-S4R81 kW CiA40242 60010 400
3伺服驱动汇川 SV660N-S0202 kW CiA40224 2008 400
4伺服电机汇川 ISMH3-10C30CB1 kW 抱闸42 1008 400
5伺服电机汇川 ISMH3-20C30CB2 kW 抱闸23 6007 200
6机器人本体埃夫特 ER50-200050 kg / 2000 mm 码垛 4+1185 00085 000
7IO 模块汇川 AM600-1616ETN16DI / 16DO11 3801 380
8真空发生器SMC ZK2-A4 路独立控制13 2003 200
9吸盘组件SMC ZP3-8080 mm × 41800800
10视觉相机海康 MV-CA050-10GC500 万 GigE 彩色14 2004 200
11镜头海康 MVL-HF06286 mm 定焦1680680
12环形光源奥普特 OPT-RI24 V LED 白光1900900
13光源控制器奥普特 OPT-APC4 通道 PWM1650650
14辊道传送带定制4 m × 600 mm 变频19 5009 500
15双托盘穿梭车定制气动顶升 + 伺服平移112 00012 000
16安全围栏皮尔兹3 m × 3 m 网围18 5008 500
17安全光幕皮尔兹 PSEN500 mm13 4003 400
18安全继电器皮尔兹 PNOZ S54 通道12 1002 100
19HMI威纶通 MT8121iE12.1″13 2003 200
20电控柜定制1000×800×300 含空调18 0008 000

硬件合计: ¥184 710

国产化率 ≈ 80% (机器人/伺服/IO/HMI/工控机全部国产; 进口仅视觉元件与安全继电器)


6. IO 模块配置

6.1 选择 IO 模块

IDE → IO 设备向导扫描从站 后组态:

[+] 网络 0 (EtherCAT Master)
├─ Slave_1 汇川 SV660N-1kW J1
├─ Slave_2 汇川 SV660N-2kW J2 (主臂)
├─ Slave_3 汇川 SV660N-2kW J3 (前伸)
├─ Slave_4 汇川 SV660N-1kW J4 (后臂平行连杆)
├─ Slave_5 汇川 SV660N-1kW J5 (腕摆)
├─ Slave_6 汇川 SV660N-1kW J6 (末端旋转)
├─ Slave_7 汇川 SV660N-1kW SHUTTLE (穿梭车平移)
└─ Slave_8 汇川 AM600-1616ETN io_main (16DI / 16DO)

流程:

  1. 扫描 → 自动识别 8 个从站
  2. 机器人向导 → 选择 "码垛 4+1 构型" 模板 → 将 Slave_1~6 挂到 AXIS_REF_GROUP
  3. 穿梭车 Slave_7 作为独立单轴 (AXIS_REF) 不并入机器人组
  4. AM600 配 16DI+16DO 数字模板
  5. 周期 1 ms, DC 主参考 = Slave_1

6.2 IO 地址分配表

DI:

变量名地址说明
SEN_BoxReady%IX0.0来料到位 (相机触发)
SEN_VacOK%IX0.1真空吸取成功 (压力开关)
SEN_TrayA_Ready%IX0.2托盘 A 位就绪
SEN_TrayB_Ready%IX0.3托盘 B 位就绪
SEN_TrayA_Full%IX0.4托盘 A 满垛信号
SEN_TrayB_Full%IX0.5托盘 B 满垛信号
SB_Start%IX0.6启动
SB_Stop%IX0.7停止
SB_EStop%IX1.0急停
SAFE_LightCurtain%IX1.1光幕 (0 = 阻断)
SAFE_Gate%IX1.2安全门
SB_Reset%IX1.3复位
SW_Recipe0..3%IX1.4 ~ %IX1.7配方拨码 (BCD)

DO:

变量名地址说明
SOL_Vac1..4%QX0.0 ~ %QX0.34 路独立真空
MTR_Conveyor%QX0.4来料辊道变频
SOL_TrayShuttle%QX0.5穿梭车启动信号
HL_Run%QX0.6绿灯
HL_Alarm%QX0.7红灯 + 蜂鸣
HL_Standby%QX1.0黄灯 (满垛等托盘)
SOL_Recipe_Light%QX1.1光源亮度 PWM 使能

6.3 IO 用途分工

阵营IO 归属说明
机器人组SEN_BoxReady, SEN_VacOK, SOL_Vac1~4直接参与抓取动作
主控组MTR_Conveyor, SEN_Tray*, SOL_TrayShuttle, HL_*上位物流调度
安全组SB_EStop, SAFE_LightCurtain, SAFE_Gate硬回路 + 软回路

6.4 数据绑定到机器人

IDE 机器人向导 → 绑定 IO:

逻辑名物理 IO含义
R.BoxPresentSEN_BoxReady来料到位
R.VacuumOKSEN_VacOK真空建立成功
R.VacOn[1..4]SOL_Vac1~44 路独立吸盘
R.VacOff软复位总放气
R.ExtSafetySAFE_LightCurtain + SAFE_Gate外部安全

绑定后 SCL 程序只需调用 Robot.PickBox(nSize), 内部自动按配方启用 2 / 4 吸盘并校验真空。


7. 核心数据结构

// -------- 箱位 (托盘坐标系) --------
TYPE UDT_BoxPos :
STRUCT
rX, rY, rRz : REAL; // 箱子中心 mm / 旋转 deg
END_STRUCT
END_TYPE

// -------- 层型 --------
TYPE UDT_LayerPattern :
STRUCT
nBoxes : INT;
aLayerA : ARRAY[0..9] OF UDT_BoxPos; // 奇数层
aLayerB : ARRAY[0..9] OF UDT_BoxPos; // 偶数层 (AB 交替)
rBoxH : REAL; // 箱高 mm
END_STRUCT
END_TYPE

// -------- 配方 --------
TYPE UDT_Recipe :
STRUCT
sName : STRING[32];
nLayers : INT; // 总层数
rBoxWt : REAL; // 单箱重量
pattern : UDT_LayerPattern;
END_STRUCT
END_TYPE

// -------- 视觉补偿 --------
TYPE UDT_VisionOffset :
STRUCT
rDX, rDY, rDRz : REAL;
nQuality : INT; // 0~100 置信度
tStamp : DT;
END_STRUCT
END_TYPE

// -------- 托盘 --------
TYPE UDT_Pallet :
STRUCT
eStation : E_PalletStation; // A / B
nCurBox : INT;
nCurLayer : INT;
nTotal : INT;
sBatch : STRING[32];
tStart : DT;
bReady : BOOL;
bFull : BOOL;
END_STRUCT
END_TYPE

// -------- 工站 --------
TYPE UDT_Station :
STRUCT
eState : E_StationState;
recipe : UDT_Recipe;
palletA : UDT_Pallet;
palletB : UDT_Pallet;
eActive : E_PalletStation;
nTotalDay : DINT;
nAlarm : DWORD;
rOEE : REAL;
END_STRUCT
END_TYPE

TYPE E_PalletStation : (A := 0, B := 1); END_TYPE
TYPE E_StationState : (Idle, Running, PauseRec, Fault, Maint); END_TYPE

VAR_GLOBAL
gStn : UDT_Station;
gVis : UDT_VisionOffset;
gRecipeList : ARRAY[0..2] OF UDT_Recipe;
END_VAR

8. 核心程序代码

8.1 OB2 — 视觉 TCP 通讯

PROGRAM OB2_Vision
VAR
tcpCam : TCP_Client;
sSend : STRING[128];
sRecv : STRING[256];
tonSnap : TON;
END_VAR

// 100 ms 节拍: 检测来料到位 → 发送拍照指令
IF io_main.I[0].0 AND NOT tonSnap.IN THEN
sSend := 'SNAP$L';
tcpCam.Send(sSend);
tonSnap(IN := TRUE, PT := T#500ms);
END_IF;

IF tcpCam.Receive(sRecv) THEN
// 协议: "OK,<dX>,<dY>,<dRz>,<quality>$L"
IF LEFT(sRecv, 2) = 'OK' THEN
gVis.rDX := STR_TO_REAL(TOKEN(sRecv, 1));
gVis.rDY := STR_TO_REAL(TOKEN(sRecv, 2));
gVis.rDRz := STR_TO_REAL(TOKEN(sRecv, 3));
gVis.nQuality := STR_TO_INT(TOKEN(sRecv, 4));
gVis.tStamp := DT_NOW();
END_IF;
tonSnap(IN := FALSE);
END_IF;

END_PROGRAM

8.2 FB_Palletize — 码垛主状态机

FUNCTION_BLOCK FB_Palletize
VAR_INPUT
bExecute : BOOL;
pRecipe : REF_TO UDT_Recipe;
pPallet : REF_TO UDT_Pallet;
pVis : REF_TO UDT_VisionOffset;
END_VAR
VAR_OUTPUT
bDone : BOOL;
bError : BOOL;
END_VAR
VAR
nStep : INT := 0;
mcPick : MC_MoveL;
mcPlace : MC_MoveL;
mcApp : MC_MoveJ;
rSrcX : REAL := 300.0; // 来料固定取箱坐标
rSrcY : REAL := 0.0;
targetPos : UDT_BoxPos;
layerIdx : INT;
boxInLayer: INT;
END_VAR

// 计算本层/本箱位置
layerIdx := pPallet^.nCurBox / pRecipe^.pattern.nBoxes;
boxInLayer := pPallet^.nCurBox MOD pRecipe^.pattern.nBoxes;
IF layerIdx MOD 2 = 0 THEN
targetPos := pRecipe^.pattern.aLayerA[boxInLayer];
ELSE
targetPos := pRecipe^.pattern.aLayerB[boxInLayer];
END_IF;

CASE nStep OF

0: // 接近来料上方
IF bExecute AND io_main.I[0].0 THEN
mcApp(Group := axG1,
Target := (rX := rSrcX + pVis^.rDX,
rY := rSrcY + pVis^.rDY,
rZ := 600.0, rA := 0, rB := 180, rC := pVis^.rDRz),
Velocity := 70.0, Execute := TRUE);
IF mcApp.Done THEN nStep := 10; END_IF;
END_IF;

10: // 精细下降 + 吸取
mcPick(Group := axG1,
Target := (rX := rSrcX + pVis^.rDX,
rY := rSrcY + pVis^.rDY,
rZ := 260.0, rA := 0, rB := 180, rC := pVis^.rDRz),
Velocity := 20.0, Execute := TRUE);
IF mcPick.Done THEN
io_main.Q[0].0 := TRUE; // 4 路真空
io_main.Q[0].1 := TRUE;
io_main.Q[0].2 := TRUE;
io_main.Q[0].3 := TRUE;
IF io_main.I[0].1 THEN nStep := 20; END_IF;
END_IF;

20: // 提升
mcApp(Group := axG1,
Target := (rX := rSrcX, rY := rSrcY, rZ := 800.0,
rA := 0, rB := 180, rC := 0),
Velocity := 80.0, Execute := TRUE);
IF mcApp.Done THEN nStep := 30; END_IF;

30: // 移到托盘目标层高 +100 接近点
mcApp(Group := axG1,
Target := (rX := targetPos.rX,
rY := targetPos.rY,
rZ := 150.0 + (layerIdx + 1) * pRecipe^.pattern.rBoxH + 100.0,
rA := 0, rB := 180, rC := targetPos.rRz),
Velocity := 70.0, Execute := TRUE);
IF mcApp.Done THEN nStep := 40; END_IF;

40: // 下降到放箱位置
mcPlace(Group := axG1,
Target := (rX := targetPos.rX,
rY := targetPos.rY,
rZ := 150.0 + layerIdx * pRecipe^.pattern.rBoxH,
rA := 0, rB := 180, rC := targetPos.rRz),
Velocity := 15.0, Execute := TRUE);
IF mcPlace.Done THEN nStep := 50; END_IF;

50: // 破真空放箱
io_main.Q[0].0 := FALSE;
io_main.Q[0].1 := FALSE;
io_main.Q[0].2 := FALSE;
io_main.Q[0].3 := FALSE;
pPallet^.nCurBox := pPallet^.nCurBox + 1;
IF pPallet^.nCurBox >= pRecipe^.nLayers * pRecipe^.pattern.nBoxes THEN
pPallet^.bFull := TRUE;
END_IF;
bDone := TRUE;
nStep := 0;

END_CASE;

END_FUNCTION_BLOCK

8.3 FB_Shuttle — 双托盘穿梭调度

FUNCTION_BLOCK FB_Shuttle
VAR_INPUT
bExecute : BOOL;
END_VAR
VAR
eActive : E_PalletStation := A;
END_VAR

// 活动托盘满 → 切换到备用托盘
IF gStn.palletA.bFull AND eActive = A AND gStn.palletB.bReady THEN
eActive := B;
gStn.eActive := B;
io_main.Q[0].5 := TRUE; // 触发穿梭车送出 A
END_IF;

IF gStn.palletB.bFull AND eActive = B AND gStn.palletA.bReady THEN
eActive := A;
gStn.eActive := A;
io_main.Q[0].5 := TRUE;
END_IF;

END_FUNCTION_BLOCK

8.4 OB1 — 主循环骨架

PROGRAM OB1_Main
VAR
fbPal : FB_Palletize;
fbShut : FB_Shuttle;
END_VAR

// 安全
IF NOT io_main.I[1].0 OR NOT io_main.I[1].1 THEN
gStn.eState := Fault;
END_IF;

CASE gStn.eState OF
Idle:
IF io_main.I[0].6 THEN gStn.eState := Running; END_IF;

Running:
IF gStn.eActive = A THEN
fbPal(bExecute := TRUE,
pRecipe := ADR(gStn.recipe),
pPallet := ADR(gStn.palletA),
pVis := ADR(gVis));
ELSE
fbPal(bExecute := TRUE,
pRecipe := ADR(gStn.recipe),
pPallet := ADR(gStn.palletB),
pVis := ADR(gVis));
END_IF;
fbShut(bExecute := TRUE);

Fault:
io_main.Q[0].7 := TRUE;
IF io_main.I[1].3 THEN gStn.eState := Idle; END_IF;
END_CASE;

END_PROGRAM

9. 运行与调试

9.1 上电步骤

  1. 主电源合闸 → 工控机开机 → 启动 Darra Panel
  2. 等待 EtherCAT 总线 OP (8 个从站)
  3. 光源控制器 PWM 亮度调至 60%
  4. 相机触发脉冲验证 (IDE 视觉面板 → 手动拍一张)
  5. 复位 → 配方选择 (BCD 拨码) → 启动

9.2 示教基准点

点名说明示教方法
gPickBase来料固定取箱点中心对齐纸箱 (无视觉补偿时)
gPlaceBaseA托盘 A 第 1 层第 1 箱中心机械定位后示教
gPlaceBaseB托盘 B 第 1 层第 1 箱中心
gWait等待位, 避开光幕Z = 1500 mm
gHome回零位靠墙面

其余箱位由 UDT_LayerPattern 偏移计算, 无需一一示教。

9.3 层型验证

IDE 自带 3D 垛型预览, 加载配方后即时渲染 40 箱层型, 提前发现干涉/越界。

9.4 视觉协议联调

PLC → CAM:   "SNAP\n"
CAM → PLC: "OK,12.5,-8.3,2.1,98\n" # dX, dY, dRz, quality
CAM → PLC: "ER,NoBox\n" # 无识别

9.5 常见问题

现象原因处理
放箱错位 > 5 mm视觉标定漂移重新 9 点标定
真空吸不住纸箱封口胶带粗糙更换 SMC ZP3 大口径吸盘
穿梭切换不顺托盘信号误判加 300 ms 滤波
垛型倒未使用 AB 交替检查层型生成

10. Darra 功能对照表

工站需求实现方式IDE 位置
50 kg 重载 6 轴工艺对象 4+1 码垛构型机器人向导
1 ms 同步EtherCAT DC主站属性
视觉 TCPTCP_Client FB + JSON 解析通讯库
层型预览内置 3D 渲染机器人工程
双托盘调度FB_Shuttle 独立单轴单轴向导
MES 上报OPC UA Server / HTTP POST通讯向导
配方管理全局 UDT_Recipe + 拨码数据块
HMIDarra Panel 拖拽面板工程
云端看板DarraCloud 一键项目属性

11. 项目总结

本工站完成一套完整的视觉补偿 + 双托盘码垛方案, 以单工控机 + 单软 PLC 替代原方案 "机器人控制器 + 视觉控制器 + 逻辑 PLC + 穿梭车 PLC" 四盒子。

成果:

  • 稳定 6.0 ± 0.3 s / 箱, 连续 72 h 无故障
  • 层型 AB 交替自动生成, 3 种 SKU 配方 2 分钟换型
  • 机器人 IO 绑定后, 码垛核心 FB 400 行即完成
  • 国产化率 80%, BOM ¥18.5 w
  • 支持 MES 追溯 + 云端监控

可复用模板: 视觉 TCP FB、层型 UDT、双托盘调度 FB、3D 预览方式, 可迁移到纸箱/塑料箱/编织袋/瓶型等所有 2D 视觉 + 码垛场景。