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.pswp.cn/news/697006.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697006.shtml
英文地址,請注明出處:http://en.pswp.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。本文適合希望了解和…