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
}
///
/// 排料流程
///
public class DischargeFlow : BaseFlow
{
private DischargeFlow() { }
private static DischargeFlow instance;
public event Action> OnMatchResult;
public event Action> OnUpCameraGrabResult;
public event Action OnShowGrabResult;
public event Action OnStockTrayProductHasOrNotResult;
public event Action 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 mrs = new List();
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 totalTask = new List();
List dealTask = new List();
//TurnoverInfo curTurnoverTask = new TurnoverInfo();
TurnoverInfo curTask = new TurnoverInfo();
List idleNozzle = new List();
Nozzle curNozzle = new Nozzle();
///
/// 当前穴位的点位
///
SlotPoint curSlotPoint = new SlotPoint();
SlotPoint nozzleDist = new SlotPoint();
//List unloadNozzles = new List();
TraySlot downSlot = new TraySlot();
OffsetPoint turnoverOffsetPoint = new OffsetPoint();
int needGrabNum = 0;//需要拍照的吸嘴数量
int reGrabCount = 0;//重拍次数
ErrorCode errCode = ErrorCode.Ok;
List testLoadList = new List();
List testUnLoadList = new List();
///
/// 从料仓到周转盘
///
private bool StockTrayToTurnoverTray = true;
SchedulingMessageBox msgBox;
///
/// 未执行的任务数量
///
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();
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($"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($"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($"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 buttonText = new Dictionary();
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($"Nozzle{needGrabNum}CenterX") - 30;
targetY = SysConfigParam.GetValue($"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("Nozzle1CenterX") + 30;
targetY = SysConfigParam.GetValue($"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 grabPoints = new List();
//获取有几个吸嘴需要拍照
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($"Nozzle{i}CenterX"));
}
}
else
{
for (int i = 1; i < needGrabNum + 1; i++)
{
grabPoints.Add(SysConfigParam.GetValue($"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($"Nozzle1CenterX") + 10;
}
else
{
targetX = SysConfigParam.GetValue($"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();
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 errCodeList = new List();
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($"TurnoverNozzle{curNozzle.NozzleIndex}TakeHeight");
/*提前打开周转盘真空吸*/
VacManager.TurnoverTrayVacSuction(EVacOperator.Open, false, curNozzle.ToIndex + 1);
}
else
{
targetZ = SysConfigParam.GetValue($"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($"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 buttons = new Dictionary()
{
{ 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("LoadXStartPos"), GlobalVar.WholeSpeed);
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
{
errCode = AxisControl.LoadY.MovePos(SysConfigParam.GetValue("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;
}
}
///
/// 判断排料轴是否可以干其他的活
///
public void WaitCanMove()
{
while(true)
{
if(flowStep== EDischargeFlowStep.等待任务)
{
return;
}
Thread.Sleep(10);
}
}
public void ScanBarCode()
{
SchedulingMessageBox box = new SchedulingMessageBox();
if(GlobalVar.RunSpace)
{
List 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 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 result = UpCameraScanBarCodeFlow.Instance.ScanMulti(1, false);
//List 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 buttonTexts = new Dictionary() {
{ 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 result = UpCameraScanBarCodeFlow.Instance.ScanMulti(24, true);
// List 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 buttonTexts = new Dictionary() {
{ 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);
}
}
}
}
}
}
///
/// 取料完成后更新吸嘴状态
///
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;
}
///
/// 获取吸嘴取料取不起来时,吸嘴在原取料位的偏移
/// 奇数向下偏移
/// 偶数向上偏移
///
///
///
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;
}
///
/// 检测排料Y轴是否可以到周转盘
///
///
private bool CanGoTurnoverTray()
{
//获取周转Y轴的位置,当排料Y轴去周转盘的时候,检测是否安全
double turnoverYPos = Ops.GetCurPosition("TurnoverY");
if (turnoverYPos - SysConfigParam.GetValue("PressY") < -1)
return false;
return true;
}
///
/// 检测XY是否可以去周转盘
///
///
public bool XYCanGoTurnoverTray()
{
if (!CanGoTurnoverTray())
return false;
return true;
}
///
/// 判断XY是否可以在本区域运动
///
///
public bool XYCanGoLocalArea()
{
//获取周转Y轴的位置,当排料Y轴去周转盘的时候,检测是否安全
double turnoverYPos = Ops.GetCurPosition("TurnoverY");
if (turnoverYPos - SysConfigParam.GetValue("TurnoverDumpY") < -0.5)
return false;
return true;
}
public string GetCurStep()
{
return flowStep.ToString();
}
///
/// 到哪个盘哪个穴位
///
///
///
///
public string WitchTrayWitchSlot(TurnoverType trayType,int slotIndex)
{
return $"{trayType}盘{slotIndex+1}穴位";
}
///
/// 复位流程步序
///
private void ResetFlow()
{
flowStep = EDischargeFlowStep.等待任务;
}
/////
///// 检测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)