本文就基于 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 源程序的结构图,在项目开头引入对应命名空间。
1 2 3 4 5 using ABB.Robotics.Controllers; using ABB.Robotics.Controllers.Discovery; using ABB.Robotics.Controllers.MotionDomain; using ABB.Robotics.Controllers.RapidDomain; using ABB.Robotics.Controllers.IOSystemDomain;
然后就可以敲代码实现一些功能了。
机械臂控制器的连接和断开 先上代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 private 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 程序变量的读写 首先是变量读取:
1 2 3 RapidData 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
变量类型。
对于变量写入,必须要将机械臂控制器置于自动模式,而且要事先知道要修改变量的类型:
1 2 3 4 5 6 7 8 9 10 11 RapidData 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
模块。下面针对数字信号,实现信号读取、信号值改变、输入信号监听三个方面。
信号获取 1 2 3 Signal sig = robot.IOSystem.GetSignal(IOName.Text); DigitalSignal digitalSig = (DigitalSignal)sig; int val = digitalSig.Get();
获取的val
即为名为IOName.Text
的数字信号的值,为 0 或 1。
信号写入 1 2 3 4 5 6 7 8 9 10 Signal 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
事件添加预订,该预订在信号状态反转时触发。
1 2 3 4 5 6 7 8 9 10 Signal sig = robot1.IOSystem.GetSignal(IOName.Text); DigitalSignal digitalSig = (DigitalSignal)sig; sig.Changed += new EventHandler<SignalChangedEventArgs>(sig_Changed); private void sig_Changed(object sender, SignalChangedEventArgs e) { //通过e获取监听到的信号状态 SignalState state = e.NewSignalState; float val = state.Value; }
通过val
可以获取监听变量的值,如果值变为期望的状态则可以在后续代码添加相应的动作。
机械臂当前位姿的读取 获取当前位姿的功能在开发包的MotionSystem
中。获取当前位姿有两种形式:
一种是获取当前机械臂末端位姿,包含 xyz 坐标和四元数构成的姿态;
另一种是六个关节的偏移角。
首先看第一种,获取末端位姿:
1 2 3 4 5 6 7 8 RobTarget 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();
然后是第二种,获取六关节偏移角:
1 2 3 4 5 6 7 JointTarget 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();
最后更新时间:2020-08-16 22:58:49
转载请注明出处