using Rs.Framework; using Rs.Motion; using Rs.Motion.Base; using Rs.MotionPlat.Commom; using Rs.MotionPlat.Entitys.Trays; using Rs.MotionPlat.Flow.SafePosFlow; using Rs.MotionPlat.Flow.SubFlow; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using static Rs.MotionPlat.Commom.SchedulingMessageBox; namespace Rs.MotionPlat.Flow.NgFlow { enum EWarningSuckerNgFlowStep { 等待测试完成, 到取料位上方, 等待到取料位上方, 到取料位下方, 等待到取料位下方, 取料完成到安全位, 等待取料完成到安全位, 镭射头检测, 手动处理后镭射头检测, 到放报警料穴位上方, 等待到放报警料穴位上方, 到放报警料穴位下方, 等待到放报警料穴位下方, 放料完成到安全位, 等待放料完成到安全位, 有无料光纤检测, 回安全位 } /// /// 强力吸头异常处理流程 /// public class WarningSuckerNgFlow { private WarningSuckerNgFlow() { } private static WarningSuckerNgFlow instance; public static WarningSuckerNgFlow Instance { get { if(instance==null) instance = new WarningSuckerNgFlow(); return instance; } } /// /// 强力吸嘴重取次数 /// int retakeNum = 0; bool exit = false; Stopwatch timeout= new Stopwatch(); string logInfo = string.Empty; string alarmInfo = string.Empty; TestHeightResult heightResult=new TestHeightResult(); /// /// 报警轴列表 /// List alarmAxisList = new List(); SchedulingMessageBox msgBox; EWarningSuckerNgFlowStep step = EWarningSuckerNgFlowStep.等待测试完成; /// /// 任务完成事件 /// ManualResetEvent taskFinishedEvent = new ManualResetEvent(true); /// /// 开始处理NG产品 /// /// /// public void DealNgProduct(ETrayType exceptionTray,int exceptionSlotIndex) { ErrorCode errCode = ErrorCode.Ok; SlotPoint targetSlot = new SlotPoint(); exit = false; step = EWarningSuckerNgFlowStep.等待测试完成; taskFinishedEvent.Reset(); while (!exit) { if (MachineManage.Instance.MachineStatus == EMachineStatus.Stop) { Thread.Sleep(10); continue; } switch (step) { case EWarningSuckerNgFlowStep.等待测试完成: if(TurnoverFlow.Instance.GetStep()=="等待任务" || TurnoverFlow.Instance.GetStep() == "取料异常报警" || TurnoverFlow.Instance.GetStep()== "周转盘放料完成后真空检测") { logInfo = GetClassName() + "测试工位已完成"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.到取料位上方; } break; case EWarningSuckerNgFlowStep.到取料位上方: if (exceptionTray == ETrayType.Turnover) { targetSlot = TrayPointManager.GetTurnoverTrayForceNozzlePoint(exceptionSlotIndex); errCode = AxisControl.TurnoverX.MovePos(targetSlot.X, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis) { errCode = AxisControl.TurnoverY.MovePos(targetSlot.Y, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis) { logInfo = GetClassName() + $"到{exceptionTray}盘{exceptionSlotIndex}穴位上方"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.等待到取料位上方; } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverY, errCode); } } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverX, errCode); } } break; case EWarningSuckerNgFlowStep.等待到取料位上方: if (Ops.IsStop(AxisAlias.TurnoverX, AxisAlias.TurnoverY) || GlobalVar.VirtualAxis) { if(Ops.IsArrived(AxisAlias.TurnoverX) || GlobalVar.VirtualAxis) { if(Ops.IsArrived(AxisAlias.TurnoverY) || GlobalVar.VirtualAxis) { logInfo = GetClassName() + $"已运动到{exceptionTray}盘{exceptionSlotIndex}穴位上方"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.到取料位下方; } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverY, "Axis not arrived target position"); step = EWarningSuckerNgFlowStep.到取料位上方; } } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverX, "Axis not arrived target position"); step = EWarningSuckerNgFlowStep.到取料位上方; } } break; case EWarningSuckerNgFlowStep.到取料位下方: errCode = AxisControl.TurnoverZ.MovePos(GlobalVar.TurnoverTrayForceNozzleTakeHeight, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis) { Ops.On("独立吸头气缸"); logInfo = GetClassName() + "独立吸头气缸下降"; MessageQueue.Instance.Insert(logInfo); timeout.Restart(); logInfo = GetClassName() + "到异常处理位下方"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.等待到取料位下方; } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, errCode); } break; case EWarningSuckerNgFlowStep.等待到取料位下方: if (Ops.IsStop(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { Thread.Sleep(100); if (Ops.IsArrived(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { logInfo = GetClassName() + "已运动到异常处理位下方"; MessageQueue.Instance.Insert(logInfo); //打开强力吸嘴真空 VacManager.ForceNozzleVacSuction(EVacOperator.Open); //关闭周转盘真空吸 VacManager.TurnoverTrayVacSuction(EVacOperator.Close, true, exceptionSlotIndex); //打开周转盘这空破 VacManager.TurnoverTrayVacBreak(EVacOperator.Open, true,exceptionSlotIndex); step = EWarningSuckerNgFlowStep.取料完成到安全位; } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, "Axis not arrived target position"); step = EWarningSuckerNgFlowStep.到取料位下方; } } break; case EWarningSuckerNgFlowStep.取料完成到安全位: errCode = AxisControl.TurnoverZ.MovePos(0, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis) { Ops.Off("独立吸头气缸"); logInfo = GetClassName() + "独立吸头气缸上升"; MessageQueue.Instance.Insert(logInfo); logInfo = GetClassName() + "取料完成到安全位"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.等待取料完成到安全位; timeout.Restart(); } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, errCode); } break; case EWarningSuckerNgFlowStep.等待取料完成到安全位: if (Ops.IsStop(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { if (Ops.IsArrived(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { Thread.Sleep(100); logInfo = GetClassName() + "已运动到异常处理位安全位"; MessageQueue.Instance.Insert(logInfo); //关闭周转盘真空破 VacManager.TurnoverTrayVacBreak(EVacOperator.Close,true, exceptionSlotIndex); step = EWarningSuckerNgFlowStep.镭射头检测; } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, "Axis not arrived target position"); step = EWarningSuckerNgFlowStep.取料完成到安全位; } } break; case EWarningSuckerNgFlowStep.镭射头检测: heightResult = LaserFlow.Instance.HasProduct(ETrayType.Turnover, exceptionSlotIndex); if (heightResult.HasProduct) { retakeNum++; if(retakeNum<3) { logInfo = $"周转盘{exceptionSlotIndex}号穴位取料失败,失败次数:{retakeNum}"; MessageQueue.Instance.Warn(logInfo); step = EWarningSuckerNgFlowStep.到取料位上方; } else { TransitModuleSafePosFlow.Instance.GoSafePostion( EExceptionSafePos.Socket); alarmInfo = $"{exceptionTray}盘{exceptionSlotIndex}穴位取料失败{retakeNum}次,请人工处理"; msgBox = PromptMessageBox.ShowDialog(66666, alarmInfo, ETipButton.Ok); step = EWarningSuckerNgFlowStep.手动处理后镭射头检测; } } else { MessageQueue.Instance.Insert("WarningSuckerNgFlow-镭射头检测OK"); step = EWarningSuckerNgFlowStep.到放报警料穴位上方; } break; case EWarningSuckerNgFlowStep.手动处理后镭射头检测: { heightResult = LaserFlow.Instance.HasProduct(ETrayType.Turnover, exceptionSlotIndex); if (heightResult.HasProduct) { TransitModuleSafePosFlow.Instance.GoSafePostion(EExceptionSafePos.Socket); alarmInfo = $"{exceptionTray}盘{exceptionSlotIndex}穴位产品未取出,请人工处理"; msgBox = PromptMessageBox.ShowDialog(AlarmConstID.LaserCheckFailAlarm, alarmInfo, ETipButton.Ok); step = EWarningSuckerNgFlowStep.手动处理后镭射头检测; } else { MessageQueue.Instance.Insert("WarningSuckerNgFlow-镭射头检测OK"); step = EWarningSuckerNgFlowStep.回安全位; } } break; case EWarningSuckerNgFlowStep.到放报警料穴位上方: int exceptionRow = TurnoverTrayManager.Instance.Slot(exceptionSlotIndex).Row; if(exceptionRow % 2 == 0) { targetSlot = TrayPointManager.GetExceptiontTrayPoint(1); } else { targetSlot = TrayPointManager.GetExceptiontTrayPoint(2); } errCode = AxisControl.TurnoverX.MovePos(targetSlot.X, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok ||GlobalVar.VirtualAxis) { errCode = AxisControl.TurnoverY.MovePos(targetSlot.Y, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis) { logInfo = GetClassName() + "到放报警料穴位上方"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.等待到放报警料穴位上方; } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverY, errCode); } } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverX, errCode); } break; case EWarningSuckerNgFlowStep.等待到放报警料穴位上方: if (Ops.IsStop(AxisAlias.TurnoverX, AxisAlias.TurnoverY) || GlobalVar.VirtualAxis) { if (Ops.IsArrived(AxisAlias.TurnoverX) || GlobalVar.VirtualAxis) { if (Ops.IsArrived( AxisAlias.TurnoverY) || GlobalVar.VirtualAxis) { logInfo = GetClassName() + $"已运动到已运动到放报警料穴位上方"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.到放报警料穴位下方; } else { AxisControl.TurnoverY.Get_Target_Position(out double targetPos); PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverY, $"Axis not arrived target position {targetPos}"); step = EWarningSuckerNgFlowStep.到放报警料穴位上方; } } else { AxisControl.TurnoverX.Get_Target_Position(out double targetPos); PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverX, $"Axis not arrived target position {targetPos}"); step = EWarningSuckerNgFlowStep.到放报警料穴位上方; } } break; case EWarningSuckerNgFlowStep.到放报警料穴位下方: errCode = AxisControl.TurnoverZ.MovePos(GlobalVar.ExceptionTrayForceNozzleDumpHeight, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis) { Ops.On("独立吸头气缸"); logInfo = GetClassName() + "独立吸头气缸下降"; MessageQueue.Instance.Insert(logInfo); timeout.Restart(); logInfo = GetClassName() + "到异常处理位下方"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.等待到放报警料穴位下方; } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, errCode); } break; case EWarningSuckerNgFlowStep.等待到放报警料穴位下方: if (Ops.IsStop(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { Thread.Sleep(300); if (Ops.IsArrived(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { logInfo = GetClassName() + "已运动到放报警料穴位下方"; MessageQueue.Instance.Insert(logInfo); //关闭强力吸嘴真空吸 VacManager.ForceNozzleVacSuction(EVacOperator.Close); //打开强力吸嘴的真空破 VacManager.ForceNozzleVacBreak(EVacOperator.Open); //关闭强力吸嘴的真空破 VacManager.ForceNozzleVacBreak(EVacOperator.Close); step = EWarningSuckerNgFlowStep.放料完成到安全位; } else { AxisControl.TurnoverZ.Get_Target_Position(out double targetPos); PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, $"Axis not arrived target position {targetPos}"); step = EWarningSuckerNgFlowStep.到放报警料穴位下方; } } break; case EWarningSuckerNgFlowStep.放料完成到安全位: errCode = AxisControl.TurnoverZ.MovePos(0, GlobalVar.WholeSpeed); if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis) { Ops.Off("独立吸头气缸"); logInfo = GetClassName() + "独立吸头气缸上升"; MessageQueue.Instance.Insert(logInfo); logInfo = GetClassName() + "放料完成到安全位"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.等待放料完成到安全位; timeout.Restart(); } else { PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, errCode); } break; case EWarningSuckerNgFlowStep.等待放料完成到安全位: if (Ops.IsStop(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { if (Ops.IsArrived(AxisAlias.TurnoverZ) || GlobalVar.VirtualAxis) { logInfo = GetClassName() + "放料完成已运动到安全位"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.有无料光纤检测; } else { AxisControl.TurnoverZ.Get_Target_Position(out double targetPos); PromptMessageBox.ShowAxisAlarmDialog(AxisControl.TurnoverZ, $"Axis not arrived target position {targetPos}"); step = EWarningSuckerNgFlowStep.放料完成到安全位; } } break; case EWarningSuckerNgFlowStep.有无料光纤检测: if(!Ops.IsOn("NG料光纤检测") || GlobalVar.RunSpace) { logInfo = "检测到NG料盘中无产品,流程继续"; MessageQueue.Instance.Insert(logInfo); step = EWarningSuckerNgFlowStep.回安全位; } else { alarmInfo = "NG料盘中有产品,请手动取出!"; MessageQueue.Instance.Warn(GetClassName() + alarmInfo); msgBox = PromptMessageBox.ShowDialog(AlarmConstID.NgProductFiberCheckAlarm, alarmInfo, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetRetry_Skip_MoveToSafe_ButtonText()); switch (msgBox.Button) { case ETipButton.Skip: logInfo = GetClassName()+ "选择了跳过按钮"; MessageQueue.Instance.Insert(logInfo); break; case ETipButton.Yes://移动到安全位 logInfo = "选择了移动到安全位按钮"; MessageQueue.Instance.Insert(logInfo); TransitModuleSafePosFlow.Instance.GoSafePostion( EExceptionSafePos.Socket); break; } } break; case EWarningSuckerNgFlowStep.回安全位: TransitModuleSafePosFlow.Instance.GoSafePostion(EExceptionSafePos.Socket); exit = true; taskFinishedEvent.Set(); break; default: break; } Thread.Sleep(10); } } public bool Wait() { return taskFinishedEvent.WaitOne(); } public string GetClassName() { return this.GetType().Name + "-"; } } }