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{//等待客户端的连接,并且创建一个负责通信的Socketvar 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:1if (!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\nRobertSoketMsgModel 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 initprgCall tcpClient
Fend
Function tcpClientReceiveData$ = ""'设置IP地址,端口号,结束符等'SetNet #201, "192.168.2.100", 3000, CRLF, NONE, 0SetNet #201, "192.168.10.203", 2000, CRLF, NONE, 0retry_tcpip_201:		'断线重连CloseNet #201'机器人作为客户端,打开端口OpenNet #201 As Client '从'等待连接WaitNet #201'连接成功显示Print "TCP 连接成功"Print #201, " 连接成功"Print "ReceiveData:" + ReceiveData$receive_again:		'再次收发数据Print "wait ReceiveData";Print "----------------------------"DoIf ChkNet(201) < 0 Then '检查端口状态(>0时)Print "tcp_off,try_again"GoTo retry_tcpip_201ElseIf ChkNet(201) > 0 ThenRead #201, ReceiveData$, ChkNet(201)Print "ReceiveData$ = ", ReceiveData$Exit DoEndIfLoopParseStr ReceiveData$, data$(), ","  '如果要发送code,messageNo$ = data$(1)  'code=1				 '格式如下:任意数据;code;messageDeviceId$ = data$(2)  'message=1FlowId$ = data$(3)Msg$ = data$(4)MsgTime$ = data$(5)
'	c = Val(data$(3))Print "解析后的值:" + No$ + "," + DeviceId$ + "," + FlowId$ + "," + Msg$ + "," + MsgTime$Call getNoValCall getFlowIdValCall getDeviceIdValPrint "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$ = "" 'resetEndIfGoTo receive_again
Fend
'做工作,根据上位机发送的指令执行相应动作
Function doWorkPrint "执行doWork"String message$Boolean isOkisOk = 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/s2If FlowIdVal$ = "0" Then '通过上位机判断,机械手执行'相应的动作流程	回原点=0		'Jump P20 LimZ 0 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置0=最高位isOk = TrueElseIf FlowIdVal$ = "1" Then '通过上位机判断,机械手执行'相应的动作流程	移动到取料1的位置		'Jump P1 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = TrueElseIf FlowIdVal$ = "2" Then'相应的动作流程	移动到取料2的位置		'Jump P2 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = TrueElseIf FlowIdVal$ = "3" Then'相应的动作流程	移动到[扫码]的位置'Jump P3 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = TrueElseIf FlowIdVal$ = "4" Then'相应的动作流程	移动到[焊接准备]的位置'Pass 用于移动机械臂并使其穿过指定点数据(位置)附近。不穿过指定点数据(位置)自身。可通过使用Pass 命令来避开障碍物。Pass P40, P41, P42isOk = TrueElseIf FlowIdVal$ = "5" Then'相应的动作流程	移动到[平台放料]的位置Go P5  '全轴同时的PTP动作isOk = TrueElseIf FlowIdVal$ = "6" Then'相应的动作流程	移动到[平台取料]的位置Go P6isOk = TrueElseIf FlowIdVal$ = "7" Then'相应的动作流程	移动到[平台旋转位]的位置Go P7isOk = TrueElseIf FlowIdVal$ = "8" Then'相应的动作流程	移动到[旋转]的位置'Go P7 +U(180) '+U Z轴旋转isOk = TrueElseIf FlowIdVal$ = "10" Then'相应的动作流程	移动到[出料扫码]的位置'Jump P10 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = TrueElseIf FlowIdVal$ = "11" Then'相应的动作流程	移动到[出料1]的位置'Jump P11 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = True'message$ = "失败测试"ElseIf FlowIdVal$ = "12" Then'相应的动作流程	移动到[出料2]的位置'Jump P12 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = TrueElseIf FlowIdVal$ = "13" Then'相应的动作流程	移动到[NG出料1]的位置'Jump P13 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = TrueElseIf FlowIdVal$ = "14" Then'相应的动作流程	移动到[NG出料1]的位置'Jump P14 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100isOk = TrueEndIfIf isOk ThenSendData$ = "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",Status:1"  '操作完成后回复上位机的数据,Status=表示处理成功,0表示处理失败ElseSendData$ = "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",Status:0," + "Msg:" + message$ '操作完成后回复上位机的数据,Status=表示处理成功,0表示处理失败EndIf
Fend
Function getNoValNoVal$ = Mid$(No$, InStr(No$, ":") + 1, Len(No$) - InStr(No$, ":"))
Fend
'获取FlowId的值
Function getFlowIdValFlowIdVal$ = Mid$(FlowId$, InStr(FlowId$, ":") + 1, Len(FlowId$) - InStr(FlowId$, ":"))
Fend
'获取DeviceId的值
Function getDeviceIdValDeviceIdVal$ = Mid$(DeviceId$, InStr(DeviceId$, ":") + 1, Len(DeviceId$) - InStr(DeviceId$, ":"))
Fend
Function init_constantrainit '常变量初始化Off 519On 520Off 521Off 522Off 523Off 524Off 525Off 526Off 527Off 528Off 529
Fend
Function init_robotinit '机械手初始化If Motor = Off ThenMotor OnEndIfIf 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 SLockPower HighSpeed 20 'GO ,JUMP ,最大100Accel 20, 20SpeedS 100; 'ARC ,MOVE2000AccelS 100.100Call huanshouOn 521   '回原完成器人回原请求Off 530 '机器人回原请求PauseFendFunction huanshouIf CZ(Here) < 0 ThenMove Here :Z(0) 'Z轴回到最高位EndIf'--------一象限---------------'If CZ(Here) < 0 And CY(Here) < -90 ThenIf Hand(Here) = Lefty ThenError 8000ElseJump P110Move P111Move P112EndIfEndIf'--------二象限---------------'If CY(Here) < 369.102 And CX(Here) > 0 ThenIf Hand(Here) = Lefty ThenMove P100Move P99Move P97ElseMove P101Move P98EndIfEndIf'--------三象限---------------'If CX(Here) > 0 And CY(Here) < 369.102 ThenIf Hand(Here) = Lefty ThenMove P120ElseMove P121EndIfEndIf
Fend
Function initprg '初始化Print Time$ + "机器人初始化中"Call init_constantrainit'常变量初始化机械手初始化Call init_robotinitPrint '机器人初始化完成
Fend

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/697006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux|centos7|录屏神器asciinema的编译安装和离线化安装使用

前言&#xff1a; asciinema这个录屏软件前面有一点研究&#xff0c;但它的部署安装比较麻烦&#xff0c;虽然此软件的安装部署方式是很多的&#xff0c;比如yum安&#xff0c;apt&#xff0c;brew&#xff0c;docker&#xff0c;pip&#xff0c;rust编译&#xff0c;docker等…

创建一个基于Node.js的实时聊天应用

在当今数字化社会&#xff0c;实时通讯已成为人们生活中不可或缺的一部分。无论是在社交媒体平台上与朋友交流&#xff0c;还是在工作场合中与同事协作&#xff0c;实时聊天应用都扮演着重要角色。与此同时&#xff0c;Node.js作为一种流行的后端技术&#xff0c;为开发者提供了…

CrossOver虚拟机软件2024有哪些功能?最新版本支持哪些游戏?

CrossOver由codewaver公司开发的类虚拟机软件&#xff0c;目的是使linux和Mac OS X操作系统和window系统兼容。CrossOver不像Parallels或VMware的模拟器&#xff0c;而是实实在在Mac OS X系统上运行的一个软件。CrossOvers能够直接在Mac上运行Windows软件与游戏&#xff0c;而不…

Java架构师之路七、大数据:Hadoop、Spark、Hive、HBase、Kafka等

目录 Hadoop&#xff1a; Spark&#xff1a; Hive&#xff1a; HBase&#xff1a; Kafka&#xff1a; Java架构师之路六、高并发与性能优化&#xff1a;高并发编程、性能调优、线程池、NIO、Netty、高性能数据库等。-CSDN博客Java架构师之路八、安全技术&#xff1a;Web安…

[前端]开启VUE之路-NODE.js版本管理

VUE前端开发框架&#xff0c;以Node.js为底座。用历史性的项目来学习&#xff0c;为了降低开发环境的影响因素&#xff0c;各种版本号最好能一致。前端项目也是一样。为了项目能够快速启动&#xff0c;Node.js的版本管理&#xff0c;可以带来很大的便利&#xff08;node.js快速…

2023年全年回顾

本年度比较折腾&#xff0c;整体而言可以分为两个大的阶段&#xff0c;简单而言&#xff0c;转岗前和转岗后。 个人收获 据说程序员有几大浪漫&#xff0c;比如操作系统、编译器、浏览器、游戏引擎等。 之前参与过游戏引擎&#xff0c;现在有机会参与存储业务交付&#xff0c…

LangChain支持哔哩哔哩视频总结

是基于LangChain框架下的开发&#xff0c;所以最开始请先 pip install Langchain pip install bilibili-api-python 技术要点&#xff1a; 使用Langchain框架自带的Document loaders 修改BiliBiliLoader的源码&#xff0c;自带的并不支持当前b站的视频加载 源码文件修改&a…

如何在 Emacs Prelude 上使用 graphviz 的 dot 绘制流程图

文章目录 如何在Emacs Prelude上使用graphviz的dot绘制流程图 <2022-08-23 周二> 如何在Emacs Prelude上使用graphviz的dot绘制流程图 标题中的Emacs Prelude是指&#xff1a;bbatsov/prelude&#xff0c;在custom.el中添加即可&#xff1a; ;;; graphviz (prelude-re…

【高德地图】Android高德地图绘制标记点Marker

&#x1f4d6;第4章 Android高德地图绘制标记点Marker ✅绘制默认 Marker✅绘制多个Marker✅绘制自定义 Marker✅Marker点击事件✅Marker动画效果✅Marker拖拽事件✅绘制默认 Infowindow&#x1f6a9;隐藏InfoWindow 弹框 ✅绘制自定义 InfoWindow&#x1f6a9;实现 InfoWindow…

Java 中 CopyOnWriteArrayList和CopyOnWriteArraySet

什么是CopyOnWriteArrayList和CopyOnWriteArraySet CopyOnWriteArrayList和CopyOnWriteArraySet都是Java并发编程中提供的线程安全的集合类。 CopyOnWriteArrayList是一个线程安全的ArrayList&#xff0c;其内部通过volatile数组和显式锁ReentrantLock来实现线程安全。它采用…

解决ios17无法复制的问题

原代码写过一片js实现复制的代码 那段代码有问题 以下是之前写的一段有问题的原代码&#xff1a; let url "kkkkkk";const hiddenTextarea document.createElement("textarea");hiddenTextarea.style.position "absolute";hiddenTextarea.st…

ArcgisForJS如何实现添加含图片样式的点要素?

文章目录 0.引言1.加载底图2.获取点要素的坐标3.添加含图片样式的几何要素4.完整实现 0.引言 ArcGIS API for JavaScript 是一个用于在Web和移动应用程序中创建交互式地图和地理空间分析应用的库。本文在ArcGIS For JavaScript中使用Graphic对象来创建包含图片样式的点要素。 …

MIT-6.824-Lab2,Raft部分笔记|Use Go

文章目录 前记Paper6&#xff1a;RaftLEC5、6&#xff1a;RaftLAB22AtaskHintlockingstructureguide设计与编码 2BtaskHint设计与编码 2CtaskHint question后记 LEC5&#xff1a;GO, Threads, and Raftgo threads技巧raft实验易错点debug技巧 前记 趁着研一考完期末有点点空余…

软考29-上午题-【数据结构】-排序

一、排序的基本概念 1-1、稳定性 稳定性指的是相同的数据所在的位置经过排序后是否发生变化。若是排序后&#xff0c;次序不变&#xff0c;则是稳定的。 1-2、归位 每一趟排序能确定一个元素的最终位置。 1-3、内部排序 排序记录全部存放在内存中进行排序的过程。 1-4、外部…

vue使用.sync和update实现父组件与子组件数据绑定的案例

在 Vue 中&#xff0c;.sync 是一个用于实现双向数据绑定的特殊修饰符。它允许父组件通过一种简洁的方式向子组件传递一个 prop&#xff0c;并在子组件中修改这个 prop 的值&#xff0c;然后将修改后的值反馈回父组件&#xff0c;实现双向数据绑定。 使用 .sync 修饰符的基本语…

微信小程序 --- wx.request网络请求封装

网络请求封装 网络请求模块难度较大&#xff0c;如果学习起来感觉吃力&#xff0c;可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API&#xff0c;如 wx.request()&#xff0c;wx.login() 等。这类 API 接口…

【精选】Java面向对象进阶——内部类

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

【操作系统】磁盘文件管理系统

实验六 磁盘文件管理的模拟实现 实验目的 文件系统是操作系统中用来存储和管理信息的机构&#xff0c;具有按名存取的功能&#xff0c;不仅能方便用户对信息的使用&#xff0c;也有效提高了信息的安全性。本实验模拟文件系统的目录结构&#xff0c;并在此基础上实现文件的各种…

FISCO BCOS(十七)利用脚本进行区块链系统监控

要利用脚本进行区块链系统监控&#xff0c;你可以使用各种编程语言编写脚本&#xff0c;如Python、Shell等 利用脚本进行区块链系统监控可以提高系统的稳定性、可靠性&#xff0c;并帮助及时发现和解决潜在问题&#xff0c;从而确保区块链网络的正常运行。本文可以利用脚本来解…

Java实战:分布式Session解决方案

本文将详细介绍Java分布式Session的解决方案。我们将探讨分布式Session的基本概念&#xff0c;以及常见的分布式Session管理技术&#xff0c;如Cookie、Token、Redis等。此外&#xff0c;我们将通过具体的示例来展示如何在Java应用程序中实现分布式Session。本文适合希望了解和…