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#
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;
|
|
}
|
|
}
|
|
}
|