EPSON机器人与PC上位机软件C#网络TCP通讯

项目背景:

        在非标设备PIN焊接机中用到了爱普生机器人。上位机软件使用c#wpf开发。主要逻辑在上位机中。用爱普生机器人给焊接平台实现自动上下料。

通讯方式:网络TCP通讯,Socket

角色:上位机为服务端,机器人为客户端。

责任分工:

        上位软件负责向机器人发送流程指令。

        机器人负责执行点位移动并返回执行结果。机器人有两个回复,一个是成功接收指令的回复,一个执行完成的回复。

指令格式:

        上位机发送指令格式:SendData,No:{0},DeviceId:{1},FlowId:{2},Msg:{3},MsgTime:{4}

        机器人回复格式:"ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",IsSucceed:1" '回复上位机指令接收成功

        机器人执行后回复:SendData$ = "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",Status:0," + "Msg:" + message$

上位机代码:

RobertSoketMsgModel

/// <summary>
/// 机器人通讯 消息实体
/// </summary>
public class RobertSoketMsgModel
{
    /// <summary>
    /// 规则
    /// 第一段是设备ID(1)
    /// 第二段是类型ID(1)
    /// 第三段是时间戳到3位MS
    /// 1120231215162010110
    /// </summary>
    public string No { get; set; }

    /// <summary>
    /// 响应编号
    /// </summary>
    public string ResponseNo { get; set; }

    /// <summary>
    /// 设备ID【1:一号机器人】
    /// </summary>
    public int DeviceId { get; set; }

    /// <summary>
    /// 流程ID FlowIdEnum
    /// </summary>
    public int FlowId { get; set; }

    /// <summary>
    /// 消息
    /// </summary>
    public string Msg { get; set; }

    /// <summary>
    /// 消息时间
    /// </summary>
    public DateTime MsgTime { get; set; }

    /// <summary>
    /// 是否接收成功
    /// </summary>
    public int IsSucceed { get; set; }

    /// <summary>
    /// 状态 成功为1,失败为0
    /// </summary>
    public int Status { get; set; }

    public override string ToString()
    {
        return string.Format("No:{0},ResponseNo:{1},DeviceId:{2},FlowId:{3},Msg:{4},MsgTime:{5},IsSucceed:{6},Status:{7}",
            No,ResponseNo,DeviceId, FlowId, Msg,MsgTime.ToString("yyyy-MM-dd HH:mm:ss"),IsSucceed, Status);
    }

    /// <summary>
    /// 发送数据
    /// </summary>
    /// <returns></returns>
    public string ToSendString()
    {
        return string.Format("SendData,No:{0},DeviceId:{1},FlowId:{2},Msg:{3},MsgTime:{4}",
            No, DeviceId, FlowId, Msg, MsgTime.ToString("yyyy-MM-dd HH:mm:ss"));
    }
}

/// <summary>
/// 流程ID
/// </summary>
public enum FlowIdEnum
{
    //回原点=0,取料1=1(p1),取料2=2(p2),扫码=3(p3),焊接准备=4(p40),平台放料=5(p5),平台取料=6(p6),平台旋转位=7(p7),旋转=8(p8),
    //出料1=9(p9),出料2=10(p10),NG出料1=11(p11),NG出料2=12(p12)

    /// <summary>
    /// 回原点
    /// </summary>
    [Description("回原点")]
    GoHome = 0,

    /// <summary>
    /// 取料1
    /// </summary>
    [Description("取料1")]
    GetMaterial1 = 1,

    /// <summary>
    /// 取料2
    /// </summary>
    [Description("取料2")]
    GetMaterial2 = 2,

    /// <summary>
    /// 进料扫码(读码)
    /// </summary>
    [Description("进料扫码")]
    ReadMaterialCodeIn = 3,

    /// <summary>
    /// 焊接准备
    /// </summary>
    [Description("焊接准备")]
    WeldPrepare = 4,

    /// <summary>
    /// 焊接平台放料
    /// </summary>
    [Description("焊接平台放料")]
    WeldPlatformPut = 5,

    /// <summary>
    /// 焊接平台取料
    /// </summary>
    [Description("焊接平台取料")]
    WeldPlatformGet = 6,

    /// <summary>
    /// 平台旋转位
    /// </summary>
    [Description("平台旋转位")]
    WeldRotatePos = 7,

    //旋转=8(p8),
    /// <summary>
    /// 旋转(电爪)
    /// </summary>
    [Description("旋转(电爪)")]
    Rotate = 8,

    /// <summary>
    /// 焊接
    /// </summary>
    [Description("焊接")]
    Weld = 9,

    /// <summary>
    /// 出料扫码(读码)
    /// </summary>
    [Description("出料扫码")]
    ReadMaterialCodeOut = 10,

    /// <summary>
    /// 出料1
    /// </summary>
    [Description("出料1")]
    OutMaterial1 = 11,

    /// <summary>
    /// 出料2
    /// </summary>
    [Description("出料2")]
    OutMateria2 = 12,

    /// <summary>
    /// NG出料1
    /// </summary>
    [Description("NG出料1")]
    OutNgMaterial= 13,

    /// <summary>
    /// NG出料2
    /// </summary>
    [Description("NG出料2")]
    OutNgMateria2 = 14,
}

Socket

/// <summary>
/// 机器人 通讯
/// </summary>
public class RobertSocketServer
{
    private string _className = "RobertSocketServer";

    /// <summary>
    /// 设备总数
    /// </summary>
    private int _DeviceCount = 1;

    /// <summary>
    /// 是否有在线客户端
    /// </summary>
    public bool IsHaveClient = false;

    //将远程连接客户端的IP地址和Socket存入集合中
    Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();

    private ICommunicationLogService _serverCommunicationLog = ServiceIocFactory.GetRegisterServiceImp<ICommunicationLogService>();

    /// <summary>
    /// 运行日志服务
    /// </summary>        
    private IRunningLogService _srerviceRunninglogs = ServiceIocFactory.GetRegisterServiceImp<IRunningLogService>();

    /// <summary>
    /// 心跳回复时间
    /// </summary>
    private Dictionary<int, DateTime> _heartbeatReplyTime = new Dictionary<int, DateTime>();

    /// <summary>
    /// IP
    /// </summary>
    private string _ip;
    /// <summary>
    /// 端口
    /// </summary>
    private int _port = 6000;

    public RobertSocketServer(string ip, int port = 6000)
    {
        _ip = ip;
        if (port > 0)
        {
            _port = port;
        }
        if (!string.IsNullOrEmpty(_ip))
        {
            startListen();
        }
        else
        {
            throw new Exception("IP地址不能为空");
        }
    }

    /// <summary>
    /// 添加客户端
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="socket"></param>
    /// <returns></returns>
    private bool addClient(string ip, Socket socket)
    {
        var isSucceed = false;
        if (!string.IsNullOrEmpty(ip) && socket != null)
        {
            if (!dicSocket.ContainsKey(ip))
            {
                dicSocket.Add(ip, socket);
                _DeviceCount = dicSocket.Count;
                IsHaveClient = true;
            }
            isSucceed = true;
        }
        return isSucceed;
    }

    /// <summary>
    /// 移除客户端
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    private bool removeClient(string ip)
    {
        var isSucceed = false;
        if (!string.IsNullOrEmpty(ip))
        {
            if (dicSocket.ContainsKey(ip))
            {
                dicSocket.Remove(ip);
            }
            if (dicSocket.Count == 0)
            {
                IsHaveClient = false;
            }
            isSucceed = true;
        }
        return isSucceed;
    }

    /// <summary>
    /// 开始监听
    /// </summary>
    private void startListen()
    {
        try
        {
            //1、创建Socket(寻址方案.IP 版本 4 的地址,
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //2.绑定IP 端口
            IPAddress ipAddress = IPAddress.Parse(_ip);
            IPEndPoint point = new IPEndPoint(ipAddress, _port);
            socket.Bind(point);
            WorkFlow.ShowMsg("机器人通讯服务端已经启动监听", "startListen", _className);

            //3.开启监听
            socket.Listen(10);//10监听对列的最大长度

            //4.开始接受客户端的连接 会卡界面 所以要开线程异步处理
            Task.Run(() => { Listen(socket); });
        }
        catch (Exception ex)
        {
            WorkFlow.ShowAlarmMsg("机器人通讯 服务器监听 异常:" + ex.Message, "startListen");
        }
    }

    /// <summary>
    /// 4 开始接受客户端的连接
    /// </summary>
    /// <param name="socket"></param>
    private void Listen(Socket socket)
    {
        if (socket != null)
        {
            while (true)
            {
                try
                {
                    //等待客户端的连接,并且创建一个负责通信的Socket
                    var accept = socket.Accept();
                    //将远程连接客户端的IP地址和Socket存入集合中
                    var ip = accept.RemoteEndPoint.ToString();
                    if (addClient(ip, accept))
                    {
                        //客户端IP地址和端口号存入下拉框
                        //cmbClientList.Items.Add(ip);
                        WorkFlow.ShowMsg("机器人客户端:" + ip + ":连接成功", "Listen", _className);

                        Task.Run(() => { ReciveClientMsg(accept); });
                    }
                }
                catch (Exception ex)
                {
                    WorkFlow.ShowAlarmMsg("开始接受机器人客户端的连接 异常:" + ex.Message, "Listen", _className);
                }
            }
        }
    }

    /// <summary>
    /// 接收客户端消息
    /// </summary>
    private void ReciveClientMsg(Socket socket)
    {
        WorkFlow.ShowMsg("机器人服务器已启动成功,可以接收客户端连接!时间:" + DateTime.Now.ToString(),
            "ReciveClientMsg", _className);
        //客户端连接成功后,服务器应该接收客户端发来的消息
        byte[] buffer = new byte[1024 * 1024 * 5];
        string reciveMsg = string.Empty;
        //不停的接收消息
        while (true)
        {
            try
            {
                //实际接收到的有效字节数
                int byteLength = 0;
                try
                {
                    byteLength = socket.Receive(buffer);
                }
                catch (Exception)
                {
                    //客户端异常退出
                    clientExit(socket, "异常");
                    return;//让方法结束,结束当前接收客户端消息异步线程
                }
                if (byteLength > 0)
                {
                    reciveMsg = Encoding.UTF8.GetString(buffer, 0, byteLength);
                    //ResponseNo:9876543,IsSucceed:1
                    //ResponseNo:9876543,Status:1
                    if (!string.IsNullOrEmpty(reciveMsg) && reciveMsg.Contains("ResponseNo"))
                    {
                        var rspModel = getMsgModelByStr(reciveMsg);
                        if (rspModel != null)
                        {
                            var isSucceed = 0;
                            if (rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode())
                            {
                                isSucceed = rspModel.IsSucceed;
                            }
                            else if (rspModel.Status == TrueOrFalseEnum.True.GetHashCode())
                            {
                                isSucceed = rspModel.Status;
                            }
                            rspModel.IsSucceed = isSucceed;
                            var logModel = new CommunicationLogModel()
                            {
                                DeviceId = rspModel.DeviceId,
                                Msg = rspModel.Msg,
                                MsgTime = rspModel.MsgTime,
                                No = rspModel.ResponseNo,
                                Type = rspModel.FlowId,
                                IsSucceed = rspModel.IsSucceed,
                                ResponseNo = rspModel.ResponseNo
                            };
                            logModel.ClassName = _className;
                            logModel.Method = "ReciveClientMsg";
                            logModel.CreatedBy = _ip;
                            logModel.CreatedOn = DateTime.Now;
                            logModel.UpdatedBy = Global.EthernetType.GetEnumDesc();

                            FlowIdEnum flowIdEnum = (FlowIdEnum)rspModel.FlowId;
                            if (rspModel.Status == TrueOrFalseEnum.True.GetHashCode())
                            {
                                RobertSocketCommonServer.AddClientRspMsg(rspModel);
                                WorkFlow.ShowMsg("收机器人2>" + rspModel.DeviceId + "机" + flowIdEnum.GetEnumDesc() + "回复:" + (rspModel.Status == TrueOrFalseEnum.True.GetHashCode() ? "处理成功" : "处理失败"), "ReciveClientMsg");
                            }
                            else if (rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode())
                            {
                                RobertSocketCommonServer.IsSendSucceed = rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode();
                                WorkFlow.ShowMsg("收机器人2>" + rspModel.DeviceId + "机" + flowIdEnum.GetEnumDesc() + "回复:" + (rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode() ? "指令接收成功" : "指令接收失败"), "ReciveClientMsg");
                            }
                            _serverCommunicationLog.AddModelAutoIncrement(logModel);
                        }
                    }
                    //var msg = "客户端" + socket.RemoteEndPoint + " 发送:  " + reciveMsg + "   时间:" + DateTime.Now.ToString();
                    //WorkFlow.ShowMsg(msg, "ReciveClientMsg", _className);
                }
                else
                {
                    //客户端正常退出
                    clientExit(socket);
                    return;//让方法结束,结束当前接收客户端消息异步线程
                }
            }
            catch (Exception ex)
            {
                WorkFlow.ShowAlarmMsg("接收客户商消息 异常:" + ex.Message, "ReciveClientMsg", _className);
            }
        }
    }

    /// <summary>
    /// 客户端退出
    /// </summary>
    /// <param name="socket"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    private bool clientExit(Socket socket, string type = "正常")
    {
        var isSucceed = false;
        var ip = socket.RemoteEndPoint.ToString();
        if (removeClient(ip))
        {
            //cmbClientList.Items.Remove(ip);
            WorkFlow.ShowMsg("客户端" + socket.RemoteEndPoint + type + "退出。 时间:" + DateTime.Now.ToString(),
                "clientExit", _className);
            isSucceed = true;
            //Task.Factory.StartNew(() =>
            //{
            //    WindowHelper.OpenAlarmWindow(ip + "客户端退出报警!", "通讯报警");
            //});
        }
        return isSucceed;
    }

    /// <summary>
    /// 向客户端发送消息
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public bool SendMsgToClient(string msg)
    {
        var isOk = false;
        //var msg = txtSendMes.Text.Trim();
        //var clientIp = cmbClientList.SelectedItem.ToString();
        //if (dicSocket.ContainsKey(clientIp))
        //{
        if (!string.IsNullOrEmpty(msg))
        {
            if (dicSocket.Count == 0)
            {
                //MessageBox.Show("没有可以发送的客户端");
                WorkFlow.ShowMsgSocket("没有可以发送的客户端");
            }
            else
            {
                foreach (var clientIp in dicSocket.Keys)
                {
                    var socket = dicSocket[clientIp];
                    if (socket.Connected)//判断是否连接成功
                    {
                        //数据编码
                        var buffer = Encoding.UTF8.GetBytes(msg);
                        var dataList = new List<byte>();
                        //dataList.Add(0);//类型:文本,字符串
                        dataList.AddRange(buffer);

                        //socket.Send(dataList.ToArray(), 0, buffer.Length, SocketFlags.None);
                        socket.Send(dataList.ToArray());
                    }
                }
                Thread.Sleep(100);
            }
        }
        else
        {
            //MessageBox.Show("发送的消息不能为空!");
            WorkFlow.ShowMsg("发送的消息不能为空!", "SendMsgToClient", _className);
        }
        //}
        return isOk;
    }

    /// <summary>
    /// 解析机器人回传信息
    /// </summary>
    /// <param name="rspStr"></param>
    /// <returns></returns>
    private RobertSoketMsgModel getMsgModelByStr(string rspStr)
    {
        //ResponseNo:9876543,WorkId:1,IsSucceed:1
        //ResponseNo:9876543,WorkId:1,Status:1,Msg:"执行失败"
        //\r\n
        RobertSoketMsgModel rspModel = null;
        if (!string.IsNullOrEmpty(rspStr))
        {
            rspStr = rspStr.Replace("\r\n", string.Empty);
            var responseNo = string.Empty;
            int DeviceId = 0;
            int FlowId = 0;
            var isSucceed = TrueOrFalseEnum.False.GetHashCode();
            var strList = rspStr.Split(',').ToList();
            if (strList.Count > 0)
            {
                responseNo = strList[0].Replace("ResponseNo:", string.Empty);
                DeviceId = strList[1].Replace("DeviceId:", string.Empty).ToInt();
                FlowId = strList[2].Replace("FlowId:", string.Empty).ToInt();

                rspModel = new RobertSoketMsgModel();
                rspModel.ResponseNo = responseNo;
                rspModel.FlowId = FlowId;
                rspModel.DeviceId = DeviceId;
                rspModel.MsgTime = DateTime.Now;
                if (rspStr.Contains("IsSucceed") && strList.Count >= 4)
                {
                    isSucceed = strList[3].Replace("IsSucceed:", string.Empty).ToInt();
                    rspModel.IsSucceed = isSucceed;
                }
                else if (rspStr.Contains("Status") && strList.Count >= 4)
                {
                    rspModel.Status = strList[3].Replace("Status:", string.Empty).ToInt();
                    if (strList.Count > 5)
                    {
                        rspModel.Msg = strList[4].Replace("Msg:", string.Empty);
                    }
                    else
                    {
                        rspModel.Msg = rspModel.Status == TrueOrFalseEnum.True.GetHashCode() ? "执行成功" : "执行失败";
                    }
                }
            }
        }
        return rspModel;
    }
}

RobertSocketCommonServer

/// <summary>
/// 机器人 通讯公共方法(服务端)
/// </summary>
public class RobertSocketCommonServer
{
    private static string _className = "RobertSocketCommonServer";
    private static string commMsg = "机器人";
    private static ICommunicationLogService _serverCommunicationLog = ServiceIocFactory.GetRegisterServiceImp<ICommunicationLogService>();
    /// <summary>
    /// 公共日志服务
    /// </summary>
    private static ICommonLogService _serviceLogs = ServiceIocFactory.GetRegisterServiceImp<ICommonLogService>();

    /// <summary>
    /// 客户端响应消息
    /// </summary>
    private static Dictionary<string, RobertSoketMsgModel> _clientResponseMsgDic = new Dictionary<string, RobertSoketMsgModel>();

    /// <summary>
    /// 是否发送要料消息
    /// </summary>
    //public static bool IsSendInMsg = false;

    /// <summary>
    /// 是否发送成功
    /// </summary>
    public static bool IsSendSucceed = false;

    /// <summary>
    /// 创建一个请求消息模型
    /// </summary>
    /// <param name="deviceId">设备ID</param>
    /// <param name="type">类型</param>
    /// <returns></returns>
    public static RobertSoketMsgModel CreateInMsgModel(int deviceId, FlowIdEnum flowId)
    {
        return new RobertSoketMsgModel()
        {
            DeviceId = deviceId,
            Msg = flowId.ToString(),//deviceId + commMsg + type.GetEnumDesc(),
            MsgTime = DateTime.Now,
            No = AppCommonMethods.GenerateMsgNoRobert(flowId, deviceId),
            FlowId = flowId.GetHashCode()
        };
    }

    /// <summary>
    /// 发送指令
    /// </summary>
    /// <param name="deviceId">设备ID</param>
    public static RobertSoketMsgModel SendReq(FlowIdEnum flowId, int deviceId = 1)
    {
        IsSendSucceed = false;
        var msgModel = CreateInMsgModel(deviceId, flowId);
        //var reqJson = JsonConvert.SerializeObject(msgModel);
        Global.RobertEthernetServer.SendMsgToClient(msgModel.ToSendString());
        var logModel = new CommunicationLogModel()
        {
            DeviceId = msgModel.DeviceId,
            Msg = msgModel.Msg,
            MsgTime = msgModel.MsgTime,
            No = msgModel.No,
            Type = flowId.GetHashCode()
        };
        logModel.ClassName = _className;
        logModel.Method = "SendLocalInReq";
        logModel.CreatedBy = Global.EAP_IpAddress;
        logModel.CreatedOn = DateTime.Now;
        logModel.UpdatedBy = Global.EthernetType.GetEnumDesc();
        _serverCommunicationLog.AddModelAutoIncrement(logModel);
        //SoketMsgQueueService.Instance.Enqueue(msgModel);
        return msgModel;
    }

    /// <summary>
    /// 本机发送放(出)料请求
    /// </summary>
    /// <param name="deviceId">设备ID</param>
    //public static string SendLocalOutReq(int deviceId)
    //{
    //    var msgModel = CreateInMsgModel(deviceId, SoketTypeEnum.OutRequest);
    //    var logModel = new CommunicationLogModel()
    //    {
    //        DeviceId = msgModel.DeviceId,
    //        Msg = msgModel.Msg,
    //        MsgTime = msgModel.MsgTime,
    //        No = msgModel.No,
    //        Type = msgModel.Type.GetHashCode()
    //    };
    //    logModel.ClassName = _className;
    //    logModel.Method = "SendLocalOutReq";
    //    logModel.CreatedBy = Global.EAP_IpAddress;
    //    logModel.CreatedOn = DateTime.Now;
    //    logModel.UpdatedBy = Global.EthernetType.GetEnumDesc();
    //    _serverCommunicationLog.AddModelAutoIncrement(logModel);
    //    SoketMsgQueueService.Instance.Enqueue(msgModel);
    //    return msgModel.No;
    //}

    /// <summary>
    /// 添加客户端响应消息
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public static bool AddClientRspMsg(RobertSoketMsgModel model)
    {
        var isOk = false;
        if (model != null && !_clientResponseMsgDic.ContainsKey(model.ResponseNo))
        {
            _clientResponseMsgDic.Add(model.ResponseNo, model);
            isOk = true;
        }
        return isOk;
    }

    /// <summary>
    /// 获取客户端响应消息
    /// </summary>
    /// <param name="no"></param>
    /// <returns></returns>
    public static RobertSoketMsgModel GetClientRspMsg(string no)
    {
        RobertSoketMsgModel msgModel = null;
        if (_clientResponseMsgDic.ContainsKey(no))
        {
            msgModel = _clientResponseMsgDic[no];
            _clientResponseMsgDic.Remove(no);
        }
        return msgModel;
    }

    /// <summary>
    /// While等待获取客户端响应消息
    /// </summary>
    /// <param name="no"></param>
    /// <param name="maxCount">最大等待次数</param>
    /// <returns></returns>
    public static RobertSoketMsgModel GetClientRspMsgWhile(string no, string msg, RobertSoketMsgModel reqModel = null, int maxCount = 60)
    {
        RobertSoketMsgModel msgModel = null;
        var count = 0;
        while (msgModel == null)
        {
            msgModel = GetClientRspMsg(no);
            Thread.Sleep(200);
            //Thread.Sleep(1000);
            WorkFlow.ShowMsg("While等待获取" + commMsg + "..." + msg, "GetClientRspMsgWhile", RunningLogTypeEnum.Alarm);
            //if (count >= maxCount)
            //{
            //    var showMsg = msg + ",未收到" + commMsg + "响应消息。是否继续等待?";
            //    var commonModel = WindowHelper.OpenWindow(showMsg, "等待获取客户端响应消息报警", "继续等", "不等了");
            //    if (commonModel != null && commonModel.IsSucceed)
            //    {
            //        if (reqModel != null)
            //        {
            //            var modelJson = JsonConvert.SerializeObject(reqModel);
            //            Global.EthernetServer.SendMsgToClient(modelJson);//发送物料_通知
            //            var logModelRsp = JsonConvert.DeserializeObject<CommunicationLogModel>(modelJson);
            //            logModelRsp.ClassName = _className;
            //            logModelRsp.Method = "GetClientRspMsgWhile";
            //            logModelRsp.Remark = showMsg;
            //            logModelRsp.CreatedBy = Global.EAP_IpAddress;
            //            logModelRsp.CreatedOn = DateTime.Now;
            //            logModelRsp.UpdatedBy = Global.EthernetType.GetEnumDesc();
            //            _serverCommunicationLog.AddModelAutoIncrement(logModelRsp);
            //        }
            //        count = 0;
            //    }
            //    else
            //    {
            //        break;
            //    }
            //}
            count++;
        }
        return msgModel;
    }

    /// <summary>
    /// 移动到点位
    /// </summary>
    /// <param name="flowId"></param>
    /// <returns></returns>
    public static bool MoveToPos(FlowIdEnum flowId)
    {
        var isSucceed = false;
        var reqModel = SendReq(flowId);
        if (IsSendSucceed)
        {
            var rspModel = GetClientRspMsgWhile(reqModel.No, "机器人的指令处理回复");
            if (rspModel != null)
            {
                isSucceed = rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode();
                WorkFlow.ShowMsg("收到机器人处理完成回复[" + flowId.GetEnumDesc() + "]" + rspModel.IsSucceed, "MoveToPos");
            }
            else
            {
                WorkFlow.ShowMsg("未收到机器人处理完成回复[" + flowId.GetEnumDesc() + "]", "MoveToPos");
            }
        }
        else
        {
            WorkFlow.ShowMsg("发送指令到机器人,发送失败。[" + flowId.GetEnumDesc() + "]", "MoveToPos");
        }
        return isSucceed;
    }
}

机器人代码:

Global String ReceiveData$, data$(0), SendData$
Global String No$, DeviceId$, FlowId$, Msg$, MsgTime$ '假设receive有三组数据,分到三个值里
Global String NoVal$, DeviceIdVal$, FlowIdVal$, MsgVal$, MsgTimeVal$
Function main
	'Call initprg
	Call tcpClient
Fend
Function tcpClient
	ReceiveData$ = ""
	'设置IP地址,端口号,结束符等
    'SetNet #201, "192.168.2.100", 3000, CRLF, NONE, 0
    SetNet #201, "192.168.10.203", 2000, CRLF, NONE, 0
    
    retry_tcpip_201:		'断线重连
    
    CloseNet #201
    '机器人作为客户端,打开端口
    OpenNet #201 As Client '从
    '等待连接
    WaitNet #201
    '连接成功显示
    Print "TCP 连接成功"
    Print #201, " 连接成功"
    Print "ReceiveData:" + ReceiveData$
    receive_again:		'再次收发数据
    Print "wait ReceiveData";
    Print "----------------------------"
    Do
    	If ChkNet(201) < 0 Then '检查端口状态(>0时)
    		Print "tcp_off,try_again"
    		GoTo retry_tcpip_201
    	ElseIf ChkNet(201) > 0 Then
    		Read #201, ReceiveData$, ChkNet(201)
    		Print "ReceiveData$ = ", ReceiveData$
    		Exit Do
    	EndIf
    Loop
    
    ParseStr ReceiveData$, data$(), ","  '如果要发送code,message
	No$ = data$(1)  'code=1				 '格式如下:任意数据;code;message
	DeviceId$ = data$(2)  'message=1
	FlowId$ = data$(3)
	Msg$ = data$(4)
	MsgTime$ = data$(5)
'	c = Val(data$(3))
	
	Print "解析后的值:" + No$ + "," + DeviceId$ + "," + FlowId$ + "," + Msg$ + "," + MsgTime$
	Call getNoVal
	Call getFlowIdVal
	Call getDeviceIdVal
	Print "FlowIdVal:" + FlowIdVal$
	Print #201, "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",IsSucceed:1" '回复上位机指令接收成功
	'Print "len:" + Str$(Len(No$))
	'Print "index:" + Str$(InStr(No$, "No:"))
	'Print "noVal:" + Mid$(No$, InStr(No$, ":") + 1, Len(No$) - InStr(No$, ":"))
	Call doWork  '调用动作指令
	
	If SendData$ <> "" Then  '通过调用,获得数据,机械手反馈运动状态
		Print SendData$
		Print #201, SendData$
		SendData$ = "" 'reset
	EndIf
	GoTo receive_again
Fend
'做工作,根据上位机发送的指令执行相应动作
Function doWork
	Print "执行doWork"
	String message$
	Boolean isOk
	isOk = False
	'回原点=0,取料1=1(p1),取料2=2(p2),进料扫码=3(p3),焊接准备=4(p40),焊接平台放料=5(p5),焊接平台取料=6(p6),平台旋转位=7(p7),旋转(电爪)=8(p8),
	'焊接=9,出料扫码=10,出料1=11(p11),出料2=12(p12),NG出料1=13(p13),NG出料2=14(p14)
	'CP运动命令  Move,Arc, Arc3
	'PTP运动命令 Jump,Go
	'----------------------------
	'PTP运动命令的速度设定
	'PTP运动速度的设定
	'格式:Speed s, [a, b]
	's : 速度设定值(1~100%)
	'a: 第3轴上升的速度设定值(1~100%) (可省略)
 	'b: 第3轴下降的速度设定值(1~100%) (可省略)
	'使用示例
	'Speed 80
    'Speed 100, 80, 50
	'PTP动作的加减速度的设定
	'格 式: Accel a, b, [c, d, e, f]
	'a : 加速设定值(1~100%)
 	'b: 减速设定值(1~100%)
	'c,d : 第3轴上升的加减速设定值(1~100%) (可省略)
	'e,f : 第3轴下降的加减速设定值(1~100%) (可省略)
	'使用示例: Accel 80, 80
	'Accel 100, 100, 20, 80, 80, 20
	'------------------
	'CP运动命令  
	'SpeedS CP动作的速度的设定      SpeedS 500    速度设定值:1~1120 mm/s
	'AccelS CP动作的加减速度的设定  AccelS 2000   加减速度设定值 : 1~5000 mm/s2
	
	If FlowIdVal$ = "0" Then '通过上位机判断,机械手执行
			'相应的动作流程	回原点=0		
			'Jump P20 LimZ 0 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置0=最高位
			
		isOk = True
	ElseIf FlowIdVal$ = "1" Then '通过上位机判断,机械手执行
			'相应的动作流程	移动到取料1的位置		
			'Jump P1 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
			
		isOk = True
	ElseIf FlowIdVal$ = "2" Then
			'相应的动作流程	移动到取料2的位置		
			'Jump P2 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
		isOk = True
	ElseIf FlowIdVal$ = "3" Then
			'相应的动作流程	移动到[扫码]的位置
			'Jump P3 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
		isOk = True
	ElseIf FlowIdVal$ = "4" Then
			'相应的动作流程	移动到[焊接准备]的位置
			'Pass 用于移动机械臂并使其穿过指定点数据(位置)附近。不穿过指定点数据(位置)自身。可通过使用Pass 命令来避开障碍物。
			Pass P40, P41, P42
		isOk = True
	ElseIf FlowIdVal$ = "5" Then
			'相应的动作流程	移动到[平台放料]的位置
			Go P5  '全轴同时的PTP动作
		isOk = True
	ElseIf FlowIdVal$ = "6" Then
			'相应的动作流程	移动到[平台取料]的位置
			Go P6
		isOk = True
	ElseIf FlowIdVal$ = "7" Then
			'相应的动作流程	移动到[平台旋转位]的位置
			Go P7
		isOk = True
	ElseIf FlowIdVal$ = "8" Then
			'相应的动作流程	移动到[旋转]的位置
			'Go P7 +U(180) '+U Z轴旋转
		isOk = True
	ElseIf FlowIdVal$ = "10" Then
			'相应的动作流程	移动到[出料扫码]的位置
			'Jump P10 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
		isOk = True
	ElseIf FlowIdVal$ = "11" Then
			'相应的动作流程	移动到[出料1]的位置
			'Jump P11 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
		isOk = True
		'message$ = "失败测试"
	ElseIf FlowIdVal$ = "12" Then
			'相应的动作流程	移动到[出料2]的位置
			'Jump P12 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
		isOk = True
	ElseIf FlowIdVal$ = "13" Then
			'相应的动作流程	移动到[NG出料1]的位置
			'Jump P13 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
		isOk = True
	ElseIf FlowIdVal$ = "14" Then
			'相应的动作流程	移动到[NG出料1]的位置
			'Jump P14 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
		isOk = True
	EndIf
	If isOk Then
		SendData$ = "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",Status:1"  '操作完成后回复上位机的数据,Status=表示处理成功,0表示处理失败
	Else
		SendData$ = "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",Status:0," + "Msg:" + message$ '操作完成后回复上位机的数据,Status=表示处理成功,0表示处理失败
	EndIf
Fend
Function getNoVal
	NoVal$ = Mid$(No$, InStr(No$, ":") + 1, Len(No$) - InStr(No$, ":"))
Fend
'获取FlowId的值
Function getFlowIdVal
	FlowIdVal$ = Mid$(FlowId$, InStr(FlowId$, ":") + 1, Len(FlowId$) - InStr(FlowId$, ":"))
Fend
'获取DeviceId的值
Function getDeviceIdVal
	DeviceIdVal$ = Mid$(DeviceId$, InStr(DeviceId$, ":") + 1, Len(DeviceId$) - InStr(DeviceId$, ":"))
Fend
Function init_constantrainit '常变量初始化
 Off 519
 On 520
 Off 521
 Off 522
 Off 523
 Off 524
 Off 525
 Off 526
 Off 527
 Off 528
 Off 529
Fend
Function init_robotinit '机械手初始化
	If Motor = Off Then
		Motor On
    EndIf
   
	If SFree(1) Or SFree(2) Or SFree(3) Or SFree(4) Then SLock
	'If SFree(1) 0r SFree(2) 0r SFree(3) 0r SFree(4) Then SLock
	Power High
	Speed 20 'GO ,JUMP ,最大100
	Accel 20, 20
    SpeedS 100; 'ARC ,MOVE2000
	
 	AccelS 100.100
	Call huanshou

	On 521   '回原完成器人回原请求
	Off 530 '机器人回原请求
	Pause

Fend

Function huanshou
	If CZ(Here) < 0 Then
		Move Here :Z(0) 'Z轴回到最高位
	EndIf
	'--------一象限---------------'
	If CZ(Here) < 0 And CY(Here) < -90 Then
		If Hand(Here) = Lefty Then
			Error 8000
		Else
			Jump P110
			Move P111
			Move P112
		EndIf
	EndIf
	'--------二象限---------------'
	If CY(Here) < 369.102 And CX(Here) > 0 Then
		If Hand(Here) = Lefty Then
			Move P100
			Move P99
			Move P97
		Else
			Move P101
			Move P98
		EndIf
	EndIf
	'--------三象限---------------'
	If CX(Here) > 0 And CY(Here) < 369.102 Then
		If Hand(Here) = Lefty Then
			Move P120
		Else
			Move P121
		EndIf
	EndIf
Fend
Function initprg '初始化
	Print Time$ + "机器人初始化中"
	Call init_constantrainit
 	'常变量初始化机械手初始化

	Call init_robotinit

 	Print '机器人初始化完成
Fend

相关推荐

  1. EPSON机器人PC软件C#网络TCP通讯

    2024-02-23 13:16:02       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-23 13:16:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-23 13:16:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-23 13:16:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-23 13:16:02       20 阅读

热门阅读

  1. SpringBoot 使用 JWT 保护 Rest Api 接口

    2024-02-23 13:16:02       26 阅读
  2. websoket

    2024-02-23 13:16:02       28 阅读
  3. vue+electron 自动更新

    2024-02-23 13:16:02       27 阅读
  4. 【LeetCode周赛】第 385 场周赛

    2024-02-23 13:16:02       34 阅读
  5. QT-Day2

    QT-Day2

    2024-02-23 13:16:02      26 阅读
  6. 网页数据的解析提取(Beautiful Soup库详解)

    2024-02-23 13:16:02       34 阅读
  7. 冬眠...

    2024-02-23 13:16:02       32 阅读
  8. 分布式场景怎么Join,一文讲解

    2024-02-23 13:16:02       27 阅读
  9. 数仓面试题整理(2)

    2024-02-23 13:16:02       25 阅读
  10. [前端]开启VUE之路-NODE.js版本管理

    2024-02-23 13:16:02       27 阅读
  11. selenium处理鼠标悬停才能显示的元素

    2024-02-23 13:16:02       30 阅读
  12. 设计模式-抽象工厂模式(C++)

    2024-02-23 13:16:02       31 阅读