一、介绍
本项目包括【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。
阅读全文
5486