Skip to content

相机应用

1. 通讯介绍

目前机械臂和视觉通讯的有两种方式:

  1. 视觉和相机直接连接,一般采用的通讯方式都是TCP/IP。通过在程序里面需要拍照的地方插入运行脚本,这里面也有两种坐标偏移 ;

​ (1)机械臂直接获取需要的目标点位----绝对坐标;

​ (2)机械臂获取需要偏移的距离----相对坐标;

  1. 视觉通过PLC通过Modbus、Profinet等通讯方式进行连接, 拍照后由PLC把需要偏移的数值发给机械臂,根据相对位置进行X 、Y、RZ的偏移。

2. ARCS中相机通讯的方式

  1. ARCS中可以使用socket通信来实现机器人与相机的TCP/IP通讯,在AUBO开发者官网中提供了相关示例

    应用示例 | AUBO 开发者

相机TCP/IP通讯.lua

-- 示例相机使用TCP/IP方式进行通讯,进行拍照接收和发送数据
-- 导入socket库,用于实现网络通信功能
local socket = require("socket.core")  

-- 相对于模板的旋转角度,初始化为0
offset_rz = 0   
-- 相对于模板在x轴方向的偏移量,初始化为0
offset_x = 0
-- 相对于模板在y轴方向的偏移量,初始化为0
offset_y = 0

-- 创建一个TCP连接,用于与服务器进行通信
local tcp = socket.tcp()               
-- 设置主机地址,该地址为要连接的服务器的IP地址
local host = '192.168.1.66'            
-- 设置端口号,该端口号为服务器监听的端口
local port = '8000'                   
-- 定义拍照结果的标志位:识别成功为1,2,3,4,未识别为5
flag = "0"                             
-- 存储VisionMaster发送的数据,初始化为nil
str1 = nil                            

-- 自定义函数,用于将字符串按指定分隔符进行分割
-- 参数str:要分割的字符串
-- 参数delimiter:分隔符
function string.split(str , delimiter) 
    -- 检查输入的字符串是否为nil、空字符串或者分隔符是否为nil
    if str == nil or str ==' ' or delimiter == nil then
        -- 如果条件满足,返回nil
        return nil
    end 
    -- 用于存储分割后的结果
    local result = {}
    -- 使用gmatch函数按分隔符对字符串进行匹配分割
    for match in (str..delimiter):gmatch("(.-)"..delimiter) do
        -- 将匹配到的子字符串插入到结果表中
        table.insert(result, match)
    end
    -- 返回分割后的结果表
    return result
end

-- 定义拍照函数,用于控制相机拍照并处理返回结果
function photo1()
    -- 尝试连接相机控制器
    local clicon = tcp:connect(host,port) 
    -- 如果连接成功
    if(clicon) then                       
        -- 打印连接成功的消息
        print('connect '..host..' ok!')   
    -- 如果连接失败
    else                                
        -- 打印连接错误的消息
        print('connect error')           
    end  
    -- 定义拍照的触发字符
    take_photo = "photo1"                     
    -- 设置TCP连接的超时时间为2秒
    tcp:settimeout(2)                     
    -- 无限循环,直到有条件退出
    while (true) do                       
        -- 如果TCP连接的状态为关闭
        if status == "closed" then        
            -- 打印服务器关闭的消息
            print("server is closed!")    
            -- 退出循环
            break                        
        end  
        -- 如果str1不为nil
        if str1 ~= nil then                
            -- 取str1的第一个字符赋值给flag
            flag = string.sub(str1,1,1)   
            -- 将flag转换为数字类型
            TPresult = tonumber(flag)
        end  
        -- 如果flag不是1也不是5
        if (flag ~= "1") and (flag ~= "5") then                
            -- 发送拍照的触发字符
            tcp:send(take_photo)          
            -- 等待1秒
            sleep(1)                     
            -- 从TCP连接接收数据,读取到换行符(\n)为止,并存储到str1中
            s, status, str1 = tcp:receive() 
            -- 打印接收到的数据
            print("if str1: ", str1)       
        -- 如果flag是1(表示识别成功)
        else                              
            -- 使用逗号作为分隔符分割str1字符串
            table1 = string.split(str1 ,",")  
            -- 将分割结果中的第二个元素转换为数字,并将单位从毫米转换为米
            offset_x = tonumber(table1[2])/1000	
            -- 将分割结果中的第三个元素转换为数字,并将单位从毫米转换为米
            offset_y = tonumber(table1[3])/1000
            -- 将分割结果中的第四个元素转换为数字
            offset_rz = tonumber(table1[4])
            -- 打印offset_x的值
            print("offset_x= ", offset_x)           
            -- 打印offset_y的值
            print("offset_y= ", offset_y)           
            -- 打印offset_rz的值
            print("offset_rz= ", offset_rz)           
            -- 退出循环
            break                               
        end  
        -- 等待0.2秒后继续循环
        sleep(0.2)                           
    end
    -- 关闭TCP连接
    tcp:close()                           
    -- 重置标志位
    falg = "0"
    -- 重置接收到的数据
    str1 = nil
end
  1. Modbus主站通讯,通过plc做为数据的中转站,将数据发送给plc,或收到PLC发送的数据

    Modbus通讯参考:29 ARCS Modbus使用说明 · AUBO 应用笔记

    modbus主站读写寄存器浮点数.lua

    --示例modbodbus主站读写浮点数
    function writeModbusFloat(value, lowSignalName, highSignalName)
        local word = math.float2words(value)
        local low_word = word[1]
        local high_word = word[2]
        modbusSetOutputSignal(highSignalName, high_word)
        modbusSetOutputSignal(lowSignalName, low_word)
    end
    
    function readModbusFloat(lowSignalName, highSignalName)
        return math.words2float(modbusGetSignalStatus(lowSignalName), modbusGetSignalStatus(highSignalName))
    end
    
    --示例modbus主站读取寄存器地址Modbus_0,Modbus_14的值,并赋值给变量P1,注意浮点数的读写需要占用两个寄存器地址
    P1 = readModbusFloat("Modbus_0", "Modbus_1")
    --示例modbus主站寄寄存器地址Modbus_0,Modbus_1写入-3.14,注意浮点数的读写需要占用两个寄存器地址
    writeModbusFloat(-3.14, "Modbus_0", "Modbus_1")
  2. 使用从站通讯(modbus从站与Profinet从站都可用),通过plc做为数据的中转站,将数据发送给plc,或收到PLC发送的数据

    从站读写通用寄存器浮点数.lua

    --从站通用寄存器读写浮点数
    function writeModbusFloat(value, low, high)
        local word= math.float2words(value)
        local high_word=word[1]
        local low_word=word[2]
        setInt16Register(high, high_word)
        setInt16Register(low, low_word)
    end
    
    function readModbusFloat(low, high)    
        return math.words2float(getInt16Register(high), getInt16Register(low))
    end
    --示例从站往通用寄存器地址300,301写入-3.14,注意浮点数的读写需要占用两个通用寄存器地址
    writeModbusFloat(-3.14, 0, 1)
    --示例从站读取通用寄存器地址300,301的值,注意浮点数的读写需要占用两个通用寄存器地址
    P1=readModbusFloat(0, 1)

3. 偏移实现

  1. 通过自定义坐标系实现偏移

    参考示例:40 视觉偏移示例 · AUBO 应用笔记

  2. 通过方向-直达节点实现偏移

  3. 0.31分支版本相对于变量或路点实现偏移