RobotStudio教程:ABB机器人拆垛与码垛应用示教编程与虚拟仿真

目录

任务描述

机器人拆垛与码垛工作站创建

机器人拆垛与码垛工作流程分析

机器人位置偏移函数介绍

机器人拆垛与码垛应用示教编程

机器人拆垛与码垛虚拟仿真


任务描述

在RobotStudio软件中创建ABB机器人拆垛与码垛工作站,并示教机器人拆垛与码垛程序,实现机器人拆垛与码垛应用虚拟仿真。ABB机器人的型号规格、工具等外围设备根据实际需要自行选定。

拆垛垛块排序如下图所示,垛块长度为600mm,宽度为200mm,高度也为200mm。垛块共码放了3层,每一层码放8块。每一层的垛块横向摆放6块,竖向摆放2块,并且层与层之间垛块采用混合交叉方式码放。

码垛垛块排序与拆垛垛块排序方式基本一致,也是码放3层,每层横竖码放共8块,层与层之间也是采用混合交叉码放方式,只是码垛垛块的码放位置与拆垛垛块的码放位置为镜像对称码放,如下图所示。

机器人拆垛与码垛工作站创建

在RobotStudio软件中创建虚拟仿真项目,添加一台ABB机器人模型,机器人使用吸盘工具,可从外部导入设计好的三维模型。再添加两个托盘,并布局到合适位置,其中一个用于码放拆垛垛块,另一个用于码放码垛垛块。

按照任务描述要求,使用软件自带的模型创建功能创建码垛垛块。垛块创建好后,将垛块一层一层地码放到拆垛托盘上。在码垛托盘上也分别横竖码放两个垛块,作为机器人示教编程的位置参考。模型全部布局完成后,其效果如下图所示。

从布局创建ABB机器人虚拟系统,然后添加动态吸盘Smart组件,用来吸取与释放垛块。动态吸盘Smart组件的添加方法可参考之前发布过的文章《RobotStudio软件:机床上下料工作站机器人工具Smart组件添加》,这里不再过多介绍。

机器人拆垛与码垛工作流程分析

机器人码垛应用其实也是一种搬运应用,只是这种应用是机器人按照一定的规律重复点对点的运动路径的搬运应用。机器人拆垛应用可以看作是机器人码垛运动的逆运行。

一般情况下,机器人码垛的垛块规格、码垛的层数以及每一层垛块的码放个数、码放样式都是固定的,并且具备一定的数学运算关系,通过这个数学运算关系就能规划出机器人拆垛与码垛应用的运动路径。

如下图所示,是本例ABB机器人拆垛与码垛应用的工作原理示意图。机器人位于拆垛垛块与码垛垛块中间,也就是大地坐标系位置处,两边的垛块码放位置关于大地坐标系YZ轴所在平面镜像对称。工作时,机器人先由左侧的拆垛托盘上从右向左、从上向下依次吸取垛块;然后运动到右侧的码垛托盘处从右向左、从下向上依次释放垛块。

如果将码垛托盘上序号为1的垛块与序号为7的垛块分别作为机器人吸取垛块的示教点,以大地坐标系为参考,那么其余的垛块的示教点就可以看作是这两个垛块的示教点沿着大地坐标系X、Y、Z轴按照一定的距离的动态偏移。

机器人拆垛运动过程与码垛运动过程基本相同,只是示教点的偏移方向与码垛示教点的偏移方向在大地坐标系Y轴与Z轴方向上相反。

机器人位置偏移函数介绍

根据上述分析可知,在对机器人示教编程时,除了要用到机器人的常规运动指令外,还要用到另外一种运动功能,即机器人位置偏移函数。

市面上常见的工业机器人都具备这种位置偏移函数,当然,ABB机器人也不例外。“Offs”就是ABB机器人的位置偏移函数,它的功能是用于在已有的机器人位置的工件坐标系中添加一个偏移量。这里一定要注意,它是在机器人的工件坐标系中叠加的偏移量,其完整的函数语句格式如下图所示。

函数Offs中Point的数据类型为robtarget,其余三个偏移量的数据类型均为num。

机器人拆垛与码垛应用示教编程

在ABB机器人虚拟示教器中创建机器人拆垛与码垛例行程序,首先将机器人各个关节手动运行到合适位置,然后将当前姿态示教为机器人HOME点程序,示教点名称为pHome。

再将机器人分别手动运行到拆垛托盘上的1号、7号垛块处,以及码垛托盘上的1号、7号垛块处,并示教出这4个机器人姿态的点位程序,4个示教点分别命名为pLPick、pLPick90、pRPlace、pRPlace90。

在示教过程中,机器人TCP使用标定好的吸盘工具TCP,工件坐标系使用默认的工件坐标系(wobj0)。当然,工件坐标系也可以分别在拆垛托盘和码垛托盘上分别标定。这里要注意的是,一般情况下,在RobotStudio软件中ABB机器人默认工件坐标系(wobj0)通常与虚拟仿真环境中的大地坐标系重合。

机器人拆垛与码垛程序关键点示教完成后,根据上述工作流程分析即可编写出机器人工作逻辑判断程序以及垛块吸取与释放位置偏移程序,完整的程序代码如下图所示。

完整的ABB机器人拆垛与码垛程序代码如下所示。

MODULE Module1
	CONST robtarget pHome:=[[1405.50,0.00,1620.00],[2.35481E-8,-7.53893E-9,1,-1.77528E-16],[0,0,-1,0],[9E+9,9E+9,9E+9,9E+9,9E+9,9E+9]];
	CONST robtarget pLPick:=[[1600.00,-1100.00,740.00],[1.01751E-7,-1.31278E-7,1,-7.4175E-8],[-1,-1,-1,0],[9E+9,9E+9,9E+9,9E+9,9E+9,9E+9]];
	CONST robtarget pRPlace:=[[1600.00,1100.00,340.00],[9.86443E-9,-1.70914E-8,1,-1.23181E-8],[0,-1,0,0],[9E+9,9E+9,9E+9,9E+9,9E+9,9E+9]];
	CONST robtarget pLPick90:=[[1400.00,-700.00,740.00],[1.50459E-7,0.707107,0.707107,-6.22807E-8],[-1,-1,0,0],[9E+9,9E+9,9E+9,9E+9,9E+9,9E+9]];
	CONST robtarget pRPlace90:=[[1400.00,700.00,340.00],[8.97325E-9,0.707107,0.707107,4.92759E-9],[0,-1,1,0],[9E+9,9E+9,9E+9,9E+9,9E+9,9E+9]];
    PERS robtarget pLPickSafety:=[[800,-700,640],[1.50459E-7,0.707107,0.707107,-6.22807E-8],[-1,-1,0,0],[9E+9,9E+9,9E+9,9E+9,9E+9,9E+9]];
    PERS robtarget pRPlaceSafety:=[[800,700,1040],[8.97325E-9,0.707107,0.707107,4.92759E-9],[0,-1,1,0],[9E+9,9E+9,9E+9,9E+9,9E+9,9E+9]];
    CONST num L:=600;
    CONST num W:=200;
    CONST num H:=200;
	CONST num LHNum:=6;
    CONST num LVNum:=2;
	CONST num Layer:=3;
    PROC main()
        MoveJ pHome, v1500, fine, tVacuume;
        Reset doVacuume;
        FOR i FROM 1 TO (LHNum+LVNum)*Layer DO
            !First layer horizontal
        	IF i<=LHNum THEN
                !Pick
                pLPickSafety:=Offs(Offs(pLPick,-W*(i-1),0,-H*(Layer-3)),0,0,300);
        		MoveJ pLPickSafety, v1500, z50, tVacuume;
                MoveL Offs(pLPick,-W*(i-1),0,-H*(Layer-3)), v1000, fine, tVacuume;
                Set doVacuume;
                WaitDI diVacuumeOK,1;
                MoveL pLPickSafety, v1000, fine, tVacuume;
                !Place
                pRPlaceSafety:=Offs(Offs(pRPlace,-W*(i-1),0,H*(Layer-3)),0,0,300);
                MoveJ pRPlaceSafety, v1500, z50, tVacuume;
                MoveL Offs(pRPlace,-W*(i-1),0,H*(Layer-3)), v1000, fine, tVacuume;
                Reset doVacuume;
                WaitDI diVacuumeOK,0;
                MoveL pRPlaceSafety, v1000, fine, tVacuume;
            !First layer vertical
            ELSEIF i>LHNum AND i<=(LHNum+LVNum) THEN
                !Pick
                pLPickSafety:=Offs(Offs(pLPick90,-L*(i-LHNum-1),0,-H*(Layer-3)),0,0,300);
                MoveJ pLPickSafety, v1500, z50, tVacuume;
                MoveL Offs(pLPick90,-L*(i-LHNum-1),0,-H*(Layer-3)), v1000, fine, tVacuume;
                Set doVacuume;
                WaitDI diVacuumeOK,1;
                MoveL pLPickSafety, v1000, fine, tVacuume;
                !Place
                pRPlaceSafety:=Offs(Offs(pRPlace90,-L*(i-LHNum-1),0,H*(Layer-3)),0,0,300);
                MoveJ pRPlaceSafety, v1500, z50, tVacuume;
                MoveL Offs(pRPlace90,-L*(i-LHNum-1),0,H*(Layer-3)), v1000, fine, tVacuume;
                Reset doVacuume;
                WaitDI diVacuumeOK,0;
                MoveL pRPlaceSafety, v1000, fine, tVacuume;
            !Second layer horizontal
            ELSEIF i>LHNum+LVNum AND i<=2*(LHNum+LVNum)-LVNum THEN
                !Pick
                pLPickSafety:=Offs(Offs(pLPick,-W*(i-LHNum-LVNum-1),W,-H*(Layer-2)),0,0,300);
        		MoveJ pLPickSafety, v1500, z50, tVacuume;
                MoveL Offs(pLPick,-W*(i-LHNum-LVNum-1),W,-H*(Layer-2)), v1000, fine, tVacuume;
                Set doVacuume;
                WaitDI diVacuumeOK,1;
                MoveL pLPickSafety, v1000, fine, tVacuume;
                !Place
                pRPlaceSafety:=Offs(Offs(pRPlace,-W*(i-LHNum-LVNum-1),-W,H*(Layer-2)),0,0,300);
                MoveJ pRPlaceSafety, v1500, z50, tVacuume;
                MoveL Offs(pRPlace,-W*(i-LHNum-LVNum-1),-W,H*(Layer-2)), v1000, fine, tVacuume;
                Reset doVacuume;
                WaitDI diVacuumeOK,0;
                MoveL pRPlaceSafety, v1000, fine, tVacuume;
            !Second layer vertical
            ELSEIF i>2*(LHNum+LVNum)-LVNum AND i<=2*(LHNum+LVNum) THEN
                !Pick
                pLPickSafety:=Offs(Offs(pLPick90,-L*(i-2*LHNum-LVNum-1),-L,-H*(Layer-2)),0,0,300);
                MoveJ pLPickSafety, v1500, z50, tVacuume;
                MoveL Offs(pLPick90,-L*(i-2*LHNum-LVNum-1),-L,-H*(Layer-2)), v1000, fine, tVacuume;
                Set doVacuume;
                WaitDI diVacuumeOK,1;
                MoveL pLPickSafety, v1000, fine, tVacuume;
                !Place
                pRPlaceSafety:=Offs(Offs(pRPlace90,-L*(i-2*LHNum-LVNum-1),L,H*(Layer-2)),0,0,300);
                MoveJ pRPlaceSafety, v1500, z50, tVacuume;
                MoveL Offs(pRPlace90,-L*(i-2*LHNum-LVNum-1),L,H*(Layer-2)), v1000, fine, tVacuume;
                Reset doVacuume;
                WaitDI diVacuumeOK,0;
                MoveL pRPlaceSafety, v1000, fine, tVacuume;
            !Third layer horizontal
            ELSEIF i>2*(LHNum+LVNum) AND i<=3*(LHNum+LVNum)-LVNum THEN
                !Pick
                pLPickSafety:=Offs(Offs(pLPick,-W*(i-2*LHNum-2*LVNum-1),0,-H*(Layer-1)),0,0,300);
        		MoveJ pLPickSafety, v1500, z50, tVacuume;
                MoveL Offs(pLPick,-W*(i-2*LHNum-2*LVNum-1),0,-H*(Layer-1)), v1000, fine, tVacuume;
                Set doVacuume;
                WaitDI diVacuumeOK,1;
                MoveL pLPickSafety, v1000, fine, tVacuume;
                !Place
                pRPlaceSafety:=Offs(Offs(pRPlace,-W*(i-2*LHNum-2*LVNum-1),0,H*(Layer-1)),0,0,300);
                MoveJ pRPlaceSafety, v1500, z50, tVacuume;
                MoveL Offs(pRPlace,-W*(i-2*LHNum-2*LVNum-1),0,H*(Layer-1)), v1000, fine, tVacuume;
                Reset doVacuume;
                WaitDI diVacuumeOK,0;
                MoveL pRPlaceSafety, v1000, fine, tVacuume;
            !Third layer vertical
            ELSE
                !Pick
                pLPickSafety:=Offs(Offs(pLPick90,-L*(i-3*LHNum-2*LVNum-1),0,-H*(Layer-1)),0,0,300);
                MoveJ pLPickSafety, v1500, z50, tVacuume;
                MoveL Offs(pLPick90,-L*(i-3*LHNum-2*LVNum-1),0,-H*(Layer-1)), v1000, fine, tVacuume;
                Set doVacuume;
                WaitDI diVacuumeOK,1;
                MoveL pLPickSafety, v1000, fine, tVacuume;
                !Place
                pRPlaceSafety:=Offs(Offs(pRPlace90,-L*(i-3*LHNum-2*LVNum-1),0,H*(Layer-1)),0,0,300);
                MoveJ pRPlaceSafety, v1500, z50, tVacuume;
                MoveL Offs(pRPlace90,-L*(i-3*LHNum-2*LVNum-1),0,H*(Layer-1)), v1000, fine, tVacuume;
                Reset doVacuume;
                WaitDI diVacuumeOK,0;
                MoveL pRPlaceSafety, v1000, fine, tVacuume;
        	ENDIF
        ENDFOR
        MoveJ pHome, v1500, fine, tVacuume;
    ENDPROC
ENDMODULE

机器人拆垛与码垛虚拟仿真

在RobotStudio软件中对ABB机器人仿真运行,其中一段的仿真运行效果如下方动态图所示,可以看到机器人从拆垛托盘上吸取垛块,并按照一定的码放顺序将其码放到码垛托盘上。

 The End


上一篇:ABB机器人:工件坐标系介绍以及标定操作与使用方法

好的,下面是ABB机器人码垛编程的实例: 1. 首先,我们需要定义一个坐标系,以便机器人能够准确地定位并将物品码垛。可以使用ABB机器人的操作面板或者RobotStudio软件来创建一个坐标系。 2. 接下来,我们需要编写程序来控制机器人的动作。以下是一个简单的程序,用于将物品从传送带上取下并码垛: ``` MODULE MainModule CONST numLayers = 4 CONST numItemsPerLayer = 5 VAR layerCount : INT VAR itemCount : INT VAR xPos : REAL VAR yPos : REAL VAR zPos : REAL PROC Main() SetDO 1, 1 WaitTime 1 SetDO 1, 0 layerCount := 0 WHILE layerCount < numLayers DO itemCount := 0 WHILE itemCount < numItemsPerLayer DO PickItem() xPos := layerCount * 100 yPos := itemCount * 50 zPos := layerCount * 50 PlaceItem() itemCount := itemCount + 1 ENDWHILE layerCount := layerCount + 1 ENDWHILE ENDPROC PROC PickItem() MoveL Offs(200, 0, 0), v1000, fine, TCP("Tool") MoveL Offs(0, 0, -50), v1000, fine, TCP("Tool") SetDO 2, 1 WaitTime 1 SetDO 2, 0 MoveL Offs(0, 0, 50), v1000, fine, TCP("Tool") MoveL Offs(-200, 0, 0), v1000, fine, TCP("Tool") ENDPROC PROC PlaceItem() MoveL Offs(xPos, yPos, zPos), v1000, fine, TCP("Tool") MoveL Offs(0, 0, -50), v1000, fine, TCP("Tool") SetDO 3, 1 WaitTime 1 SetDO 3, 0 MoveL Offs(0, 0, 50), v1000, fine, TCP("Tool") ENDPROC ENDMODULE ``` 3. 这个程序中,我们定义了一个包含4层、每层5个物品的码垛。程序中的PickItem()过程用于从传送带上取下一个物品,PlaceItem()过程用于将物品放置在指定的坐标位置。 4. 程序中还包含了一些机器人动作的指令,例如MoveL用于移动到指定位置,SetDO用于控制机器人的数字输出信号。 5. 在程序编写完成后,将程序上传到机器人控制器中,并启动程序。机器人将自动执行码垛任务。 希望这个实例能够帮助你了解ABB机器人码垛编程的基本流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IndRobSim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值