项目背景:
在非标设备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