Fanuc 机器人二次开发(Socket通讯加数据传输)

        在开发Yaskawa机器人之前,同样开发过Fanuc机器人,在我接触Fanuc机器人的时候,我还吐槽那老式的示教器极其难用,设置也不是特别合理,直到碰到了Yaskawa。过段时间,又得去摸Nachi机器人,适配这个工作既不能了解比较深的学问,又得时常去摸别的品牌的机器人,被一些难搞的设计整的头皮发麻,最重要的还是很无聊,适配的经验就是先摸清楚程序怎么运行,怎么能去控制机器人,再考虑逻辑怎么写,测试环境也要考察一下,才能顺利进行下去。

        言归正传,Fanac机器人要想在后台时刻通讯,必须要把karel设置功能开启,并将程序运行设置成电源开启后自动运行。机器人的选项包可以在ROBOGUIDE仿真里面看一下,网络通讯使用的是socket选项包,并且要把系统变量的karel enable修改一下。测试时,把karel编译的.pc程序插U盘导入在实际的机器人上进行运行。Fanuc好在不需要像Yaskawa一样只能实机测试软件,在没有机器人实机的条件下,可以在仿真环境下运行。但是Karel程序不能主动的控制机器人运动,需要编写额外的示教程序,然后在Karel程序里面进行调用,我之前的项目是通过通信,将机器人当时的位姿记录下来,记录完成后,自动的按照传输的点位进行运动。

        Fanuc机器人的控制组很容易被程序占用,如果是不进行控制的程序,记得在程序详细里把控制组修改成全都是0。为了保密,这里只分享一点通用的代码,包括Socket通信、获取当前的姿态信息、数据打包、数据转换、发送。如果想自动化运行的话,可以写个另外的控制程序,在后台运行通信程序的时候,再运行另外一个karel控制程序来调用运动的TP程序。通信程序将想移动到的点位、运动参数等都写在寄存器里,TP程序读取寄存器进行运动,而两个karel程序之间可以采用CMOS变量进行通讯。在karel设置里可以同时运行两个karel程序,只要保证控制组不冲突,并且忽略报警跟报错即可,即本资源代码的前几行,把注释删掉即可。

PROGRAM TCP_TEST
%NOLOCKGROUP

--%NOPAUSE  = ERROR + TPENABLE + COMMAND
--%NOABORT = ERROR + TPENABLE + COMMAND

CONST 
    ROBOT_STATE_SIZE = 8      --size of robot state
    data_package_length = 50  --number of data packet byte


VAR
    g_move_target_data  IN CMOS FROM Main_TEST: ARRAY[12] OF REAL  --robot move parameter
    g_move_parmas_data  IN CMOS FROM Main_TEST: ARRAY[2] OF INTEGER   --robot type parameter
    order_head : ARRAY[4] OF BYTE                                        --order hedd of data packet
    loop_connect :  BOOLEAN                                              --flag of TCP Connect 
    fileVar  : FILE                                                      --recieve and send data by this file 
    data_buffer : ARRAY[data_package_length] OF BYTE                     --byte type of send data
    send_data : ARRAY[data_package_length] OF STRING[1]                  --send data transform to ASCⅡ
    recv_data : ARRAY[data_package_length] OF STRING[1]                  --recieve data from host software 
    cur_time : STRING[20]                                                --current time
    i,n,j,m : INTEGER                                                    --iterator
    status : INTEGER   
    loop : BOOLEAN                                                        --itrator in routine
CONST
    TCPSever = 'S1:' --sever port of system par
    
TYPE 
    RoboTarget = STRUCTURE
        current_joint : JOINTPOS
        current_pose : XYZWPR
    ENDSTRUCTURE

-------------------------------------------------------------------------  
ROUTINE VariableInit FROM TCP_TEST                                  --*√*state Init
ROUTINE InterruptInit FROM TCP_TEST                                --*√*get home_detect state
ROUTINE TcpInit FROM TCP_TEST                                      --*√*create tcp connect with a cilent 
ROUTINE Analyze FROM TCP_TEST                                      --analyze data packet from host-software
ROUTINE SendStateData FROM TCP_TEST                                  --collect and transform state data for send
ROUTINE Oxtofloat(data:ARRAY[*] OF STRING) : REAL FROM  TCP_TEST    --*√*transform Ox to float. input 4 byte = ARRAY[8] OF STRING[1], output: float
ROUTINE Oxtoint(data:ARRAY[*] OF STRING) : INTEGER FROM TCP_TEST     --*√*transform Ox to int. input 1 byte = ARRAY[2] OF STRING[1], output: INTEGER   
ROUTINE GET_CUR_TIME : STRING FROM TCP_TEST                         --*√*get current time. output: string
ROUTINE inttoOx(data : INTEGER) : ARRAY[*] OF STRING FROM TCP_TEST   --*√*transform int to Ox. input: INTEGER, output 1 byte = ARRAY[2] OF STRING[1] 
ROUTINE send_TCP(data:ARRAY[*] OF STRING) FROM TCP_TEST             --*√*operation of send data packet to cilent. input: STRING[96] 
ROUTINE SplitData FROM TCP_TEST                                     --Split data packet to per-type
ROUTINE GET_ACTRO_SPEED : REAL FROM TCP_TEST                        --*√*get current robot tcp speed
-------------------------------------------------------------------------  

BEGIN
    WRITE(CHR(128),CHR(137)) -- clear TP user window
    VariableInit
    TcpInit
    Analyze

END TCP_TEST

------------------------------------------------------------------------- 
--Step1.2.2: local var variable declaration
--Init Robot State

ROUTINE VariableInit 
VAR 
	entry : INTEGER
BEGIN
    g_analyze_complete = FALSE 
    SET_VAR(entry, '*SYSTEM*','$SCR_GRP[1].$M_POS_ENB',TRUE,status)
    SET_VAR(entry, '*SYSTEM*','$SCR_GRP[1].$M_DST_ENB',TRUE,status) --set param for current speed
    $GROUP[1].$UTOOL = $MNUTOOL[1,1]                                --uTool 1  set param for get cur pos
	$GROUP[1].$UFRAME = $MNUFRAME[1,1]                              --uFrame 1
END VariableInit

------------------------------------------------------------------------- 
--Init Tcp Socket 
ROUTINE TcpInit
VAR 
    status : INTEGER
    dataType : INTEGER
    entry : INTEGER
CONST 
    --IP = '192.168.1.1'
    SeverPort = 8800
BEGIN 
    dataType = 3 --1 : INTEGER   2 : REAL  3 : STRING
    SET_FILE_ATR(fileVar,ATR_IA)
    SET_VAR(entry, '*SYSTEM*','$HOSTS_CFG[1].$SERVER_PORT',SeverPort,status)
    MSG_DISCO(TCPSever,status)
    WRITE('~robot start listening~',CR)
    MSG_CONNECT(TCPSever,status)
    IF status = 0 THEN
        WRITE('TCP connect successful',CR)
    ENDIF
    WRITE ('Robot start read file',CR)
    OPEN FILE fileVar('RW',TCPSever)
    status =  IO_STATUS(fileVar)
    IF status <> 0 THEN 
        WRITE('file open fail',CR)
    ENDIF
END TcpInit

------------------------------------------------------------------------- 
--read data packet and analyze
ROUTINE Analyze 
VAR
    order_type : INTEGER
    entry : INTEGER
    status : INTEGER
    temp_str : STRING[100]
   
BEGIN 
	loop = TRUE
	WHILE loop DO	
	    BYTES_AHEAD(fileVar, entry, status)
	    DELAY 50
	    IF status <> 0  THEN 
	        WRITE('return entry-data fail',CR)
	    ELSE
	        IF entry = 50 THEN   --READ 50 CHAR
	            READ fileVar (temp_str :: 50)
	            status = IO_STATUS(fileVar)
	            IF status <> 0 THEN
	                WRITE('read recvfile fail',CR)
	            ELSE 
	                FOR i = 1 TO 50 DO
	                recv_data[i] = SUB_STR(temp_str,i,1) 
	                WRITE(recv_data[i])
	                ENDFOR
	                SplitData --处理数据
	                SendStateData --发送数据
	                WRITE('recv error type data',CR)
	                ENDSELECT
	            ENDIF
	         ENDIF
	    ENDIF
	ENDWHILE
END Analyze


 ------------------------------------------------------------------------- 
--send datapcket to host software
ROUTINE SendStateData
CONST
    JOINT_SIZE = 6
    POSE_SIZE = 6
    MOVE_PARAM = 2
VAR
    Current_data : RoboTarget
    Dealy_data : RoboTarget
    Joint_array : ARRAY[9] OF REAL
    joint_data : ARRAY[JOINT_SIZE] OF REAL
    pose_data : ARRAY[POSE_SIZE] OF REAL  
    temp_byte : ARRAY[8] OF BYTE
    status :INTEGER
    act_speed : REAL
    move_type : INTEGER --control robot move type
    temp_int : INTEGER
BEGIN

    Current_data.current_joint = CURJPOS(0,0)
    Current_data.current_pose = CURPOS(0,0)
    CNV_JPOS_REL(Current_data.current_joint,Joint_array,status)
    FOR i = 1 TO 6 DO
        joint_data[i] = Joint_array[i] --获取当前角度
    ENDFOR
    pose_data[1] = Current_data.current_pose.w --获取当前基于基座的法兰偏移值
    pose_data[2] = Current_data.current_pose.p
    pose_data[3] = Current_data.current_pose.r
    pose_data[4] = Current_data.current_pose.x
    pose_data[5] = Current_data.current_pose.y
    pose_data[6] = Current_data.current_pose.z

    act_speed = GET_ACTRO_SPEED --获取当前速度

    --joint_data    
    j = 1
    FOR i = 1 TO JOINT_SIZE DO
        ADD_REALPC(temp_byte,1,joint_data[i],status)
        data_buffer[(4*j-3)] = temp_byte[3]
        data_buffer[(4*j-2)] = temp_byte[4]
        data_buffer[(4*j-1)] = temp_byte[5]
        data_buffer[(4*j)] = temp_byte[6]
        j = j + 1
    ENDFOR 

    --pose_data
    j = 1
    FOR i = 1 TO POSE_SIZE DO 
        ADD_REALPC(temp_byte,1,pose_data[i],status)
        data_buffer[(24+4*j-3)] = temp_byte[3]
        data_buffer[(24+4*j-2)] = temp_byte[4]
        data_buffer[(24+4*j-1)] = temp_byte[5]
        data_buffer[(24+4*j)] = temp_byte[6]
        j = j + 1 
    ENDFOR
    data_buffer[49] = act_speed
    data_buffer[50] = move_type
    --transform byte data to ASCⅡstring
    FOR i = 1 TO 50 DO
    	temp_int = data_buffer[i]    --将浮点数转换成十六进制的字节
        send_data[i] = CHR(temp_int) --转换成字符
    ENDFOR
    --send send_data by socket
    send_TCP(send_data)
END SendStateData

------------------------------------------------------------------------- 
--send data use tcp connect
ROUTINE send_TCP
VAR
    status : INTEGER
BEGIN
    WRITE fileVar(data)
    status  = IO_STATUS(fileVar)
    IF status = 0 THEN
        WRITE('send data successful',CR)
    ENDIF
END send_TCP


-------------------------------------------------------------------------
--get current time 
ROUTINE GET_CUR_TIME
VAR
    CURTIME : INTEGER
    DATA_TIME : STRING[50]
BEGIN
    GET_TIME(CURTIME)
    CNV_TIME_STR(CURTIME,DATA_TIME)
    RETURN (DATA_TIME)
END GET_CUR_TIME

-------------------------------------------------------------------------
--spilt data packet and 
ROUTINE SplitData
VAR
    --ASCⅡ
    joint_str : ARRAY[48] OF STRING[1]
    pose_str : ARRAY[48] OF STRING[1]
    MoveTarget_str : ARRAY[48] OF INTEGER --FLOAT   4BYTE/PER
    MoveParams_str : ARRAY[2] OF INTEGER  --INT     1BYTE/PER
    temp_real : ARRAY[8] OF REAL
    inttoOx_str : ARRAY[2] OF STRING[1]
    temp_str : ARRAY[8] OF STRING[1]
    temp_int : INTEGER
BEGIN
	WRITE(CR)
    FOR i = 1 TO 48 DO
        MoveTarget_str[i] = ORD(recv_data[i+4],1)
    ENDFOR
    FOR i = 1 TO 2 DO 
        MoveParams_str[i] = ORD(recv_data[i + 48],1)  --字符转换成十六进制的byte
    ENDFOR

    FOR i = 1 TO 24 DO
    	temp_int = MoveTarget_str[i]
    	inttoOx_str = inttoOx(temp_int) --Byte整数转换成十六进制字符
        joint_str[(2*i-1)] = inttoOx_str[1] 
        joint_str[(2*i)] = inttoOx_str[2]
        WRITE(CR,joint_str[1],joint_str[2])  
    ENDFOR

    FOR i = 25 TO 48 DO
    	temp_int = MoveTarget_str[i]
    	inttoOx_str = inttoOx(temp_int)
        pose_str[(2*i-49)] = inttoOx_str[1]
        pose_str[(2*i-48)] = inttoOx_str[2]
    ENDFOR
    ------------------------------------------------
    FOR i = 1 TO 4 DO
        recv_head[i] = OrderHead_str[i]
    ENDFOR
    
    FOR i = 1 TO 6 DO
    	FOR j = 1 TO 8 DO
	        temp_str[j] = joint_str[i*8-8+j]
    	ENDFOR
    		temp_real[i] = Oxtofloat(temp_str) --十六进制转换成浮点数
	        g_move_target_data[i] = temp_real[i]
    ENDFOR 

    FOR i = 1 TO 6 DO
    	FOR j = 1 TO 8 DO
        temp_str[j] = pose_str[i*8-8+j]
    	ENDFOR
    	temp_real[i] = Oxtofloat(temp_str)
        g_move_target_data[i+6] = temp_real[i]
    ENDFOR 

    FOR i = 1 TO 2 DO
        g_move_parmas_data[i] = MoveParams_str[i]
    ENDFOR
END SplitData

------------------------------------------------------------------------- 
--TRANSFORM Ox to float
ROUTINE Oxtofloat
VAR 
    B : REAL
    data_binary : ARRAY[32] OF INTEGER
    data_ox : ARRAY[8] OF INTEGER
    data_float : REAL 	
    str_array : ARRAY[6] OF STRING[1] 
    S : INTEGER
    E : INTEGER
    int_exe : INTEGER
    real_exe : REAL
    i,j,n,m : INTEGER
    str : STRING[1]
    
BEGIN
    str_array[1] = 'A'
    str_array[2] = 'B'
    str_array[3] = 'C'
    str_array[4] = 'D'
    str_array[5] = 'E'
    str_array[6] = 'F'
    
    FOR i = 1 TO 8 DO
        j = 0
        m = 0
        str = data[i]
        FOR n = 1 TO 6 DO
            IF str = str_array[n] THEN
                m = n
            ENDIF
        ENDFOR
        SELECT m OF 
            CASE (1) : 
                j = 10
            CASE (2) : 
                j = 11
            CASE (3) : 
                j = 12
            CASE (4) : 
                j = 13
            CASE (5) : 
                j = 14
            CASE (6) : 
                j = 15
        ELSE: 
            CNV_STR_INT(str,j)
        ENDSELECT
        data_ox[i] = j
    ENDFOR
    
    FOR i = 1 TO 4 DO
        j = data_ox[(2*i-1)]
        n = data_ox[(2*i)]
        IF j >= 8 THEN 
            data_binary[(i*8-7)] = 1
        j = j - 8
        ELSE 
            data_binary[(i*8-7)] = 0
        ENDIF
        IF j >= 4 THEN 
            data_binary[(i*8-6)] = 1
            j = j - 4
        ELSE 
            data_binary[(i*8-6)] = 0
        ENDIF
        IF j >= 2 THEN 
            data_binary[(i*8-5)] = 1
            j =j - 2
        ELSE 
            data_binary[(i*8-5)] = 0
        ENDIF
        IF j >= 1 THEN 
            data_binary[(i*8-4)] = 1
            j = j - 1
        ELSE 
            data_binary[(i*8-4)] = 0
        ENDIF
        
        IF n >= 8 THEN 
            data_binary[(i*8-3)] = 1
        n = n - 8
        ELSE 
            data_binary[(i*8-3)] = 0
        ENDIF
        IF n >= 4 THEN 
            data_binary[(i*8-2)] = 1
            n = n - 4
        ELSE 
            data_binary[(i*8-2)] = 0
        ENDIF
        IF n >= 2 THEN 
            data_binary[(i*8-1)] = 1
            n = n - 2
        ELSE 
            data_binary[(i*8-1)] = 0
        ENDIF
        IF n >= 1 THEN 
            data_binary[(i*8)] = 1
            j = j - 1
        ELSE 
            data_binary[(i*8)] = 0
        ENDIF
    ENDFOR

    IF data_binary[1] = 0 THEN
            S = 1
    ELSE 
            S = -1
    ENDIF

    E = 0
    int_exe = 1
    FOR i = 9 DOWNTO 2 DO 
        E = E + data_binary[i] * int_exe
        int_exe = int_exe * 2
    ENDFOR
    E = E - 127
    real_exe = 0.5
    FOR i = 1 TO E+1 DO
        real_exe = real_exe * 2
    ENDFOR	
    data_float = 1 * real_exe
    FOR i = 10 DOWNTO 32 DO 
        real_exe = real_exe * 0.5
        data_float = data_binary[i] * real_exe  + data_float 
    ENDFOR
    data_float = data_float * S
    RETURN (data_float)
END Oxtofloat

------------------------------------------------------------------------- 
--int transform to Ox
ROUTINE inttoOx
VAR 
    result : ARRAY[2] OF STRING[1] 
    temp_str : ARRAY[2] OF STRING[2]
    str_array : ARRAY[6] OF STRING[1] 
    
BEGIN 
    str_array[1] = 'A'
    str_array[2] = 'B'
    str_array[3] = 'C'
    str_array[4] = 'D'
    str_array[5] = 'E'
    str_array[6] = 'F'
    IF data DIV 16 < 10 THEN 
        CNV_INT_STR(data DIV 16,2,0,temp_str[1])
        result[1] = SUB_STR(temp_str[1],2,1)
    ELSE    
        FOR i = 1 TO 6 DO
            IF data DIV 16 = 9 + i THEN 
                result[1] = str_array[i]
            ENDIF
        ENDFOR
    ENDIF
    IF data MOD 16 < 10 THEN 
        CNV_INT_STR(data MOD 16,2,0,temp_str[2])
        result[2] = SUB_STR(temp_str[2],2,1)
    ELSE
        FOR i = 1 TO 6 DO
            IF data MOD 16 = 9 + i THEN
                result[2] = str_array[i]
            ENDIF
        ENDFOR
    ENDIF
    RETURN (result)
END inttoOx
------------------------------------------------------------------------- 
ROUTINE GET_ACTRO_SPEED 

VAR
    speed : REAL
    entry : INTEGER
BEGIN
    speed = $SCR_GRP[1].$MCH_SPD
    RETURN(speed)
END GET_ACTRO_SPEED 

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Fanuc机器人二次开发是指在已有的Fanuc机器人基础上进行进一步的个性化定制、功能扩展和性能优化。通过二次开发,可以使Fanuc机器人适应特定的生产环境和生产需求。 Fanuc机器人二次开发涉及到软件和硬件两个方面。在软件方面,可以根据实际需要编写自定义的控制程序,实现更复杂、精确的运动控制和操作逻辑。例如,可以开发专门的路径规划算法,使机器人灵活、高效地完成任务。还可以编写自定义的用户界面,提供更友好、直观的操作界面,方便操作人员使用。 在硬件方面,可以根据特定需求选择不同的附件和传感器进行安装。例如,可以增视觉系统,提高机器人的感知能力和准确性。还可以添力传感器,实现力控操作,使机器人能够适应不同的工材料和零件。 Fanuc机器人二次开发还可以通过与其他设备的联动实现更复杂的自动化生产线。可以与传送带、仓储系统、机床等进行无缝对接,实现材料的自动装卸、工工艺的衔接等。这样可以大幅提高生产效率和质量。 总之,Fanuc机器人二次开发可以根据实际需求进行个性化定制,使机器人在现有的基础上更适应生产环境,并实现更高的效率和精度。这对于提高生产线的智能化水平和竞争力具有重要意义。 ### 回答2: Fanuc机器人二次开发是指在已有的Fanuc机器人系统的基础上进行定制化修改和功能拓展的过程。通常情况下,通过二次开发可以使Fanuc机器人适应更多的应用场景和实现更高级的功能需求。 Fanuc机器人二次开发的具体内容包括但不限于以下几个方面: 1. 硬件定制:根据用户的需求和特定场景,可以对机器人控制系统进行硬件定制。例如,使用不同的传感器或执行器来扩展机器人的感知和执行能力。还可以根据特定的应用需求对机器人的结构进行改进和优化,以提高机器人的稳定性和操作性。 2. 软件定制:Fanuc机器人的控制系统使用了R-J3、R-J3iC和R-30iB等不同的控制器平台。通过二次开发,可以根据实际使用需求对机器人的软件控制系统进行定制。例如,定制专用的运动轨迹规划算法、控制逻辑和安全功能等。还可以使用Fanuc提供的开发工具和编程语言,如TP程序代替XCR程序,以实现更精细、高级的控制和运动控制。 3. 界面定制:Fanuc机器人的操作界面通常由触摸屏、按钮和键盘等组成。通过二次开发,可以根据用户的需要定制界面,如增自定义按钮、菜单和工具栏等。还可以将机器人与其他设备、机器人或计算机进行连接,实现远程监控、导航和控制。 4. 应用定制:Fanuc机器人广泛应用于工业自动化领域,如焊接、装配、搬运等。通过二次开发,可以根据具体的应用需求对机器人进行定制。例如,开发特定的工具、末端执行器、夹具等。还可以通过增机器人的感知和决策功能,使其适应复杂的环境和任务。 总之,Fanuc机器人二次开发可以根据用户的需求和实际应用场景,对机器人的硬件、软件、界面和应用等进行定制和修改,以实现更高级的功能和适应更复杂的任务需求。 ### 回答3: Fanuc机器人二次开发是指在Fanuc机器人系统的基础上进行的进一步定制和开发。Fanuc机器人系统提供了一套完整的机器人控制和运行环境,但有时候它无法完全满足特定的生产需求。因此,使用Fanuc机器人二次开发可以对机器人进行定制化的改进和扩展。 Fanuc机器人二次开发可以包括以下几个方面: 1. 编程开发:Fanuc机器人系统通常使用专门的编程语言(例如KAREL或TP),通过二次开发可以编写新的程序和指令,实现更复杂的运动控制和操作逻辑。 2. 界面开发:通过二次开发可以定制机器人的操作界面,设计更直观和易用的用户界面,以方便操作人员进行控制和监控。 3. 传感器集成:Fanuc机器人系统可以集成各种类型的传感器,通过二次开发可以实现传感器与机器人系统的有效连接和数据交换,以实现更高级的自动化任务。 4. 远程控制和监控:通过二次开发可以实现对Fanuc机器人系统的远程监控和控制,使得操作人员可以在远程地点实时监控机器人的工作状态和进行远程操作控制。 5. 数据分析和优化:通过二次开发可以对机器人系统中的数据进行分析和优化,比如对机器人的运动轨迹进行优化,以提高生产效率和质量。 Fanuc机器人二次开发需要具备相关的机器人系统知识和编程技能。通过二次开发,可以根据实际需求对机器人系统进行定制化的优化,以满足不同生产场景的要求,提高生产效率和质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值