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.

2051 lines
122 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using HalconDotNet;
using NPOI.SS.Formula.Eval;
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 Rs.MotionPlat.Flow.SafePosFlow;
using Rs.MotionPlat.Flow.SubFlow;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static Rs.MotionPlat.Commom.SchedulingMessageBox;
namespace Rs.MotionPlat.Flow
{
public enum EDischargeFlowStep
{
,
/*取料*/
,
,
,
,
,
,
,
,
,
/*拍照*/
,
,
,
,
,
,
/*放料*/
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
IDLE
}
/// <summary>
/// 排料流程
/// </summary>
public class DischargeFlow : BaseFlow
{
private DischargeFlow() { }
private static DischargeFlow instance;
public event Action<List<MatchResult>> OnMatchResult;
public event Action<List<VisionResult>> OnUpCameraGrabResult;
public event Action<VisionResult,bool> OnShowGrabResult;
public event Action<SlotProductHasOrNotResult> OnStockTrayProductHasOrNotResult;
public event Action<SlotProductHasOrNotResult> OnTurnoverTrayProductHasOrNotResult;
public static DischargeFlow Instance
{
get
{
if (instance == null)
{
instance = new DischargeFlow();
}
return instance;
}
}
private AlarmEntity alarmEntity;
Stopwatch timeout = new Stopwatch();
EDischargeFlowStep flowStep = EDischargeFlowStep.;
EDischargeFlowStep restoreFlowStep = EDischargeFlowStep.IDLE;
HObject[] imgs = new HObject[2];
List<MatchResult> mrs = new List<MatchResult>();
int reFetchNum = 0;//重取料次数
bool bFetchBack = false;
double targetX = 0.0;
double targetY = 0.0;
double targetZ = 0.0;
double targetR = 0.0;
//double targetPos = 0.0;
TraySlot tray = new TraySlot();
// List<TurnoverInfo> totalTask = new List<TurnoverInfo>();
List<TurnoverInfo> dealTask = new List<TurnoverInfo>();
//TurnoverInfo curTurnoverTask = new TurnoverInfo();
TurnoverInfo curTask = new TurnoverInfo();
List<Nozzle> idleNozzle = new List<Nozzle>();
Nozzle curNozzle = new Nozzle();
/// <summary>
/// 当前穴位的点位
/// </summary>
SlotPoint curSlotPoint = new SlotPoint();
SlotPoint nozzleDist = new SlotPoint();
//List<Nozzle> unloadNozzles = new List<Nozzle>();
TraySlot downSlot = new TraySlot();
OffsetPoint turnoverOffsetPoint = new OffsetPoint();
int needGrabNum = 0;//需要拍照的吸嘴数量
int reGrabCount = 0;//重拍次数
ErrorCode errCode = ErrorCode.Ok;
List<TurnoverInfo> testLoadList = new List<TurnoverInfo>();
List<TurnoverInfo> testUnLoadList = new List<TurnoverInfo>();
/// <summary>
/// 从料仓到周转盘
/// </summary>
private bool StockTrayToTurnoverTray = true;
SchedulingMessageBox msgBox;
/// <summary>
/// 未执行的任务数量
/// </summary>
private int undoTaskNum = 0;
int scanNum = 0;
public override void Run()
{
switch (flowStep)
{
case EDischargeFlowStep.:
if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Load) > 0
|| LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Unload) > 0
|| LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Change) > 0)
{
StockTrayToTurnoverTray = true;
logInfo = GetClassName() + $"接收到排料任务";
MessageQueue.Instance.Insert(logInfo);
if (GlobalVar.CleanOut && GlobalVar.DischargeNozzleHasProduct)
{
foreach (TurnoverInfo ti in LoadAndUnloadTask.Instance.GetUnDealedTask())
{
ti.Dealed = true;
}
mrs = new List<MatchResult>();
for (int i = 0; i < 8; i++)
{
mrs.Add(new MatchResult());
}
flowStep = EDischargeFlowStep.;
}
else
{
if (GlobalVar.FirstDischarge)
{
GlobalVar.FirstDischarge = false;
//设备遗留产品检测
//吸嘴全部用真空吸检测周转盘用上相机检测SOCKET用镭射头检测
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
}
break;
case EDischargeFlowStep.:
//先取上料任务,再取下料任务,最后取换料任务
if(StockTrayToTurnoverTray)
{
if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Load) > 0)
{
curTask = LoadAndUnloadTask.Instance.GetLoadTask();
}
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Unload) > 0)
{
curTask = LoadAndUnloadTask.Instance.GetUnLoadTask();
}
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Change) > 0)
{
curTask = LoadAndUnloadTask.Instance.GetChangeTask();
}
}
else
{
if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Unload) > 0)
{
curTask = LoadAndUnloadTask.Instance.GetUnLoadTask();
}
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Load) > 0)
{
curTask = LoadAndUnloadTask.Instance.GetLoadTask();
}
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskType.Change) > 0)
{
curTask = LoadAndUnloadTask.Instance.GetChangeTask();
}
}
curNozzle = NozzleManager.GetIdelNozzle();
if (curTask!=null && curNozzle != null)
{
if (XYCanGoLocalArea() || GlobalVar.VirtualAxis)
{
curSlotPoint = null;
curNozzle.FromType=curTask.FromType;
if (curTask.FromType == TurnoverType.Turnover)
{
curSlotPoint = TrayPointManager.GetSlotPoint( ETrayType.Turnover, curTask.FromIndex + 1);
curNozzle.FromIndex = curTask.FromIndex;
logInfo = GetClassName()+ $"排料{curNozzle.NozzleIndex}号吸嘴到{curTask.FromType.ToString()}盘{curNozzle.FromIndex + 1}号穴位取料";
MessageQueue.Instance.Insert(logInfo);
}
else if (curTask.FromType == TurnoverType.ToBeTested)
{
TraySlot slot = GlobalTray.Input1Tray.GetSlot(ESlotStatus.Have);
if (slot != null)
{
curSlotPoint = TrayPointManager.GetSlotPoint( ETrayType.Input1, slot.Index);
curNozzle.FromIndex= slot.Index-1;
logInfo =GetClassName()+ $"排料{curNozzle.NozzleIndex}号吸嘴到{curTask.FromType.ToString()}盘{curNozzle.FromIndex+1}号穴位取料";
MessageQueue.Instance.Insert(logInfo);
}
else
{
GlobalTray.Input1Tray.ChangeStatus(ESlotStatus.Have);
//slot = GlobalTray.Input2Tray.GetSlot(ESlotStatus.Have);
//if (slot != null)
//{
// curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Input2, slot.Index);
// curNozzle.FromIndex = slot.Index - 1;
// logInfo = GetClassName() + $"排料{curNozzle.NozzleIndex}号吸嘴到{curTask.FromType.ToString()}盘{curNozzle.FromIndex + 1}号穴位取料";
// MessageQueue.Instance.Insert(logInfo);
//}
//else
//{
// slot = GlobalTray.Input3Tray.GetSlot(ESlotStatus.Have);
// if (slot != null)
// {
// curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Input3, slot.Index);
// curNozzle.FromIndex = slot.Index - 1;
// logInfo = GetClassName() + $"排料{curNozzle.NozzleIndex}号吸嘴到{curTask.FromType.ToString()}盘{curNozzle.FromIndex + 1}号穴位取料";
// MessageQueue.Instance.Insert(logInfo);
// }
// else
// {
// //这里报警input已经没有产品了
// }
//}
}
}
if (curSlotPoint != null)
{
nozzleDist = TrayPointManager.GetDistToNozzle1(curNozzle.NozzleIndex);
targetX = curSlotPoint.X + nozzleDist.X;
targetY = curSlotPoint.Y + nozzleDist.Y;
errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
//if(Ops.IsHomedAndNearStartPos($"NozzleR{NozzleIndex}"))
{
errCode = AxisControl.LoadY.MovePos(targetY, (int)(GlobalVar.WholeSpeed));
if(errCode== ErrorCode.Ok|| GlobalVar.VirtualAxis)
{
targetR = SysConfigParam.GetValue<Double>($"NozzleR{curNozzle.NozzleIndex}StartPos");
errCode = AxisControl.GetAxis($"NozzleR{curNozzle.NozzleIndex}").MovePos(targetR, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok | GlobalVar.VirtualAxis)
{
if (GlobalVar.VirtualAxis)
{
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
}
flowStep = EDischargeFlowStep.;
}
else
{
//MsgBox.ShowAxisAlarmDialog($"NozzleR{curNozzle.NozzleIndex}", errCode);
alarmEntity = AlarmCollection.Get($"NozzleR{curNozzle.NozzleIndex}运动异常").Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
else
{
//MsgBox.ShowAxisAlarmDialog(AxisControl.LoadY, errCode);
AlarmMessageBox.ShowDialog(true, ETipButton.Ok, null, AlarmConstID.LoadY, errCode.ToString());
}
}
//else
// {
// Msg.ShowError($"吸头 NozzleR{NozzleIndex} 不在起始位,请手动手动回原后运动到起始位");
// }
}
else
{
//MsgBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode);
AlarmMessageBox.ShowDialog(true, ETipButton.Ok, null, AlarmConstID.LoadX,errCode.ToString());
}
}
}
else
{
//logInfo = "x y r move is unsafe";
//Msg.ShowError(logInfo);
MessageQueue.Instance.Warn($"LoadY运动不安全请检查TurnoverY的位置");
AlarmMessageBox.ShowDialog(true, ETipButton.Ok, null, AlarmConstID., $"{AxisAlias.LoadY}", $"{ AxisAlias.TurnoverY}");
}
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop("LoadX", "LoadY", $"NozzleR{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
{
if (AxisArrived.LoadXYIsArrived(targetX, targetY))
{
logInfo = GetClassName() + $"已运动到{WitchTrayWitchSlot(curNozzle.FromType, curNozzle.FromIndex)}取料位上方";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
if (AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").HomeStatus == EHomeStatus.Finished || GlobalVar.VirtualAxis)
{
if (curTask.FromType == TurnoverType.Turnover)
{
targetZ = GetVacOffsetHeight(reFetchNum) + SysConfigParam.GetValue<double>($"TurnoverNozzle{curNozzle.NozzleIndex}TakeHeight");
//在周转盘取料,提前把真空吸打开
VacManager.DischargeVacSuction(EVacOperator.Open, false, curNozzle.NozzleIndex);
VacManager.TurnoverTrayVacSuction(EVacOperator.Close, false, curNozzle.FromIndex + 1);
}
else if (curTask.FromType == TurnoverType.ToBeTested)
{
targetZ = GetVacOffsetHeight(reFetchNum) + SysConfigParam.GetValue<double>($"TrayNozzle{curNozzle.NozzleIndex}TakeHeight");
}
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(targetZ, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
logInfo = GetClassName() + $"到{WitchTrayWitchSlot(curNozzle.FromType, curNozzle.FromIndex)}号穴位取料位下方";
MessageQueue.Instance.Insert(logInfo);
if (GlobalVar.VirtualAxis)
{
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
}
flowStep = EDischargeFlowStep.;
}
else
{
//MsgBox.ShowAxisAlarmDialog($"NozzleZ{curNozzle.NozzleIndex}", errCode);
//AlarmMessageBox.ShowDialog(true,ETipButton.Ok,null,)
alarmEntity = AlarmCollection.Get($"NozzleZ{curNozzle.NozzleIndex}运动异常").Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
else
{
logInfo = GetClassName()+ $"NozzleZ{curNozzle.NozzleIndex} 轴状态未回原,请手动回原后点击确定";
MessageQueue.Instance.Warn(logInfo);
//MsgBox.ShowDialog(AlarmConstID.AxisNotAtHomeAlarm, logInfo, ETipButton.Ok);
AlarmMessageBox.ShowDialog(true, ETipButton.Ok, null, AlarmConstID., $"NozzleZ{curNozzle.NozzleIndex}");
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
{
if (AxisArrived.LoadXYIsArrived(targetX, targetY))
{
logInfo = GetClassName() + $"已运动到{WitchTrayWitchSlot(curNozzle.FromType, curNozzle.FromIndex)}号穴位取料位下方";
MessageQueue.Instance.Insert(logInfo);
if (curTask.FromType == TurnoverType.Turnover)
{
VacManager.TurnoverTrayVacBreak(EVacOperator.Open, true, curNozzle.FromIndex + 1);
}
else
{
VacManager.DischargeVacSuction(EVacOperator.Open, true, curNozzle.NozzleIndex);
}
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(0, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
if(GlobalVar.VirtualAxis)
{
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
}
logInfo = GetClassName()+ $"取{WitchTrayWitchSlot(curNozzle.FromType, curNozzle.FromIndex)}号穴位产品完成抬起";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
alarmEntity = AlarmCollection.Get($"NozzleZ{curNozzle.NozzleIndex}运动异常").Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
{
logInfo = GetClassName()+$"取{WitchTrayWitchSlot(curNozzle.FromType, curNozzle.FromIndex)}号穴位产品完成已抬起";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
break;
case EDischargeFlowStep.:
if (Ops.IsOn($"{curNozzle.NozzleIndex}号吸嘴真空吸检测") || GlobalVar.RunSpace)
{
reFetchNum = 0;
logInfo = GetClassName()+$"排料吸嘴{curNozzle.NozzleIndex}号真空检测OK";
MessageQueue.Instance.Insert(logInfo);
GlobalTray.DischargeNozzle.ChangeStatus(curNozzle.NozzleIndex, ESlotStatus.Have);
UpdateNozzleStatus(curNozzle, curTask);
undoTaskNum = LoadAndUnloadTask.Instance.GetTaskNum(curTask.taskMode);
if (undoTaskNum > 0 && NozzleManager.GetNozzlesByStatus(ENozzleStatus.IDLE).Count > 0)
{
logInfo =GetClassName()+ $"还有{undoTaskNum}条任务未执行,并且有空闲吸嘴,继续取料";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
else
{
if(reFetchNum==0)
{
//这个时候Z&R回原一次然后再重新取料
ZRHomeFlow.Instance.GoHome(curNozzle.NozzleIndex);
}
reFetchNum++;
if (reFetchNum >= GlobalVar.DischargeRetakeNum)
{
DischargeDumpFlow.Instance.Start(curTask.FromType, curNozzle.NozzleIndex, curNozzle.FromIndex);
//alarmInfo = $"排料{curNozzle.NozzleIndex}号吸嘴取{curNozzle.FromIndex+1}号穴位产品{reFetchNum}次失败";
if(curTask.FromType== TurnoverType.ToBeTested)
{
//alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.料仓tray盘取料报警), curNozzle.NozzleIndex, curNozzle.FromIndex + 1);
alarmEntity = AlarmCollection.Get(AlarmConstID.tray).Transform(curNozzle.NozzleIndex, (curNozzle.FromIndex + 1));
}
else if(curTask.FromType== TurnoverType.Turnover)
{
//alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.排料头在周转盘取料失败报警), curNozzle.NozzleIndex, curNozzle.FromIndex + 1);
alarmEntity = AlarmCollection.Get(AlarmConstID.).Transform(curNozzle.NozzleIndex, curNozzle.FromIndex + 1);
}
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
ETipButton btnText = (ETipButton.Retry | ETipButton.Skip| ETipButton.Yes);
Dictionary<ETipButton, string> buttonText = new Dictionary<ETipButton, string>();
buttonText.Add(ETipButton.Retry, "重试|Retry");
buttonText.Add(ETipButton.Skip, "跳过|Skip");
buttonText.Add(ETipButton.Yes, "移动到安全位|MoveToSafePos");
if (curTask.FromType == TurnoverType.ToBeTested)
{
buttonText.Add(ETipButton.No, "结束上料|EndInput");
btnText |= ETipButton.No;
}
ETipButton button = AlarmMessageBox.ShowDialog(alarmEntity, btnText, buttonText);
//switch (box.Button)
switch(button)
{
case ETipButton.Retry:
logInfo = GetClassName() + $"选择了重试,继续取料";
MessageQueue.Instance.Insert(logInfo);
reFetchNum = 0;
flowStep = EDischargeFlowStep.;
break;
case ETipButton.Skip:
SlotProductHasOrNotResult haveProduct = null;
logInfo = GetClassName() + "选择了跳过";
MessageQueue.Instance.Insert(logInfo);
if(curTask.FromType== TurnoverType.ToBeTested)
{
haveProduct = UpCameraCheckFlow.Instance.CheckStockTrayHasProduct(ETrayType.Input1, curNozzle.FromIndex+1, true);
OnStockTrayProductHasOrNotResult?.Invoke(haveProduct);
}
else if(curTask.FromType== TurnoverType.Turnover)
{
haveProduct = UpCameraCheckFlow.Instance.CheckTurnoverTrayHasProduct(null, curTask.FromIndex + 1);
OnStockTrayProductHasOrNotResult?.Invoke(haveProduct);
}
if(!haveProduct.HasProduct)
{
logInfo = GetClassName() + "检测到产品已拿走,流程继续";
MessageQueue.Instance.Insert(logInfo);
reFetchNum = 0;
//执行料仓Tray取料NG时的处理流程流程处理结束后流程继续
if (curTask.FromType == TurnoverType.Turnover)
{
TurnoverTrayManager.Instance.Slot(curTask.FromIndex + 1).ClearProduct();
GlobalTray.TurnoverTray.ChangeStatus(curTask.FromIndex + 1, ESlotStatus.NotHave);
curTask.Dealed = true;
}
else if (curTask.FromType == TurnoverType.ToBeTested)
{
GlobalTray.Input1Tray.ChangeStatus(curNozzle.FromIndex+1, ESlotStatus.NotHave);
}
undoTaskNum = LoadAndUnloadTask.Instance.GetTaskNum(curTask.taskMode);
if (undoTaskNum > 0 && NozzleManager.GetNozzlesByStatus(ENozzleStatus.IDLE).Count > 0)
{
logInfo = GetClassName()+ $"跳过后检测到还有{undoTaskNum}条任务未执行,继续取料";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
else
{
//alarmInfo = $"检测到{curNozzle.FromIndex+1}号穴位产品未取出,请处理";
alarmEntity = AlarmCollection.Get(AlarmConstID.).Transform(curNozzle.FromIndex + 1);
flowStep = EDischargeFlowStep.;
}
break;
case ETipButton.Yes://移动到安全位
//通知料仓把料盘退回到安全位
if(curTask.FromType== TurnoverType.Turnover)
{
logInfo = GetClassName() + $"通知排料头回安全位";
MessageQueue.Instance.Insert(logInfo);
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
logInfo = GetClassName() + $"排料头已回到安全位";
MessageQueue.Instance.Insert(logInfo);
}
alarmEntity = AlarmCollection.Get(AlarmConstID.tray).Transform(curNozzle.NozzleIndex, (curNozzle.FromIndex + 1));
flowStep = EDischargeFlowStep.;
break;
case ETipButton.No://结束上料
logInfo = GetClassName() + $"选择了结束上料,通知中控结束上料";
MessageQueue.Instance.Insert(logInfo);
reFetchNum = 0;
TestCenter.Instance.EndInput();
LoadAndUnloadTask.Instance.ClearUndoTask();
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count > 0)
{
flowStep = EDischargeFlowStep.;
}
else
{
if (LoadAndUnloadTask.Instance.GetUnDealedTask().Count > 0)
{
ScanBarCode();
StockTrayToTurnoverTray = !StockTrayToTurnoverTray;
flowStep = EDischargeFlowStep.;
}
else
{
ScanBarCode();
flowStep = EDischargeFlowStep.;
}
}
break;
default:
break;
}
break;
case EDischargeFlowStep.:
if (XYCanGoTurnoverTray() || GlobalVar.VirtualAxis)
{
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count > 0)
{
logInfo = GetClassName() + $"到下相机拍照起始位";
Ops.On("下相机光源");
MessageQueue.Instance.Insert(logInfo);
if(!GlobalVar.VirtualAxis)
{
ImageProcess.ClearAutoTrigger();
HikCamera.Instance.SetExposure("locationCamera", GlobalVar.FlyGrabExposureTime);
HikCamera.Instance.SetGain("locationCamera", GlobalVar.FlyGrabGain);
}
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload)[0].ToType == TurnoverType.Turnover)
{
needGrabNum = NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count();
targetX = SysConfigParam.GetValue<double>($"Nozzle{needGrabNum}CenterX") - 30;
targetY = SysConfigParam.GetValue<double>($"Nozzle2CenterY");
errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
errCode = AxisControl.LoadY.MovePos(targetY, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
flowStep = EDischargeFlowStep.;
}
}
}
else
{
targetX = SysConfigParam.GetValue<double>("Nozzle1CenterX") + 30;
targetY = SysConfigParam.GetValue<double>($"Nozzle1CenterY");
errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
errCode = AxisControl.LoadY.MovePos(targetY, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
flowStep = EDischargeFlowStep.;
}
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
{
logInfo = GetClassName() + $"检测到排料吸嘴没有需要下料的产品,任务结束回安全位";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop("LoadX", "LoadY") || GlobalVar.VirtualAxis)
{
if(AxisArrived.LoadXYIsArrived(targetX,targetY))
{
logInfo = GetClassName() + $"已运动到下相机拍照起始位";
MessageQueue.Instance.Insert(logInfo);
if (!GlobalVar.VirtualAxis)
{
HikCamera.Instance.SetTrigger("locationCamera", ETriggerMode.Auto);
}
List<double> grabPoints = new List<double>();
//获取有几个吸嘴需要拍照
needGrabNum = NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count();
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload)[0].ToType == TurnoverType.Turnover)
{
for (int i = needGrabNum; i >= 1; i--)
{
grabPoints.Add(SysConfigParam.GetValue<double>($"Nozzle{i}CenterX"));
}
}
else
{
for (int i = 1; i < needGrabNum + 1; i++)
{
grabPoints.Add(SysConfigParam.GetValue<double>($"Nozzle{i}CenterX"));
}
}
//LogHelper.Debug(GetClassName()+$"拍照点位:{grabPoints.ToJoinString(",")}");
errCode = AxisControl.LoadX.SetPosCompare(2, grabPoints.ToArray());
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
if (XYCanGoTurnoverTray() || GlobalVar.VirtualAxis)
{
logInfo = GetClassName() + $"到下相机拍照结束位";
MessageQueue.Instance.Insert(logInfo);
//IoManager.Instance.WriteOut("下左相机光源触发", 1);
//Thread.Sleep(50);
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload)[0].ToType == TurnoverType.Turnover)
{
targetX = SysConfigParam.GetValue<double>($"Nozzle1CenterX") + 10;
}
else
{
targetX = SysConfigParam.GetValue<double>($"Nozzle{needGrabNum}CenterX") - 10;
}
errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.FlyCameraSpeed);
if (errCode== ErrorCode.Ok || GlobalVar.VirtualAxis)
{
flowStep = EDischargeFlowStep.;
}
else
{
//PromptMessageBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode);
alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX).Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop("LoadX") || GlobalVar.VirtualAxis)
{
if(AxisArrived.LoadXYIsArrived(targetX,targetY))
{
logInfo = GetClassName() + $"已运动到下相机拍照结束位";
MessageQueue.Instance.Insert(logInfo);
if (!GlobalVar.VirtualAxis)
{
AxisControl.LoadX.ClearCompare(1);
}
Ops.Off("下相机光源");
timeout.Restart();
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
if(timeout.ElapsedMilliseconds<3000)
{
imgs = ImageProcess.GetAutoImage();
if ((imgs != null && imgs.Length == needGrabNum) || GlobalVar.VirtualAxis)
{
logInfo = GetClassName() + $"相机拍照完成,准备处理照片";
MessageQueue.Instance.Insert(logInfo);
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload)[0].ToType == TurnoverType.Turnover)
{
imgs = imgs.Reverse().ToArray();
}
if (GlobalVar.RunSpace)
{
if(GlobalVar.EnableScanBarCodeByDownCamera)
{
foreach (Nozzle nl in NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload))
{
if (string.IsNullOrEmpty(nl.SN))
{
nl.SN = VirtualBarCode.Code;// (nl.FromIndex + 1).ToString().PadLeft(18, '0');
}
}
}
mrs = new List<MatchResult>();
for (int i = 0; i < needGrabNum; i++)
{
mrs.Add(new MatchResult());
}
flowStep = EDischargeFlowStep.;
}
else
{
//拍照完成
flowStep = EDischargeFlowStep.;
}
}
}
else
{
MessageQueue.Instance.Warn("下相机拍照超时,重拍");
flowStep = EDischargeFlowStep.;
}
break;
case EDischargeFlowStep.:
if (mrs != null && mrs.Count > 0)
{
mrs.Clear();
GC.Collect();
}
mrs = VisionProcess.Instance.MatchDownCam(imgs);
if (mrs != null && mrs.Count == imgs.Length && (mrs.Where(m=>m.IsOK==true).Count()==imgs.Length || GlobalVar.DownCameraFlyRegrabNum==0))
{
logInfo = GetClassName() + $"图片处理完成,准备放料";
MessageQueue.Instance.Insert(logInfo);
int count = 0;
if(GlobalVar.EnableScanBarCodeByDownCamera)
{
foreach (Nozzle nozzle in NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload))
{
nozzle.SN = mrs[count].SN;
count++;
}
}
//int ni = 1;
//foreach (MatchResult item in mrs)
//{
// NozzleManager.GetNozzle(ni).SN = item.SN;
// ni++;
//}
reGrabCount = 0;
OnMatchResult?.Invoke(mrs);
flowStep = EDischargeFlowStep.;
}
else
{
int ni = 1;
List<int> errCodeList = new List<int>();
foreach (MatchResult item in mrs)
{
if(item.IsOK)
{
if(GlobalVar.EnableScanBarCodeByDownCamera)
{
NozzleManager.GetNozzle(ni).SN = item.SN;
}
}
else
{
errCodeList.Add(ni);
NozzleManager.GetNozzle(ni).SN = null;
}
ni++;
}
OnMatchResult?.Invoke(mrs);
if(reGrabCount < GlobalVar.DownCameraFlyRegrabNum)
{
reGrabCount++;
flowStep = EDischargeFlowStep.;
}
else
{
if(GlobalVar.LocationFailAutoSkip)
{
reGrabCount = 0;
flowStep = EDischargeFlowStep.;
}
else
{
reGrabCount = 0;
//alarmInfo = $"{string.Join(",", errCodeList)}号排料吸嘴拍照失败";
alarmEntity = AlarmCollection.Get(AlarmConstID.).Transform(errCodeList.ToJoinString(","));
//DialogResult dr = Msg.ShowQuestion(, System.Windows.Forms.MessageBoxButtons.RetryCancel);
//TestCenterMessageBox.Show(AlarmConstID.DownCameraFlyFailAlarm, alarmInfo, ETipButton.Retry | ETipButton.Cancel);
//box = MsgBox.ShowDialog(AlarmConstID.DownCameraFlyFailAlarm, alarmInfo, ETipButton.Retry | ETipButton.Cancel);// TestCenterMessageBox.WaitResult(AlarmConstID.DownCameraFlyFailAlarm);
ETipButton box = AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Retry | ETipButton.Cancel, null, true);
// if (box.Button == ETipButton.Cancel)
if(box== ETipButton.Cancel)
{
flowStep = EDischargeFlowStep.;
}
//else if (box.Button == ETipButton.Retry)
else if(box== ETipButton.Retry)
{
Thread.Sleep(500);
flowStep = EDischargeFlowStep.;
}
}
}
}
break;
case EDischargeFlowStep.:
{
bool canGo = false;
if (curNozzle.ToType == TurnoverType.Turnover)
{
canGo = XYCanGoTurnoverTray();
}
else
{
canGo = XYCanGoLocalArea();
}
if (canGo || GlobalVar.VirtualAxis)
{
turnoverOffsetPoint.Reset();
tray = null;
targetX = 0.0;
targetY = 0.0;
///获取需要放料的吸嘴
curSlotPoint = null;
curNozzle = NozzleManager.GetToUnloadNozzle();
if (curNozzle != null)
{
if (curNozzle.ToType == TurnoverType.Turnover)
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{curNozzle.ToType}盘{curNozzle.ToIndex + 1}号穴位上方";
MessageQueue.Instance.Insert(logInfo);
curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, curNozzle.ToIndex + 1);
turnoverOffsetPoint = TurnoverSlotOffset.GetOffsetPoint(curNozzle.ToIndex + 1);
}
else if (curNozzle.ToType == TurnoverType.ToBeTested)
{
downSlot = GlobalTray.Input1Tray.GetSlot(ESlotStatus.NotHave);
if (downSlot != null)
{
curNozzle.ToIndex = downSlot.Index - 1;
curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Input1, downSlot.Index);
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{curNozzle.ToType}盘{curNozzle.ToIndex + 1}号穴位上方";
MessageQueue.Instance.Insert(logInfo);
}
else
{
}
}
else if (curNozzle.ToType == TurnoverType.Passed)
{
downSlot = GlobalTray.Good1Tray.GetSlot(ESlotStatus.NotHave);
if (downSlot != null)
{
curNozzle.ToIndex = downSlot.Index - 1;
curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Good1, downSlot.Index);
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{curNozzle.ToType}盘{curNozzle.ToIndex + 1}号穴位上方";
MessageQueue.Instance.Insert(logInfo);
}
else
{
GlobalTray.Good1Tray.ChangeStatus(ESlotStatus.NotHave);
//downSlot = GlobalTray.Good2Tray.GetSlot(ESlotStatus.NotHave);
//if (downSlot != null)
//{
// curNozzle.ToIndex = downSlot.Index - 1;
// curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Good2, downSlot.Index);
// logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{curNozzle.ToType}盘{curNozzle.ToIndex + 1}号穴位上方";
// MessageQueue.Instance.Insert(logInfo);
//}
//else
//{
// downSlot = GlobalTray.Good3Tray.GetSlot(ESlotStatus.NotHave);
// if (downSlot != null)
// {
// curNozzle.ToIndex = downSlot.Index - 1;
// curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Good3, downSlot.Index);
// logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{curNozzle.ToType}盘{curNozzle.ToIndex + 1}号穴位上方";
// MessageQueue.Instance.Insert(logInfo);
// }
// else
// {
// //在这里报警,产品没有地方放了
// }
//}
}
}
else if (curNozzle.ToType == TurnoverType.Failed)
{
downSlot = GlobalTray.RejectTray.GetSlot(ESlotStatus.NotHave);
if (downSlot != null)
{
curNozzle.ToIndex = downSlot.Index - 1;
curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Reject, downSlot.Index);
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{curNozzle.ToType}盘{curNozzle.ToIndex + 1}号穴位上方";
MessageQueue.Instance.Insert(logInfo);
}
else
{
//在这里报警,产品没有地方放了
}
}
else if (curNozzle.ToType == TurnoverType.Multifunction)
{
//如果吸嘴是1并且最后一列
downSlot = GlobalTray.MultiTray.GetSlot(ESlotStatus.NotHave);
if (downSlot != null)
{
curNozzle.ToIndex = downSlot.Index - 1;
curSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Multi, downSlot.Index);
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{curNozzle.ToType}盘{curNozzle.ToIndex + 1}号穴位上方,SN={curNozzle.SN}";
MessageQueue.Instance.Insert(logInfo);
}
else
{
//在这里报警,产品没有地方放了
}
}
}
if (curSlotPoint != null)
{
nozzleDist = TrayPointManager.GetDistToNozzle1(curNozzle.NozzleIndex);
if (mrs!=null && mrs.Count>0 && mrs.Count>=curNozzle.NozzleIndex && mrs[curNozzle.NozzleIndex - 1].OffsetRow < 3 && mrs[curNozzle.NozzleIndex - 1].OffsetCol < 3)
{
targetX = mrs[curNozzle.NozzleIndex - 1].OffsetCol + curSlotPoint.X + nozzleDist.X + turnoverOffsetPoint.X;
targetY = mrs[curNozzle.NozzleIndex - 1].OffsetRow + curSlotPoint.Y + nozzleDist.Y + turnoverOffsetPoint.Y;
}
else
{
targetX = curSlotPoint.X + nozzleDist.X + turnoverOffsetPoint.X;
targetY = curSlotPoint.Y + nozzleDist.Y + turnoverOffsetPoint.Y;
}
//在这里保存图片,图片的名称以 时间+穴位定义
if(curNozzle.ToType== TurnoverType.Turnover)
{
//判断文件夹是否存在
string dirname = $"d://images/{DateTime.Now.ToString("yyyyMMdd")}/load";
if (!Directory.Exists(dirname))
{
Directory.CreateDirectory(dirname);
}
if(mrs != null && mrs.Count > 0 && mrs.Count >= curNozzle.NozzleIndex && mrs[curNozzle.NozzleIndex - 1].Himage!=null)
{
HOperatorSet.WriteImage(mrs[curNozzle.NozzleIndex - 1].Himage, "bmp", 0, $"{dirname}//{DateTime.Now.ToString("yyyyMMddHHmmssfff")}_{curNozzle.ToIndex + 1}");
}
}
else
{
//判断文件夹是否存在
string dirname = $"d://images/{DateTime.Now.ToString("yyyyMMdd")}/unload";
if (!Directory.Exists(dirname))
{
Directory.CreateDirectory(dirname);
}
if (mrs != null && mrs.Count > 0 && mrs.Count >= curNozzle.NozzleIndex && mrs[curNozzle.NozzleIndex - 1].Himage != null)
{
HOperatorSet.WriteImage(mrs[curNozzle.NozzleIndex - 1].Himage, "bmp", 0, $"{dirname}//{DateTime.Now.ToString("yyyyMMddHHmmssfff")}_{curNozzle.FromIndex + 1}");
}
}
logInfo =GetClassName()+ $"运动到放料位上方 X:{targetX}Y:{targetY}";
MessageQueue.Instance.Insert(logInfo);
errCode = AxisControl.LoadX.MovePos(targetX, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
errCode = AxisControl.LoadY.MovePos(targetY, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
errCode = AxisControl.GetAxis($"NozzleR{curNozzle.NozzleIndex}").MoveOffset((mrs[curNozzle.NozzleIndex - 1].OffsetA) + turnoverOffsetPoint.A, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
if (GlobalVar.VirtualAxis)
{
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
}
flowStep = EDischargeFlowStep.;
}
else
{
//AlarmMessageBox.ShowDialog(true, ETipButton.Ok, null, AlarmConstID.轴运动异常, $"NozzleR{curNozzle.NozzleIndex}", errCode.ToString());
//MsgBox.ShowAxisAlarmDialog($"NozzleR{curNozzle.NozzleIndex}", errCode);
alarmEntity = AlarmCollection.Get($"NozzleR{curNozzle.NozzleIndex}运动异常").Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
else
{
//MsgBox.ShowAxisAlarmDialog(AxisControl.LoadY, errCode);
//AlarmMessageBox.ShowDialog(true, ETipButton.Ok, null, AlarmConstID.轴运动异常, $"{AxisAlias.LoadY}", errCode.ToString());
alarmEntity = AlarmCollection.Get(AlarmConstID.LoadY).Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
else
{
//MsgBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode);
alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX).Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
}
else
{
alarmInfo = "loady r move isn't safe";
MessageQueue.Instance.Warn(alarmInfo);
//MsgBox.ShowDialog(AlarmConstID.MoveUnsafeAlarm, alarmInfo, ETipButton.Ok);
AlarmMessageBox.ShowDialog(true, ETipButton.Ok, null, AlarmConstID., $"{AxisAlias.LoadY}", $"{AxisAlias.TurnoverY }");
}
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop("LoadX", "LoadY",$"NozzleR{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
{
if(AxisArrived.LoadXYIsArrived(targetX, targetY))
{
//当放料到tray盘区域时并且周转再盘已经没有要下料的穴位时通知周转模组可以运动了
//if (curNozzle.ToType != TurnoverType.Turnover && TurnoverTrayManager.Instance.GetSlots(ETurnoverTraySlotType.Tested, ETurnoverTraySlotStatus.Have).Count() == 0)
//{
// LogHelper.Debug("通知周转模组可以运动");
// TurnoverFlow.Instance.CanMoveFromTestTrayToTurnoverTray();
//}
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号已运动到{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}放料位上方";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
if (!curNozzle.HasProduct()&&!GlobalVar.RunSpace)
{
bool exit = false;
while (!exit)
{
//弹框报警
//alarmInfo = $"{curNozzle.NozzleIndex}吸嘴真空吸异常,可能丢料,请检查吸嘴的状态";
if(curNozzle.ToType== TurnoverType.Turnover)
{
//alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.排料投在周转盘放料时丢料报警), curNozzle.NozzleIndex);
alarmEntity = AlarmCollection.Get(AlarmConstID.).Transform(curNozzle.NozzleIndex);
}
else
{
//alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.料仓tray盘放料时丢料报警), curNozzle.NozzleIndex,curNozzle.ToType.ToString());
alarmEntity = AlarmCollection.Get(AlarmConstID.tray).Transform(curNozzle.NozzleIndex, curNozzle.ToType.ToString());
}
//alarmid = AlarmConstID.料仓tray盘放料时丢料报警;
//if (curNozzle.ToType == TurnoverType.Turnover)
//{
// //alarmid = AlarmConstID.排料投在周转盘放料时丢料报警;
//}
//else
//{
//}
//TestCenterMessageBox.Show(AlarmConstID.DischargeNozzleLostProductAlarm, alarmInfo, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());
//msgBox = MsgBox.ShowDialog(alarmid, alarmInfo, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());// TestCenterMessageBox.WaitResult(AlarmConstID.DischargeNozzleLostProductAlarm);
ETipButton buttonRet = AlarmMessageBox.ShowDialog(alarmEntity, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());
//switch (msgBox.Button)
switch(buttonRet)
{
case ETipButton.Skip:
if (!curNozzle.HasProduct())
{
curNozzle.Reset();
curNozzle.VacSuction(EIoOperate.Close);
curNozzle.VacBreak(EIoOperate.Open);
curNozzle.VacBreak(EIoOperate.Close);
exit = true;
flowStep = EDischargeFlowStep.;
}
break;
case ETipButton.Yes:
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
DischargeModuleGoSafePosFlow.Instance.Wait();
break;
default:
break;
}
}
}
else
{
flowStep = EDischargeFlowStep.;
}
break;
case EDischargeFlowStep.:
if (curNozzle.ToType == TurnoverType.Turnover)
{
targetZ = SysConfigParam.GetValue<double>($"TurnoverNozzle{curNozzle.NozzleIndex}TakeHeight");
/*提前打开周转盘真空吸*/
VacManager.TurnoverTrayVacSuction(EVacOperator.Open, false, curNozzle.ToIndex + 1);
}
else
{
targetZ = SysConfigParam.GetValue<double>($"TrayNozzle{curNozzle.NozzleIndex}TakeHeight") + GlobalVar.DischargeNozzleDumpStockTrayOffsetHeight;
}
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(targetZ, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号到{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}放料位下方";
MessageQueue.Instance.Insert(logInfo);
VirtualAxisSleep();
flowStep = EDischargeFlowStep.;
}
else
{
//PromptMessageBox.ShowAxisAlarmDialog($"NozzleZ{curNozzle.NozzleIndex}", errCode);
alarmEntity = AlarmCollection.Get($"NozzleZ{curNozzle.NozzleIndex}运动异常").Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
{
if(AxisArrived.LoadXYIsArrived(targetX,targetY))
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号已运动到{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}放料位下方";
MessageQueue.Instance.Insert(logInfo);
if (curNozzle.ToType == TurnoverType.Turnover)
{
/*关闭排料吸嘴真空吸*/
//logInfo = GetClassName() + $"关闭{curNozzle.NozzleIndex}号排料吸嘴真空吸";
//MessageQueue.Instance.Insert(logInfo);
//Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空吸电磁阀");//关闭真空
//Thread.Sleep(GlobalVar.LoadNozzleCloseVacSuctionDelaytime);
VacManager.DischargeVacSuction(EVacOperator.Close, true, curNozzle.NozzleIndex);
/*打开排料吸嘴真空破*/
//logInfo = GetClassName() + $"打开{curNozzle.NozzleIndex}号排料吸嘴真空破";
//MessageQueue.Instance.Insert(logInfo);
//Ops.On($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
//Thread.Sleep(GlobalVar.LoadNozzleOpenVacBreakDelaytime);
VacManager.DischargeVacBreak(EVacOperator.Open, true, curNozzle.NozzleIndex);
flowStep = EDischargeFlowStep.;
}
else
{
GlobalTray.DischargeNozzle.ChangeStatus(curNozzle.NozzleIndex, ESlotStatus.NotHave);
/*关闭排料吸嘴真空吸*/
//logInfo = GetClassName() + $"关闭{curNozzle.NozzleIndex}号排料吸嘴真空吸";
//MessageQueue.Instance.Insert(logInfo);
//Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空吸电磁阀");
//Thread.Sleep(GlobalVar.LoadNozzleCloseVacSuctionDelaytime);
VacManager.DischargeVacSuction(EVacOperator.Close, true, curNozzle.NozzleIndex);
/*打开排料吸嘴真空破*/
//logInfo = GetClassName() + $"打开{curNozzle.NozzleIndex}号排料吸嘴真空破";
//MessageQueue.Instance.Insert(logInfo);
//Ops.On($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
//Thread.Sleep(GlobalVar.LoadNozzleOpenVacBreakDelaytime);
VacManager.DischargeVacBreak(EVacOperator.Open, true, curNozzle.NozzleIndex);
/*关闭排料吸嘴真空破*/
//logInfo = GetClassName() + $"关闭{curNozzle.NozzleIndex}号排料吸嘴真空破";
//MessageQueue.Instance.Insert(logInfo);
//Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
//Thread.Sleep(GlobalVar.LoadNozzleCloseVacBreakDelaytime);
VacManager.DischargeVacBreak(EVacOperator.Close, false, curNozzle.NozzleIndex);
flowStep = EDischargeFlowStep.;
}
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
targetZ = SysConfigParam.GetValue<double>($"TurnoverNozzle{curNozzle.NozzleIndex}TakeHeight")+GlobalVar.DischargeNozzleDumpTurnoverTrayOffset;
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(targetZ, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号周转盘放料完成,准备抬起{GlobalVar.DischargeNozzleDumpTurnoverTrayOffset}mm后关闭破真空";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
PromptMessageBox.ShowAxisAlarmDialog($"NozzleZ{curNozzle.NozzleIndex}", errCode);
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
{
/*关闭排料吸嘴真空破*/
//Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
//Thread.Sleep(GlobalVar.LoadNozzleCloseVacBreakDelaytime);
VacManager.DischargeVacBreak(EVacOperator.Close,false,curNozzle.NozzleIndex);
logInfo = GetClassName() + $"关闭排料{curNozzle.NozzleIndex}号吸嘴真空破";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
break;
case EDischargeFlowStep.:
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(0, GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}放料完成抬起";
MessageQueue.Instance.Insert(logInfo);
if (GlobalVar.VirtualAxis)
{
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
}
flowStep = EDischargeFlowStep.;
}
else
{
//PromptMessageBox.ShowAxisAlarmDialog($"NozzleZ{curNozzle.NozzleIndex}", errCode);
alarmEntity = AlarmCollection.Get($"NozzleZ{curNozzle.NozzleIndex}运动异常").Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
break;
case EDischargeFlowStep.:
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
{
logInfo = GetClassName()+$"排料吸嘴{curNozzle.NozzleIndex}号{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}放料完成已起位";
MessageQueue.Instance.Insert(logInfo);
if(curNozzle.ToType== TurnoverType.Turnover)
{
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
if (curNozzle.ToType == TurnoverType.Turnover)
{
if (Ops.IsOn($"周转盘{curNozzle.ToIndex + 1}号穴位真空吸检测") || GlobalVar.RunSpace)
{
logInfo = GetClassName() + $"周转盘{curNozzle.ToIndex + 1}号穴位真空吸检测OK";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
//打开真空吸
curNozzle.VacSuction(EIoOperate.Open);
//如果粘料
if (curNozzle.HasProduct())
{
bool skip = false;
while (!skip)
{
//粘料报警,提示用户粘料,移动到安全位,或者点击跳过
//alarmInfo = $"排料{curNozzle.NozzleIndex}号吸嘴可能粘料,请查看吸嘴状态后处理";
//alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.排料头粘料报警), curNozzle.NozzleIndex);
alarmEntity = AlarmCollection.Get(AlarmConstID.).Transform(curNozzle.NozzleIndex);
MessageQueue.Instance.Warn(GetClassName() + alarmEntity.CN);
//TestCenterMessageBox.Show(AlarmConstID.NozzleTackinessAlarm, alarmInfo, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());
//msgBox = MsgBox.ShowDialog(AlarmConstID.排料头粘料报警, alarmInfo, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());// TestCenterMessageBox.WaitResult(AlarmConstID.NozzleTackinessAlarm);
ETipButton btnRet = AlarmMessageBox.ShowDialog(alarmEntity, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());
//switch (msgBox.Button)
switch(btnRet)
{
case ETipButton.Skip:
logInfo = GetClassName() + "选择了跳过按钮";
MessageQueue.Instance.Insert(logInfo);
if (!curNozzle.HasProduct())
{
curNozzle.VacSuction(EIoOperate.Close);
curNozzle.Reset();
skip = true;
flowStep = EDischargeFlowStep.;
}
break;
case ETipButton.Yes:
logInfo = GetClassName() + "选择了移动到安全位按钮";
MessageQueue.Instance.Insert(logInfo);
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
break;
}
}
}
else
{
//如果没有粘料,说明产品放下去了,这个时候用相机检测产品是否在穴位种
VisionResult vr = UpCameraScanBarCodeFlow.Instance.ScanSingle(curNozzle.ToIndex + 1, true,true,false);
//VisionResult vr = UpCameraScanBarCodeFlow.Instance.WaitSingle();
if (UpCameraScanBarCodeFlow.Instance.CheckResult(vr))
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号SN={curNozzle.SN}放{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}";
MessageQueue.Instance.Insert(logInfo);
curNozzle.VacSuction(EIoOperate.Close);
flowStep = EDischargeFlowStep.;
}
else
{
//异常处理
bool exit = false;
Dictionary<ETipButton, string> buttons = new Dictionary<ETipButton, string>()
{
{ ETipButton.Retry,"重拍|Regrab" },
{ETipButton.Skip,"跳过|Skip" },
{ETipButton.Yes,"移动到安全位|MoveToSafePos" }
};
while (!exit)
{
//alarmInfo = $"周转盘{curNozzle.ToIndex + 1}号穴位真空吸异常";
alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.), curNozzle.NozzleIndex, curNozzle.ToIndex + 1);
MessageQueue.Instance.Warn(GetClassName() + alarmInfo);
//TestCenterMessageBox.Show(AlarmConstID.TurnoverDumpFailAlarm, alarmInfo, ETipButton.Retry | ETipButton.Skip | ETipButton.Yes, buttons);
msgBox = PromptMessageBox.ShowDialog(AlarmConstID., alarmInfo, ETipButton.Retry | ETipButton.Skip | ETipButton.Yes, buttons);// TestCenterMessageBox.WaitResult(AlarmConstID.TurnoverDumpFailAlarm);
if (msgBox != null)
{
switch (msgBox.Button)
{
case ETipButton.Retry://重拍
logInfo = GetClassName() + $"选择了重拍";
MessageQueue.Instance.Insert(logInfo);
vr = UpCameraScanBarCodeFlow.Instance.ScanSingle(curNozzle.ToIndex + 1, true,true,true);
//vr = UpCameraScanBarCodeFlow.Instance.WaitSingle();
if (UpCameraScanBarCodeFlow.Instance.CheckResult(vr))
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号SN={curNozzle.SN}放{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}";
MessageQueue.Instance.Insert(logInfo);
curNozzle.VacSuction(EIoOperate.Close);
exit = true;
flowStep = EDischargeFlowStep.;
}
break;
case ETipButton.Skip://跳过
logInfo = GetClassName() + $"选择了跳过";
MessageQueue.Instance.Insert(logInfo);
if (!UpCameraCheckFlow.Instance.CheckTurnoverTrayHasProduct(null, curNozzle.ToIndex + 1).HasProduct)
{
VacManager.TurnoverTrayVacSuction(EVacOperator.Close, true, curNozzle.ToIndex + 1);
curNozzle.Reset();
flowStep = EDischargeFlowStep.;
exit = true;
}
break;
case ETipButton.Yes://移动到安全位
logInfo = GetClassName() + $"选择了移动到安全位";
MessageQueue.Instance.Insert(logInfo);
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
DischargeModuleGoSafePosFlow.Instance.Wait();
break;
default:
break;
}
}
}
}
}
}
}
break;
case EDischargeFlowStep.:
//打开真空吸
curNozzle.VacSuction(EIoOperate.Open);
if(!GlobalVar.RunSpace && curNozzle.HasProduct())
{
bool skip = false;
while(!skip)
{
//粘料报警,提示用户粘料,移动到安全位,或者点击跳过
//alarmInfo = $"排料{curNozzle.NozzleIndex}号吸嘴可能粘料,请查看吸嘴状态后处理";
//alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.排料头粘料报警), curNozzle.NozzleIndex);
alarmEntity = AlarmCollection.Get(AlarmConstID.).Transform(curNozzle.NozzleIndex);
MessageQueue.Instance.Warn(GetClassName()+ alarmEntity.CN);
//TestCenterMessageBox.Show(AlarmConstID.NozzleTackinessAlarm, alarmInfo, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());
//msgBox = MsgBox.ShowDialog(AlarmConstID.排料头粘料报警, alarmInfo, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());// TestCenterMessageBox.WaitResult(AlarmConstID.NozzleTackinessAlarm);
ETipButton btnRet = AlarmMessageBox.ShowDialog(alarmEntity, MessageButtonManager.GetSkip_MoveToSafe_Button(), MessageButtonManager.GetSkip_MoveToSafe_ButtonText());
//switch (msgBox.Button)
switch(btnRet)
{
case ETipButton.Skip:
logInfo = GetClassName() + "选择了跳过按钮";
MessageQueue.Instance.Insert(logInfo);
if (!curNozzle.HasProduct())
{
curNozzle.VacSuction(EIoOperate.Close);
curNozzle.Reset();
skip = true;
flowStep = EDischargeFlowStep.;
}
break;
case ETipButton.Yes:
logInfo = GetClassName() + "选择了移动到安全位按钮";
MessageQueue.Instance.Insert(logInfo);
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
break;
}
}
}
else
{
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号SN={curNozzle.SN}放{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}";
MessageQueue.Instance.Insert(logInfo);
curNozzle.VacSuction(EIoOperate.Close);
flowStep = EDischargeFlowStep.;
}
break;
case EDischargeFlowStep.:
//AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").Home();
//MessageQueue.Instance.Insert($"{curNozzle.NozzleIndex}号排料吸嘴回原");
//Ops.HomeAndGoStartPos($"NozzleR{NozzleIndex}");
if (curNozzle.Status == ENozzleStatus.ToUnload)
{
GlobalTray.DischargeNozzle.ChangeStatus(curNozzle.NozzleIndex, ESlotStatus.NotHave);
logInfo = GetClassName() + $"排料吸嘴{curNozzle.NozzleIndex}号{WitchTrayWitchSlot(curNozzle.ToType, curNozzle.ToIndex)}放料任务完成";
MessageQueue.Instance.Insert(logInfo);
if (curNozzle.ToType == TurnoverType.Turnover)
{
GlobalTray.TurnoverTray.ChangeStatus(curNozzle.ToIndex + 1, ESlotStatus.Have);
TurnoverTrayManager.Instance.Slot(curNozzle.ToIndex + 1).AddProduct(curNozzle);
}
else if (curNozzle.ToType == TurnoverType.ToBeTested)
{
//curNozzle.ToFloor = StockManager.Instance.GetStock(ETrayType.Input).GetFloor();
GlobalTray.Input1Tray.ChangeStatus(curNozzle.ToIndex+1, ESlotStatus.Have);
TrayStatusManager.Fill(ETrayType.Input1, curNozzle.ToIndex + 1);
}
else if (curNozzle.ToType == TurnoverType.Passed)
{
//curNozzle.ToFloor = StockManager.Instance.GetStock(ETrayType.Ok).GetFloor();
GlobalTray.Good1Tray.ChangeStatus(curNozzle.ToIndex + 1, ESlotStatus.Have);
TrayStatusManager.Fill(ETrayType.Good1, curNozzle.ToIndex + 1);
}
else if (curNozzle.ToType == TurnoverType.Failed)
{
//curNozzle.ToFloor = StockManager.Instance.GetStock(ETrayType.Ng).GetFloor();
GlobalTray.RejectTray.ChangeStatus(curNozzle.ToIndex + 1, ESlotStatus.Have);
TrayStatusManager.Fill(ETrayType.Reject, curNozzle.ToIndex + 1);
}
else if (curNozzle.ToType == TurnoverType.Multifunction)
{
//curNozzle.ToFloor = StockManager.Instance.GetStock(ETrayType.Multi).GetFloor();
GlobalTray.MultiTray.ChangeStatus(curNozzle.ToIndex + 1, ESlotStatus.Have);
TrayStatusManager.Fill(ETrayType.Multi, curNozzle.ToIndex + 1);
}
LoadAndUnloadTask.Instance.AddTurnoverResult(curNozzle);
}
curNozzle.Reset();
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count > 0)
{
flowStep = EDischargeFlowStep.;
}
else
{
//release memory
//foreach (var item in mrs)
//{
// item.Dispose();
//}
//mrs.Clear();
if(mrs!=null&&mrs.Count>0)
{
Array.Clear(imgs, 0, imgs.Length);
mrs.Clear();
GC.Collect();
}
//GC.Collect();
if(curNozzle.ToType== TurnoverType.Turnover)
{
ScanBarCode();
}
if (LoadAndUnloadTask.Instance.GetUnDealedTask().Count > 0)
{
StockTrayToTurnoverTray = !StockTrayToTurnoverTray;
flowStep = EDischargeFlowStep.;
}
else
{
flowStep = EDischargeFlowStep.;
}
}
break;
case EDischargeFlowStep.:
//检测一下是否需要换盘
{
#region 通知中控排料任务结束
if(curNozzle.ToType!= TurnoverType.Turnover && !GlobalVar.CleanOut)
{
if (TestCenter.Instance.LoadResult())
{
logInfo = GetClassName() + $"通知中控任务完成";
MessageQueue.Instance.Insert(logInfo);
LoadAndUnloadTask.Instance.Clear();
logInfo = GetClassName() + $"任务完成,清除任务";
MessageQueue.Instance.Insert(logInfo);
MachineManage.Instance.SetLoadUnloadStatus(ERunState.Waiting);
}
}
#endregion
errCode = AxisControl.LoadX.MovePos(SysConfigParam.GetValue<double>("LoadXStartPos"), GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
errCode = AxisControl.LoadY.MovePos(SysConfigParam.GetValue<double>("LoadYStartPos"), GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
if (GlobalVar.VirtualAxis)
{
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
}
logInfo = GetClassName() + $"排料任务结束到安全位";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
else
{
//MsgBox.ShowAxisAlarmDialog(AxisControl.LoadY, errCode);
alarmEntity = AlarmCollection.Get(AlarmConstID.LoadY).Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
else
{
//MsgBox.ShowAxisAlarmDialog(AxisControl.LoadX, errCode);
alarmEntity = AlarmCollection.Get(AlarmConstID.LoadX).Transform(errCode.ToString());
AlarmMessageBox.ShowDialog(alarmEntity, ETipButton.Ok, null);
}
}
break;
case EDischargeFlowStep.:
if(Ops.IsStop("LoadX", "LoadY") || GlobalVar.VirtualAxis)
{
if (curNozzle.ToType == TurnoverType.Turnover)
{
if (TestCenter.Instance.LoadResult())
{
logInfo = GetClassName() + $"通知中控任务完成";
MessageQueue.Instance.Insert(logInfo);
LoadAndUnloadTask.Instance.Clear();
logInfo = GetClassName() + $"任务完成,清除任务";
MessageQueue.Instance.Insert(logInfo);
MachineManage.Instance.SetLoadUnloadStatus(ERunState.Waiting);
}
}
TurnoverFlow.Instance.CanMoveFromTestTrayToTurnoverTray();
logInfo = GetClassName()+ $"任务结束已回到安全位";
MessageQueue.Instance.Insert(logInfo);
flowStep = EDischargeFlowStep.;
}
break;
default:
break;
}
}
/// <summary>
/// 判断排料轴是否可以干其他的活
/// </summary>
public void WaitCanMove()
{
while(true)
{
if(flowStep== EDischargeFlowStep.)
{
return;
}
Thread.Sleep(10);
}
}
public void ScanBarCode()
{
SchedulingMessageBox box = new SchedulingMessageBox();
if(GlobalVar.RunSpace)
{
List<TurnoverTraySlot> slots = TurnoverTrayManager.Instance.GetSlots(ETurnoverTraySlotType.WaitTest, ETurnoverTraySlotStatus.Have);
foreach (var slot in slots)
{
LoadAndUnloadTask.Instance.CopyBarcodeToTask(slot.Index - 1, VirtualBarCode.Code);
}
}
else
{
if (LoadAndUnloadTask.Instance.GetUndealedLoadToTurnoverTask().Count == 0)
{
if (GlobalVar.GRR)
{
scanNum++;
}
if (scanNum == 1 || !GlobalVar.GRR)
{
if (GlobalVar.EnableVirtuleBarCode)
{
List<TurnoverTraySlot> slots = TurnoverTrayManager.Instance.GetSlots(ETurnoverTraySlotType.WaitTest, ETurnoverTraySlotStatus.Have);
foreach (var slot in slots)
{
LoadAndUnloadTask.Instance.CopyBarcodeToTask(slot.Index - 1, VirtualBarCode.Code);
}
}
else
{
//没有需要给周转盘上料的任务后,就开始上相机扫码
//判断周转盘第一行有没有产品,如果有产品则拍第一行
if (TurnoverTrayManager.Instance.HasProduct(ETrayRow.One))
{
//找拍照起点和终点
SlotPoint grabStartPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, 1);
SlotPoint grabEndPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, 8);
List<VisionResult> result = UpCameraScanBarCodeFlow.Instance.ScanMulti(1, false);
//List<VisionResult> result = UpCameraScanBarCodeFlow.Instance.Wait();
foreach (var vr in result)
{
if (TurnoverTrayManager.Instance.Slot(vr.SlotIndex).IsHasProduct)
{
if (vr.SearchModelOK)//定位成功
{
if (!GlobalVar.EnableScanBarCodeByDownCamera)
{
if (GlobalVar.RunSpace)
{
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, VirtualBarCode.Code);
}
else
{
if (vr.ScanBarCodeOK)
{
OnShowGrabResult?.Invoke(vr, true);
//复制二维码
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, vr.SN);
TurnoverTrayManager.Instance.Slot(vr.SlotIndex).SN = vr.SN;
}
else
{
int failNum = 1;
while (true)
{
if (failNum < 4)
{
//如果扫码失败再重扫一次
VisionResult vrsigle =UpCameraScanBarCodeFlow.Instance.ScanSingle(vr.SlotIndex, true,false,true);
//VisionResult vrsigle = UpCameraScanBarCodeFlow.Instance.WaitSingle();
if (vrsigle.ScanBarCodeOK)
{
OnShowGrabResult?.Invoke(vrsigle, true);
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, vrsigle.SN);
TurnoverTrayManager.Instance.Slot(vr.SlotIndex).SN = vrsigle.SN;
break;
}
else
{
failNum++;
OnShowGrabResult?.Invoke(vrsigle, true);
//复制二维码
//LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, "");
Thread.Sleep(500);
}
if(vrsigle != null)
{
vrsigle=null;
GC.Collect();
}
}
else
{
alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.), vr.SlotIndex);
Dictionary<ETipButton, string> buttonTexts = new Dictionary<ETipButton, string>() {
{ ETipButton.Retry,"重试|Retry"},
{ ETipButton.Cancel,"自动移走|Auto remove"}
};
box = PromptMessageBox.ShowDialog(AlarmConstID., alarmInfo, ETipButton.Retry | ETipButton.Cancel, buttonTexts);
if (box.Button == ETipButton.Retry)
{
failNum = 1;
}
else if(box.Button== ETipButton.Cancel)
{
//OnShowGrabResult?.Invoke(vrsigle, true);
//复制二维码
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, "");
TurnoverTrayManager.Instance.Slot(vr.SlotIndex).SN = "";
break;
}
}
}
}
}
}
}
else
{
//定位失败,或者超出指定范围
}
}
else
{
OnShowGrabResult?.Invoke(vr, false);
}
//vr.Dispose();
}
if (result != null && result.Count > 0)
{
result.Clear();
GC.Collect();
}
//OnUpCameraGrabResult?.Invoke(result);
}
//判断周转盘第三行有没有产品,如果有产品则拍第三行
if (TurnoverTrayManager.Instance.HasProduct(ETrayRow.Three))
{
//找拍照起点和终点
SlotPoint grabStartPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, 17);
SlotPoint grabEndPoint = TrayPointManager.GetSlotPoint(ETrayType.Turnover, 24);
List<VisionResult> result = UpCameraScanBarCodeFlow.Instance.ScanMulti(24, true);
// List<VisionResult> result = UpCameraScanBarCodeFlow.Instance.Wait();
foreach (var vr in result)
{
if (TurnoverTrayManager.Instance.Slot(vr.SlotIndex).IsHasProduct)
{
if (vr.SearchModelOK)//定位成功
{
if (!GlobalVar.EnableScanBarCodeByDownCamera)
{
if (GlobalVar.RunSpace)
{
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, VirtualBarCode.Code);
}
else
{
if (vr.ScanBarCodeOK)
{
OnShowGrabResult?.Invoke(vr, true);
//复制二维码
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, vr.SN);
TurnoverTrayManager.Instance.Slot(vr.SlotIndex).SN = vr.SN;
}
else
{
int failNum = 1;
while (true)
{
if (failNum < 4)
{
//如果扫码失败再重扫一次
VisionResult vrsigle =UpCameraScanBarCodeFlow.Instance.ScanSingle(vr.SlotIndex, true,false,true);
//VisionResult vrsigle = UpCameraScanBarCodeFlow.Instance.WaitSingle();
if (vrsigle.ScanBarCodeOK)
{
OnShowGrabResult?.Invoke(vrsigle, true);
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, vrsigle.SN);
TurnoverTrayManager.Instance.Slot(vr.SlotIndex).SN = vrsigle.SN;
break;
}
else
{
failNum++;
OnShowGrabResult?.Invoke(vrsigle, true);
//复制二维码
//LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, "");
Thread.Sleep(500);
}
if(vrsigle != null)
{
vrsigle = null;
GC.Collect();
}
}
else
{
//box = MsgBox.ShowDialog(AlarmConstID.ScanBarCodeFailAlarm, $"{vr.SlotIndex}穴位扫码失败", ETipButton.Retry | ETipButton.Skip);
alarmInfo = string.Format(AlarmCollection.GetAlarm(AlarmConstID.), vr.SlotIndex);
Dictionary<ETipButton, string> buttonTexts = new Dictionary<ETipButton, string>() {
{ ETipButton.Retry,"重试|Retry"},
{ ETipButton.Cancel,"自动移走|Auto remove"}
};
box = PromptMessageBox.ShowDialog(AlarmConstID., alarmInfo, ETipButton.Retry | ETipButton.Cancel, buttonTexts);
if (box.Button == ETipButton.Retry)
{
failNum = 1;
}
else if (box.Button == ETipButton.Cancel)
{
//OnShowGrabResult?.Invoke(vrsigle, true);
//复制二维码
LoadAndUnloadTask.Instance.CopyBarcodeToTask(vr.SlotIndex - 1, "");
TurnoverTrayManager.Instance.Slot(vr.SlotIndex).SN = "";
break;
}
}
}
}
}
}
}
else
{
//定位失败,或者超出指定范围
}
}
else
{
OnShowGrabResult?.Invoke(vr, false);
}
//vr.Dispose();
}
if (result != null && result.Count > 0)
{
result.Clear();
GC.Collect();
}
//OnUpCameraGrabResult?.Invoke(result);
}
}
}
}
}
}
/// <summary>
/// 取料完成后更新吸嘴状态
/// </summary>
private void UpdateNozzleStatus(Nozzle nozzle,TurnoverInfo turnoverInfo)
{
nozzle.Status = ENozzleStatus.ToUnload;
//nozzle.FromType = turnoverInfo.FromType;
nozzle.ToType = turnoverInfo.ToType;
nozzle.ToIndex = turnoverInfo.ToIndex;
turnoverInfo.SuckerNo = nozzle.NozzleIndex;
nozzle.TurnoverGUID = turnoverInfo.GUID;
if (turnoverInfo.FromType == TurnoverType.Turnover)
{
TurnoverTrayManager.Instance.Slot(turnoverInfo.FromIndex + 1).ClearProduct();
nozzle.FromFloor = turnoverInfo.FromFloor;
nozzle.SN = turnoverInfo.SN;
//nozzle.FromIndex = turnoverInfo.FromIndex;
GlobalTray.TurnoverTray.ChangeStatus(nozzle.FromIndex + 1, ESlotStatus.NotHave);
}
else if (turnoverInfo.FromType == TurnoverType.ToBeTested)
{
//nozzle.FromFloor = StockManager.Instance.GetStock(ETrayType.Input).GetFloor();
nozzle.SN = "";
//nozzle.FromIndex = GlobalTray.InputTray.GetSlot(ESlotStatus.Have).Index - 1;
GlobalTray.Input1Tray.ChangeStatus(nozzle.FromIndex+1, ESlotStatus.NotHave);
TrayStatusManager.Clear(ETrayType.Input1, nozzle.FromIndex + 1);
}
nozzle.Update();
turnoverInfo.Dealed = true;
}
/// <summary>
/// 获取吸嘴取料取不起来时,吸嘴在原取料位的偏移
/// 奇数向下偏移
/// 偶数向上偏移
/// </summary>
/// <param name="fetchNum"></param>
/// <returns></returns>
private double GetVacOffsetHeight(int fetchNum)
{
if(fetchNum==0) return 0;
//先判断是奇数还是偶数
int count = 0;
int oddOrEven = fetchNum & 0x01;
double offsetDisct = 0.0;
if (oddOrEven == 1)
{
count = (fetchNum / 2) + 1;
offsetDisct = -0.1 * count;
}
else if (oddOrEven == 0)
{
count = (fetchNum / 2);
offsetDisct = 0.1 * count;
}
return offsetDisct;
}
/// <summary>
/// 检测排料Y轴是否可以到周转盘
/// </summary>
/// <returns></returns>
private bool CanGoTurnoverTray()
{
//获取周转Y轴的位置当排料Y轴去周转盘的时候检测是否安全
double turnoverYPos = Ops.GetCurPosition("TurnoverY");
if (turnoverYPos - SysConfigParam.GetValue<double>("PressY") < -1)
return false;
return true;
}
/// <summary>
/// 检测XY是否可以去周转盘
/// </summary>
/// <returns></returns>
public bool XYCanGoTurnoverTray()
{
if (!CanGoTurnoverTray())
return false;
return true;
}
/// <summary>
/// 判断XY是否可以在本区域运动
/// </summary>
/// <returns></returns>
public bool XYCanGoLocalArea()
{
//获取周转Y轴的位置当排料Y轴去周转盘的时候检测是否安全
double turnoverYPos = Ops.GetCurPosition("TurnoverY");
if (turnoverYPos - SysConfigParam.GetValue<double>("TurnoverDumpY") < -0.5)
return false;
return true;
}
public string GetCurStep()
{
return flowStep.ToString();
}
/// <summary>
/// 到哪个盘哪个穴位
/// </summary>
/// <param name="trayType"></param>
/// <param name="slotIndex"></param>
/// <returns></returns>
public string WitchTrayWitchSlot(TurnoverType trayType,int slotIndex)
{
return $"{trayType}盘{slotIndex+1}穴位";
}
/// <summary>
/// 复位流程步序
/// </summary>
private void ResetFlow()
{
flowStep = EDischargeFlowStep.;
}
///// <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;
//}
}
}