• 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

    1. ///
    2. /// 机器人通讯 消息实体
    3. ///
    4. public class RobertSoketMsgModel
    5. {
    6. ///
    7. /// 规则
    8. /// 第一段是设备ID(1)
    9. /// 第二段是类型ID(1)
    10. /// 第三段是时间戳到3位MS
    11. /// 1120231215162010110
    12. ///
    13. public string No { get; set; }
    14. ///
    15. /// 响应编号
    16. ///
    17. public string ResponseNo { get; set; }
    18. ///
    19. /// 设备ID【1:一号机器人】
    20. ///
    21. public int DeviceId { get; set; }
    22. ///
    23. /// 流程ID FlowIdEnum
    24. ///
    25. public int FlowId { get; set; }
    26. ///
    27. /// 消息
    28. ///
    29. public string Msg { get; set; }
    30. ///
    31. /// 消息时间
    32. ///
    33. public DateTime MsgTime { get; set; }
    34. ///
    35. /// 是否接收成功
    36. ///
    37. public int IsSucceed { get; set; }
    38. ///
    39. /// 状态 成功为1,失败为0
    40. ///
    41. public int Status { get; set; }
    42. public override string ToString()
    43. {
    44. return string.Format("No:{0},ResponseNo:{1},DeviceId:{2},FlowId:{3},Msg:{4},MsgTime:{5},IsSucceed:{6},Status:{7}",
    45. No,ResponseNo,DeviceId, FlowId, Msg,MsgTime.ToString("yyyy-MM-dd HH:mm:ss"),IsSucceed, Status);
    46. }
    47. ///
    48. /// 发送数据
    49. ///
    50. ///
    51. public string ToSendString()
    52. {
    53. return string.Format("SendData,No:{0},DeviceId:{1},FlowId:{2},Msg:{3},MsgTime:{4}",
    54. No, DeviceId, FlowId, Msg, MsgTime.ToString("yyyy-MM-dd HH:mm:ss"));
    55. }
    56. }
    57. ///
    58. /// 流程ID
    59. ///
    60. public enum FlowIdEnum
    61. {
    62. //回原点=0,取料1=1(p1),取料2=2(p2),扫码=3(p3),焊接准备=4(p40),平台放料=5(p5),平台取料=6(p6),平台旋转位=7(p7),旋转=8(p8),
    63. //出料1=9(p9),出料2=10(p10),NG出料1=11(p11),NG出料2=12(p12)
    64. ///
    65. /// 回原点
    66. ///
    67. [Description("回原点")]
    68. GoHome = 0,
    69. ///
    70. /// 取料1
    71. ///
    72. [Description("取料1")]
    73. GetMaterial1 = 1,
    74. ///
    75. /// 取料2
    76. ///
    77. [Description("取料2")]
    78. GetMaterial2 = 2,
    79. ///
    80. /// 进料扫码(读码)
    81. ///
    82. [Description("进料扫码")]
    83. ReadMaterialCodeIn = 3,
    84. ///
    85. /// 焊接准备
    86. ///
    87. [Description("焊接准备")]
    88. WeldPrepare = 4,
    89. ///
    90. /// 焊接平台放料
    91. ///
    92. [Description("焊接平台放料")]
    93. WeldPlatformPut = 5,
    94. ///
    95. /// 焊接平台取料
    96. ///
    97. [Description("焊接平台取料")]
    98. WeldPlatformGet = 6,
    99. ///
    100. /// 平台旋转位
    101. ///
    102. [Description("平台旋转位")]
    103. WeldRotatePos = 7,
    104. //旋转=8(p8),
    105. ///
    106. /// 旋转(电爪)
    107. ///
    108. [Description("旋转(电爪)")]
    109. Rotate = 8,
    110. ///
    111. /// 焊接
    112. ///
    113. [Description("焊接")]
    114. Weld = 9,
    115. ///
    116. /// 出料扫码(读码)
    117. ///
    118. [Description("出料扫码")]
    119. ReadMaterialCodeOut = 10,
    120. ///
    121. /// 出料1
    122. ///
    123. [Description("出料1")]
    124. OutMaterial1 = 11,
    125. ///
    126. /// 出料2
    127. ///
    128. [Description("出料2")]
    129. OutMateria2 = 12,
    130. ///
    131. /// NG出料1
    132. ///
    133. [Description("NG出料1")]
    134. OutNgMaterial= 13,
    135. ///
    136. /// NG出料2
    137. ///
    138. [Description("NG出料2")]
    139. OutNgMateria2 = 14,
    140. }

    Socket

    1. ///
    2. /// 机器人 通讯
    3. ///
    4. public class RobertSocketServer
    5. {
    6. private string _className = "RobertSocketServer";
    7. ///
    8. /// 设备总数
    9. ///
    10. private int _DeviceCount = 1;
    11. ///
    12. /// 是否有在线客户端
    13. ///
    14. public bool IsHaveClient = false;
    15. //将远程连接客户端的IP地址和Socket存入集合中
    16. Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
    17. private ICommunicationLogService _serverCommunicationLog = ServiceIocFactory.GetRegisterServiceImp();
    18. ///
    19. /// 运行日志服务
    20. ///
    21. private IRunningLogService _srerviceRunninglogs = ServiceIocFactory.GetRegisterServiceImp();
    22. ///
    23. /// 心跳回复时间
    24. ///
    25. private Dictionary<int, DateTime> _heartbeatReplyTime = new Dictionary<int, DateTime>();
    26. ///
    27. /// IP
    28. ///
    29. private string _ip;
    30. ///
    31. /// 端口
    32. ///
    33. private int _port = 6000;
    34. public RobertSocketServer(string ip, int port = 6000)
    35. {
    36. _ip = ip;
    37. if (port > 0)
    38. {
    39. _port = port;
    40. }
    41. if (!string.IsNullOrEmpty(_ip))
    42. {
    43. startListen();
    44. }
    45. else
    46. {
    47. throw new Exception("IP地址不能为空");
    48. }
    49. }
    50. ///
    51. /// 添加客户端
    52. ///
    53. ///
    54. ///
    55. ///
    56. private bool addClient(string ip, Socket socket)
    57. {
    58. var isSucceed = false;
    59. if (!string.IsNullOrEmpty(ip) && socket != null)
    60. {
    61. if (!dicSocket.ContainsKey(ip))
    62. {
    63. dicSocket.Add(ip, socket);
    64. _DeviceCount = dicSocket.Count;
    65. IsHaveClient = true;
    66. }
    67. isSucceed = true;
    68. }
    69. return isSucceed;
    70. }
    71. ///
    72. /// 移除客户端
    73. ///
    74. ///
    75. ///
    76. private bool removeClient(string ip)
    77. {
    78. var isSucceed = false;
    79. if (!string.IsNullOrEmpty(ip))
    80. {
    81. if (dicSocket.ContainsKey(ip))
    82. {
    83. dicSocket.Remove(ip);
    84. }
    85. if (dicSocket.Count == 0)
    86. {
    87. IsHaveClient = false;
    88. }
    89. isSucceed = true;
    90. }
    91. return isSucceed;
    92. }
    93. ///
    94. /// 开始监听
    95. ///
    96. private void startListen()
    97. {
    98. try
    99. {
    100. //1、创建Socket(寻址方案.IP 版本 4 的地址,
    101. Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    102. //2.绑定IP 端口
    103. IPAddress ipAddress = IPAddress.Parse(_ip);
    104. IPEndPoint point = new IPEndPoint(ipAddress, _port);
    105. socket.Bind(point);
    106. WorkFlow.ShowMsg("机器人通讯服务端已经启动监听", "startListen", _className);
    107. //3.开启监听
    108. socket.Listen(10);//10监听对列的最大长度
    109. //4.开始接受客户端的连接 会卡界面 所以要开线程异步处理
    110. Task.Run(() => { Listen(socket); });
    111. }
    112. catch (Exception ex)
    113. {
    114. WorkFlow.ShowAlarmMsg("机器人通讯 服务器监听 异常:" + ex.Message, "startListen");
    115. }
    116. }
    117. ///
    118. /// 4 开始接受客户端的连接
    119. ///
    120. ///
    121. private void Listen(Socket socket)
    122. {
    123. if (socket != null)
    124. {
    125. while (true)
    126. {
    127. try
    128. {
    129. //等待客户端的连接,并且创建一个负责通信的Socket
    130. var accept = socket.Accept();
    131. //将远程连接客户端的IP地址和Socket存入集合中
    132. var ip = accept.RemoteEndPoint.ToString();
    133. if (addClient(ip, accept))
    134. {
    135. //客户端IP地址和端口号存入下拉框
    136. //cmbClientList.Items.Add(ip);
    137. WorkFlow.ShowMsg("机器人客户端:" + ip + ":连接成功", "Listen", _className);
    138. Task.Run(() => { ReciveClientMsg(accept); });
    139. }
    140. }
    141. catch (Exception ex)
    142. {
    143. WorkFlow.ShowAlarmMsg("开始接受机器人客户端的连接 异常:" + ex.Message, "Listen", _className);
    144. }
    145. }
    146. }
    147. }
    148. ///
    149. /// 接收客户端消息
    150. ///
    151. private void ReciveClientMsg(Socket socket)
    152. {
    153. WorkFlow.ShowMsg("机器人服务器已启动成功,可以接收客户端连接!时间:" + DateTime.Now.ToString(),
    154. "ReciveClientMsg", _className);
    155. //客户端连接成功后,服务器应该接收客户端发来的消息
    156. byte[] buffer = new byte[1024 * 1024 * 5];
    157. string reciveMsg = string.Empty;
    158. //不停的接收消息
    159. while (true)
    160. {
    161. try
    162. {
    163. //实际接收到的有效字节数
    164. int byteLength = 0;
    165. try
    166. {
    167. byteLength = socket.Receive(buffer);
    168. }
    169. catch (Exception)
    170. {
    171. //客户端异常退出
    172. clientExit(socket, "异常");
    173. return;//让方法结束,结束当前接收客户端消息异步线程
    174. }
    175. if (byteLength > 0)
    176. {
    177. reciveMsg = Encoding.UTF8.GetString(buffer, 0, byteLength);
    178. //ResponseNo:9876543,IsSucceed:1
    179. //ResponseNo:9876543,Status:1
    180. if (!string.IsNullOrEmpty(reciveMsg) && reciveMsg.Contains("ResponseNo"))
    181. {
    182. var rspModel = getMsgModelByStr(reciveMsg);
    183. if (rspModel != null)
    184. {
    185. var isSucceed = 0;
    186. if (rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode())
    187. {
    188. isSucceed = rspModel.IsSucceed;
    189. }
    190. else if (rspModel.Status == TrueOrFalseEnum.True.GetHashCode())
    191. {
    192. isSucceed = rspModel.Status;
    193. }
    194. rspModel.IsSucceed = isSucceed;
    195. var logModel = new CommunicationLogModel()
    196. {
    197. DeviceId = rspModel.DeviceId,
    198. Msg = rspModel.Msg,
    199. MsgTime = rspModel.MsgTime,
    200. No = rspModel.ResponseNo,
    201. Type = rspModel.FlowId,
    202. IsSucceed = rspModel.IsSucceed,
    203. ResponseNo = rspModel.ResponseNo
    204. };
    205. logModel.ClassName = _className;
    206. logModel.Method = "ReciveClientMsg";
    207. logModel.CreatedBy = _ip;
    208. logModel.CreatedOn = DateTime.Now;
    209. logModel.UpdatedBy = Global.EthernetType.GetEnumDesc();
    210. FlowIdEnum flowIdEnum = (FlowIdEnum)rspModel.FlowId;
    211. if (rspModel.Status == TrueOrFalseEnum.True.GetHashCode())
    212. {
    213. RobertSocketCommonServer.AddClientRspMsg(rspModel);
    214. WorkFlow.ShowMsg("收机器人2>" + rspModel.DeviceId + "机" + flowIdEnum.GetEnumDesc() + "回复:" + (rspModel.Status == TrueOrFalseEnum.True.GetHashCode() ? "处理成功" : "处理失败"), "ReciveClientMsg");
    215. }
    216. else if (rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode())
    217. {
    218. RobertSocketCommonServer.IsSendSucceed = rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode();
    219. WorkFlow.ShowMsg("收机器人2>" + rspModel.DeviceId + "机" + flowIdEnum.GetEnumDesc() + "回复:" + (rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode() ? "指令接收成功" : "指令接收失败"), "ReciveClientMsg");
    220. }
    221. _serverCommunicationLog.AddModelAutoIncrement(logModel);
    222. }
    223. }
    224. //var msg = "客户端" + socket.RemoteEndPoint + " 发送: " + reciveMsg + " 时间:" + DateTime.Now.ToString();
    225. //WorkFlow.ShowMsg(msg, "ReciveClientMsg", _className);
    226. }
    227. else
    228. {
    229. //客户端正常退出
    230. clientExit(socket);
    231. return;//让方法结束,结束当前接收客户端消息异步线程
    232. }
    233. }
    234. catch (Exception ex)
    235. {
    236. WorkFlow.ShowAlarmMsg("接收客户商消息 异常:" + ex.Message, "ReciveClientMsg", _className);
    237. }
    238. }
    239. }
    240. ///
    241. /// 客户端退出
    242. ///
    243. ///
    244. ///
    245. ///
    246. private bool clientExit(Socket socket, string type = "正常")
    247. {
    248. var isSucceed = false;
    249. var ip = socket.RemoteEndPoint.ToString();
    250. if (removeClient(ip))
    251. {
    252. //cmbClientList.Items.Remove(ip);
    253. WorkFlow.ShowMsg("客户端" + socket.RemoteEndPoint + type + "退出。 时间:" + DateTime.Now.ToString(),
    254. "clientExit", _className);
    255. isSucceed = true;
    256. //Task.Factory.StartNew(() =>
    257. //{
    258. // WindowHelper.OpenAlarmWindow(ip + "客户端退出报警!", "通讯报警");
    259. //});
    260. }
    261. return isSucceed;
    262. }
    263. ///
    264. /// 向客户端发送消息
    265. ///
    266. ///
    267. ///
    268. public bool SendMsgToClient(string msg)
    269. {
    270. var isOk = false;
    271. //var msg = txtSendMes.Text.Trim();
    272. //var clientIp = cmbClientList.SelectedItem.ToString();
    273. //if (dicSocket.ContainsKey(clientIp))
    274. //{
    275. if (!string.IsNullOrEmpty(msg))
    276. {
    277. if (dicSocket.Count == 0)
    278. {
    279. //MessageBox.Show("没有可以发送的客户端");
    280. WorkFlow.ShowMsgSocket("没有可以发送的客户端");
    281. }
    282. else
    283. {
    284. foreach (var clientIp in dicSocket.Keys)
    285. {
    286. var socket = dicSocket[clientIp];
    287. if (socket.Connected)//判断是否连接成功
    288. {
    289. //数据编码
    290. var buffer = Encoding.UTF8.GetBytes(msg);
    291. var dataList = new List<byte>();
    292. //dataList.Add(0);//类型:文本,字符串
    293. dataList.AddRange(buffer);
    294. //socket.Send(dataList.ToArray(), 0, buffer.Length, SocketFlags.None);
    295. socket.Send(dataList.ToArray());
    296. }
    297. }
    298. Thread.Sleep(100);
    299. }
    300. }
    301. else
    302. {
    303. //MessageBox.Show("发送的消息不能为空!");
    304. WorkFlow.ShowMsg("发送的消息不能为空!", "SendMsgToClient", _className);
    305. }
    306. //}
    307. return isOk;
    308. }
    309. ///
    310. /// 解析机器人回传信息
    311. ///
    312. ///
    313. ///
    314. private RobertSoketMsgModel getMsgModelByStr(string rspStr)
    315. {
    316. //ResponseNo:9876543,WorkId:1,IsSucceed:1
    317. //ResponseNo:9876543,WorkId:1,Status:1,Msg:"执行失败"
    318. //\r\n
    319. RobertSoketMsgModel rspModel = null;
    320. if (!string.IsNullOrEmpty(rspStr))
    321. {
    322. rspStr = rspStr.Replace("\r\n", string.Empty);
    323. var responseNo = string.Empty;
    324. int DeviceId = 0;
    325. int FlowId = 0;
    326. var isSucceed = TrueOrFalseEnum.False.GetHashCode();
    327. var strList = rspStr.Split(',').ToList();
    328. if (strList.Count > 0)
    329. {
    330. responseNo = strList[0].Replace("ResponseNo:", string.Empty);
    331. DeviceId = strList[1].Replace("DeviceId:", string.Empty).ToInt();
    332. FlowId = strList[2].Replace("FlowId:", string.Empty).ToInt();
    333. rspModel = new RobertSoketMsgModel();
    334. rspModel.ResponseNo = responseNo;
    335. rspModel.FlowId = FlowId;
    336. rspModel.DeviceId = DeviceId;
    337. rspModel.MsgTime = DateTime.Now;
    338. if (rspStr.Contains("IsSucceed") && strList.Count >= 4)
    339. {
    340. isSucceed = strList[3].Replace("IsSucceed:", string.Empty).ToInt();
    341. rspModel.IsSucceed = isSucceed;
    342. }
    343. else if (rspStr.Contains("Status") && strList.Count >= 4)
    344. {
    345. rspModel.Status = strList[3].Replace("Status:", string.Empty).ToInt();
    346. if (strList.Count > 5)
    347. {
    348. rspModel.Msg = strList[4].Replace("Msg:", string.Empty);
    349. }
    350. else
    351. {
    352. rspModel.Msg = rspModel.Status == TrueOrFalseEnum.True.GetHashCode() ? "执行成功" : "执行失败";
    353. }
    354. }
    355. }
    356. }
    357. return rspModel;
    358. }
    359. }

    RobertSocketCommonServer

    1. ///
    2. /// 机器人 通讯公共方法(服务端)
    3. ///
    4. public class RobertSocketCommonServer
    5. {
    6. private static string _className = "RobertSocketCommonServer";
    7. private static string commMsg = "机器人";
    8. private static ICommunicationLogService _serverCommunicationLog = ServiceIocFactory.GetRegisterServiceImp();
    9. ///
    10. /// 公共日志服务
    11. ///
    12. private static ICommonLogService _serviceLogs = ServiceIocFactory.GetRegisterServiceImp();
    13. ///
    14. /// 客户端响应消息
    15. ///
    16. private static Dictionary<string, RobertSoketMsgModel> _clientResponseMsgDic = new Dictionary<string, RobertSoketMsgModel>();
    17. ///
    18. /// 是否发送要料消息
    19. ///
    20. //public static bool IsSendInMsg = false;
    21. ///
    22. /// 是否发送成功
    23. ///
    24. public static bool IsSendSucceed = false;
    25. ///
    26. /// 创建一个请求消息模型
    27. ///
    28. /// 设备ID
    29. /// 类型
    30. ///
    31. public static RobertSoketMsgModel CreateInMsgModel(int deviceId, FlowIdEnum flowId)
    32. {
    33. return new RobertSoketMsgModel()
    34. {
    35. DeviceId = deviceId,
    36. Msg = flowId.ToString(),//deviceId + commMsg + type.GetEnumDesc(),
    37. MsgTime = DateTime.Now,
    38. No = AppCommonMethods.GenerateMsgNoRobert(flowId, deviceId),
    39. FlowId = flowId.GetHashCode()
    40. };
    41. }
    42. ///
    43. /// 发送指令
    44. ///
    45. /// 设备ID
    46. public static RobertSoketMsgModel SendReq(FlowIdEnum flowId, int deviceId = 1)
    47. {
    48. IsSendSucceed = false;
    49. var msgModel = CreateInMsgModel(deviceId, flowId);
    50. //var reqJson = JsonConvert.SerializeObject(msgModel);
    51. Global.RobertEthernetServer.SendMsgToClient(msgModel.ToSendString());
    52. var logModel = new CommunicationLogModel()
    53. {
    54. DeviceId = msgModel.DeviceId,
    55. Msg = msgModel.Msg,
    56. MsgTime = msgModel.MsgTime,
    57. No = msgModel.No,
    58. Type = flowId.GetHashCode()
    59. };
    60. logModel.ClassName = _className;
    61. logModel.Method = "SendLocalInReq";
    62. logModel.CreatedBy = Global.EAP_IpAddress;
    63. logModel.CreatedOn = DateTime.Now;
    64. logModel.UpdatedBy = Global.EthernetType.GetEnumDesc();
    65. _serverCommunicationLog.AddModelAutoIncrement(logModel);
    66. //SoketMsgQueueService.Instance.Enqueue(msgModel);
    67. return msgModel;
    68. }
    69. ///
    70. /// 本机发送放(出)料请求
    71. ///
    72. /// 设备ID
    73. //public static string SendLocalOutReq(int deviceId)
    74. //{
    75. // var msgModel = CreateInMsgModel(deviceId, SoketTypeEnum.OutRequest);
    76. // var logModel = new CommunicationLogModel()
    77. // {
    78. // DeviceId = msgModel.DeviceId,
    79. // Msg = msgModel.Msg,
    80. // MsgTime = msgModel.MsgTime,
    81. // No = msgModel.No,
    82. // Type = msgModel.Type.GetHashCode()
    83. // };
    84. // logModel.ClassName = _className;
    85. // logModel.Method = "SendLocalOutReq";
    86. // logModel.CreatedBy = Global.EAP_IpAddress;
    87. // logModel.CreatedOn = DateTime.Now;
    88. // logModel.UpdatedBy = Global.EthernetType.GetEnumDesc();
    89. // _serverCommunicationLog.AddModelAutoIncrement(logModel);
    90. // SoketMsgQueueService.Instance.Enqueue(msgModel);
    91. // return msgModel.No;
    92. //}
    93. ///
    94. /// 添加客户端响应消息
    95. ///
    96. ///
    97. ///
    98. public static bool AddClientRspMsg(RobertSoketMsgModel model)
    99. {
    100. var isOk = false;
    101. if (model != null && !_clientResponseMsgDic.ContainsKey(model.ResponseNo))
    102. {
    103. _clientResponseMsgDic.Add(model.ResponseNo, model);
    104. isOk = true;
    105. }
    106. return isOk;
    107. }
    108. ///
    109. /// 获取客户端响应消息
    110. ///
    111. ///
    112. ///
    113. public static RobertSoketMsgModel GetClientRspMsg(string no)
    114. {
    115. RobertSoketMsgModel msgModel = null;
    116. if (_clientResponseMsgDic.ContainsKey(no))
    117. {
    118. msgModel = _clientResponseMsgDic[no];
    119. _clientResponseMsgDic.Remove(no);
    120. }
    121. return msgModel;
    122. }
    123. ///
    124. /// While等待获取客户端响应消息
    125. ///
    126. ///
    127. /// 最大等待次数
    128. ///
    129. public static RobertSoketMsgModel GetClientRspMsgWhile(string no, string msg, RobertSoketMsgModel reqModel = null, int maxCount = 60)
    130. {
    131. RobertSoketMsgModel msgModel = null;
    132. var count = 0;
    133. while (msgModel == null)
    134. {
    135. msgModel = GetClientRspMsg(no);
    136. Thread.Sleep(200);
    137. //Thread.Sleep(1000);
    138. WorkFlow.ShowMsg("While等待获取" + commMsg + "..." + msg, "GetClientRspMsgWhile", RunningLogTypeEnum.Alarm);
    139. //if (count >= maxCount)
    140. //{
    141. // var showMsg = msg + ",未收到" + commMsg + "响应消息。是否继续等待?";
    142. // var commonModel = WindowHelper.OpenWindow(showMsg, "等待获取客户端响应消息报警", "继续等", "不等了");
    143. // if (commonModel != null && commonModel.IsSucceed)
    144. // {
    145. // if (reqModel != null)
    146. // {
    147. // var modelJson = JsonConvert.SerializeObject(reqModel);
    148. // Global.EthernetServer.SendMsgToClient(modelJson);//发送物料_通知
    149. // var logModelRsp = JsonConvert.DeserializeObject(modelJson);
    150. // logModelRsp.ClassName = _className;
    151. // logModelRsp.Method = "GetClientRspMsgWhile";
    152. // logModelRsp.Remark = showMsg;
    153. // logModelRsp.CreatedBy = Global.EAP_IpAddress;
    154. // logModelRsp.CreatedOn = DateTime.Now;
    155. // logModelRsp.UpdatedBy = Global.EthernetType.GetEnumDesc();
    156. // _serverCommunicationLog.AddModelAutoIncrement(logModelRsp);
    157. // }
    158. // count = 0;
    159. // }
    160. // else
    161. // {
    162. // break;
    163. // }
    164. //}
    165. count++;
    166. }
    167. return msgModel;
    168. }
    169. ///
    170. /// 移动到点位
    171. ///
    172. ///
    173. ///
    174. public static bool MoveToPos(FlowIdEnum flowId)
    175. {
    176. var isSucceed = false;
    177. var reqModel = SendReq(flowId);
    178. if (IsSendSucceed)
    179. {
    180. var rspModel = GetClientRspMsgWhile(reqModel.No, "机器人的指令处理回复");
    181. if (rspModel != null)
    182. {
    183. isSucceed = rspModel.IsSucceed == TrueOrFalseEnum.True.GetHashCode();
    184. WorkFlow.ShowMsg("收到机器人处理完成回复[" + flowId.GetEnumDesc() + "]" + rspModel.IsSucceed, "MoveToPos");
    185. }
    186. else
    187. {
    188. WorkFlow.ShowMsg("未收到机器人处理完成回复[" + flowId.GetEnumDesc() + "]", "MoveToPos");
    189. }
    190. }
    191. else
    192. {
    193. WorkFlow.ShowMsg("发送指令到机器人,发送失败。[" + flowId.GetEnumDesc() + "]", "MoveToPos");
    194. }
    195. return isSucceed;
    196. }
    197. }

    机器人代码:

    1. Global String ReceiveData$, data$(0), SendData$
    2. Global String No$, DeviceId$, FlowId$, Msg$, MsgTime$ '假设receive有三组数据,分到三个值里
    3. Global String NoVal$, DeviceIdVal$, FlowIdVal$, MsgVal$, MsgTimeVal$
    4. Function main
    5. 'Call initprg
    6. Call tcpClient
    7. Fend
    8. Function tcpClient
    9. ReceiveData$ = ""
    10. '设置IP地址,端口号,结束符等
    11. 'SetNet #201, "192.168.2.100", 3000, CRLF, NONE, 0
    12. SetNet #201, "192.168.10.203", 2000, CRLF, NONE, 0
    13. retry_tcpip_201: '断线重连
    14. CloseNet #201
    15. '机器人作为客户端,打开端口
    16. OpenNet #201 As Client '从
    17. '等待连接
    18. WaitNet #201
    19. '连接成功显示
    20. Print "TCP 连接成功"
    21. Print #201, " 连接成功"
    22. Print "ReceiveData:" + ReceiveData$
    23. receive_again: '再次收发数据
    24. Print "wait ReceiveData";
    25. Print "----------------------------"
    26. Do
    27. If ChkNet(201) < 0 Then '检查端口状态(>0时)
    28. Print "tcp_off,try_again"
    29. GoTo retry_tcpip_201
    30. ElseIf ChkNet(201) > 0 Then
    31. Read #201, ReceiveData$, ChkNet(201)
    32. Print "ReceiveData$ = ", ReceiveData$
    33. Exit Do
    34. EndIf
    35. Loop
    36. ParseStr ReceiveData$, data$(), "," '如果要发送code,message
    37. No$ = data$(1) 'code=1 '格式如下:任意数据;code;message
    38. DeviceId$ = data$(2) 'message=1
    39. FlowId$ = data$(3)
    40. Msg$ = data$(4)
    41. MsgTime$ = data$(5)
    42. ' c = Val(data$(3))
    43. Print "解析后的值:" + No$ + "," + DeviceId$ + "," + FlowId$ + "," + Msg$ + "," + MsgTime$
    44. Call getNoVal
    45. Call getFlowIdVal
    46. Call getDeviceIdVal
    47. Print "FlowIdVal:" + FlowIdVal$
    48. Print #201, "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",IsSucceed:1" '回复上位机指令接收成功
    49. 'Print "len:" + Str$(Len(No$))
    50. 'Print "index:" + Str$(InStr(No$, "No:"))
    51. 'Print "noVal:" + Mid$(No$, InStr(No$, ":") + 1, Len(No$) - InStr(No$, ":"))
    52. Call doWork '调用动作指令
    53. If SendData$ <> "" Then '通过调用,获得数据,机械手反馈运动状态
    54. Print SendData$
    55. Print #201, SendData$
    56. SendData$ = "" 'reset
    57. EndIf
    58. GoTo receive_again
    59. Fend
    60. '做工作,根据上位机发送的指令执行相应动作
    61. Function doWork
    62. Print "执行doWork"
    63. String message$
    64. Boolean isOk
    65. isOk = False
    66. '回原点=0,取料1=1(p1),取料2=2(p2),进料扫码=3(p3),焊接准备=4(p40),焊接平台放料=5(p5),焊接平台取料=6(p6),平台旋转位=7(p7),旋转(电爪)=8(p8),
    67. '焊接=9,出料扫码=10,出料1=11(p11),出料2=12(p12),NG出料1=13(p13),NG出料2=14(p14)
    68. 'CP运动命令 Move,Arc, Arc3
    69. 'PTP运动命令 Jump,Go
    70. '----------------------------
    71. 'PTP运动命令的速度设定
    72. 'PTP运动速度的设定
    73. '格式:Speed s, [a, b]
    74. 's : 速度设定值(1~100%)
    75. 'a: 第3轴上升的速度设定值(1100%) (可省略)
    76. 'b: 第3轴下降的速度设定值(1~100%) (可省略)
    77.  '使用示例
    78. 'Speed 80
    79. 'Speed 100, 80, 50
    80. 'PTP动作的加减速度的设定
    81. '格 式: Accel a, b, [c, d, e, f]
    82. 'a : 加速设定值(1~100%)
    83. 'b: 减速设定值(1100%)
    84. 'c,d : 第3轴上升的加减速设定值(1~100%) (可省略)
    85. 'e,f : 第3轴下降的加减速设定值(1100%) (可省略)
    86. '使用示例: Accel 80, 80
    87. 'Accel 100, 100, 20, 80, 80, 20
    88. '------------------
    89. 'CP运动命令
    90. 'SpeedS CP动作的速度的设定 SpeedS 500 速度设定值:1~1120 mm/s
    91. 'AccelS CP动作的加减速度的设定 AccelS 2000 加减速度设定值 : 15000 mm/s2
    92. If FlowIdVal$ = "0" Then '通过上位机判断,机械手执行
    93. '相应的动作流程 回原点=0
    94. 'Jump P20 LimZ 0 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置0=最高位
    95. isOk = True
    96. ElseIf FlowIdVal$ = "1" Then '通过上位机判断,机械手执行
    97. '相应的动作流程 移动到取料1的位置
    98. 'Jump P1 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    99. isOk = True
    100. ElseIf FlowIdVal$ = "2" Then
    101. '相应的动作流程 移动到取料2的位置
    102. 'Jump P2 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    103. isOk = True
    104. ElseIf FlowIdVal$ = "3" Then
    105. '相应的动作流程 移动到[扫码]的位置
    106. 'Jump P3 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    107. isOk = True
    108. ElseIf FlowIdVal$ = "4" Then
    109. '相应的动作流程 移动到[焊接准备]的位置
    110. 'Pass 用于移动机械臂并使其穿过指定点数据(位置)附近。不穿过指定点数据(位置)自身。可通过使用Pass 命令来避开障碍物。
    111. Pass P40, P41, P42
    112. isOk = True
    113. ElseIf FlowIdVal$ = "5" Then
    114. '相应的动作流程 移动到[平台放料]的位置
    115. Go P5 '全轴同时的PTP动作
    116. isOk = True
    117. ElseIf FlowIdVal$ = "6" Then
    118. '相应的动作流程 移动到[平台取料]的位置
    119. Go P6
    120. isOk = True
    121. ElseIf FlowIdVal$ = "7" Then
    122. '相应的动作流程 移动到[平台旋转位]的位置
    123. Go P7
    124. isOk = True
    125. ElseIf FlowIdVal$ = "8" Then
    126. '相应的动作流程 移动到[旋转]的位置
    127. 'Go P7 +U(180) '+U Z轴旋转
    128. isOk = True
    129. ElseIf FlowIdVal$ = "10" Then
    130. '相应的动作流程 移动到[出料扫码]的位置
    131. 'Jump P10 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    132. isOk = True
    133. ElseIf FlowIdVal$ = "11" Then
    134. '相应的动作流程 移动到[出料1]的位置
    135. 'Jump P11 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    136. isOk = True
    137. 'message$ = "失败测试"
    138. ElseIf FlowIdVal$ = "12" Then
    139. '相应的动作流程 移动到[出料2]的位置
    140. 'Jump P12 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    141. isOk = True
    142. ElseIf FlowIdVal$ = "13" Then
    143. '相应的动作流程 移动到[NG出料1]的位置
    144. 'Jump P13 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    145. isOk = True
    146. ElseIf FlowIdVal$ = "14" Then
    147. '相应的动作流程 移动到[NG出料1]的位置
    148. 'Jump P14 LimZ -100 'Jump 门形动作,LimZ以限定第三轴目标坐标Z上移的位置-100
    149. isOk = True
    150. EndIf
    151. If isOk Then
    152. SendData$ = "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",Status:1" '操作完成后回复上位机的数据,Status=表示处理成功,0表示处理失败
    153. Else
    154. SendData$ = "ResponseNo:" + NoVal$ + ",DeviceId:" + DeviceIdVal$ + ",FlowId:" + FlowIdVal$ + ",Status:0," + "Msg:" + message$ '操作完成后回复上位机的数据,Status=表示处理成功,0表示处理失败
    155. EndIf
    156. Fend
    157. Function getNoVal
    158. NoVal$ = Mid$(No$, InStr(No$, ":") + 1, Len(No$) - InStr(No$, ":"))
    159. Fend
    160. '获取FlowId的值
    161. Function getFlowIdVal
    162. FlowIdVal$ = Mid$(FlowId$, InStr(FlowId$, ":") + 1, Len(FlowId$) - InStr(FlowId$, ":"))
    163. Fend
    164. '获取DeviceId的值
    165. Function getDeviceIdVal
    166. DeviceIdVal$ = Mid$(DeviceId$, InStr(DeviceId$, ":") + 1, Len(DeviceId$) - InStr(DeviceId$, ":"))
    167. Fend
    168. Function init_constantrainit '常变量初始化
    169. Off 519
    170. On 520
    171. Off 521
    172. Off 522
    173. Off 523
    174. Off 524
    175. Off 525
    176. Off 526
    177. Off 527
    178. Off 528
    179. Off 529
    180. Fend
    181. Function init_robotinit '机械手初始化
    182. If Motor = Off Then
    183. Motor On
    184. EndIf
    185. If SFree(1) Or SFree(2) Or SFree(3) Or SFree(4) Then SLock
    186. 'If SFree(1) 0r SFree(2) 0r SFree(3) 0r SFree(4) Then SLock
    187. Power High
    188. Speed 20 'GO ,JUMP ,最大100
    189. Accel 20, 20
    190. SpeedS 100; 'ARC ,MOVE2000
    191. AccelS 100.100
    192. Call huanshou
    193. On 521 '回原完成器人回原请求
    194. Off 530 '机器人回原请求
    195. Pause
    196. Fend
    197. Function huanshou
    198. If CZ(Here) < 0 Then
    199. Move Here :Z(0) 'Z轴回到最高位
    200. EndIf
    201. '--------一象限---------------'
    202. If CZ(Here) < 0 And CY(Here) < -90 Then
    203. If Hand(Here) = Lefty Then
    204. Error 8000
    205. Else
    206. Jump P110
    207. Move P111
    208. Move P112
    209. EndIf
    210. EndIf
    211. '--------二象限---------------'
    212. If CY(Here) < 369.102 And CX(Here) > 0 Then
    213. If Hand(Here) = Lefty Then
    214. Move P100
    215. Move P99
    216. Move P97
    217. Else
    218. Move P101
    219. Move P98
    220. EndIf
    221. EndIf
    222. '--------三象限---------------'
    223. If CX(Here) > 0 And CY(Here) < 369.102 Then
    224. If Hand(Here) = Lefty Then
    225. Move P120
    226. Else
    227. Move P121
    228. EndIf
    229. EndIf
    230. Fend
    231. Function initprg '初始化
    232. Print Time$ + "机器人初始化中"
    233. Call init_constantrainit
    234. '常变量初始化机械手初始化
    235. Call init_robotinit
    236. Print '机器人初始化完成
    237. Fend

  • 相关阅读:
    Vue 安装与创建第一Docker的项目
    TB-RK1808M0最新固件烧录和驱动更新
    Unreal引擎自带的有用的工具函数,持续更新中
    《向量数据库指南》——向量数据库是小题大作的方案?
    如何将图片识别为可编辑的Word文件
    Linux系统编程04
    计算机网络:物理层
    跨域请求方案整理实践
    C++基础——前后置++--,流插入提取运算符重载函数
    Java IO---File类
  • 原文地址:https://blog.csdn.net/cjh16606260986/article/details/136229421