using HalconDotNet; using Rs.Camera; using Rs.Controls; using Rs.Framework; using Rs.Motion; using Rs.MotionPlat.Commom; using Rs.MotionPlat.Entitys; using Rs.MotionPlat.Entitys.Trays; using Rs.MotionPlat.Flow.Camera; using Rs.MotionPlat.Flow.Common; 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.SubFlow { enum EUpCameraScanBarCodeFlowStep { 到扫码起始位, 等待到扫码起始位, 到扫码结束位, 等待到扫码结束位, 等待扫码结束, 拍照结果处理, } enum EUpCameraFixedScanBarCodeFlowStep { 到扫码位上方, 等待运动到扫码位上方, 等待扫码结束, 拍照结果处理 } /// /// 上相机扫码流程 /// public class UpCameraScanBarCodeFlow { public event Action OnTurnoverTrayProductLocateResult; private UpCameraScanBarCodeFlow() { } private static UpCameraScanBarCodeFlow instance; public static UpCameraScanBarCodeFlow Instance { get { if(instance == null) instance = new UpCameraScanBarCodeFlow(); return instance; } } private EUpCameraScanBarCodeFlowStep step = EUpCameraScanBarCodeFlowStep.到扫码起始位; private EUpCameraFixedScanBarCodeFlowStep fixedStep = EUpCameraFixedScanBarCodeFlowStep.到扫码位上方; ErrorCode errCode = ErrorCode.Ok; HObject[] grabImages= null; Stopwatch timeout = new Stopwatch(); string logInfo = string.Empty; Stopwatch scanBarCodeWait= new Stopwatch(); //double targetLoadX=0.0,targetLoadY=0.0; bool exit = true; //ManualResetEvent grabFinishedEvent = new ManualResetEvent(true); /// /// /// 开始扫码,先把所有的穴位全部扫一遍,扫不到的最后再定点扫码, /// 如果定位失败的穴位,即便没有扫到码,也不再扫码 /// /// 拍照起始点 /// 拍照终止点 /// 是否反转拍照 public List ScanMulti(int startSlotIndex, bool isReverse) { TargetPosition targetPostion = new TargetPosition(); AlarmEntity alarmEntity = null; List vReslutList = new List(); if (exit == false) return null; //grabFinishedEvent.Reset(); SlotPoint startPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, startSlotIndex); SlotPoint endPoint = new SlotPoint(); exit = false; step = EUpCameraScanBarCodeFlowStep.到扫码起始位; //Task.Run(() => { while (!exit) { if (MachineManage.Instance.MachineStatus == EMachineStatus.Stop) { Thread.Sleep(10); continue; } switch (step) { case EUpCameraScanBarCodeFlowStep.到扫码起始位: if (!isReverse) { targetPostion.X = startPoint.X - 50; targetPostion.Y = startPoint.Y; errCode = AxisControl.LoadX.MovePos(targetPostion.X, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis) { errCode = AxisControl.LoadY.MovePos(targetPostion.Y, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis) { logInfo = GetClassName() + $"正向扫码,到扫码起始位"; MessageQueue.Instance.Insert(logInfo); step = EUpCameraScanBarCodeFlowStep.等待到扫码起始位; } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadY, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadY运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } } else { targetPostion.X = startPoint.X + 50; targetPostion.Y = startPoint.Y; errCode = AxisControl.LoadX.MovePos(targetPostion.X, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok) { errCode = AxisControl.LoadY.MovePos(targetPostion.Y, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok) { logInfo = GetClassName() + $"反向扫码,到扫码起始位"; MessageQueue.Instance.Insert(logInfo); step = EUpCameraScanBarCodeFlowStep.等待到扫码起始位; } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadY, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadY运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } } break; case EUpCameraScanBarCodeFlowStep.等待到扫码起始位: if (Ops.IsStop(AxisAlias.LoadX, AxisAlias.LoadY) || GlobalVar.VirtualAxis) { if(AxisArrived.LoadXYIsArrived(targetPostion.X,targetPostion.Y)) { //Thread.Sleep(1000); List grabPoints = new List(); if (!isReverse) { endPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, startSlotIndex + 7); for (int i = startSlotIndex; i < startSlotIndex + 8; i++) { grabPoints.Add(TrayPointManager.GetSlotPoint(ETrayType.Turnover, i).X); } } else { endPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, startSlotIndex - 7); for (int i = startSlotIndex; i > startSlotIndex - 8; i--) { grabPoints.Add(TrayPointManager.GetSlotPoint(ETrayType.Turnover, i).X); } } ImageProcess.ClearAutoTrigger(); HikCamera.Instance.SetExposure("upCamera", GlobalVar.UpCameraExposureTime); HikCamera.Instance.SetGain("upCamera", GlobalVar.UpCameraGain); HikCamera.Instance.SetTrigger("upCamera", ETriggerMode.Auto); AxisControl.LoadX.SetPosCompare(2, grabPoints.ToArray()); AxisControl.LoadX.CompareStatus(out short pstatu, out int pcount); logInfo = GetClassName() + $"已运动到扫码起始位"; MessageQueue.Instance.Insert(logInfo); step = EUpCameraScanBarCodeFlowStep.到扫码结束位; } else { step = EUpCameraScanBarCodeFlowStep.到扫码起始位; } } break; case EUpCameraScanBarCodeFlowStep.到扫码结束位: if (!isReverse) { targetPostion.X = endPoint.X + 50; errCode = AxisControl.LoadX.MovePos(targetPostion.X, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis) { logInfo = GetClassName() + $"正向扫码,到扫码结束位"; MessageQueue.Instance.Insert(logInfo); step = EUpCameraScanBarCodeFlowStep.等待到扫码结束位; } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } } else { targetPostion.X = endPoint.X - 50; errCode = AxisControl.LoadX.MovePos(targetPostion.X, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok) { logInfo = GetClassName() + $"反向扫码,到扫码结束位"; MessageQueue.Instance.Insert(logInfo); step = EUpCameraScanBarCodeFlowStep.等待到扫码结束位; } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } } break; case EUpCameraScanBarCodeFlowStep.等待到扫码结束位: if (Ops.IsStop(AxisAlias.LoadX, AxisAlias.LoadY) || GlobalVar.VirtualAxis) { if(AxisArrived.LoadXYIsArrived(targetPostion.X, targetPostion.Y)) { logInfo = GetClassName() + $"已运动到扫码结束位"; MessageQueue.Instance.Insert(logInfo); timeout.Restart(); step = EUpCameraScanBarCodeFlowStep.等待扫码结束; } else { step = EUpCameraScanBarCodeFlowStep.到扫码结束位; } } break; case EUpCameraScanBarCodeFlowStep.等待扫码结束: grabImages = ImageProcess.GetAutoImage(); if (timeout.ElapsedMilliseconds < 3000) { LogHelper.Debug(GetClassName()+$"扫码完成,num={grabImages.Length}"); //AxisControl.LoadX.CompareStatus(out short pstatu, out int pcount); if ((grabImages != null && grabImages.Length == 8) || GlobalVar.VirtualAxis) { grabImages = ImageRotate.Rotates(grabImages, "upCamera"); step = EUpCameraScanBarCodeFlowStep.拍照结果处理; } } else { //拍照超时 MessageQueue.Instance.Warn(GetClassName() + "上相机拍照超时,重新拍照"); step = EUpCameraScanBarCodeFlowStep.到扫码起始位; } break; case EUpCameraScanBarCodeFlowStep.拍照结果处理: vReslutList.Clear(); GC.Collect(); int slotIndex = 0; foreach (var img in grabImages) { int sIndex = 0; if (!isReverse) { sIndex = startSlotIndex + slotIndex; } else { sIndex = startSlotIndex - slotIndex; } VisionResult vr = new VisionResult(); if (TurnoverTrayManager.Instance.Slot(sIndex).IsHasProduct) { vr = VisionManager.TurnoverTrayDumpProductOK(img, GlobalVar.EnableTurnoverTrayRecheck, true, sIndex); } vr.SlotIndex = sIndex; vReslutList.Add(vr); slotIndex++; } exit = true; //grabFinishedEvent.Set(); break; } } // }); return vReslutList; } public VisionResult ScanSingle(int SlotIndex,bool needGo=true,bool bNeedLocate=true,bool bNeedScanBarcode=true) { TargetPosition targetPostion = new TargetPosition(); AlarmEntity alarmEntity = null; VisionResult singleResult = null; if (exit == false) return null; HObject imageSingle = new HObject(); exit = false; if(!needGo) { ImageProcess.ClearManualTrigger(); HikCamera.Instance.SetExposure("upCamera", GlobalVar.UpCameraExposureTime); HikCamera.Instance.SetGain("upCamera",GlobalVar.UpCameraGain); HikCamera.Instance.SetTrigger("upCamera", ETriggerMode.Manual); AxisControl.LoadX.ComparePulse(2, false); fixedStep = EUpCameraFixedScanBarCodeFlowStep.等待扫码结束; } else { fixedStep = EUpCameraFixedScanBarCodeFlowStep.到扫码位上方; } while (!exit) { if (MachineManage.Instance.MachineStatus == EMachineStatus.Stop) { Thread.Sleep(10); continue; } switch (fixedStep) { case EUpCameraFixedScanBarCodeFlowStep.到扫码位上方: SlotPoint targetPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, SlotIndex); targetPostion.X= targetPoint.X; targetPostion.Y = targetPoint.Y; errCode = AxisControl.LoadX.MovePos(targetPostion.X, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis) { errCode = AxisControl.LoadY.MovePos(targetPostion.Y, GlobalVar.FlyCameraSpeed); if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis) { logInfo = GetClassName() + $"到{SlotIndex}号穴位拍照位上方"; MessageQueue.Instance.Insert(logInfo); fixedStep = EUpCameraFixedScanBarCodeFlowStep.等待运动到扫码位上方; } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadY, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadY运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } } else { //PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode); alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX运动异常).Transform(errCode.ToString()); AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null); } break; case EUpCameraFixedScanBarCodeFlowStep.等待运动到扫码位上方: if (Ops.IsStop(AxisAlias.LoadX, AxisAlias.LoadY) || GlobalVar.VirtualAxis) { if(AxisArrived.LoadXYIsArrived(targetPostion.X,targetPostion.Y)) { logInfo = GetClassName() + $"已运动到{SlotIndex}号穴位拍照位上方"; MessageQueue.Instance.Insert(logInfo); ImageProcess.ClearManualTrigger(); HikCamera.Instance.SetTrigger("upCamera", ETriggerMode.Manual); HikCamera.Instance.SetExposure("upCamera", GlobalVar.UpCameraExposureTime); HikCamera.Instance.SetGain("upCamera", GlobalVar.UpCameraGain); AxisControl.LoadX.ComparePulse(2, false); scanBarCodeWait.Restart(); fixedStep = EUpCameraFixedScanBarCodeFlowStep.等待扫码结束; } else { fixedStep = EUpCameraFixedScanBarCodeFlowStep.到扫码位上方; } } break; case EUpCameraFixedScanBarCodeFlowStep.等待扫码结束: if (scanBarCodeWait.ElapsedMilliseconds < 3000) { HObject image = ImageProcess.GetManualImage(); if (image != null) { logInfo = GetClassName() + "拍照完成"; MessageQueue.Instance.Insert(logInfo); imageSingle = ImageRotate.Rotate(image, "upCamera"); fixedStep = EUpCameraFixedScanBarCodeFlowStep.拍照结果处理; } } else { logInfo = GetClassName() + "拍照超时,重新拍照"; MessageQueue.Instance.Warn(logInfo); fixedStep = EUpCameraFixedScanBarCodeFlowStep.到扫码位上方; } break; case EUpCameraFixedScanBarCodeFlowStep.拍照结果处理: singleResult = VisionManager.TurnoverTrayDumpProductOK(imageSingle, bNeedLocate, bNeedScanBarcode, SlotIndex); singleResult.SlotIndex = SlotIndex; exit = true; logInfo = GetClassName() + "拍照处理完成"; MessageQueue.Instance.Insert(logInfo); break; } } return singleResult; } public string GetClassName() { return "UpCameraScanBarCodeFlow-"; } //public List Wait() //{ // grabFinishedEvent.WaitOne(); // return vReslutList; //} //public VisionResult WaitSingle() //{ // grabFinishedEvent.WaitOne(); // return singleResult; //} public bool CheckResult(VisionResult vr) { if (vr.SearchModelOK) { bool suc= ((Math.Abs(vr.OffsetX) - GlobalVar.TurnoverTrayLocateXRange <= 0) && (Math.Abs(vr.OffsetY) - GlobalVar.TurnoverTrayLocateYRange <= 0) && (Math.Abs(vr.OffsetR) - GlobalVar.TurnoverTrayLocateRRange <= 0)); OnTurnoverTrayProductLocateResult?.Invoke(vr,suc); return suc; } return false; } /// /// 检测XY是否在目标位置上 /// /// /// /// private bool XYIsInTargetPos(double xTargetPos, double yTargetPos) { Stopwatch timer = new Stopwatch(); timer.Start(); while (timer.ElapsedMilliseconds < 3000) { double xCurPos = Ops.GetCurPosition(AxisControl.LoadX); double yCurPos = Ops.GetCurPosition(AxisControl.LoadY); if ((Math.Abs(xTargetPos - xCurPos) < AxisControl.LoadX.Config.Tolerance && Math.Abs(yTargetPos - yCurPos) < AxisControl.LoadY.Config.Tolerance) || GlobalVar.VirtualAxis) { timer.Stop(); return true; } } timer.Stop(); return false; } } }