C#建立服务端程序与KUKA通讯实现测量位姿自动读取

首先给出C#上位机程序:

using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;//线程类
using System.Windows.Forms;

namespace KRC2Server
{
    public partial class Form1 : Form
    {
        //创建相关变量
        public Thread MyThread;//线程1
        public Thread thread;
        public Socket WatchSocket;//服务端socket
        public Socket clientSocket;//监听socket
        public IPEndPoint LocalEP;//IP+端口
        public IPAddress LocalIPv4;//获取当前IP的变量
        public int DefaultPort;//下拉框的端口值1
        public int DefaultPort2;//下拉框的端口值2
        public int DefaultPort3;//下拉框的端口值3
        public int SelectPort;//选择的下拉框
        public int SaveNum;
        private byte[] buffer = new byte[1024 * 1024 * 2];//接收到的消息的二进制字符串
        private string TxtNum = "0";
        private bool OpenORClose = false;
        public int saveNum=0;
        public int AutoSaveNum = 0;
        //private byte[] BYte = new byte[8];

        public Form1()
        {
            InitializeComponent();
        }

        //定义回调:解决跨线程访问问题
        private delegate void SetTextValueCallBack(int Num, string strValue);
        //声明回调
        private SetTextValueCallBack setCallBack;

        private void Form1_Load(object sender, EventArgs e)
        {
            //初始化列表框
            string[] init_item = { "X","Y","Z", "EX", "EY", "EZ",
               "axis1","axis2","axis3","axis4","axis5","axis6"};
            for (int i = 0; i < 12; i++)
            {
                ListViewItem item = new ListViewItem(init_item[i]);
                item.SubItems.Add("");
                listView_kukapose.Items.Insert(i, item);
            }
            
            //获取本地IPv4地址
            IPAddress LocalIpv4 = null;
            //获取本机所有的IP地址列表
            IPAddress[] IpList = Dns.GetHostAddresses(Dns.GetHostName());
            //循环遍历所有IP地址
            foreach (IPAddress IP in IpList)
            {
                //判断是否是IPv4地址
                if (IP.AddressFamily == AddressFamily.InterNetwork)
                {
                    LocalIpv4 = IP;
                }
                else
                {
                    continue;
                }
            }
            string LocalIP = Convert.ToString(LocalIpv4);
            //TxtIP.AppendText(LocalIP);
            TxtIP.Text = LocalIP;//textbox中显示当前的IP
            LocalIPv4 = IPAddress.Parse(this.TxtIP.Text.Trim());//转换为IPAddress格式,并删除字符中句首和句末的空白格
            DefaultPort = 59152;
            DefaultPort2 = 59153;
            DefaultPort3 = 59154;
            TxtPort.Items.Add(Convert.ToString(DefaultPort));//下拉框显示
            TxtPort.Items.Add(Convert.ToString(DefaultPort2));
            TxtPort.Items.Add(Convert.ToString(DefaultPort3));
            TxtPort.SelectedIndex = 0;
            if(File.Exists(@"KukaPoseOrigin.txt"))
                File.Delete(@"KukaPoseOrigin.txt");
            if (File.Exists(@"AutoKukaPoseOrigin.txt"))
                File.Delete(@"AutoKukaPoseOrigin.txt");
            StartServer.Text = "启动服务器";
        }
        //******************************//
        //启动服务器

        //******************************//
        private void StartServer_Click(object sender, EventArgs e)
        {
            StartListen();

        }

        private void StartListen()
        {
            try
            {
                //实例化套接字
                WatchSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //根据下拉框选择端口值
                if (0 == TxtPort.SelectedIndex)
                    SelectPort = DefaultPort;
                else if (1 == TxtPort.SelectedIndex)
                    SelectPort = DefaultPort2;
                else if (2 == TxtPort.SelectedIndex)
                    SelectPort = DefaultPort3;
                //创建网络端口,包括ip和端口
                LocalEP = new IPEndPoint(LocalIPv4, SelectPort);
                WatchSocket.Bind(LocalEP);
                WatchSocket.Listen(10);
                MyThread = new Thread(ListenClientConnect);//开启新线程去接收客户端
                MyThread.Start();
                textLog.AppendText( "服务器" + SelectPort.ToString() + "监听成功"+"\r\n");
                StartServer.Text = "正在监听......";

                //实例化回调
                setCallBack = new SetTextValueCallBack(SetTextValue);

            }
            catch(Exception ex)
            {
                textLog.AppendText("服务器" + SelectPort.ToString() + "监听失败" + "\r\n");
                //clientSocket.Shutdown(SocketShutdown.Both);
                //clientSocket.Close();
                return;
            }
        }

        private void ListenClientConnect()
        {
            //while (true)
            //{
                try
                {
                    while(true)
                    {
                        //Socket创建的新连接
                        Socket clientSocket = WatchSocket.Accept();
                        textLog.AppendText( "连接成功" + "\r\n");
                        //clientSocket.SendFile("连接成功");
                        clientSocket.Send(Encoding.UTF8.GetBytes("服务端发送消息:"));
                        //Thread thread = new Thread(ReceiveMessage);//开启新线程与客户端互相发送消息
                        thread = new Thread(ReceiveMessage);
                        thread.Start(clientSocket);
                        StartServer.BackColor = Color.Green;
                        StartServer.Enabled = false;
                        StartServer.Text = "已打开服务器-" + SelectPort.ToString();
                    }
                }
                catch (Exception ex)
                {
                //break;
                //textLog.AppendText("服务器" + SelectPort.ToString() + "失去连接" + "\r\n");
            }
            //textLog.AppendText("服务器" + SelectPort.ToString() + "失去连接" + "\r\n");
            //}


        }

        private void ReceiveMessage(object socket)
        {
            clientSocket = (Socket)socket;
            while(true)
            {
                try
                {
                    //获取从客户端发来的数据
                    //int length = clientSocket.Receive(buffer);//将消息接收到buffer中,length记录二进制的长度
                    string ip = LocalEP.ToString();
                    int size = clientSocket.Receive(buffer);
                    string StrMsg = Encoding.UTF8.GetString(buffer, 0, size);
                    if(StrMsg != "")
                    {
                        textLog.AppendText(ip + "Send" + "\r\n");
                        textLog.AppendText(StrMsg + "\r\n");//将消息显示在对话框中
                    }
                    
                    //string StrReceiveMsg = Encoding.UTF8.GetString(buffer, 0, length);//将消息转成string
                    //if(StrReceiveMsg!="")
                    //{
                    if (OpenORClose==true)
                        {
                           
                            if(StrMsg!="Flag1"&&StrMsg!="")
                            {
                                //string[] StrTmp = StrMsg.Split(',');
                                //listView_kukapose.Invoke(setCallBack, 0, StrTmp[0]);
                                //listView_kukapose.Invoke(setCallBack, 1, StrTmp[1]);
                                //listView_kukapose.Invoke(setCallBack, 2, StrTmp[2]);
                                //listView_kukapose.Invoke(setCallBack, 3, StrTmp[3]);
                                //listView_kukapose.Invoke(setCallBack, 4, StrTmp[4]);
                                //listView_kukapose.Invoke(setCallBack, 5, StrTmp[5]);
                                //listView_kukapose.Invoke(setCallBack, 6, StrTmp[6]);
                                //listView_kukapose.Invoke(setCallBack, 7, StrTmp[7]);
                                //listView_kukapose.Invoke(setCallBack, 8, StrTmp[8]);
                                //listView_kukapose.Invoke(setCallBack, 9, StrTmp[9]);
                                //listView_kukapose.Invoke(setCallBack, 10, StrTmp[10]);
                                //listView_kukapose.Invoke(setCallBack, 11, StrTmp[11]);

                            //KUKA Robot
                            string[] StrTmp = StrMsg.Split('\"');
                            listView_kukapose.Invoke(setCallBack, 0, StrTmp[1]);
                            listView_kukapose.Invoke(setCallBack, 1, StrTmp[3]);
                            listView_kukapose.Invoke(setCallBack, 2, StrTmp[5]);
                            listView_kukapose.Invoke(setCallBack, 3, StrTmp[11]);
                            listView_kukapose.Invoke(setCallBack, 4, StrTmp[9]);
                            listView_kukapose.Invoke(setCallBack, 5, StrTmp[7]);
                            listView_kukapose.Invoke(setCallBack, 6, StrTmp[13]);
                            listView_kukapose.Invoke(setCallBack, 7, StrTmp[15]);
                            listView_kukapose.Invoke(setCallBack, 8, StrTmp[17]);
                            listView_kukapose.Invoke(setCallBack, 9, StrTmp[19]);
                            listView_kukapose.Invoke(setCallBack, 10, StrTmp[21]);
                            listView_kukapose.Invoke(setCallBack, 11, StrTmp[23]);
                        }
                            else if(StrMsg=="Flag1")
                            {
                                AutoSaveNum += 1;
                                Txt_AutoNum.Text = Convert.ToString(AutoSaveNum);
                                //TxtNum = Convert.ToString(AutoSaveNum);
                                FileStream fs = new FileStream(@"AutoKukaPoseOrigin.txt", FileMode.Append);//采用FileMode.Append可以在txt中叠加而不覆盖,@加字符串可以代表不需要加转义字符
                                StreamWriter sw = new StreamWriter(fs);//输出流
                                float X = float.Parse(listView_kukapose.Items[0].SubItems[1].Text);//Parse表示将字符串转换为任意类型,这里转换为float
                                float Y = float.Parse(listView_kukapose.Items[1].SubItems[1].Text);
                                float Z = float.Parse(listView_kukapose.Items[2].SubItems[1].Text);
                                float EX = float.Parse(listView_kukapose.Items[3].SubItems[1].Text);
                                float EY = float.Parse(listView_kukapose.Items[4].SubItems[1].Text);
                                float EZ = float.Parse(listView_kukapose.Items[5].SubItems[1].Text);
                                double Ex = EX * Math.PI / 180;
                                double Ey = EY * Math.PI / 180;
                                double Ez = EZ * Math.PI / 180;
                                sw.Write(Convert.ToString(AutoSaveNum) + "," +
                                    " " + X.ToString("#0.000000") +
                                    "," + Y.ToString("#0.000000") +
                                    "," + Z.ToString("#0.000000") +
                                    "," +
                                    " " + Ex.ToString("#0.000000") +
                                    "," + Ey.ToString("#0.000000") +
                                    "," + Ez.ToString("#0.000000") +
                                    "\r\n");
                                sw.Close();
                                fs.Close();
                            }
                        }
                  else
                        {
                        
                        //string[] StrTmps = StrMsg.Split(',');
                        //listView_kukapose.Invoke(setCallBack, 0, StrTmps[0]);
                        //listView_kukapose.Invoke(setCallBack, 1, StrTmps[1]);
                        //listView_kukapose.Invoke(setCallBack, 2, StrTmps[2]);
                        //listView_kukapose.Invoke(setCallBack, 3, StrTmps[3]);
                        //listView_kukapose.Invoke(setCallBack, 4, StrTmps[4]);
                        //listView_kukapose.Invoke(setCallBack, 5, StrTmps[5]);
                        //listView_kukapose.Invoke(setCallBack, 6, StrTmps[6]);
                        //listView_kukapose.Invoke(setCallBack, 7, StrTmps[7]);
                        //listView_kukapose.Invoke(setCallBack, 8, StrTmps[8]);
                        //listView_kukapose.Invoke(setCallBack, 9, StrTmps[9]);
                        //listView_kukapose.Invoke(setCallBack, 10, StrTmps[10]);
                        //listView_kukapose.Invoke(setCallBack, 11, StrTmps[11]);

                        //KUKA Robot
                        string[] StrTmp = StrMsg.Split('\"');
                        listView_kukapose.Invoke(setCallBack, 0, StrTmp[1]);
                        listView_kukapose.Invoke(setCallBack, 1, StrTmp[3]);
                        listView_kukapose.Invoke(setCallBack, 2, StrTmp[5]);
                        listView_kukapose.Invoke(setCallBack, 3, StrTmp[11]);
                        listView_kukapose.Invoke(setCallBack, 4, StrTmp[9]);
                        listView_kukapose.Invoke(setCallBack, 5, StrTmp[7]);
                        listView_kukapose.Invoke(setCallBack, 6, StrTmp[13]);
                        listView_kukapose.Invoke(setCallBack, 7, StrTmp[15]);
                        listView_kukapose.Invoke(setCallBack, 8, StrTmp[17]);
                        listView_kukapose.Invoke(setCallBack, 9, StrTmp[19]);
                        listView_kukapose.Invoke(setCallBack, 10, StrTmp[21]);
                        listView_kukapose.Invoke(setCallBack, 11, StrTmp[23]);
                    }

                        
                   // }

                    
                    //Console.WriteLine("接收客户端{0},消息{1}", clientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(buffer, 0, length));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                    //textLog.AppendText("服务器" + SelectPort.ToString() + "失去连接" + "\r\n");
                    break;
                }
                //textLog.AppendText("服务器" + SelectPort.ToString() + "失去连接" + "\r\n");
            }
            textLog.AppendText("服务器" + SelectPort.ToString() + "失去连接" + "\r\n");
        }

        private void SetTextValue(int Num, string strValue)
        {
            float Pose = float.Parse(strValue);
            listView_kukapose.Items[Num].SubItems[1].Text = Pose.ToString("#0.000000");
        }



        private void Form1_FormClose(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("您确定要注销登录吗?", "KRC4Server", MessageBoxButtons.YesNo) == DialogResult.Yes)//中文版本
            {

                //关闭socket避免占用端口
                if (clientSocket != null)
                {
                    WatchSocket.Close();
                    clientSocket.Close();
                    MyThread.Abort();
                    thread.Abort();
                    clientSocket = null;
                }
                    
                    //关闭线程
                    //MyThread.Abort();
                    //SocketServer = null;

                    e.Cancel = false;
            }
            else e.Cancel = true;
        }

        // 检查一个Socket是否可连接
        //private bool IsSocketConnected(Socket client)
        //{
        //    bool blockingState = client.Blocking;
        //    try
        //    {
        //        byte[] tmp = new byte[1];
        //        client.Blocking = false;
        //        client.Send(tmp, 0, 0);
        //        return false;
        //    }
        //    catch (SocketException e)
        //    {
        //        // 产生 10035 == WSAEWOULDBLOCK 错误,说明被阻止了,但是还是连接的
        //        if (e.NativeErrorCode.Equals(10035))
        //            return false;
        //        else
        //            return true;
        //    }
        //    finally
        //    {
        //        client.Blocking = blockingState;    // 恢复状态
        //    }
        //}

        private void button1_Click(object sender, EventArgs e)
        {
            if ("" == listView_kukapose.Items[0].SubItems[1].Text)
            {
                MessageBox.Show("未接收到位姿,无法保存!", "提示");
            }
            else
            {
                
                saveNum += 1;
                textBox_num.Text = Convert.ToString(saveNum);
                TxtNum = Convert.ToString(saveNum);
                FileStream fs = new FileStream(@"KukaPoseOrigin.txt", FileMode.Append);//采用FileMode.Append可以在txt中叠加而不覆盖,@加字符串可以代表不需要加转义字符
                StreamWriter sw = new StreamWriter(fs);//输出流
                float X = float.Parse(listView_kukapose.Items[0].SubItems[1].Text);//Parse表示将字符串转换为任意类型,这里转换为float
                float Y = float.Parse(listView_kukapose.Items[1].SubItems[1].Text);
                float Z = float.Parse(listView_kukapose.Items[2].SubItems[1].Text);
                float EX = float.Parse(listView_kukapose.Items[3].SubItems[1].Text);
                float EY = float.Parse(listView_kukapose.Items[4].SubItems[1].Text);
                float EZ = float.Parse(listView_kukapose.Items[5].SubItems[1].Text);
                double Ex = EX * Math.PI / 180;
                double Ey = EY * Math.PI / 180;
                double Ez = EZ * Math.PI / 180;
                sw.Write(TxtNum + "," +
                    " " + X.ToString("#0.000000") +
                    "," + Y.ToString("#0.000000") +
                    "," + Z.ToString("#0.000000") +
                    "," +
                    " " + Ex.ToString("#0.000000") +
                    "," + Ey.ToString("#0.000000") +
                    "," + Ez.ToString("#0.000000") +
                    "\r\n");
                sw.Close();
                fs.Close();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if(OpenORClose==false)
            {
                OpenORClose = true;
                button2.Text = "取消连续";
            }
            else if (OpenORClose == true)
            {
                OpenORClose = false;
                button2.Text = "连续保存";
            }

        }
    }
}

接下来将具体举出几个值得注意的地方

1.在创建服务端监听和接收时,按照规范应该采用多线程进行通讯,如下面代码展示了服务端创建以及采用新的线程去监听。其中Mythread为新的线程

private void StartListen()
        {
            try
            {
                //实例化套接字
                WatchSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //根据下拉框选择端口值
                if (0 == TxtPort.SelectedIndex)
                    SelectPort = DefaultPort;
                else if (1 == TxtPort.SelectedIndex)
                    SelectPort = DefaultPort2;
                else if (2 == TxtPort.SelectedIndex)
                    SelectPort = DefaultPort3;
                //创建网络端口,包括ip和端口
                LocalEP = new IPEndPoint(LocalIPv4, SelectPort);
                WatchSocket.Bind(LocalEP);
                WatchSocket.Listen(10);
                MyThread = new Thread(ListenClientConnect);//开启新线程去接收客户端
                MyThread.Start();
                textLog.AppendText( "服务器" + SelectPort.ToString() + "监听成功"+"\r\n");
                StartServer.Text = "正在监听......";

                //实例化回调
                setCallBack = new SetTextValueCallBack(SetTextValue);

            }
            catch(Exception ex)
            {
                textLog.AppendText("服务器" + SelectPort.ToString() + "监听失败" + "\r\n");
                //clientSocket.Shutdown(SocketShutdown.Both);
                //clientSocket.Close();
                return;
            }
        }

2.设置的Flag1可以自行替换成其他标志,其作用是kuka发过来进行判断该进行位置保存。
下面是上位机的样子
上位机运行状态
其中包含手动保存和自动保存模块,后面显示目前保存的坐标点数,其存在两个txt中,分别为:AutoKukaPoseOrigin.txt&KukaPoseOrigin.txt,具体见下图
在这里插入图片描述

下面是对应的KUKA的SRC和XML程序:

SRC:

&ACCESS RVP
&PARAM EDITMASK = *
&PARAM TEMPLATE = C:\KRC\Roboter\Template\ExpertVorgabe
DEF TYM()

;FOLD Declaration
  INT i
  DECL EKI_STATUS RET
  CHAR valueChar[256]
  CHAR Bytes1[64]
  INT valueInt
  BOOL valueBOOL
  FRAME valueFrame
  $FLAG[1]=FALSE
  $FLAG[2]=FALSE
  BAS(#TOOL,0)
  BAS(#BASE,0)
;ENDFOLD (Declaration)
;FOLD Communicated data
  ;FOLD Receive from external program
  ; <Sensor>
    ; <Message>Example message</Message>
    ; <Positions>
      ; <Current X="4645.2" />
      ; <Before>
        ; <X>0.9842</X>
      ; </Before>
    ; </Positions>
    ; <Nmb>8</Nmb>
    ; <Status>
      ; <IsActive>1</IsActive>
    ; </Status>
    ; <Read>
      ; <xyzabc X="210.3" Y="825.3" Z="234.3" A="84.2" B="12.3" C="43.5" />
    ; </Read>
    ; <Show error="0" temp="9929">Taginfo in attributes</Show>
    ; <Free>2912</Free>
  ; </Sensor>
  ;ENDFOLD (Receive from external program)
  ;FOLD Send to external program
  ; <Robot>
    ; <Data>
      ; <ActPos X="1000.12">
      ; </ActPos>
      ; <LastPos A="..." B="..." C="..." X="..." Y="..." Z="...">
      ; </LastPos>
    ; </Data>
    ; <Mode>ConnectSensor</Mode>
    ; <RobotLamp>
      ; <GrenLamp>
        ; <LightOn>1</LightOn>
      ; </GrenLamp>
    ; </RobotLamp>
    ; <Status>12345678</Status>
  ; </Robot>
  ;ENDFOLD (Send to external program)
;ENDFOLD (Communicated data)


RET=EKI_Init("XmlTYM")
RET=EKI_Open("XmlTYM")

;FOLD Write data to connection
  ; Write frame to <LastPos X="" Y="" Z="" A="" B="" C="" />这是将控制器中的值写入结构变量中
  RET=EKI_SetFrame("XmlTYM","Robot/Data/Pos", $POS_ACT)
  ; Write real to <Axis ="" />
  RET=EKI_SetReal("XmlTYM","Robot/Data/Axis/@A1", $AXIS_ACT.A1)
  RET=EKI_SetReal("XmlTYM","Robot/Data/Axis/@A2", $AXIS_ACT.A2)
  RET=EKI_SetReal("XmlTYM","Robot/Data/Axis/@A3", $AXIS_ACT.A3)
  RET=EKI_SetReal("XmlTYM","Robot/Data/Axis/@A4", $AXIS_ACT.A4)
  RET=EKI_SetReal("XmlTYM","Robot/Data/Axis/@A5", $AXIS_ACT.A5)
  RET=EKI_SetReal("XmlTYM","Robot/Data/Axis/@A6", $AXIS_ACT.A6)
  ; Write int to <Status></Status>
  RET=EKI_SetInt("XmlTYM","Robot/Status", 12345678)
  ; Write string to <Mode></Mode>
  RET=EKI_SetString("XmlTYM","Robot/Mode","ConnectSensor")
  ; Write bool to <LightOn></LightOn>
  RET=EKI_SetBool("XmlTYM","Robot/RobotLamp/GrenLamp/LightOn",true);XmlTYM是通道名称,Robot/RobotLamp/GrenLamp/LightOn是结构中的位置名称,true是写入存储器的值
;ENDFOLD (Write data to connection)

RET = EKI_Send("XmlTYM","Robot")
WAIT SEC 0.1
loop
Bytes1[]="Flag1"
RET = EKI_Send("XmlTYM",Bytes1[])
WAIT FOR $FLAG[2]
wait sec 2
$flag[2]=false
endloop

  FOR i=(1) TO (256)  
      valueChar[i]=0
  ENDFOR

  valueInt=0
  valueBOOL=FALSE
  valueFrame={X 0.0,Y 0.0,A 0.0,B 0.0,C 0.0}
;wait until data read
WAIT FOR $FLAG[998]

;FOLD Get received sensor data
  ; Get string in <Message>Example message</Message>
  RET=EKI_GetString("XmlTYM","Sensor/Message",valueChar[])
  ; Get int value in <Nmb>8</Nmb>
  RET=EKI_GetInt("XmlTYM","Sensor/Nmb",valueInt)
  ; Get bool value in textnode <IsActive>1</IsActive>
  RET=EKI_GetBool("XmlTYM","Sensor/Status/IsActive" ,valueBOOL)
  ; Get frame in <xyzabc X="210.3" Y="825.3" Z="234.3" A="84.2" B="12.3" C="43.5" />
  RET=EKI_GetFrame("XmlTYM","Sensor/Read/xyzabc",valueFrame)
;ENDFOLD (Get received sensor data)
RET=EKI_Close("XmlTYM")
RET=EKI_Clear("XmlTYM")
END 


XML:

<ETHERNETKRL>
	<CONFIGURATION>
		<EXTERNAL>
			<IP>192.168.125.2</IP>
			<PORT>59152</PORT>
		</EXTERNAL>
	</CONFIGURATION>
	<RECEIVE>
		<XML>
			<ELEMENT Tag="Sensor/Message" Type="STRING"/>
			<ELEMENT Tag="Sensor/Nmb" Type="INT"/>
			<ELEMENT Tag="Sensor/Status/IsActive" Type="BOOL"/>
			<ELEMENT Tag="Sensor/Read/xyzabc" Type="FRAME"/>
			<ELEMENT Tag="Sensor/Fre" Set_Flag="998"/>
		</XML>
		
		<RAW>

         <ELEMENT Tag="Buffer" Type="STREAM" Set_Flag="2" EOS="13,10"/>
		</RAW>
	</RECEIVE>
	<SEND>
		<XML>
		;下面是发送数据的数据结构
			<ELEMENT Tag="Robot/Data/Pos/@X"/>
			<ELEMENT Tag="Robot/Data/Pos/@Y"/>
			<ELEMENT Tag="Robot/Data/Pos/@Z"/>
			<ELEMENT Tag="Robot/Data/Pos/@A"/>
			<ELEMENT Tag="Robot/Data/Pos/@B"/>
			<ELEMENT Tag="Robot/Data/Pos/@C"/>
			<ELEMENT Tag="Robot/Data/Axis/@A1"/>
			<ELEMENT Tag="Robot/Data/Axis/@A2"/>
			<ELEMENT Tag="Robot/Data/Axis/@A3"/>
			<ELEMENT Tag="Robot/Data/Axis/@A4"/>
			<ELEMENT Tag="Robot/Data/Axis/@A5"/>
			<ELEMENT Tag="Robot/Data/Axis/@A6"/>
			<ELEMENT Tag="Robot/Status"/>
			;下面两行是为了发送数据所配置的XML结构
			<ELEMENT Tag="Robot/Mode"/>
			<ELEMENT Tag="Robot/RobotLamp/GrenLamp/LightOn"/>
		</XML>
	</SEND>
</ETHERNETKRL>
  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值