随着机器人技术的不断进步,机器人的工作已经不仅仅是简单的执行运行指令,往往会伴随着大量的计算和通讯任务。其中通讯用来和外部设备交互,做数据传输或一些逻辑控制,而计算则常用来做一些数学运算,进制转换,机器人的位姿运算等等。
艾利特机械臂采用jbi程序+lua脚本的方式来实现多种符合场景下的使用,将大量复杂的运算、通讯任务和运动程序进行分离,jbi程序主要负责运动,lua脚本用来数据运算和通讯交互。这样可以保证运动任务的高效运行,不掺杂过多冗余的计算指令,同时脚本内容专一,只负责后台运算和通讯。在稍微大型的项目中,分离式的设计不仅可以保证程序的易读性,同时在编写过程中也可以多人协作,计算和通讯的验证和示教点位工作并行进行。这种设计即保证了机器人基础功能运动指令的简单插入,同时大大提高了机器人能够执行任务的上限。
运动和计算的分离式设计,可以避免运动指令和计算指令的大量掺杂,导致调试阶段程序调试效率低不好调试,后期运动程序与计算指令掺杂过多不易维护的情况,这也类似PLC编程时,往往工程师喜欢用STL文本去实现重复复杂的运算指令。同时JBI程序搭配类工业风的示教器操作风格可以更快的示教点位,验证点位,程序调用等,而脚本使用LUA语言,可以使工程师无缝从STL文本编程切换。在脚本编程中,不仅可以lua语言本身的丰富的API外,还可以使用艾利特机器人实现的接口,获取机器人的各种状态和数据,使用机器人的硬件接口。
从设计角度来说,lua的执行优先级没有jbi高,但是执行却是在同步执行的。所以在实际使用中,lua和jbi程序的执行往往需要互锁,两者进行逻辑上的同步,才能达到理想的效果。我们也十分期待共同与工程师的进步和成长,不断践行Always easier then before,不仅从机器人的使用角度摆脱重复危险的工作,也从工程师的角度一起成长,将繁杂的调试任务拆分,尽量去复用写过的每一行程序。
下面来介绍如何使用EC机器人进行Lua脚本和jbi程序的交互。
EC系列的全局变量一共有五种。
上述的全局变量均可通过jbi和lua进行操作,通常使用情况下,会使用B、I、D变量进行逻辑的交互和简单数据的传递,而P变量用作放置关节数据,V变量用作放置笛卡尔数据。
P变量和V变量存放对应的数据后,可以使用示教器手动移动到目标位置,或者通过移动指令直接移动到指定的位置。
NOP
// 设置全局变量B0 为 1
SET B000 1
// 设置全局变量I0 为 1
SET I000 1
// 设置全局变量D0 为 1
SET D000 1
// 设置全局变量P0的j1数据 为 1
SET P000(0) 1
// 设置全局变量V0的x数据 为 1
SET V000(0) 1
// 将后面的数据赋值给P0,当插入指令时,自动选取当前关节角度插入
// 插入后修改指令时,也是默认更新数据为当前关节角度
SETJOINT P000 170.2074,-85.7738,102.0724,-104.2114,89.9468,-14.3515,0.0000,0.0000
// 将后面的数据赋值给P0,当插入指令时,自动选取当前关节角度插入
// 插入后修改指令时,也是默认更新数据为当前笛卡尔角度
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
-- 从全局变量获取数据
local b0 = get_global_variable("B0")
local i0 = get_global_variable("I0")
local d0 = get_global_variable("D0")
-- 对于P,V变量,由于存储连续的6个数据,可以通过以下几种方式获取
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")}
-- 向全局变量赋值数据
-- 设置B0为1
set_global_variable("B0", 1)
-- 设置D0为1
set_global_variable("D0", 1)
-- 设置I0为1
set_global_variable("I0", 1)
-- 设置P0的数据为1,2,3,4,5,6
set_global_variable("P0", 1, 2, 3, 4, 5, 6)
-- 设置V0的数据为1,2,3,4,5,6
set_global_variable("V0", 1, 2, 3, 4, 5, 6)
NOP
// 设置数据
SET D000 0
SET D001 -90
SET D002 0
SET D003 -90
SET D004 90
SET D005 0
// 将B001设置为1,使lua进行计算赋值
SET B001 1
// 等待B001为0,等于0代表lua的计算赋值完成
WAIT B001=0
TIMER T=0.002 S
MOVJ P001 VJ=30% CR=0.0MM ACC=50 DEC=50
END
sleep(1)
elite_print("runing")
-- 等待jbi运行
repeat
elite_print("Waiting B1 == 1!")
until (get_global_variable("B1") == 1)
-- 获取数据并赋值
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")
上述两个程序同时运行后,LUA侧会一直等B1=1,当jbi初始化D变量后,设置B1为1,lua侧开始获取数据并将其赋值给P1,随后设置B1为0,然后JBI侧检测到B1为0,即运行到新的P1点。