You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

468 lines
23 KiB
C#

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
{
,
,
,
}
/// <summary>
/// 上相机扫码流程
/// </summary>
public class UpCameraScanBarCodeFlow
{
public event Action<VisionResult,bool> 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);
/// <summary>
/// /// 开始扫码,先把所有的穴位全部扫一遍,扫不到的最后再定点扫码,
/// 如果定位失败的穴位,即便没有扫到码,也不再扫码
/// </summary>
/// <param name="startPoint">拍照起始点</param>
/// <param name="endPoint">拍照终止点</param>
/// <param name="isReverse">是否反转拍照</param>
public List<VisionResult> ScanMulti(int startSlotIndex, bool isReverse)
{
TargetPosition targetPostion = new TargetPosition();
AlarmEntity alarmEntity = null;
List<VisionResult> vReslutList = new List<VisionResult>();
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<double> grabPoints = new List<double>();
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<VisionResult> 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;
}
/// <summary>
/// 检测XY是否在目标位置上
/// </summary>
/// <param name="xTargetPos"></param>
/// <param name="yTargetPos"></param>
/// <returns></returns>
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;
}
}
}