本文就基于 C#的 ABB 机械臂二次开发相关内容做一个介绍,主要包括与机械臂控制器的连接和断开、机械臂 RAPID 程序变量的读写、机械臂输入信号的监听和输出信号的控制、机械臂当前位姿的读取。
ABB SDK经过两年多对机械臂的接触,真觉得 ABB 机械臂好用。不仅仅是因为精度较高,更重要的是比较开放,支持 C#的二次开发,甚至也支持网络服务器开发,通过 RESTful API 实现控制。个人认为是机械臂行业的龙头老大。
https://developercenter.robotstudio.com/pc-sdk
这个网址是 ABB 机械臂 PC SDK 的开发者中心,提供了 C#、VB 两种语言的二次开发 API 文档和一些简单案例。但目前似乎只支持 Windows 系统。我采用的是 C#语言进行开发。
在这个网址找到 SDK 安装包并安装到本地,在目录中找到三个 dll 文件(ABB.Robotics.Controllers.PC.dll、RobotStudio.Services.RobApi.dll、RobotStudio.Services.RobApi.Desktop.dll),在 C#程序中对其进行引用。
ABB SDK结构
上图是 SDK 源程序的结构图,在项目开头引入对应命名空间。
12345using ABB.Robotics.Controllers;using ABB.Robotics.Controllers.Discovery;using ABB.Robotics.Controllers.MotionDomain;using ABB.Robotics.Controllers.RapidDomain;using ABB.Robotics.Controllers.IOSystemDomain;然后就可以敲代码实现一些功能了。
机械臂控制器的连接和断开先上代码。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576private NetworkScanner scanner = null;public Controller robot = null;private void Form1_Load(object sender, EventArgs e){ //机器人通信模块 try { scanner = new NetworkScanner(); } catch (Exception) { MessageBox.Show("ABBSDK初始化错误"); }}private void btn_ConnectRob_Click(object sender, EventArgs e){ try { //扫描网络中的控制器 scanner.Scan(); //获取扫描到的控制器信息 ControllerInfoCollection controllers = scanner.Controllers; //遍历信息 foreach (ControllerInfo controllerInfo in controllers) { //判断控制器是否可用,是否是需要连接的 if (controllerInfo.Availability == Availability.Available && (controllerInfo.SystemName == textB_RobID.Text || controllerInfo.Id == textB_RobID.Text)) { //创建控制器对象 robot = ControllerFactory.CreateFrom(controllerInfo); //登录 robot.Logon(UserInfo.DefaultUser); MessageBox.Show("robot登录成功"); } } if (robot == null) { MessageBox.Show("robot登录失败,未找到对应机械臂"); } } catch (Exception exception) { MessageBox.Show(exception.Message, Name, MessageBoxButtons.OK, MessageBoxIcon.Error); return; }}private void btn_CloseRob_Click(object sender, EventArgs e){ try { //判断是否已连接 if (RobControl.IsConnected(robot)) { //控制器登出 robot.Logoff(); MessageBox.Show("robot已断开连接"); } } catch (Exception exception) { MessageBox.Show(exception.Message, Name, MessageBoxButtons.OK, MessageBoxIcon.Error); return; }}//判断是否连接public bool IsConnected(Controller controller){ if (controller == null || controller.CurrentUser == null) return false; return controller.Connected;}控件设计如下:两个按钮分别控制控制器的连接和断开,连接控制器时连接名称为 TextBox 文本字符串的控制器。
连接断开控制器
连接控制器的基本流程是:
先创建一个扫描器,使用Scan()对当前局域网中的所有机械臂控制器进行扫描; 通过扫描器的Controllers属性将所有信息存入集合中,每个控制器信息以ControllerInfo的形式储存,包含的控制器的名称、ID、IP、是否虚拟、是否可用等信息。 创建一个Controller对象,调用ControllerFactory.CreateFrom()方法创建控制器,方法传入扫描到的ControllerInfo。 使用控制器的Logon()方法实现登录。断开控制器就比较简单了,对已登录的控制器执行Logoff()方法登出。
机械臂 RAPID 程序变量的读写首先是变量读取:
123RapidData rapiddata = robot1.Rapid.GetTask(cTasks1.Text.ToString()).GetModule(cBmodules1.Text.ToString()).GetRapidData(cvalue1.Text.ToString());value1.Text = rapiddata.StringValue.ToString();textBox1.Text = rapiddata.RapidType.ToString();依次通过 Task、Module、变量名获取对应的RapidData,然后可以通过RapidData的StringValue属性获取值、通过RapidType变量类型。
对于变量写入,必须要将机械臂控制器置于自动模式,而且要事先知道要修改变量的类型:
1234567891011RapidData data = robot1.Rapid.GetTask(cTasks1.Text.ToString()).GetModule(cBmodules1.Text.ToString()).GetRapidData(cvalue1.Text.ToString());if (data.RapidType.ToString() == "robtarget"){ RobTarget tempdata = (RobTarget)data.Value; tempdata.FillFromString2(value1.Text.ToString()); //请求权限并写入控制器 using (Mastership m = Mastership.Request(robot1.Rapid)) { data.Value = tempdata; }}首先读出要写入的变量,获取RapidData类型数据,将其值强制转换为其类型,通过FillFromString2()方法传入新值的内容,然后请求权限将这个值重新赋给RapidData数据的值即可。
机械臂输入信号的监听和输出信号的控制机械臂的 IO 操作需要调用开发包的IOSystem模块。下面针对数字信号,实现信号读取、信号值改变、输入信号监听三个方面。
信号获取123Signal sig = robot.IOSystem.GetSignal(IOName.Text);DigitalSignal digitalSig = (DigitalSignal)sig;int val = digitalSig.Get();获取的val即为名为IOName.Text的数字信号的值,为 0 或 1。
信号写入12345678910Signal sig = robot1.IOSystem.GetSignal(IOName.Text);DigitalSignal digitalSig = (DigitalSignal)sig;if (IOValue.Text == "1"){ digitalSig.Set();}else if (IOValue.Text == "0"){ digitalSig.Reset();}digitalSig.Set()表示将数字信号置 1,digitalSig.Reset()表示将数字信号置 0。
信号监听可以向信号的Changed事件添加预订,该预订在信号状态反转时触发。
12345678910Signal sig = robot1.IOSystem.GetSignal(IOName.Text);DigitalSignal digitalSig = (DigitalSignal)sig;sig.Changed += new EventHandler(sig_Changed);private void sig_Changed(object sender, SignalChangedEventArgs e){ //通过e获取监听到的信号状态 SignalState state = e.NewSignalState; float val = state.Value;}通过val可以获取监听变量的值,如果值变为期望的状态则可以在后续代码添加相应的动作。
机械臂当前位姿的读取获取当前位姿的功能在开发包的MotionSystem中。获取当前位姿有两种形式:
一种是获取当前机械臂末端位姿,包含 xyz 坐标和四元数构成的姿态; 另一种是六个关节的偏移角。首先看第一种,获取末端位姿:
12345678RobTarget robtarget = robot1.MotionSystem.ActiveMechanicalUnit.GetPosition(CoordinateSystemType.WorkObject);xvalue.Text = robtarget.Trans.X.ToString();yvalue.Text = robtarget.Trans.Y.ToString();zvalue.Text = robtarget.Trans.Z.ToString();q1value.Text = robtarget.Rot.Q1.ToString();q2value.Text = robtarget.Rot.Q2.ToString();q3value.Text = robtarget.Rot.Q3.ToString();q4value.Text = robtarget.Rot.Q4.ToString();然后是第二种,获取六关节偏移角:
1234567JointTarget jointtarget = robot1.MotionSystem.ActiveMechanicalUnit.GetPosition();value1.Text = a.RobAx.Rax_1.ToString();value2.Text = a.RobAx.Rax_2.ToString();value3.Text = a.RobAx.Rax_3.ToString();value4.Text = a.RobAx.Rax_4.ToString();value5.Text = a.RobAx.Rax_5.ToString();value6.Text = a.RobAx.Rax_6.ToString();