• 正文
  • 相关推荐
申请入驻 产业图谱

C#上位机通过TCP通讯实现库卡(KUKA)机器人运动控制与数据监控

07/21 11:46
5486
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

一、介绍

本项目包括【KUKA端】、【PC端】及【附件】三部分

1.1    KUKA端

config.dat //包含全局变量,定义全局变量

sps.sub //提交解释器文件 实时传输机器人关节位置

motion16.src //主程序 实现KUKA端与PC端的以太网连接 通过接收PC端发送的XML数据控制机器人运动

motion16.dat //与主程序同名 存放于同一个文件夹中 构成一个模块

Xml_motion16.xml //保存以太网通讯所需的IP地址与端口信息 定义以太网通讯中XML数据的结构

1.2    PC端

Program.cs //入口

Form1.cs //窗口

Form1.cs //代码

using System;using System.Collections.Generic;using System.Collections;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Threading;using System.Diagnostics;using System.Net;using System.Net.Sockets;using System.IO;
namespace KUKA_Motion{    public partial class Form1 : Form    {        //以太网变量        private Socket server;        private Socket client;
        //数据表定义及相关变量        DataTable dt = new DataTable();        int pointCount = 0;
        ThreadStart myThreadDelegate;        Thread myThread;
        public Form1()        {            InitializeComponent();
            //开启双缓冲            this.SetStyle(ControlStyles.UserPaint, true);            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);        }
        private void Form1_Load(object sender, EventArgs e)        {            //隐藏调试模块            this.Size = new Size(790, 695);
            //跨线程操纵控件            Control.CheckForIllegalCrossThreadCalls = false;
            //初始化以太网相关信息            ipAddressTB.Text = Common.IpAddress;            portTB.Text = Common.Port;            ShowMsg("输入IP地址及端口号进行连接");
            //数据表相关信息            dt.Columns.Add("Index", typeof(int));            dt.Columns.Add("Time", typeof(string));            dt.Columns.Add("A1(deg)", typeof(double));            dt.Columns.Add("A2(deg)", typeof(double));            dt.Columns.Add("A3(deg)", typeof(double));            dt.Columns.Add("A4(deg)", typeof(double));            dt.Columns.Add("A5(deg)", typeof(double));            dt.Columns.Add("A6(deg)", typeof(double));            dt.Columns.Add("X(mm)", typeof(double));            dt.Columns.Add("Y(mm)", typeof(double));            dt.Columns.Add("Z(mm)", typeof(double));            dt.Columns.Add("A(deg)", typeof(double));            dt.Columns.Add("B(deg)", typeof(double));            dt.Columns.Add("C(deg)", typeof(double));        }
        /// <summary>        /// 连接机器人        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Robot_Connect_bt_Click(object sender, EventArgs e)        {            OpenTCP();        }
        /// <summary>        /// 断开机器人连接        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Robot_Disconnect_bt_Click(object sender, EventArgs e)        {            try            {                a1ShowTB.Text = "0.000000";                a2ShowTB.Text = "0.000000";                a3ShowTB.Text = "0.000000";                a4ShowTB.Text = "0.000000"; ;                a5ShowTB.Text = "0.000000";                a6ShowTB.Text = "0.000000";                xShowTB.Text = "0.000000";                yShowTB.Text = "0.000000";                zShowTB.Text = "0.000000";                aShowTB.Text = "0.000000";                bShowTB.Text = "0.000000";                cShowTB.Text = "0.000000";
                ShowMsg("断开连接");                Send_Robot("<Sensor><Status><IsOut>TRUE</IsOut></Status><StepMode>0</StepMode><SX>" + Common.XP2[0].ToString() + "</SX><SY>" + Common.XP2[1].ToString() + "</SY><SZ>" + Common.XP2[2].ToString() + "</SZ><SA>" + Common.XP2[3].ToString() + "</SA><SB>" + Common.XP2[4].ToString() + "</SB><SC>" + Common.XP2[5].ToString() + "</SC></Sensor>");                myThread.Interrupt();                server.Close();                client.Close();            }            catch (Exception ex)            {                //MessageBox.Show(ex.Message, "Robot_Disconect_Error");            }
        }
        /// <summary>        /// TCP连接        /// </summary>        public void OpenTCP()        {            myThreadDelegate = new ThreadStart(Listen);            myThread = new Thread(myThreadDelegate);            myThread.Start();        }
        /// <summary>        /// 创建TCP服务端并监听        /// </summary>        public void Listen()//创建tcp服务端        {            //设置端口            string IP = ipAddressTB.Text;            int Port = Convert.ToInt32(portTB.Text);            //初始化终结点实例            IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(IP), Port);            //初始化SOCKET实例            server = new Socket(localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);            //允许SOCKET被绑定在已使用的地址上。            server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);            ShowMsg("等待客户端连接...");            try            {                //绑定                server.Bind(localEP);                //监听                server.Listen(10);
                client = server.Accept();                IPEndPoint clientIP = (IPEndPoint)client.RemoteEndPoint;                ShowMsg("已连接的客户端:" + clientIP.Address + ",端口:" + clientIP.Port);
                Received_Robot();            }            catch (Exception ex)            {                //MessageBox.Show(ex.Message, "Listen_Error");            }
        }

        void ShowMsg(string str)        {            MSG_BOX.AppendText(DateTime.Now + "  " + str + " rn");        }
        /// <summary>        /// 向机器人发送数据        /// </summary>        /// <param name="str"></param>        void Send_Robot(string str)        {            try            {                byte[] buffer = new byte[1024 * 1024 * 3];                buffer = ASCIIEncoding.ASCII.GetBytes(str);                client.Send(buffer);                ShowMsg(str);            }            catch (Exception ex)            {                //MessageBox.Show(ex.Message, "Send_Robot_Error");            }        }
        /// <summary>        /// 从机器人接收数据        /// </summary>        void Received_Robot()        {            while (true)            {                try                {                    byte[] buffer = new byte[1024 * 1024 * 3];                    int len = client.Receive(buffer);                    if (len == 0)                    {                        break;                    }                    string str = ASCIIEncoding.ASCII.GetString(buffer);
                    //数据处理                    DataTreat(str);
                    ShowMsg(str);                }                catch (Exception ex)                {                    //MessageBox.Show(ex.Message, "Received_Robot_Error");                }
            }        }
        /// <summary>        /// 实时返回数据显示        /// </summary>        /// <param name="str"></param>        void DataTreat(string str)        {            string a1, a2, a3, a4, a5, a6;            string x, y, z, a, b, c;
            a1 = str.Substring(str.IndexOf("<joint1>")+ "<joint1>".Length, str.IndexOf("</joint1>") - str.IndexOf("<joint1>")-"<joint1>".Length);            a2 = str.Substring(str.IndexOf("<joint2>") + "<joint2>".Length, str.IndexOf("</joint2>") - str.IndexOf("<joint2>") - "<joint2>".Length);            a3 = str.Substring(str.IndexOf("<joint3>") + "<joint3>".Length, str.IndexOf("</joint3>") - str.IndexOf("<joint3>") - "<joint3>".Length);            a4 = str.Substring(str.IndexOf("<joint4>") + "<joint4>".Length, str.IndexOf("</joint4>") - str.IndexOf("<joint4>") - "<joint4>".Length);            a5 = str.Substring(str.IndexOf("<joint5>") + "<joint5>".Length, str.IndexOf("</joint5>") - str.IndexOf("<joint5>") - "<joint5>".Length);            a6 = str.Substring(str.IndexOf("<joint6>") + "<joint6>".Length, str.IndexOf("</joint6>") - str.IndexOf("<joint6>") - "<joint6>".Length);
            x = str.Substring(str.IndexOf("<PX>") + "<PX>".Length, str.IndexOf("</PX>") - str.IndexOf("<PX>") - "<PX>".Length);            y = str.Substring(str.IndexOf("<PY>") + "<PY>".Length, str.IndexOf("</PY>") - str.IndexOf("<PY>") - "<PY>".Length);            z = str.Substring(str.IndexOf("<PZ>") + "<PZ>".Length, str.IndexOf("</PZ>") - str.IndexOf("<PZ>") - "<PZ>".Length);            a = str.Substring(str.IndexOf("<PA>") + "<PA>".Length, str.IndexOf("</PA>") - str.IndexOf("<PA>") - "<PA>".Length);            b = str.Substring(str.IndexOf("<PB>") + "<PB>".Length, str.IndexOf("</PB>") - str.IndexOf("<PB>") - "<PB>".Length);            c = str.Substring(str.IndexOf("<PC>") + "<PC>".Length, str.IndexOf("</PC>") - str.IndexOf("<PC>") - "<PC>".Length);
            a1ShowTB.Text = a1;            a2ShowTB.Text = a2;            a3ShowTB.Text = a3;            a4ShowTB.Text = a4;            a5ShowTB.Text = a5;            a6ShowTB.Text = a6;            xShowTB.Text = x;            yShowTB.Text = y;            zShowTB.Text = z;            aShowTB.Text = a;            bShowTB.Text = b;            cShowTB.Text = c;
            //数据加入table中            pointCount++;            DataRow newrow = dt.NewRow();            newrow[0] = pointCount;            newrow[1] = DateTime.Now.ToString();            newrow[2] = Convert.ToDouble(a1);            newrow[3] = Convert.ToDouble(a2);            newrow[4] = Convert.ToDouble(a3);            newrow[5] = Convert.ToDouble(a4);            newrow[6] = Convert.ToDouble(a5);            newrow[7] = Convert.ToDouble(a6);            newrow[8] = Convert.ToDouble(x);            newrow[9] = Convert.ToDouble(y);            newrow[10] = Convert.ToDouble(z);            newrow[11] = Convert.ToDouble(a);            newrow[12] = Convert.ToDouble(b);            newrow[13] = Convert.ToDouble(c);            dt.Rows.Add(newrow);
        }
        /// <summary>        /// 机器人运动到指定位置        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Move_bt_Click(object sender, EventArgs e)        {            if (xMotionTB.Text == "" || yMotionTB.Text == "" || zMotionTB.Text == "" || aMotionTB.Text == "" || bMotionTB.Text == "" || cMotionTB.Text == "")            {                MessageBox.Show("文本框不能为空");            }            else            {                string sendStr = "<Sensor><Status><IsOut>FALSE</IsOut></Status><StepMode>0</StepMode><SX>" + xMotionTB.Text + "</SX><SY>" + yMotionTB.Text + "</SY><SZ>" + zMotionTB.Text + "</SZ><SA>" + aMotionTB.Text + "</SA><SB>" + bMotionTB.Text + "</SB><SC>" + cMotionTB.Text + "</SC></Sensor>";                Send_Robot(sendStr);                ShowMsg(sendStr);                xMotionTB.Clear();                yMotionTB.Clear();                zMotionTB.Clear();                aMotionTB.Clear();                bMotionTB.Clear();                cMotionTB.Clear();            }        }
        /// <summary>        /// 机器人复位        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Reset_bt_Click(object sender, EventArgs e)        {            string sendStr = "<Sensor><Status><IsOut>FALSE</IsOut></Status><StepMode>0</StepMode><SX>" + Common.XP2[0].ToString() + "</SX><SY>" + Common.XP2[1].ToString() + "</SY><SZ>" + Common.XP2[2].ToString() + "</SZ><SA>" + Common.XP2[3].ToString() + "</SA><SB>" + Common.XP2[4].ToString() + "</SB><SC>" + Common.XP2[5].ToString() + "</SC></Sensor>";            Send_Robot(sendStr);            ShowMsg(sendStr);            xMotionTB.Text = Common.XP2[0].ToString();            yMotionTB.Text = Common.XP2[1].ToString();            zMotionTB.Text = Common.XP2[2].ToString();            aMotionTB.Text = Common.XP2[3].ToString();            bMotionTB.Text = Common.XP2[4].ToString();            cMotionTB.Text = Common.XP2[5].ToString();        }
        /// <summary>        /// 清空信息窗口内容        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void MsgBox_Clear_bt_Click(object sender, EventArgs e)        {            MSG_BOX.Clear();        }


        /// <summary>        /// 将数据表中数据导出        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void EX_DT_bt_Click(object sender, EventArgs e)        {            SaveFileDialog saveFileDialog = new SaveFileDialog();            saveFileDialog.FileName = DateTime.Now.ToString("yyMMddhhmmss");            saveFileDialog.DefaultExt = ".csv";            saveFileDialog.Filter = "CSV(逗号分隔)|*.csv|TXT 文档|*.txt";            string path;            DialogResult dialogResult = saveFileDialog.ShowDialog();            if (dialogResult == DialogResult.OK)            {                path = saveFileDialog.FileName;                datatableToCSV(dt, path);            }            pointCount = 0;            dt.Clear();        }
        /// <summary>        /// 将数据表转为CSV文件        /// </summary>        /// <param name="dt"></param>        /// <param name="pathFile"></param>        /// <returns></returns>        public bool datatableToCSV(DataTable dt, string pathFile)        {            string strLine = "";            StreamWriter sw;            try            {                sw = new StreamWriter(pathFile, false, System.Text.Encoding.GetEncoding(-0)); //覆盖                                                                                              //表头                for (int i = 0; i < dt.Columns.Count; i++)                {                    if (i > 0)                        strLine += ",";                    strLine += dt.Columns[i].ColumnName;                }                strLine.Remove(strLine.Length - 1);                sw.WriteLine(strLine);                strLine = "";                //表的内容                for (int j = 0; j < dt.Rows.Count; j++)                {                    strLine = "";                    int colCount = dt.Columns.Count;                    for (int k = 0; k < colCount; k++)                    {                        if (k > 0 && k < colCount)                            strLine += ",";                        if (dt.Rows[j][k] == null)                            strLine += "";                        else                        {                            string cell = dt.Rows[j][k].ToString().Trim();                            //防止里面含有特殊符号                            cell = cell.Replace(""", """");                            cell = """ + cell + """;                            strLine += cell;                        }                    }                    sw.WriteLine(strLine);                }                sw.Close();                string msg = "数据被成功导出到:" + pathFile;                ShowMsg(msg);            }            catch (Exception)            {                string msg = "导出错误:" + pathFile;                ShowMsg(msg);                return false;            }            return true;        }
        /// <summary>        /// 单步控制        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void step_bt_Click(object sender, EventArgs e)        {            Button bt = (Button)sender;            string sendStr = "<Sensor><Status><IsOut>FALSE</IsOut></Status><StepMode>" + bt.Tag.ToString() + "</StepMode><SX>" + Common.XP2[0].ToString() + "</SX><SY>" + Common.XP2[1].ToString() + "</SY><SZ>" + Common.XP2[2].ToString() + "</SZ><SA>" + Common.XP2[3].ToString() + "</SA><SB>" + Common.XP2[4].ToString() + "</SB><SC>" + Common.XP2[5].ToString() + "</SC></Sensor>";            Send_Robot(sendStr);            ShowMsg(sendStr);            xMotionTB.Clear();            yMotionTB.Clear();            zMotionTB.Clear();            aMotionTB.Clear();            bMotionTB.Clear();            cMotionTB.Clear();        }    }}

Common.cs //存放服务器地址与机器人原点位置

using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace KUKA_Motion{    public class Common    {        //以太网全局变量        public static string IpAddress = "172.31.1.11";        public static string Port = "59152";
        //机器人原点        private static double[] xp1 = new double[6] { 0, -90, 90, 0, 0, 0 };        private static double[] xp2 = new double[6] { 1340, 0, 1810, 165, 90, 165 };
        public static double[] XP1        {            get { return xp1; }            set { xp1 = value; }        }        public static double[] XP2        {            get { return xp2; }            set { xp2 = value; }        }    }}

文章源码已经发布在知识星球会员群

加入知识星球智能制造与自动化,加入会员可下载此公众号发布文章中的相关资料(行业报告、MES、数字化技术方案、自动化教程、自动化行业标准化资料VASSSICAR戴姆勒等、C#上位机开发、node-red开发、人工智能教程等)。

 

今天的文章,如果你感觉有价值,请记得一键三连:点赞加关注,留言,转发朋友圈,分享收藏,点击在看之后,一定记着加我个人微信:ZIDHXB。

相关推荐