using HalconDotNet; using Rs.Camera; using Rs.Controls; using Rs.Framework; using Rs.Motion; using Rs.MotionPlat.Commom; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Rs.MotionPlat.Flow.Space { enum ETakeDumpTestStep { 到料盘取料位上方, 等待到料盘取料位上方, 到料盘取料位下方, 等待到料盘取料位下方, 料盘取料完成抬起, 等待料盘取料完成抬起, 料盘取料完成真空检测, 到下相机拍照起始位, 等待到下相机拍照起始位, 到下相机拍照结束位, 等待到下相机拍照结束位, 等待相机拍照完成, 等待相机处理结果, 到周转盘放料位上方, 等待到周转盘放料位上方, 到周转盘放料位下方, 等待到周转盘放料位下方, 周转盘放料位下方真空检测, 到周转盘关闭破真空位, 等待到周转盘关闭破真空位, 周转盘破真空位真空检测, 周转盘放料完成抬起, 等待周转盘放料完成抬起, 到料盘放料位上方, 等待到料盘放料位上方, 到料盘放料位下方, 等待到料盘放料位下方, 料盘放料完成抬起, 等待料盘放料完成抬起 } public class TakeDumpTest:BaseFlow { int traySlot = 1; int turnoverSlot = 1; private ETakeDumpTestStep step = ETakeDumpTestStep.到料盘取料位上方; private static TakeDumpTest instance; public static TakeDumpTest Instance { get { if(instance==null) instance = new TakeDumpTest(); return instance; } } private TraySlot trayPoint; int NozzleIndex = 1; SlotPoint nozzleDist; SlotPoint curSlotPoint; double targetX, targetY; int FetchNum = 0; HObject[] imgs; List mrs = new List(); Motion.ErrorCode errCode = Motion.ErrorCode.Ok; public override void Run() { switch (step) { case ETakeDumpTestStep.到料盘取料位上方: curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Input", traySlot, EPointType.BASE); nozzleDist = TrayPointManager.GetDistToNozzle1(NozzleIndex); targetX = curSlotPoint.X + nozzleDist.X; targetY = curSlotPoint.Y + nozzleDist.Y; errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { errCode = AxisControl.GetAxis($"NozzleR{NozzleIndex}").MovePos(SysConfigParam.GetValue($"NozzleR{NozzleIndex}StartPos"), (int)(GlobalVar.WholeSpeed)); errCode = AxisControl.LoadY.MovePos(targetY, (int)(GlobalVar.WholeSpeed)); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待到料盘取料位上方; } } break; case ETakeDumpTestStep.等待到料盘取料位上方: if (Ops.IsStop("LoadX", "LoadY", $"NozzleR{NozzleIndex}")) { Thread.Sleep(100); step = ETakeDumpTestStep.到料盘取料位下方; } break; case ETakeDumpTestStep.到料盘取料位下方: errCode = AxisControl.GetAxis($"NozzleZ{NozzleIndex}").MovePos(SysConfigParam.GetValue($"TrayNozzle{NozzleIndex}TakeHeight"), GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待到料盘取料位下方; } break; case ETakeDumpTestStep.等待到料盘取料位下方: if (Ops.IsStop($"NozzleZ{NozzleIndex}")) { //Thread.Sleep(GlobalVar.AxisArrivedWaittime); Ops.On($"{NozzleIndex}号吸嘴真空吸电磁阀"); Thread.Sleep(100); step = ETakeDumpTestStep.料盘取料完成抬起; } break; case ETakeDumpTestStep.料盘取料完成抬起: errCode = AxisControl.GetAxis($"NozzleZ{NozzleIndex}").MovePos(0, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待料盘取料完成抬起; } break; case ETakeDumpTestStep.等待料盘取料完成抬起: if (Ops.IsStop($"NozzleZ{NozzleIndex}")) { step = ETakeDumpTestStep.料盘取料完成真空检测; } break; case ETakeDumpTestStep.料盘取料完成真空检测: if (Ops.IsOn($"{NozzleIndex}号吸嘴真空吸检测") || GlobalVar.RunSpace) { step = ETakeDumpTestStep.到下相机拍照起始位; } else { FetchNum++; if (FetchNum == 6) { Msg.ShowError($"吸嘴{NozzleIndex}取料{FetchNum}次失败报警,请处理后点击确定"); FetchNum = 0; } step = ETakeDumpTestStep.到料盘取料位下方; } break; case ETakeDumpTestStep.到下相机拍照起始位: ImageProcess.ClearAutoTrigger(); HikCamera.Instance.SetExposure("locationCamera", 50); HikCamera.Instance.SetGain("locationCamera", 20); AxisControl.LoadX.MovePos(SysConfigParam.GetValue("Nozzle1CenterX") - 10, GlobalVar.WholeSpeed); AxisControl.LoadY.MovePos(SysConfigParam.GetValue("Nozzle1CenterY"), GlobalVar.WholeSpeed); step = ETakeDumpTestStep.到下相机拍照结束位; break; case ETakeDumpTestStep.等待到下相机拍照起始位: if (Ops.IsStop("LoadX", "LoadY")) { Thread.Sleep(100); HikCamera.Instance.SetTrigger("locationCamera", ETriggerMode.Auto); List grabPoints = new List(); grabPoints.Add(SysConfigParam.GetValue($"Nozzle1CenterX")); errCode = AxisControl.LoadX.SetPosCompare(1, grabPoints.ToArray()); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.到下相机拍照结束位; } } break; case ETakeDumpTestStep.到下相机拍照结束位: IoManager.Instance.WriteOut("下左相机光源触发", 1); Thread.Sleep(50); AxisControl.LoadX.MovePos(SysConfigParam.GetValue($"Nozzle1CenterX") + 10, GlobalVar.FlyCameraSpeed); step = ETakeDumpTestStep.等待到下相机拍照结束位; break; case ETakeDumpTestStep.等待到下相机拍照结束位: Stopwatch stopwatch = new Stopwatch(); if (Ops.IsStop("LoadX")) { AxisControl.LoadX.ClearCompare(1); IoManager.Instance.WriteOut("下左相机光源触发", 0); step = ETakeDumpTestStep.等待相机拍照完成; stopwatch.Start(); } break; case ETakeDumpTestStep.等待相机拍照完成: imgs = ImageProcess.GetAutoImage(); if (imgs != null && imgs.Length == 1) { //拍照完成 step = ETakeDumpTestStep.等待相机处理结果; } break; case ETakeDumpTestStep.等待相机处理结果: mrs = VisionProcess.Instance.MatchDownCam(imgs); if (mrs != null && mrs.Count == imgs.Length && mrs.Where(m => m.IsOK == true).Count() == imgs.Length) { step = ETakeDumpTestStep.到周转盘放料位上方; } break; case ETakeDumpTestStep.到周转盘放料位上方: curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Turnover", 1, EPointType.RUN); nozzleDist = TrayPointManager.GetDistToNozzle1(NozzleIndex); if (mrs[NozzleIndex - 1].OffsetRow > 5 || mrs[NozzleIndex - 1].OffsetCol > 5) { Msg.ShowError("image process ng"); } else { targetX = mrs[NozzleIndex - 1].OffsetCol + curSlotPoint.X + nozzleDist.X; targetY = mrs[NozzleIndex - 1].OffsetRow + curSlotPoint.Y + nozzleDist.Y; errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { errCode = AxisControl.LoadY.MovePos(targetY, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { errCode = AxisControl.GetAxis($"NozzleR{NozzleIndex}").MoveOffset((mrs[NozzleIndex - 1].OffsetA), GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待到周转盘放料位上方; } } } } break; case ETakeDumpTestStep.等待到周转盘放料位上方: if (Ops.IsStop("LoadX", "LoadY", $"NozzleR{NozzleIndex}")) { Thread.Sleep(100); step = ETakeDumpTestStep.到周转盘放料位下方; } break; case ETakeDumpTestStep.到周转盘放料位下方: errCode = AxisControl.GetAxis($"NozzleZ{NozzleIndex}").MovePos(SysConfigParam.GetValue($"TurnoverNozzle{NozzleIndex}TakeHeight"), GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待到周转盘放料位下方; } break; case ETakeDumpTestStep.等待到周转盘放料位下方: if (Ops.IsStop($"NozzleZ{NozzleIndex}")) { //IoManager.Instance.WriteOut($"{NozzleIndex}号吸嘴真空吸电磁阀", 0);//关闭真空 Thread.Sleep(50); //打开周转盘真空吸 Ops.On($"周转盘1号穴位真空吸"); Thread.Sleep(100); if (Ops.IsOn("周转盘1号穴位真空吸检测")) { //如果检测到真空,则把吸头真空吸关掉 IoManager.Instance.WriteOut($"{NozzleIndex}号吸嘴真空吸电磁阀", 0);//关闭真空 Thread.Sleep(50); IoManager.Instance.WriteOut($"{NozzleIndex}号吸嘴真空破电磁阀", 1); Thread.Sleep(100); } //Thread.Sleep(SysConfigParam.GetValue("WholeVacWaitTime")); //IoManager.Instance.WriteOut($"{NozzleIndex}号吸嘴真空破电磁阀", 0); step = ETakeDumpTestStep.到周转盘关闭破真空位; } break; case ETakeDumpTestStep.周转盘放料位下方真空检测: break; case ETakeDumpTestStep.到周转盘关闭破真空位: errCode = AxisControl.GetAxis($"NozzleZ{NozzleIndex}").MovePos(SysConfigParam.GetValue($"TurnoverNozzle{NozzleIndex}TakeHeight") + 1, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待到周转盘关闭破真空位; } break; case ETakeDumpTestStep.等待到周转盘关闭破真空位: if (Ops.IsStop($"NozzleZ{NozzleIndex}")) { if (Ops.IsOn("周转盘1号穴位真空吸检测")) { IoManager.Instance.WriteOut($"{NozzleIndex}号吸嘴真空破电磁阀", 0); step = ETakeDumpTestStep.周转盘放料完成抬起; } else { Msg.ShowError("周转盘1号穴位真空吸检测异常"); step = ETakeDumpTestStep.周转盘放料完成抬起; } } break; case ETakeDumpTestStep.周转盘破真空位真空检测: break; case ETakeDumpTestStep.周转盘放料完成抬起: errCode = AxisControl.GetAxis($"NozzleZ{NozzleIndex}").MovePos(0, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待周转盘放料完成抬起; } break; case ETakeDumpTestStep.等待周转盘放料完成抬起: if (Ops.IsStop($"NozzleZ{NozzleIndex}")) { step = ETakeDumpTestStep.到料盘放料位上方; } break; case ETakeDumpTestStep.到料盘放料位上方: curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Input", traySlot, EPointType.BASE); nozzleDist = TrayPointManager.GetDistToNozzle1(NozzleIndex); targetX = curSlotPoint.X + nozzleDist.X; targetY = curSlotPoint.Y + nozzleDist.Y; errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { errCode = AxisControl.GetAxis($"NozzleR{NozzleIndex}").MovePos(SysConfigParam.GetValue($"NozzleR{NozzleIndex}StartPos"), (int)(GlobalVar.WholeSpeed)); errCode = AxisControl.LoadY.MovePos(targetY, (int)(GlobalVar.WholeSpeed)); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待到料盘取料位上方; } } break; case ETakeDumpTestStep.等待到料盘放料位上方: if (Ops.IsStop("LoadX", "LoadY", $"NozzleR{NozzleIndex}")) { Thread.Sleep(100); step = ETakeDumpTestStep.到料盘放料位下方; } break; case ETakeDumpTestStep.到料盘放料位下方: errCode = AxisControl.GetAxis($"NozzleZ{NozzleIndex}").MovePos(SysConfigParam.GetValue($"TrayNozzle{NozzleIndex}TakeHeight")+1, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待到料盘放料位下方; } break; case ETakeDumpTestStep.等待到料盘放料位下方: if (Ops.IsStop($"NozzleZ{NozzleIndex}")) { Thread.Sleep(GlobalVar.AxisArrivedWaittime); Ops.Off($"{NozzleIndex}号吸嘴真空吸电磁阀"); Thread.Sleep(100); Ops.On($"{NozzleIndex}号吸嘴真空破电磁阀"); Thread.Sleep(100); Ops.Off($"{NozzleIndex}号吸嘴真空破电磁阀"); step = ETakeDumpTestStep.料盘放料完成抬起; } break; case ETakeDumpTestStep.料盘放料完成抬起: errCode = AxisControl.GetAxis($"NozzleZ{NozzleIndex}").MovePos(0, GlobalVar.WholeSpeed); if (errCode == ErrorCode.Ok) { step = ETakeDumpTestStep.等待料盘放料完成抬起; } break; case ETakeDumpTestStep.等待料盘放料完成抬起: if (Ops.IsStop($"NozzleZ{NozzleIndex}")) { step = ETakeDumpTestStep.到料盘取料位上方; } break; default: break; } } } }