EC機(jī)器人JBI與LUA交互
隨著技術(shù)的不斷進(jìn)步,根據(jù)客戶不同的需求,現(xiàn)在機(jī)器人的工作已經(jīng)不僅僅是簡(jiǎn)單的執(zhí)行運(yùn)動(dòng)指令,往往會(huì)伴隨著大量的計(jì)算和通訊任務(wù)。其中通訊用來(lái)和外部設(shè)備交互,做數(shù)據(jù)傳輸或一些邏輯控制,而計(jì)算則常用來(lái)做一些數(shù)學(xué)運(yùn)算,進(jìn)制轉(zhuǎn)換,機(jī)器人的位姿運(yùn)算等等。
1. EC 系列的 Lua 結(jié)構(gòu)和 JBI 結(jié)構(gòu)
而我們艾利特機(jī)械臂采用 jbi 程序+lua 腳本的方式來(lái)實(shí)現(xiàn)多種符合場(chǎng)景下的使用,將大量復(fù)雜的運(yùn)算、通訊任務(wù)和運(yùn)動(dòng)程序進(jìn)行分離,jbi 程序主要負(fù)責(zé)運(yùn)動(dòng),lua 腳本用來(lái)數(shù)據(jù)運(yùn)算和通訊交 互。這樣可以保證運(yùn)動(dòng)任務(wù)的高效運(yùn)行,不摻雜過(guò)多冗余的計(jì)算指令,同時(shí)腳本內(nèi)容專一,只 負(fù)責(zé)后臺(tái)運(yùn)算和通訊。在稍微大型的項(xiàng)目中,分離式的設(shè)計(jì)不僅可以保證程序的易讀性,同時(shí)在編寫(xiě)過(guò)程中也可以多人協(xié)作,計(jì)算和通訊的驗(yàn)證和示教點(diǎn)位工作并行進(jìn)行。這種設(shè)計(jì)即保證了機(jī)器人基礎(chǔ)功能運(yùn)動(dòng)指令的簡(jiǎn)單插入,同時(shí)大大提高了機(jī)器人能夠執(zhí)行任務(wù)的上限。 運(yùn)動(dòng)和計(jì)算的分離式設(shè)計(jì),可以避免運(yùn)動(dòng)指令和計(jì)算指令的大量摻雜,導(dǎo)致調(diào)試階段程序 調(diào)試效率低不好調(diào)試,后期運(yùn)動(dòng)程序與計(jì)算指令摻雜過(guò)多不易維護(hù)的情況,這也類似PLC 編程時(shí),往往工程師喜歡用 STL 文本去實(shí)現(xiàn)重復(fù)復(fù)雜的運(yùn)算指令。同時(shí) JBI 程序搭配類工業(yè)風(fēng)的示教器操作風(fēng)格可以更快的示教點(diǎn)位,驗(yàn)證點(diǎn)位,程序調(diào)用等,而腳本使用 LUA 語(yǔ)言,可以使工程師無(wú)縫從 STL 文本編程切換。在腳本編程中,不僅可以 lua 語(yǔ)言本身的豐富的 API 外,還可以使用艾利特機(jī)器人實(shí)現(xiàn)的接口,獲取機(jī)器人的各種狀態(tài)和數(shù)據(jù),使用機(jī)器人的硬件接口。 從設(shè)計(jì)角度來(lái)說(shuō),lua 的執(zhí)行優(yōu)先級(jí)沒(méi)有 jbi 高,但是執(zhí)行卻是在同步執(zhí)行的。所以在實(shí)際 使用中,lua 和 jbi 程序的執(zhí)行往往需要互鎖,兩者進(jìn)行邏輯上的同步,才能達(dá)到理想的效果。
2. 如何進(jìn)行 Lua 腳本和 JBI 程序的交互
2.1 變量


如表格所示,艾利特機(jī)器人全局變量分為五種均可通過(guò) jbi 和 lua 進(jìn)行操作,通常使用情況下,會(huì)使用 B、I、D 變量進(jìn)行 邏輯的交互和簡(jiǎn)單數(shù)據(jù)的傳遞,而 P 變量用作放置關(guān)節(jié)數(shù)據(jù),V 變量用作放置笛卡爾數(shù)據(jù)。 P 變量和 V 變量存放對(duì)應(yīng)的數(shù)據(jù)后,可以使用示教器手動(dòng)移動(dòng)到目標(biāo)位置,或者通過(guò)移動(dòng)指令 直接到指定的位置。
2.2輸入輸出

如上表格所示,用戶也可以用數(shù)字輸入輸出或者模擬輸入輸出來(lái)進(jìn)行l(wèi)ua與JBI的交互
3.JBI如何操作全局變量
JBI 代碼:
NOP
// 設(shè)置全局變量 B0 為 1
SET B000 1
// 設(shè)置全局變量 I0 為 1
SET I000 1
// 設(shè)置全局變量 D0 為 1
SET D000
// 設(shè)置全局變量 P0 的 j1 數(shù)據(jù) 為 1
SET P000(0) 1
// 設(shè)置全局變量 V0 的 x 數(shù)據(jù) 為 1
SET V000(0) 1
// 將后面的數(shù)據(jù)賦值給 P0,當(dāng)插入指令時(shí),自動(dòng)選取當(dāng)前關(guān)節(jié)角度插入
// 插入后修改指令時(shí),也是默認(rèn)更新數(shù)據(jù)為當(dāng)前關(guān)節(jié)角度
SETJOINT P000 170.2074,-85.7738,102.0724,-104.2114,89.9468,-14.3515,0.0000,0.0000
// 將后面的數(shù)據(jù)賦值給 P0,當(dāng)插入指令時(shí),自動(dòng)選取當(dāng)前關(guān)節(jié)角度插入
// 插入后修改指令時(shí),也是默認(rèn)更新數(shù)據(jù)為當(dāng)前笛卡爾角度
SETPOSE V000 -517.8859,-34.5460,208.5253,3.1061,0.0081,1.6502
// 等待 B0 = 0
WAIT B000=0
// 等待 I0 = 0
WAIT I000=0
// 等待 D0 = 0
WAIT D000=0
END
LUA 代碼:
Sleep(1)
-- 從全局變量獲取數(shù)據(jù)
local b0 = get_global_variable("B0")
local i0 = get_global_variable("I0")
local d0 = get_global_variable("D0")
-- 對(duì)于 P,V 變量,由于存儲(chǔ)連續(xù)的 6 個(gè)數(shù)據(jù),可以通過(guò)以下幾種方式獲取
local j7 = {}
j7[1],j7[2],j7[3],j7[4],j7[5],j7[6] = get_global_variable("P0")
local pose0 = {}
pose0[1],pose0[2],pose0[3],pose0[4],pose0[5],pose0[6] = get_global_variable("V0")
local j1,j2,j3,j4,j5,j6 = get_global_variable("P0")
local p0 = {j1, j2, j3, j4, j5, j6}
local v0 = {get_global_variable("V0")}
-- 向全局變量賦值數(shù)據(jù)
-- 設(shè)置 B0 為 1
set_global_variable("B0", 1)
-- 設(shè)置 D0 為 1
set_global_variable("D0", 1)
-- 設(shè)置 I0 為 1
set_global_variable("I0", 1)
-- 設(shè)置 P0 的數(shù)據(jù)為 1,2,3,4,5,6
set_global_variable("P0", 1, 2, 3, 4, 5, 6)
-- 設(shè)置 V0 的數(shù)據(jù)為 1,2,3,4,5,6
set_global_variable("V0", 1, 2, 3, 4, 5,6)
4.1 使用全局變量簡(jiǎn)易交互示例
JBI 代碼 :
NOP
// 設(shè)置數(shù)據(jù)
SET D000 0
SET D001 -90
SET D002 0
SET D003 -90
SET D004 90
SET D005 0
// 將 B001 設(shè)置為 1,使 lua 進(jìn)行計(jì)算賦值
SET B001 1
// 等待 B001 為 0,等于 0 代表 lua 的計(jì)算賦值完成
WAIT B001=0
TIMER T=0.002 S
MOVJ P001 VJ=30% CR=0.0MM ACC=50 DEC=50
END
LUA 代碼:
sleep(1)
elite_print("runing")
-- 等待 jbi 運(yùn)行
repeat
elite_print("Waiting B1 == 1!")
until
(get_global_variable("B1") == 1)
-- 獲取數(shù)據(jù)并賦值
local j1 = get_global_variable("D0")
local j2 = get_global_variable("D1")
local j3 = get_global_variable("D2")
local j4 = get_global_variable("D3")
local j5 = get_global_variable("D4")
local j6 = get_global_variable("D5")
set_global_variable("P1", j1, j2, j3, j4, j5, j6)
set_global_variable("B1", 0)
elite_print("done")
4.2運(yùn)行效果
上述兩個(gè)程序同時(shí)運(yùn)行后,LUA 側(cè)會(huì)一直等 B1=1,當(dāng) jbi 初始化 D 變量后,設(shè)置 B1 為 1,lua 側(cè)開(kāi)始獲取數(shù)據(jù)并將其賦值給 P1,隨后設(shè)置 B1 為 0,然后 JBI 側(cè)檢測(cè)到 B1 為 0,即運(yùn)行到新的 P1
5.1 使用輸入輸出簡(jiǎn)易交互示例
JBI代碼:
//前臺(tái)設(shè)置數(shù)字輸出0為1啟動(dòng)腳本
NOP
DOUT OT#(0) 1
//等待腳本執(zhí)行完成
WAIT OT#(0)=0
MOVEL V=200MM/S CR=0MM ACC=50 DEC=50 V1
END
lua代碼:
while (true) do
repeat
--等待前臺(tái)腳本啟動(dòng)
o0=get_robot_io_status("o0")
sleep(0.01)
until(o0==1)
sleep(0.02)
client_send_data(ip,"start",0,port)
sleep(0.5)
ret,recv=client_recv_data (ip,1,0,port)
while recv=="" do
sleep(3)
client_send_data(ip,"start",0,port)
sleep(0.5)
ret,recv=client_recv_data (ip,1,0,port)
end
tempString=string.format("%s",recv)
CamData=string.split(tempString,",")
if tonumber(CamData[1])==1 then
set_global_variable("b2",1)
elseif tonumber(CamData[1])==0 then
set_global_variable("b2",0)
end
rz=math.rad(tonumber(CamData[4]))
elite_print("機(jī)器人定位數(shù)據(jù):","X=",CamData[2],",Y=",CamData[3],",RZ=",rz)
sleep(0.01)
a1,a2,a3,a4,a5,a6=get_global_variable("V1")
sleep(0.02)
set_global_variable ("V1",tonumber(CamData[2]),tonumber(CamData[3]),a3,a4,a5,rz)
set_robot_io_status("o0",0)
--腳本執(zhí)行完畢反饋給前臺(tái)
end