一.干涉的定义
机器人的部件损坏 |
任何因干涉而造成的不良后果,都将为客户带来不 可估计的损失! |
机器人程序混乱 | |
加工中的工件损坏 | |
周边其他设备设施的损坏 |
二.干涉区间
1 |
Rob1机器人进入干涉区前,发送从机欲进入干涉区的请求信号,并检测Rob2作为主机是否发送欲进入干涉区的请求信号。如果主机Rob2进入干涉区的请求信号被激活,无论此时Rob2进入或则即将进入干涉区,此时Rob1都将停止运动并等待Rob2完成运动退出干涉区。 |
2 | 如果Rob1和Rob2同时发出欲进入干涉区的请求信号,Rob2机器人优先进入,此时Rob1都将停止运动并等待Rob2完成运动退出干涉区。 |
3 |
如果Rob1作为从机已进入干涉区时,Rob2若想进入干涉区,Rob2必须停止运动并等待Rob1完成运动退出干涉区。 |
创建名为Interlock的程序主要适用于存在有关联的机器人组之间互锁,该程序包含源代码SRC文件和数据文件DAT两个文件:
1.Interlock.dat数据文件说明:
①枚举类型互锁指令E_LOCKTYPE:
GLOBAL ENUM E_LOCKTYPE ENTER_LOCK_M,ENTER_LOCK_S,LEAVE_LOCK,CYC_CONTROL,RESET_LOCK
互锁命令 |
说明 |
ENTER_LOCK_M |
作为主机器人进入干涉区 |
ENTER_LOCK_S |
作为从机器人进入干涉区 |
LEAVE_LOCK |
机器人退出干涉区 |
CYC_CONTROL |
激活干涉区监控中断 |
RESET_LOCK |
初始化并释放干涉区 |
②结构体型互锁信号S_LOCKSIG:
GLOBAL STRUC S_LOCKSIG INT ROB_IN,INT ROB_OUT
互锁信号 |
说明 |
ROB_IN |
其他机器人许可当前机器人进入干涉区的输入信号:TRUE表示许可 |
ROB_OUT |
当前机器人进入干涉区请求的输出信号:FALSE表示请求 |
③用于诊断的当前机器人激活干涉区号zLockNumber:
GLOBAL INT zLockNumber=3
④干涉区监控的中断及循环旗帜的定义:
GLOBAL CONST INT czCollInterrupt=1 ;定义干涉区监控的中断等级
GLOBAL CONST INT czCycCollision=1 ;定义干涉区监控的循环旗帜号
⑤信号安全检测时间,与SPS扫描周期:
GLOBAL CONST REAL crDeadtime=0.200000003 ;信号安全检测时间,与SPS扫描周期
⑥干涉区互锁信号:
SIGNAL giRobotInterlock $IN[89] TO $IN[104] ;许可当前机器人进入干涉区的输入信号组
SIGNAL goRobotInterlock $OUT[89] TO $OUT[104] ;当前机器人进入干涉区请求的输出信号组
DECL S_LOCKSIG TABLE_LOCK[16] ;定义机器人干涉区的互锁表
TABLE_LOCK[1]={ROB_IN 89,ROB_OUT 89} ;机器人干涉区的互锁1
TABLE_LOCK[2]={ROB_IN 90,ROB_OUT 90} ;机器人干涉区的互锁2
TABLE_LOCK[3]={ROB_IN 91,ROB_OUT 91} ;机器人干涉区的互锁3
TABLE_LOCK[4]={ROB_IN 92,ROB_OUT 92} ;机器人干涉区的互锁4
TABLE_LOCK[5]={ROB_IN 93,ROB_OUT 93} ;机器人干涉区的互锁5
TABLE_LOCK[6]={ROB_IN 94,ROB_OUT 94} ;机器人干涉区的互锁6
TABLE_LOCK[7]={ROB_IN 95,ROB_OUT 95} ;机器人干涉区的互锁7
TABLE_LOCK[8]={ROB_IN 96,ROB_OUT 96} ;机器人干涉区的互锁8
TABLE_LOCK[9]={ROB_IN 97,ROB_OUT 97} ;机器人干涉区的互锁9
TABLE_LOCK[10]={ROB_IN 98,ROB_OUT 98} ;机器人干涉区的互锁10
TABLE_LOCK[11]={ROB_IN 99,ROB_OUT 99} ;机器人干涉区的互锁11
TABLE_LOCK[12]={ROB_IN 100,ROB_OUT 100} ;机器人干涉区的互锁12
TABLE_LOCK[13]={ROB_IN 101,ROB_OUT 101} ;机器人干涉区的互锁13
TABLE_LOCK[14]={ROB_IN 102,ROB_OUT 102} ;机器人干涉区的互锁14
TABLE_LOCK[15]={ROB_IN 103,ROB_OUT 103} ;机器人干涉区的互锁15
TABLE_LOCK[16]={ROB_IN 104,ROB_OUT 104} ;机器人干涉区的互锁16
2.Interlock.src源程序文件说明:
①Interlock源程序包含以下子程序:
子程序名 |
说明 |
ANTI_COLLISION |
互锁程序 |
STOP_ROB |
互锁程序中的中断程序 |
Msg_Anticoll |
互锁激活的信息提示程序 |
SetMsg |
设置信息提示的程序 |
②互锁程序ANTI_COLLISION(eiLockType:IN,ziLockNum:IN):
传递参数 |
类型 |
取值 |
说明 |
eiLockType |
E_LOCKTYPE |
#ENTER_LOCK_M |
作为主机请求进入干涉区 |
#ENTER_LOCK_S |
作为从机请求进入干涉区 |
||
#LEAVE_LOCK |
离开干涉区 |
||
#CYC_CONTROL |
干涉区初始化:激活互锁中断 |
||
#RESET_LOCK |
干涉区初始化:重置输出信号 |
||
ziLockNum |
INT |
1…16 |
互锁序号:与TABLE_LOCK相对 |
●#ENTER_LOCK_M程序逻辑:
1 | 禁用干涉区监控中断; |
2 |
判断从站机器人是否已在该干涉区: 1.若该值为真,表示与之对应的机器人不在该干涉区,此时输出进入干涉区请求信号假值; 2.若该值为假,则表示与之对应的机器人在该干涉区,此时中间变量nbOK置为假,并提示信息-主机该干涉区被其他从机器人激活,并等待从站机器人在该干涉区的信号为真,输出从站机器人在该干涉区激活多久的信息;在循环中等待从站机器人在该干涉区的信号为真,此时输出进入干涉区请求信号; |
3 |
激活干涉区监控中断; |
●#ENTER_LOCK_S程序逻辑:
1 |
禁用干涉区监控中断 |
2 |
中间变量nbOK置为假,并提示信息-该干涉区被主机器人激活,进入循环判断,判断主机器人是否已激活 该干涉区: 若该值为真,输出进入干涉区请求信号假值;等待一个时间在判断判断主机器人激活该干涉区:如果该值为真,则将中间变量置真,并退出循环;若该值为假,则将输出进入干涉区请求信号真值,让主机器进入干涉区,该从机器人继续等待主机器人激活该干涉区值为真; |
3 | 输出进入干涉区请求信号假值; |
4 |
激活干涉区监控中断; |
●#LEAVE_LOCK程序逻辑:
1 | 如果机器人不在路径上,则等待机器人在路径上; |
2 | 输出进入干涉区请求信号真值; |
●#RESET_LOCK程序逻辑:
1 |
等待机器人在路径上; |
2 | 输出进入干涉区请求信号真值; |
●#CYC_CONTROL程序逻辑:
1 |
定义因互锁引起的停机中断; |
2 | 关闭中断; |
3 |
定义中断中的循环旗帜; |
4 | 开启中断; |
5 |
激活中断; |
代码:
DEF Interlock( )
END
;-------------Interlock Active----------------------
GLOBAL DEF ANTI_COLLISION(eiLockType:IN, ziLockNum:IN)
DECL E_LOCKTYPE eiLockType
DECL INT ziLockNum
DECL BOOL nbOK
CONTINUE
IF VARSTATE("ziLockNum")<>#INITIALIZED THEN
MsgQuit("Lock area not initialized")
HALT
ELSE
IF ziLockNum>16 OR ziLockNum<1 THEN
MsgQuit("Lock area msut be 1 to 16!")
HALT
ENDIF
ENDIF
SWITCH eiLockType
; --- Enter Collision Zone as Master ---
CASE #ENTER_LOCK_M
WAIT SEC 0
INTERRUPT DISABLE czCollInterrupt ; Disable Monitoring
IF ($IN[TABLE_LOCK[ziLockNum].ROB_IN]) THEN
$OUT[TABLE_LOCK[ziLockNum].ROB_OUT]=FALSE
ELSE
nbOK=FALSE
MSG_ANTICOLL(ziLockNum)
REPEAT
IF ($IN[TABLE_LOCK[ziLockNum].ROB_IN]) THEN
nbOK=TRUE
ELSE
nbOK=FALSE
ENDIF
WAIT SEC 0.01 ; Sampling 100 ms
UNTIL (INSTRUCTION_OK==TRUE)
$OUT[TABLE_LOCK[ziLockNum].ROB_OUT]=FALSE
ENDIF
INTERRUPT ENABLE czCollInterrupt ; Enable Monitoring
; --- Enter Collsion Zone as Slave ---
CASE #ENTER_LOCK_S
WAIT SEC 0
INTERRUPT DISABLE czCollInterrupt ; Disable Monitoring
nbOK=FALSE
MSG_ANTICOLL(ziLockNum)
REPEAT
IF ($IN[TABLE_LOCK[ziLockNum].ROB_IN]) THEN
$OUT[TABLE_LOCK[ziLockNum].ROB_OUT]=FALSE
WAIT SEC crDeadtime
IF ($IN[TABLE_LOCK[ziLockNum].ROB_IN]) THEN
nbOK=TRUE
ELSE
nbOK=FALSE
$OUT[TABLE_LOCK[ziLockNum].ROB_OUT]=TRUE
ENDIF
ENDIF
WAIT SEC 0.01 ; Sampling 100 ms
UNTIL (nbOK==TRUE)
$OUT[TABLE_LOCK[ziLockNum].ROB_OUT]=FALSE
INTERRUPT ENABLE czCollInterrupt ; Enable Monitoring
; --- Leave Collision Zone ---
CASE #LEAVE_LOCK
CONTINUE
IF NOT $ON_PATH THEN
WAIT FOR $ON_PATH
ENDIF
TRIGGER WHEN DISTANCE=1 DELAY=0 DO $OUT[TABLE_LOCK[ziLockNum].ROB_OUT]=TRUE
; --- Initialize Collision Zone ---
CASE #RESET_LOCK
WAIT SEC 0
WAIT FOR $ON_PATH
$OUT[TABLE_LOCK[ziLockNum].ROB_OUT]=TRUE
; --- Prepare for permanent Monitoring---
CASE #CYC_CONTROL
GLOBAL INTERRUPT DECL czCollInterrupt WHEN NOT $CYCFLAG[czCycCollision] DO STOP_ROB( )
INTERRUPT OFF czCollInterrupt
$CYCFLAG[czCycCollision]=TRUE
$CYCFLAG[czCycCollision]=(((goRobotInterlock B_EXOR 'B1111111111111111') B_AND giRobotInterlock) == (goRobotInterlock B_EXOR 'B1111111111111111'))
INTERRUPT ON czCollInterrupt
INTERRUPT ENABLE czCollInterrupt
; --- WARNING: Program Failure Interlocks ---
DEFAULT
HALT
MsgNotify("Unknown Collision Setting!Please Switch Ti Mode!")
WAIT FOR $T1
ENDSWITCH
END
GLOBAL DEF STOP_ROB ( )
; *** Stop Movement by Interlock Monitoring***
BRAKE
setmsg (99,3,0)
WAIT FOR $CYCFLAG[czCycCollision]
END
GLOBAL DEF Msg_Anticoll(ziLockNum :IN)
DECL INT ziLockNum
DECL REAL nrTimer
nrTimer=0.0
zLockNumber=ziLockNum
;Message Output
setmsg (ziLockNum,1,nzTimer)
$TIMER_STOP[20]=TRUE
$TIMER[20]=0
$TIMER_STOP[20]=FALSE
REPEAT
WAIT sec .01
UNTIL ($IN[TABLE_LOCK[ziLockNum].ROB_IN])==TRUE
$TIMER_STOP[20]=TRUE
nrTimer=$TIMER[20]
nrTimer=nrTimer/1000.0
setmsg (ziLockNum,2,nrTimer)
END
GLOBAL DEF SetMsg(ziLockNum:IN,ziMsg:IN,riPar:IN )
DECL KrlMsg_T Msg
DECL KrlMsgPar_T Par[3]
DECL KrlMsgOpt_T Opt
DECL INT nzHandle
DECL INT ziLockNum, ziMsg
DECL REAL riPar
;selec Msssage Text---------------------
SWITCH ziMsg
CASE 1 ;Interlock is Active
Msg = {Modul[] "Interlock", Nr 007, Msg_txt[] "Interlock Area %1 is Active!"}
CASE 2 ;Interlock was active
Msg = {Modul[] "Interlock", Nr 008, Msg_txt[] "Interlock Area %1 was active %2[s] ago!"}
CASE 3 ;Interlock Cycflag has triggered
Msg = {Modul[] "Interlock", Nr 009, Msg_txt[] "Collision Monitoring has Triggered!"}
ENDSWITCH
;Configuration of message parameter --------
Par[1] = {PAR_TYPE #VALUE, PAR_INT 0}
Par[1].PAR_INT = ziLockArea
Par[2] = {PAR_TYPE #VALUE, PAR_REAL 00.0}
Par[2].PAR_REAL = riPar
;Message Options ------------------------------------
Opt = {Vl_STOP FALSE, CLEAR_P_RESET TRUE, CLEAR_P_SAW FALSE, LOG_TO_DB TRUE}
;Message generation---------------------------
nzHandle = SET_KRLMSG (#NOTIFY, Msg, Par[], Opt)
END
四.互锁信号程序的使用:
1.初始化干涉监控:
ANTI_COLLISION(#CYC_CONTROL,0 )
2.重置并释放干涉区信号-依据自己需求:
ANTI_COLLISION(#RESET_LOCK,1)
ANTI_COLLISION(#RESET_LOCK,2)
ANTI_COLLISION(#RESET_LOCK,3)
ANTI_COLLISION(#RESET_LOCK,4)
ANTI_COLLISION(#RESET_LOCK,5)
ANTI_COLLISION(#RESET_LOCK,6)
ANTI_COLLISION(#RESET_LOCK,7)
ANTI_COLLISION(#RESET_LOCK,8)
3.进入干涉区:
-作为主机器人进入:
ANTI_COLLISION(#ENTER_LOCK_M,3)
ANTI_COLLISION(#ENTER_LOCK_M,4) ;三台机器人同时进入该区域
ANTI_COLLISION(#ENTER_LOCK_M,5)
-作为从机器人进入:
ANTI_COLLISION(#ENTER_LOCK_S,3)
ANTI_COLLISION(#ENTER_LOCK_S,4) ;三台机器人同时进入该区域
ANTI_COLLISION(#ENTER_LOCK_S,5)
复杂的互锁建议***好由PLC来统一处理;
4.退出干涉区:
ANTI_COLLISION(#LEAVE_LOCK,3)
五.说明:
本文主要讲述***优先干涉区的设定,此种方法必须区分主次关系,主机器人获得***的优先处理的权力,而从机器人在遇到主从机器人同时进入干涉区时,获得的优先级低于主机器人,必须等待主机器人处理完退出干涉区之后才能进入。