/// <summary> /// 通讯状态观察 /// </summary> private void CommunicationObser(object sender, System.Timers.ElapsedEventArgs e) { try { communicationobserve_timer.Enabled = false; //先判断小车是否已经掉线 if (LastRecLong > 2) { //如果接受消息时间已经大于2秒,则认为车子掉线了。 DelegateState.InvokeDispatchStateEvent(this.DeviceID.ToString() + "车,已经掉线,将在1秒后重新尝试连接..."); //通知调度程序 小车已经掉线 CarBaseStateInfo car = new CarBaseStateInfo(); car.bIsCommBreak = true; car.AgvID = this.DeviceID; DelegateState.InvokeCarFeedbackEvent(car); if (LastConnectLong > 3) { //如果车子掉线且连接时间超过3秒则需要重连 LogHelper.WriteLog("重连小车" + DeviceID.ToString()); ReConnect(); } } } catch (Exception ex) { DelegateState.InvokeDispatchStateEvent(this.DeviceID.ToString() + "车,观察线程异常"); LogHelper.WriteErrorLog(ex); } finally { { communicationobserve_timer.Enabled = true; } } }
/// <summary> /// 启动 /// </summary> public virtual bool Start() { try { IPAddress ip = IPAddress.Parse(ComPara.ServerIP); IPEndPoint ipep = new IPEndPoint(ip, ComPara.Port);//IP和端口 Tcpsocket.Bind(new IPEndPoint(IPAddress.Parse(CoreData.SysParameter["LocalIP"]), 0)); Tcpsocket.Connect(new IPEndPoint(ip, ComPara.Port)); CurrToken = Guid.NewGuid().ToString(); Communication(CurrToken); LastRecTime = DateTime.Now; return(true); } catch (Exception ex) { CarBaseStateInfo car = new CarBaseStateInfo(); car.AgvID = this.DeviceID; car.bIsCommBreak = true; DelegateState.InvokeCarFeedbackEvent(car); return(false); } finally { communicationobserve_timer.Enabled = true; } }
/// <summary> /// 初始化 /// </summary> public virtual bool Init() { try { Clear(); Tcpsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Tcpsocket.ReceiveTimeout = 200; return(true); } catch (Exception ex) { CarBaseStateInfo car = new CarBaseStateInfo(); car.AgvID = this.DeviceID; car.bIsCommBreak = true; DelegateState.InvokeCarFeedbackEvent(car); return(false); } }
/// <summary> /// SendPackIndex 为发送包序号 /// 命令反馈 /// </summary> public bool GetCallBack(Int16 SendPackIndex = 0, bool IsCheckCarState = false) { try { int AGVID = this.DeviceID; int offlinecount = 0; int allheadleftlengh = 7; int receivedlengh = 0; byte[] bufferhead = new byte[7];//定义6位长度为接收包头缓存长度 while (allheadleftlengh - receivedlengh > 0) { byte[] buffertemp = new byte[allheadleftlengh - receivedlengh]; if (Tcpsocket.Available <= 0) { continue; } int lengh = Tcpsocket.Receive(buffertemp); if (lengh <= 0) { if (offlinecount == 3) { LogHelper.WriteReciveAGVMessLog("接受的小车" + AGVID.ToString() + "反馈命令超时"); return(false); } offlinecount += 1; Thread.Sleep(50); } Buffer.BlockCopy(buffertemp, 0, bufferhead, receivedlengh, lengh); receivedlengh += lengh; } //解析AGV反馈信息 if (bufferhead[0] == 0xEB && bufferhead[1] == 0x90 && bufferhead[2] == 0XD1) { //判断一下报文序号 byte[] arr = new byte[] { bufferhead[4], bufferhead[3] }; Int16 RecvPackIndex = BitConverter.ToInt16(arr, 0); if (SendPackIndex == 0 || (SendPackIndex != 0 && RecvPackIndex == SendPackIndex))//如果发送和接受报文序号一致,说明成功 { offlinecount = 0; byte[] bytess = new byte[2] { bufferhead[6], bufferhead[5] }; //int allcontentleftlengh = bufferhead[6] << 8 + bufferhead[5]; int allcontentleftlengh = BitConverter.ToInt16(bytess, 0) + 1; receivedlengh = 0; byte[] buffercontent = new byte[allcontentleftlengh]; while (allcontentleftlengh - receivedlengh > 0) { byte[] buffertemp = new byte[allcontentleftlengh - receivedlengh]; if (Tcpsocket.Available <= 0) { continue; } int lengh = Tcpsocket.Receive(buffertemp); if (lengh <= 0) { if (offlinecount == 3) { LogHelper.WriteReciveAGVMessLog("接受的小车" + AGVID.ToString() + "反馈命令超时"); return(false); } offlinecount += 1; Thread.Sleep(50); } Buffer.BlockCopy(buffertemp, 0, buffercontent, receivedlengh, lengh); receivedlengh += lengh; } //接受完内容后校验 List <byte> msg = new List <byte>(); msg.AddRange(bufferhead); msg.AddRange(buffercontent); string SenDLog = ""; foreach (byte item in msg) { SenDLog += ((int)item).ToString("X") + " "; } LogHelper.WriteReciveAGVMessLog("接受的小车" + AGVID.ToString() + "反馈命令:" + SenDLog); byte CRC8 = CRC.CRC8(msg.Take(allcontentleftlengh + 6).ToArray()); if (CRC8 != msg[msg.Count - 1]) { LogHelper.WriteReciveAGVMessLog("接受的小车" + AGVID.ToString() + "反馈命令校验位不正确"); return(false); } //解析车辆信息 CarInfo car = new CarInfo(); car.AgvID = this.DeviceID; car.CarState = Convert.ToInt32(msg[7]); car.IsNeedFinshTask = Convert.ToInt32(msg[8]); car.IsNeedRedoTask = Convert.ToInt32(msg[9]); byte[] bytes = new byte[4] { msg[13], msg[12], msg[11], msg[10] }; car.X = BitConverter.ToInt32(bytes, 0) / 1000.00F; bytes = new byte[4] { msg[17], msg[16], msg[15], msg[14] }; car.Y = BitConverter.ToInt32(bytes, 0) / 1000.00F; bytes = new byte[4] { msg[21], msg[20], msg[19], msg[18] }; car.Angel = BitConverter.ToInt32(bytes, 0) / 1000.00F; //是否在码上 car.IsUpLand = Convert.ToInt32(msg[22].ToString()); //升降平台的状态 car.BangState = Convert.ToInt32(msg[23].ToString()); //夹持机构状态 car.JCState = Convert.ToInt32(msg[24].ToString()); //剩余电池容量 百分比 car.fVolt = Convert.ToInt32(msg[25].ToString()); //速度 car.speed = Convert.ToInt32(msg[26].ToString()); //报警长度 int WarnLen = Convert.ToInt32(msg[27].ToString()); car.ErrorMessage = ""; if (WarnLen > 0)//有报警 { int StartIndex = 27; for (int i = 1; i <= WarnLen; i++) { int Cat = StartIndex + 1; int Code = StartIndex + 2; car.WarnType = Convert.ToInt32(msg[Cat].ToString()); car.WarnBinaryCode = Convert.ToString(msg[Code], 2).PadLeft(8, '0'); switch (car.WarnType) { case 0: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "24C02错误-写入错误!\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "24C02错误-读取错误\r\n"; } break; case 1: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "电量检测错误-通信错误\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "电量检测错误-电量低\r\n"; } break; case 2: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "WiFi通信错误-校验错误\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "WiFi通信错误-心跳超时\r\n"; } break; case 3: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "433M通信错误\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "校验错误\r\n"; } break; case 4: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "PGV100错误-校验错误1\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "PGV100错误-通信超时1\r\n"; } if (car.WarnBinaryCode.Substring(5, 1) == "1") { car.ErrorMessage += "PGV100错误-硬件故障1\r\n"; } if (car.WarnBinaryCode.Substring(4, 1) == "1") { car.ErrorMessage += "PGV100错误-校验错误2\r\n"; } if (car.WarnBinaryCode.Substring(3, 1) == "1") { car.ErrorMessage += "PGV100错误-通信超时2\r\n"; } if (car.WarnBinaryCode.Substring(2, 1) == "1") { car.ErrorMessage += "PGV100错误-硬件故障2\r\n"; } break; case 5: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "驱动器-1号通信异常\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "驱动器-2号通信异常\r\n"; } if (car.WarnBinaryCode.Substring(5, 1) == "1") { car.ErrorMessage += "驱动器-3号通信异常\r\n"; } if (car.WarnBinaryCode.Substring(4, 1) == "1") { car.ErrorMessage += "驱动器-4号通信异常\r\n"; } if (car.WarnBinaryCode.Substring(3, 1) == "1") { car.ErrorMessage += "驱动器-1号硬件故障\r\n"; } if (car.WarnBinaryCode.Substring(2, 1) == "1") { car.ErrorMessage += "驱动器-2号硬件故障\r\n"; } if (car.WarnBinaryCode.Substring(1, 1) == "1") { car.ErrorMessage += "驱动器-3号硬件故障\r\n"; } if (car.WarnBinaryCode.Substring(0, 1) == "1") { car.ErrorMessage += "驱动器-3号硬件故障\r\n"; } break; case 6: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "安全传感器-触边\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "安全传感器-激光减速\r\n"; } if (car.WarnBinaryCode.Substring(5, 1) == "1") { car.ErrorMessage += "安全传感器-激光停车\r\n"; } if (car.WarnBinaryCode.Substring(4, 1) == "1") { car.ErrorMessage += "安全传感器-急停按钮\r\n"; } break; case 7: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "SIM2000-校验错误\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "SIM2000-通信超时\r\n"; } if (car.WarnBinaryCode.Substring(5, 1) == "1") { car.ErrorMessage += "SIM2000-硬件故障\r\n"; } break; case 8: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "升降平台-未下降到位\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "升降平台-未上升到位\r\n"; } break; case 9: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "夹持机构-未夹紧到位\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "夹持机构-未张开到位\r\n"; } break; case 10: if (car.WarnBinaryCode.Substring(7, 1) == "1") { car.ErrorMessage += "导航-丢失反光柱匹配\r\n"; } if (car.WarnBinaryCode.Substring(6, 1) == "1") { car.ErrorMessage += "导航-丢失定位二维码\r\n"; } if (car.WarnBinaryCode.Substring(5, 1) == "1") { car.ErrorMessage += "导航-丢失修正二维码\r\n"; } if (car.WarnBinaryCode.Substring(4, 1) == "1") { car.ErrorMessage += "导航-目标点对比异常\r\n"; } break; default: break; } StartIndex += 2; } } if (!string.IsNullOrEmpty(car.ErrorMessage)) { LogHelper.WriteAGVWarnMessLog(car.AgvID.ToString() + "号AGV报警异常信息:" + car.ErrorMessage); } LandmarkInfo CurrLand = CoreData.AllLands.FirstOrDefault(p => distance((float)p.LandX, (float)p.LandY, car.X, car.Y) <= 0.2); if (CurrLand != null) { car.CurrSite = Convert.ToInt16(CurrLand.LandmarkCode); LogHelper.WriteReciveAGVMessLog("小车" + AGVID.ToString() + "坐标得到的地标为:" + CurrLand.LandmarkCode); car.IsUpQCode = 1; } else { car.IsUpQCode = 0; } DelegateState.InvokeCarFeedbackEvent(car); LastRecTime = DateTime.Now; //发送复位需要判断车子状态是否为待命状态 if (IsCheckCarState) { LogHelper.WriteSendAGVMessLog("判断发送复位指令是否真正完成!"); if (car.CarState != 0) { LogHelper.WriteSendAGVMessLog("发送复位指令车子:" + car.AgvID.ToString() + "状态为:" + car.CarState.ToString()); return(false); } } return(true); } else { return(false); } } } catch (Exception ex) { LogHelper.WriteLog(this.DeviceID.ToString() + "车 AGV解析编解码错误!" + ex.Message); } return(false); }