5.1 离线软件操作

5.1.1 环境配置

由于现场环境可能出现重新标定tcp或者外部轴范围变更,因此需要检查并更新tcp和外部轴数据。

5.1.1.1 焊枪TCP设置

  1. 点击绿色的工具名称,鼠标右键,单击工具属性

  2. 将示教器中工具1的tcp数据输入到红色框中。

  3. 蓝色框中数值可以微调焊枪尖与TCP的相对位置。

5.1.1.2 激光TCP设置

  1. 在线激光头名称位置点鼠标右键,点工具属性

  2. 将激光标定结果(先扫后焊标定数据)填入到红色框。

    说明
    • 蓝色方框中,轨迹TCP偏移表示扫描高度。

    • 蓝色方框中,屏幕TCP偏移表示从标定tcp位置到光源的高度(即传感器视野)。

5.1.1.3 外部轴范围设置

  1. 扩展模型绿色的就是外部轴名称,右键,然后单击属性

  2. 映射:XYZ正方向代表的值。本项目中,X正方向为-e2,Y正方向为+e3,Z正方向为-e1。在左右极限位置填入每个方向对应的外部轴值的范围(X为e2范围,Y为e3范围,Z为e1范围)。蓝色框联动设置里,勾选自动规划,联动方向选XYZ。

    说明
    • 在设置范围时,需要设置的比实际外部轴范围小一点,这样能避免外部轴刚好运行到极限位置时机器人报警。

    • 搜索表示外部轴搜索的方向和范围,按照下图设置即可。

5.1.1.4 设置工作台

  1. 依次点击工作台库>右键>新建,输入工作台尺寸(mm)信息后,单击确定

  2. 右键工作台属性,单击工作台属性。在工作台用途列表中选择焊接

5.1.2 模型导入

  1. 右键工件集合,单击导入

  2. 单击模型导入,文件格式选择attr

5.1.3 焊缝自动提取

由于逆向建模数据自带底面信息,因此无需再次选择底面。直接点击提取焊缝即可。

说明

若焊缝无法提取,可能是未设置底面导致,参考有模型方案的功能使用说明。

如图所示,依次点击编程>路径焊接>提取>平焊缝(立焊缝)>完成

5.1.4 轨迹参数自动匹配

单击快速焊缝编辑。在工艺设置区域中,在姿态模版匹配方式中选择按照类型

说明

先设置好选项,在自动提取焊缝过程中会自动匹配轨迹参数(软件有轨迹参数库)。

5.1.5 轨迹自动优化

  1. 点击右下角快速优化,进入自动优化界面,点击右下角自动优化按钮,等待优化完成即可。

  2. 自动优化进度、时间、初始焊缝数量、实际焊缝数量、初始焊缝总长度、实际焊缝总长度及焊达率。

  3. 自动优化方式:

    • 方式一:失败立即停止,选择的焊缝有一条不可焊接,自动优化立即停止。

    • 方式二:自动过滤掉不可焊接焊缝,自动删除不可达焊缝程序,不可达焊缝会显示红色,便于查看不可达焊缝原因。

5.1.6 程序生成

  1. 在快速优化界面单击生成程序

  2. 在对应轨迹名称位置右键,并点击生成程序

    说明

    逆向建模只需要运行一个程序即可(LX_WeldMain),每工件都会生成子程序,对应主程序会调用子程序(通过大线扫粗定位对比工件)。


5.2 多工位和多工件设置

5.2.1 离线软件设置

5.2.1.1 多工位设置

  1. 以单导轨工作站为例,需要在导轨另一侧添加工位。

  2. 首先右键工作台库,单击新建

  3. 在创建工作台界面,可以设置工作台的长宽高信息。长宽高设置并没有严格要求,可尽量与导轨长度接近。

  4. 创建完成后,右键新建的工作台,单击设置坐标

  5. 设置到与工位1对称的位置即可。

  6. 右键点工作台属性

  7. 工作台用途选焊接。为避免工作台与工件穿模导致工件显示不全,可以设置工作台不透明度。为避免焊枪与工作台碰撞干扰后续自动优化,可不勾选碰撞检测

  8. 对于导轨两侧的工位,机器人在不同工位之间切换可能会撞到焊接等外部设备,需要给每个工位单独设置安全点。

5.2.2 多工件设置

在工作台属性的程序列表页面,取消单工件模式和单程序模式的勾选,可启用多工件模式。

  • 单工件模式表示当前工位每次只记录一个工件,新工件名称和程序会覆盖原来工件。

  • 单程序模式表示每个工件只记录一个程序,新程序名称会覆盖原来程序名称。程序生成后,工件名和程序名会记录到对应工位的程序列表中。

    说明

    多工件模式目前每工位最多记录5个工件。



5.3 案例说明

5.3.1 单导轨

5.3.1.1 工作站配置图

5.3.1.2 离线操作流程图

5.3.1.3 主程序流程图

5.3.1.4 多工位多工件实例

  • 多工件示意图

    • 如图所示工位1上,摆放着三个工件A、B、C。

      说明

      该图为离线软件中的工件摆放位置,不是实际位置。

  • 准备工作

生成工件对应文件

离线软件生成工件对应的点云(pcd)、位姿(pose)和列表名称(list)文件。其中,ABC点云文件分别为_A_GW1.pcd、_B_GW1.pcd和_C_GW1.pcd,位姿文件分别为_A_GW1.pose、_B_GW1.pose和_C_GW1.pose,列表文件为_list_GW1.list,其中文件内容为三个工件模型的名称_A_GW1、_B_GW1和_C_GW1。

生成主程序

主程序大致格式为:

CALL CAM222_GW1 //视觉拍照指令或程序

IF wb==1 //工位1

LBL[1]:

CALL CAM202_GW1 //视觉计算指令或程序

IF wp==1 //工件1,对应A

CALL Prog_A_1

CALL Prog_A_2

……

END IF

IF wp==2 //工件2,对应B

CALL Prog_B_1

CALL Prog_B_2

……

END IF

IF wp==3 //工件3,对应C

CALL Prog_C_1

CALL Prog_C_2

……

END IF

IF R[6]==0 //判断是否有剩余工件

GOTO LBL[2]

ELSE

GOTO LBL[1]

END IF

END IF

LBL[2]:

END

  • 视觉定位计算流程

调用拍照指令,工位1拍照,获得该工位上摆放的工件的点云数据,如下图所示。

调用视觉计算指令,视觉软件会用list文件中所有名称相同的pcd和pose文件去做匹配。

说明

每次只匹配一个工件。

匹配成功则返回定位矩阵M和工件编号(工件编号为list文件中的工件名称编号。如果定位出A工件,则返回1)。同时,工件A所在区域会被标记,不再参与计算。

然后主程序根据工件编号执行对应子程序。

IF wp==1 //工件1,对应A

CALL Prog_A_1

CALL Prog_A_2

……

再次调用视觉计算指令,定位出工件C,返回定位结果矩阵和工件编号。

然后主程序根据工件编号执行对应子程序。

IF wp==3 //工件3,对应C

CALL Prog_C_1

CALL Prog_C_2

……

再次调用视觉计算指令,定位出工件B,返回定位结果矩阵和工件编号。

然后主程序根据工件编号执行对应子程序。

IF wp==2 //工件2,对应B

CALL Prog_B_1

CALL Prog_B_2

……

再次调用视觉计算指令,视觉软件判断所有工件都被标记,认为所有工件焊接完成,焊接结束。

主程序结束,当前工位焊接完成

多工位在线更新程序示例及释义

ProgCall(ClearData);//清空定位数据

//获取离线生成的多工位程序及工件、程序数量存放到工程变量中

i:=1;

j:=wb1wpProgCount[1]+1;

LOOP(j)DO

g_wb1wpProgCount[i]:=wb1wpProgCount[i];//获取工位1程序及工件数量

i:=i+1;

END_LOOP

i:=1;

j:=wb2wpProgCount[1]+1;

LOOP(j)DO

g_wb2wpProgCount[i]:=wb1wpProgCount[i];//获取工位2程序及工件数量

i:=i+1;

END_LOOP

i:=1;

j:=0;

err:=StringToNum(StrArrayProg1[1],j);

j:=j+1;

LOOP(j)DO

g_StrArrayProg1[i]:=StrArrayProg1[i];//获取工位1程序数量及程序名

i:=i+1;

END_LOOP

i:=1;

j:=0;

err:=StringToNum(StrArrayProg2[1],j);

j:=j+1;

LOOP(j)DO

g_StrArrayProg2[i]:=StrArrayProg2[i];//获取工位2程序数量及程序名

i:=i+1;

END_LOOP

获取在线更新数据板块

flag:=0;//执行双工位标志

BINO_MIS_MATCH:=0; //拍照计数初始化

err:=robotSmart_comm(WorkMode,string1,string2,type);//获取待执行工位

IF(!err)THEN////获取工位失败则报错

Message("get WorkMode error!",eError,*,*,TRUE,FALSE);

END_IF

IF(CurStation==1)THEN

LP:work_1;

workpieceNum:=LX_CAM1_GW1();//工位1拍照,若定位成功获取工件号,失败则重复进行,超过两次,程序结束

IF(!workpieceNum)THEN

BINO_MIS_MATCH:=BINO_MIS_MATCH+1;

Message("scan error",eWarning,*,*,TRUE,TRUE);

IF(BINO_MIS_MATCH>2)THEN//拍照次数超过两次报错,程序结束

BINO_MIS_MATCH:=0;

Message("scan error",eError,*,*,TRUE,FALSE);

END_IF

GOTO(work_1);

END_IF

ELSIF(CurStation==2)THEN

LP:work_2;

workpieceNum:=LX_CAM1_GW2();//工位2拍照,若定位成功获取工件号,失败则重复进行,超过两次,程序结束

IF(!workpieceNum)THEN

BINO_MIS_MATCH:=BINO_MIS_MATCH+1;

Message("scan error",eWarning,*,*,TRUE,TRUE);

IF(BINO_MIS_MATCH>2)THEN//拍照次数超过两次报错,程序结束

BINO_MIS_MATCH:=0;

Message("scan error",eError,*,*,TRUE,FALSE);

END_IF

GOTO(work_2);

END_IF

ELSIF(CurStation==-1)THEN//若获取工位是-1,则执行双工位

flag:=1;

CurStation:=1;

GOTO(work_1); //跳转到work_1

END_IF

拍照定位、获取工件编号板块

LP:ReCut;

IF(CurStation==1)THEN

IF(workpieceNum==1)THEN

err:=UpdateProg(workpieceNum,CurStation);//执行工位1第一个工件的在线更新程序

IF(!err)THEN//更新失败则报错

Message("Update Program error!",eError,*,*,TRUE,FALSE);

END_IF

ProgLoad(CutWeld.sr\WeldPath6_exec);//加载程序

ProgCall(CutWeld.sr\WeldPath6_exec);//执行程序

ELSIF(workpieceNum==2)THEN

err:=UpdateProg(workpieceNum,CurStation);//执行工位1第二个工件的在线更新程序

IF(!err)THEN//更新失败则报错

Message("Update Program error!",eError,*,*,TRUE,FALSE);

END_IF

ProgLoad(CutWeld.sr\WeldPath5_exec);//加载程序

ProgCall(CutWeld.sr\WeldPath5_exec);//执行程序

ProgLoad(CutWeld.sr\WeldPath11_exec);//加载程序

ProgCall(CutWeld.sr\WeldPath11_exec);//执行程序

ELSE

Message("not have cutpath",eError,*,*,TRUE,FALSE);

END_IF

workpieceNum:=CalcData();//再次定位计算,检查是否有剩余工件

IF(!workpieceNum)THEN//若没有剩余工件,程序结束

Message("no extra workpieces",eInfo,*,*,TRUE);

GOTO(EndCut);

END_IF

GOTO(ReCut);//若有剩余工件,则跳转到ReCut,继续执行对应的工件号程序

ELSIF(CurStation==2)THEN

IF(workpieceNum==1)THEN

err:=UpdateProg(workpieceNum,CurStation);//执行工位2第一个工件的在线更新程序

IF(!err)THEN//更新失败则报错

Message("Update Program error!",eError,*,*,TRUE,FALSE);

END_IF

ProgLoad(CutWeld.sr\WeldPath12_exec);//加载程序

ProgCall(CutWeld.sr\WeldPath12_exec);//执行程序

ProgLoad(CutWeld.sr\WeldPath13_exec);//加载程序

ProgCall(CutWeld.sr\WeldPath13_exec);//执行程序

ELSE

Message("not have cutpath",eError,*,*,TRUE,FALSE);

END_IF

workpieceNum:=CalcData();//再次定位计算,检查是否有剩余工件

IF(!workpieceNum)THEN//若没有剩余工件,程序结束

Message("no extra workpieces",eInfo,*,*,TRUE);

GOTO(EndCut);

END_IF

GOTO(ReCut);//若有剩余工件,则跳转到ReCut,继续执行对应的工件号程序

END_IF

LP:EndCut;

IF(flag==1)THEN//执行双工位的标志

flag:=0;

CurStation:=2;//重置标志及工位

GOTO(work_2);//跳转到work_2

END_IF

EOF

在线更新、执行程序及多工件检查板块

  1. 子程序示例

PTP(ap0,NULL,NULL,tool_C4D,WORLD); //安全点

PTP(ap20879,NULL,NULL,tool_C4D,WORLD); //过渡点

PTP(ap20880,NULL,NULL,tool_C4D,WORLD); //过渡点

ProgCall(CutWeld.sr\kaihuzhao); //开护罩

linkStatus:=vision_link();//连接视觉软件

IF(!linkStatus)THEN

Pause();

END_IF

Lin(cp20864,sp_trans,NULL,NULL,tool_C4D,WORLD); //接近点

Lin(cp20865,sp_scan,NULL,NULL,tool_C4D,WORLD); //扫描起点

task:=3; //任务编号

loop:=0;

MyStartScan(task,workpiece,loop); //开始扫描

Lin(cp20866,sp_scan,olr0,NULL,tool_C4D,WORLD);

Lin(cp20867,sp_scan,olr0,NULL,tool_C4D,WORLD);

Lin(cp20868,sp_scan,olr0,NULL,tool_C4D,WORLD);

MyStopScan();//停止点

Lin(cp20869,sp_trans,NULL,NULL,tool_C4D,WORLD);

PTP(ap20881,NULL,NULL,tool_C4D,WORLD);

MyParaValues[1]:=50; //焊接点步长

MyParaValues[2]:=-10; //焊接循环点数

MyParaValues[3]:=0; //X向偏移距离

MyParaValues[4]:=0; //Y向偏移距离

MyParaValues[5]:=0; //Z向偏移距离

MyParaValues[6]:=0; //Rx旋转角度

MyParaValues[7]:=0; //Ry旋转角度

MyParaValues[8]:=0; //Rz旋转角度

MyParaValues[9]:=0; //起始焊接偏移量

MyParaValues[10]:=0; //终止焊接偏移量

MyParaValues[11]:=-100000; //焊接段长度,<0时焊接路径反向

MyPosValues[1]:=cp20874; //焊接示教点

MyPosValues[2]:=cp20873; //焊接示教点

MyPosValues[3]:=cp20872; //焊接示教点

MyPosValues[4]:=cp20871; //焊接示教点

Lin(cp20870,sp_trans,NULL,NULL,tool_C4D,WORLD);

PosCount:=4; //焊接示教点个数

MyScanWeld(workpiece,loop,-1,-1,-1,-1,ParamCount,PosCount); //开始计算

vision_dislink();//断开视觉软件

ProgCall(CutWeld.sr\guanhuzhao); //关护罩

cp2087400:=MyGetStartPoint();

cp2087100:=MyGetEndPoint();

Lin(cp2087400,sp_trans,NULL,NULL,tool_C4D,WORLD);

ARCMODE(1);

WaitIsFinished();

ARCON(arcon0,arc0); //起弧

index:=2;

len0:=MyRecvPointLength-2; //获得计算结果

LOOP(len0)DO;

rcp100:=MyRecvPoints[index];

index:=index+1;

WLin(rcp100,NULL,olr0,NULL,wd0,NULL,tool_C4D,WORLD); //焊接

END_LOOP

WLin(cp2087100,NULL,olr0,NULL,wd0,NULL,tool_C4D,WORLD); //焊接

ARCOFF(arcoff0); //关弧

linkStatus:=vision_link();

IF(!linkStatus)THEN

Pause();

END_IF

Lin(cp20875,sp_trans,NULL,NULL,tool_C4D,WORLD);

apTemp := MyAxisOffExt(ap0,ext_e1,ext_e2,ext_e3);

PTP(apTemp,NULL,NULL,tool_C4D,BASE_DATA); //安全点