項目背景:
? ? ? ? 在非標設備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