|
|
using HalconDotNet;
|
|
|
using Rs.AutoDischarge.V3.Flow;
|
|
|
using Rs.Camera;
|
|
|
using Rs.Controls;
|
|
|
using Rs.Framework;
|
|
|
using Rs.Motion;
|
|
|
using Rs.MotionPlat.Commom;
|
|
|
using Rs.MotionPlat.Flow.Space;
|
|
|
using Rs.MotionPlat.MsgBox;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Diagnostics;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
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 EWorkFlowStep
|
|
|
{
|
|
|
等待任务,
|
|
|
到取料位上方,
|
|
|
等待到取料位上方,
|
|
|
到取料位下方,
|
|
|
等待到取料位下方,
|
|
|
开真空,
|
|
|
取料完成后真空检测,
|
|
|
取料完成抬起,
|
|
|
等待取料完成抬起,
|
|
|
到下相机拍照起始位,
|
|
|
等待到下相机拍照起始位,
|
|
|
到下相机拍照结束位,
|
|
|
等待到下相机拍照结束位,
|
|
|
等待相机拍照完成,
|
|
|
等待视觉处理结果,
|
|
|
到放料位上方,
|
|
|
等待到放料位上方,
|
|
|
到放料位下方,
|
|
|
等待到放料位下方,
|
|
|
到放料关破真空位,
|
|
|
等待到放料关破真空位,
|
|
|
周转盘放料位真空检测,
|
|
|
放料完成抬起,
|
|
|
等待放料完成抬起,
|
|
|
放料真空检测,
|
|
|
放料任务完成,
|
|
|
任务结束到安全位,
|
|
|
等待任务结束到安全位,
|
|
|
测试工位上料,
|
|
|
等待测试工位上料完成,
|
|
|
测试工位下料,
|
|
|
等待测试工位下料完成,
|
|
|
等待Input料盘搬运完成,
|
|
|
等待Input料仓上料完成,
|
|
|
等待Ok料仓收料完成,
|
|
|
等待Ok料盘搬运完成,
|
|
|
等待Ng料仓收料完成,
|
|
|
等待Ng料盘搬运完成,
|
|
|
等待Multi料仓收料完成,
|
|
|
等待Multi料盘搬运完成,
|
|
|
IDLE
|
|
|
}
|
|
|
|
|
|
public class WorkFlow : BaseFlow
|
|
|
{
|
|
|
private WorkFlow() { }
|
|
|
|
|
|
private static WorkFlow instance;
|
|
|
|
|
|
public event Action<List<MatchResult>> OnMatchResult;
|
|
|
public static WorkFlow Instance
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if (instance == null)
|
|
|
{
|
|
|
instance = new WorkFlow();
|
|
|
}
|
|
|
return instance;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
EWorkFlowStep flowStep = EWorkFlowStep.等待任务;
|
|
|
EWorkFlowStep restoreFlowStep = EWorkFlowStep.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 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();
|
|
|
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>();
|
|
|
private bool turnoverToTray = true;
|
|
|
public override void Run()
|
|
|
{
|
|
|
switch (flowStep)
|
|
|
{
|
|
|
case EWorkFlowStep.等待任务:
|
|
|
WaitTask();
|
|
|
break;
|
|
|
case EWorkFlowStep.到取料位上方:
|
|
|
//先取下料任务,再取上料任务,最后取换料任务
|
|
|
if(turnoverToTray)
|
|
|
{
|
|
|
if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.Unload) > 0)
|
|
|
{
|
|
|
curTask = LoadAndUnloadTask.Instance.GetUnLoadTask();
|
|
|
}
|
|
|
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.Load) > 0)
|
|
|
{
|
|
|
curTask = LoadAndUnloadTask.Instance.GetLoadTask();
|
|
|
}
|
|
|
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.Change) > 0)
|
|
|
{
|
|
|
curTask = LoadAndUnloadTask.Instance.GetChangeTask();
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.Load) > 0)
|
|
|
{
|
|
|
curTask = LoadAndUnloadTask.Instance.GetLoadTask();
|
|
|
}
|
|
|
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.Unload) > 0)
|
|
|
{
|
|
|
curTask = LoadAndUnloadTask.Instance.GetUnLoadTask();
|
|
|
}
|
|
|
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.Change) > 0)
|
|
|
{
|
|
|
curTask = LoadAndUnloadTask.Instance.GetChangeTask();
|
|
|
}
|
|
|
}
|
|
|
curNozzle = NozzleManager.GetIdelNozzle();
|
|
|
if (curTask!=null && curNozzle != null)
|
|
|
{
|
|
|
if (XYCanMove() || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
curSlotPoint = null;
|
|
|
if (curTask.FromType == TurnoverType.Turnover)
|
|
|
{
|
|
|
curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Turnover", curTask.FromIndex + 1, EPointType.RUN);
|
|
|
logInfo = $"[{curNozzle.NozzleIndex}]号排料吸嘴到周转盘[{curTask.FromIndex + 1}]号穴位取料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
else if (curTask.FromType == TurnoverType.ToBeTested)
|
|
|
{
|
|
|
TraySlot slot = GlobalTray.InputTray.GetSlot(ESlotStatus.Have);
|
|
|
if (slot != null)
|
|
|
{
|
|
|
curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Input", slot.Index, EPointType.BASE);
|
|
|
logInfo = $"[{curNozzle.NozzleIndex}]吸排料嘴去Input盘[{slot.Index}]号穴位取料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
logInfo = "检测到Input料盘无料,准备上切盘";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
TakeTrayFlow.Instance.Take(EStockType.Input, EStockType.Empty1, ELoadUnloadType.Unload);
|
|
|
restoreFlowStep = EWorkFlowStep.到取料位上方;
|
|
|
flowStep = EWorkFlowStep.等待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)
|
|
|
{
|
|
|
errCode = AxisControl.GetAxis($"NozzleR{curNozzle.NozzleIndex}").MovePos(SysConfigParam.GetValue<Double>($"NozzleR{curNozzle.NozzleIndex}StartPos"), (int)(GlobalVar.WholeSpeed));
|
|
|
if (errCode == ErrorCode.Ok | GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
if (GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
|
|
|
}
|
|
|
flowStep = EWorkFlowStep.等待到取料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//TestCenterMessageBox.Show(1, $"轴NozzleR{curNozzle.NozzleIndex}点位运动失败,ret={errCode},请单独复位该轴后点击确定", ETipButton.Yes);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//TestCenterMessageBox.Show(1, $"轴LoadY点位运动失败,ret={errCode},请单独复位该轴后点击确定", ETipButton.Yes);
|
|
|
}
|
|
|
}
|
|
|
//else
|
|
|
// {
|
|
|
// Msg.ShowError($"吸头 NozzleR{NozzleIndex} 不在起始位,请手动手动回原后运动到起始位");
|
|
|
// }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//TestCenterMessageBox.Show(1, $"轴LoadX点位运动失败,ret={errCode},请单独复位该轴后点击确定", ETipButton.Yes);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
logInfo = "x y r move isn't safe";
|
|
|
Msg.ShowError(logInfo);
|
|
|
MessageQueue.Instance.Warn(logInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case EWorkFlowStep.等待到取料位上方:
|
|
|
if (Ops.IsStop("LoadX", "LoadY", $"NozzleR{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "已运动到取料位上方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.到取料位下方;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case EWorkFlowStep.到取料位下方:
|
|
|
if (AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").HomeStatus == EHomeStatus.Finished || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "准备运动到取料位下方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
if (curTask.FromType == TurnoverType.Turnover)
|
|
|
{
|
|
|
targetPos = GetVacOffsetHeight(reFetchNum) + SysConfigParam.GetValue<double>($"TurnoverNozzle{curNozzle.NozzleIndex}TakeHeight");
|
|
|
}
|
|
|
else if (curTask.FromType == TurnoverType.ToBeTested)
|
|
|
{
|
|
|
targetPos = GetVacOffsetHeight(reFetchNum) + SysConfigParam.GetValue<double>($"TrayNozzle{curNozzle.NozzleIndex}TakeHeight");
|
|
|
}
|
|
|
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(targetPos, GlobalVar.WholeSpeed);
|
|
|
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
if(GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
|
|
|
}
|
|
|
flowStep = EWorkFlowStep.等待到取料位下方;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
logInfo = $"NozzleZ{curNozzle.NozzleIndex} 不在原点,请手动回原后点击确定";
|
|
|
MessageQueue.Instance.Warn(logInfo);
|
|
|
TestCenterMessageBox.Show(1111, logInfo, ETipButton.Ok);
|
|
|
TestCenterMessageBox.WaitResult(1111);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case EWorkFlowStep.等待到取料位下方:
|
|
|
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "已运动到取料位下方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.开真空;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case EWorkFlowStep.开真空:
|
|
|
/*打开排料吸嘴真空吸*/
|
|
|
Ops.On($"{curNozzle.NozzleIndex}号吸嘴真空吸电磁阀");
|
|
|
Thread.Sleep(GlobalVar.LoadNozzleOpenVacSuctionDelaytime);
|
|
|
logInfo = $"打开{curNozzle.NozzleIndex}号排料吸嘴真空吸";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
if (curTask.FromType == TurnoverType.Turnover)
|
|
|
{
|
|
|
/*关闭周转盘真空吸*/
|
|
|
logInfo = $"关闭周转盘{curTask.FromIndex + 1}号穴位真空吸";
|
|
|
Ops.Off($"周转盘{curTask.FromIndex + 1}号穴位真空吸");
|
|
|
Thread.Sleep(GlobalVar.TurnoverTrayCloseVacSuctionDelaytime);
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
/*打开周转盘真空破*/
|
|
|
logInfo = $"打开周转盘{curTask.FromIndex + 1}号穴位真空破";
|
|
|
Ops.On($"周转盘{curTask.FromIndex + 1}号穴位真空破");
|
|
|
Thread.Sleep(GlobalVar.TurnoverTrayOpenVacBreakDelaytime);
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
/*关闭周转盘真空破*/
|
|
|
logInfo = $"关闭周转盘{curTask.FromIndex + 1}号穴位真空破";
|
|
|
Ops.Off($"周转盘{curTask.FromIndex + 1}号穴位真空破");
|
|
|
Thread.Sleep(GlobalVar.TurnoverTrayCloseVacBreakDelaytime);
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
flowStep = EWorkFlowStep.取料完成抬起;
|
|
|
break;
|
|
|
|
|
|
case EWorkFlowStep.取料完成抬起:
|
|
|
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(0, GlobalVar.WholeSpeed);
|
|
|
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
if(GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
|
|
|
}
|
|
|
logInfo = "取料完成准备抬起";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.等待取料完成抬起;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//TestCenterMessageBox.Show(, $"轴NozzleZ{curNozzle.NozzleIndex}运动异常,ret={errCode}", ETipButton.Ok);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待取料完成抬起:
|
|
|
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "取料完成已运动到安全位,准备真空检测";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.取料完成后真空检测;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.取料完成后真空检测:
|
|
|
if (Ops.IsOn($"{curNozzle.NozzleIndex}号吸嘴真空吸检测") || GlobalVar.RunSpace || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
reFetchNum = 0;
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴真空检测OK";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
TakeFinishedUpdateNozzleStatus(curNozzle, curTask);
|
|
|
int undoTaskNum = LoadAndUnloadTask.Instance.GetTaskNum(curTask.taskMode);
|
|
|
if (undoTaskNum > 0 && NozzleManager.GetNozzlesByStatus(ENozzleStatus.IDLE).Count > 0)
|
|
|
{
|
|
|
logInfo = $"检测到还有{undoTaskNum}条任务未执行,继续取料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.到取料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到下相机拍照起始位;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
reFetchNum++;
|
|
|
if (reFetchNum == 6)
|
|
|
{
|
|
|
ETipButton btnText = (ETipButton.Retry | ETipButton.Skip | ETipButton.Yes);
|
|
|
Dictionary<ETipButton, string> buttonText = new Dictionary<ETipButton, string>();
|
|
|
if(curTask.FromType== TurnoverType.ToBeTested)
|
|
|
{
|
|
|
buttonText.Add(ETipButton.No, "结束上料|EndInput");
|
|
|
btnText |= ETipButton.No;
|
|
|
}
|
|
|
buttonText.Add(ETipButton.Yes, "继续|Continue");
|
|
|
buttonText.Add(ETipButton.Skip, "跳过|Skip");
|
|
|
buttonText.Add(ETipButton.Retry, "重试|Retry");
|
|
|
//DialogResult dr = Msg.ShowError($"吸嘴{curNozzle.NozzleIndex}取料{FetchNum}次失败报警,请处理后点击确定", MessageBoxButtons.RetryCancel);
|
|
|
//CloseResult cr = new TakeFailMsg().ShowMsg($"吸嘴{curNozzle.NozzleIndex}取料{FetchNum}次失败报警,请处理后点击确定");
|
|
|
//结束上料/跳过/重试/继续
|
|
|
//ETipButton btnText = (ETipButton.Retry | ETipButton.Skip | ETipButton.Yes | ETipButton.No);
|
|
|
alarmInfo = $"【{curNozzle.NozzleIndex}】排料吸嘴取料{reFetchNum}次失败";
|
|
|
TestCenterMessageBox.Show(AlarmConstID.TrayTakeFailAlarm,alarmInfo , btnText);
|
|
|
SchedulingMessageBox box = TestCenterMessageBox.WaitResult(AlarmConstID.TrayTakeFailAlarm);
|
|
|
switch (box.Button)
|
|
|
{
|
|
|
case ETipButton.Yes://继续
|
|
|
reFetchNum = 0;
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴真空检测NG但选择了继续执行";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
TakeFinishedUpdateNozzleStatus(curNozzle, curTask);
|
|
|
int undoTaskNum = LoadAndUnloadTask.Instance.GetTaskNum(curTask.taskMode);
|
|
|
if (undoTaskNum > 0 && NozzleManager.GetNozzlesByStatus(ENozzleStatus.IDLE).Count > 0)
|
|
|
{
|
|
|
logInfo = $"检测到还有{undoTaskNum}条任务未执行,继续取料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.到取料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到下相机拍照起始位;
|
|
|
}
|
|
|
break;
|
|
|
case ETipButton.No:
|
|
|
reFetchNum = 0;
|
|
|
TestCenter.Instance.EndInput();
|
|
|
LoadAndUnloadTask.Instance.ClearUndoTask();
|
|
|
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count > 0)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到下相机拍照起始位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.任务结束到安全位;
|
|
|
}
|
|
|
break;
|
|
|
case ETipButton.Retry:
|
|
|
reFetchNum = 0;
|
|
|
flowStep = EWorkFlowStep.到取料位下方;
|
|
|
break;
|
|
|
case ETipButton.Skip:
|
|
|
reFetchNum = 0;
|
|
|
if (curTask.FromType == TurnoverType.Turnover)
|
|
|
{
|
|
|
GlobalTray.TurnoverTray.ChangeStatus(curTask.FromIndex + 1, ESlotStatus.NotHave);
|
|
|
curTask.Dealed = true;
|
|
|
}
|
|
|
else if (curTask.FromType == TurnoverType.ToBeTested)
|
|
|
{
|
|
|
GlobalTray.InputTray.ChangeStatus(GlobalTray.InputTray.GetSlot(ESlotStatus.Have).Index, ESlotStatus.NotHave);
|
|
|
}
|
|
|
undoTaskNum = LoadAndUnloadTask.Instance.GetTaskNum(curTask.taskMode);
|
|
|
if (undoTaskNum > 0 && NozzleManager.GetNozzlesByStatus(ENozzleStatus.IDLE).Count > 0)
|
|
|
{
|
|
|
logInfo = $"跳过后检测到还有{undoTaskNum}条任务未执行,继续取料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.到取料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到下相机拍照起始位;
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到取料位下方;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.到下相机拍照起始位:
|
|
|
if (XYCanMove() || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
turnoverToTray = !turnoverToTray;
|
|
|
logInfo = "到下相机拍照起始位";
|
|
|
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();
|
|
|
AxisControl.LoadX.MovePos(SysConfigParam.GetValue<double>($"Nozzle{needGrabNum}CenterX") - 30, GlobalVar.WholeSpeed);
|
|
|
AxisControl.LoadY.MovePos(SysConfigParam.GetValue<double>($"Nozzle8CenterY"), GlobalVar.WholeSpeed);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
AxisControl.LoadX.MovePos(SysConfigParam.GetValue<double>("Nozzle1CenterX") + 30, GlobalVar.WholeSpeed);
|
|
|
AxisControl.LoadY.MovePos(SysConfigParam.GetValue<double>("Nozzle1CenterY"), GlobalVar.WholeSpeed);
|
|
|
}
|
|
|
flowStep = EWorkFlowStep.等待到下相机拍照起始位;
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case EWorkFlowStep.等待到下相机拍照起始位:
|
|
|
if (Ops.IsStop("LoadX", "LoadY") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "已运动到下相机拍照起始位";
|
|
|
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"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
errCode = AxisControl.LoadX.SetPosCompare(1, grabPoints.ToArray());
|
|
|
if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到下相机拍照结束位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//TestCenterMessageBox.Show(1,$"轴LoadX运动异常,ret={errCode}", ETipButton.Ok);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case EWorkFlowStep.到下相机拍照结束位:
|
|
|
if (XYCanMove() || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "到下相机拍照结束位";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
IoManager.Instance.WriteOut("下左相机光源触发", 1);
|
|
|
Thread.Sleep(50);
|
|
|
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload)[0].ToType == TurnoverType.Turnover)
|
|
|
{
|
|
|
errCode = AxisControl.LoadX.MovePos(SysConfigParam.GetValue<double>($"Nozzle1CenterX") + 10, GlobalVar.FlyCameraSpeed);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
errCode = AxisControl.LoadX.MovePos(SysConfigParam.GetValue<double>($"Nozzle{needGrabNum}CenterX") - 10, GlobalVar.FlyCameraSpeed);
|
|
|
}
|
|
|
if(errCode== ErrorCode.Ok)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.等待到下相机拍照结束位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//TestCenterMessageBox.Show(1,$"轴LoadX运动异常,ret={errCode}", ETipButton.Ok);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case EWorkFlowStep.等待到下相机拍照结束位:
|
|
|
if (Ops.IsStop("LoadX") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "已运动到下相机拍照结束位";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
if(!GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
AxisControl.LoadX.ClearCompare(1);
|
|
|
}
|
|
|
IoManager.Instance.WriteOut("下左相机光源触发", 0);
|
|
|
flowStep = EWorkFlowStep.等待相机拍照完成;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待相机拍照完成:
|
|
|
imgs = ImageProcess.GetAutoImage();
|
|
|
if ((imgs != null && imgs.Length == needGrabNum)|| GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "相机拍照完成,准备处理照片";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload)[0].ToType == TurnoverType.Turnover)
|
|
|
{
|
|
|
imgs = imgs.Reverse().ToArray();
|
|
|
}
|
|
|
if (GlobalVar.RunSpace)
|
|
|
{
|
|
|
foreach(Nozzle nl in NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload))
|
|
|
{
|
|
|
if(string.IsNullOrEmpty(nl.SN))
|
|
|
{
|
|
|
nl.SN = (nl.FromIndex + 1).ToString().PadLeft(18, '0');
|
|
|
}
|
|
|
}
|
|
|
mrs = new List<MatchResult>();
|
|
|
for(int i=0;i<needGrabNum;i++)
|
|
|
{
|
|
|
mrs.Add(new MatchResult());
|
|
|
}
|
|
|
flowStep = EWorkFlowStep.到放料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//拍照完成
|
|
|
flowStep = EWorkFlowStep.等待视觉处理结果;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待视觉处理结果:
|
|
|
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 = "图片处理完成,准备放料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
int count = 0;
|
|
|
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 = EWorkFlowStep.到放料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
int ni = 1;
|
|
|
List<int> errCodeList = new List<int>();
|
|
|
foreach (MatchResult item in mrs)
|
|
|
{
|
|
|
if(item.IsOK)
|
|
|
{
|
|
|
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 = EWorkFlowStep.到下相机拍照起始位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
reGrabCount = 0;
|
|
|
alarmInfo = $"【{string.Join(",", errCodeList)}】号排料吸嘴拍照失败";
|
|
|
//DialogResult dr = Msg.ShowQuestion(, System.Windows.Forms.MessageBoxButtons.RetryCancel);
|
|
|
TestCenterMessageBox.Show(AlarmConstID.DownCameraFlyFailAlarm, alarmInfo, ETipButton.Retry | ETipButton.Cancel);
|
|
|
SchedulingMessageBox box = TestCenterMessageBox.WaitResult(AlarmConstID.DownCameraFlyFailAlarm);
|
|
|
if (box.Button== ETipButton.Cancel)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到放料位上方;
|
|
|
}
|
|
|
else if (box.Button == ETipButton.Retry)
|
|
|
{
|
|
|
Thread.Sleep(1000);
|
|
|
flowStep = EWorkFlowStep.到下相机拍照起始位;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.到放料位上方:
|
|
|
if (XYCanMove() || 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 = $"【{curNozzle.NozzleIndex}】号排料吸嘴到周转盘{curNozzle.ToIndex + 1}号穴位上方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Turnover", curNozzle.ToIndex + 1, EPointType.RUN);
|
|
|
turnoverOffsetPoint = TurnoverSlotOffset.GetOffsetPoint(curNozzle.ToIndex + 1);
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.ToBeTested)
|
|
|
{
|
|
|
downSlot = GlobalTray.InputTray.GetSlot(ESlotStatus.NotHave);
|
|
|
if (downSlot != null)
|
|
|
{
|
|
|
curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Input", downSlot.Index, EPointType.BASE);
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴到input盘{downSlot.Index}号穴位上方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.Passed)
|
|
|
{
|
|
|
downSlot = GlobalTray.OkTary.GetSlot(ESlotStatus.NotHave);
|
|
|
if (downSlot != null)
|
|
|
{
|
|
|
curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "OK", downSlot.Index, EPointType.RUN);
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴到OK盘{downSlot.Index}号穴位上方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
TakeTrayFlow.Instance.Take(EStockType.Empty2, EStockType.Ok);
|
|
|
StockManager.Instance.UnLoad(EStockType.Ok);
|
|
|
restoreFlowStep = EWorkFlowStep.到放料位上方;
|
|
|
flowStep = EWorkFlowStep.等待Ok料盘搬运完成;
|
|
|
}
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.Failed)
|
|
|
{
|
|
|
downSlot = GlobalTray.NgTray.GetSlot(ESlotStatus.NotHave);
|
|
|
if (downSlot != null)
|
|
|
{
|
|
|
curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "NG", downSlot.Index, EPointType.RUN);
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴到NG盘{downSlot.Index}号穴位上方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
TakeTrayFlow.Instance.Take(EStockType.Empty2, EStockType.Ng);
|
|
|
StockManager.Instance.UnLoad(EStockType.Ng);
|
|
|
restoreFlowStep = EWorkFlowStep.到放料位上方;
|
|
|
flowStep = EWorkFlowStep.等待Ng料盘搬运完成;
|
|
|
}
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.Multifunction)
|
|
|
{
|
|
|
downSlot = GlobalTray.MultiTray.GetSlot(ESlotStatus.NotHave);
|
|
|
if (downSlot != null)
|
|
|
{
|
|
|
curSlotPoint = TrayPointManager.GetSlotPoint(GlobalVar.CurRecipe, "Multi", downSlot.Index, EPointType.RUN);
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴到Multi盘{downSlot.Index}号穴位上方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
TakeTrayFlow.Instance.Take(EStockType.Empty2, EStockType.Multi);
|
|
|
StockManager.Instance.UnLoad(EStockType.Multi);
|
|
|
restoreFlowStep = EWorkFlowStep.到放料位上方;
|
|
|
flowStep = EWorkFlowStep.等待Multi料盘搬运完成;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (curSlotPoint!=null)
|
|
|
{
|
|
|
nozzleDist = TrayPointManager.GetDistToNozzle1(curNozzle.NozzleIndex);
|
|
|
if(mrs[curNozzle.NozzleIndex - 1].OffsetRow <5 && mrs[curNozzle.NozzleIndex - 1].OffsetCol<5)
|
|
|
{
|
|
|
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;
|
|
|
}
|
|
|
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 = EWorkFlowStep.等待到放料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm($"NozzleR{curNozzle.NozzleIndex}", errCode);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm("LoadY", errCode);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm("LoadX", errCode);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
alarmInfo = "x y r move isn't safe";
|
|
|
MessageQueue.Instance.Warn(alarmInfo);
|
|
|
TestCenterMessageBox.Show(AlarmConstID.MoveUnsafeAlarm, alarmInfo, ETipButton.Ok);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待到放料位上方:
|
|
|
if (Ops.IsStop("LoadX", "LoadY",$"NozzleR{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴已运动到放料位上方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.到放料位下方;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.到放料位下方:
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴到放料位下方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
if (curNozzle.ToType == TurnoverType.Turnover)
|
|
|
{
|
|
|
targetPos = SysConfigParam.GetValue<double>($"TurnoverNozzle{curNozzle.NozzleIndex}TakeHeight");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
targetPos = SysConfigParam.GetValue<double>($"TrayNozzle{curNozzle.NozzleIndex}TakeHeight") + 1;
|
|
|
}
|
|
|
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(targetPos, GlobalVar.WholeSpeed);
|
|
|
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
VirtualAxisSleep();
|
|
|
flowStep = EWorkFlowStep.等待到放料位下方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm($"NozzleZ{curNozzle.NozzleIndex}", errCode);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待到放料位下方:
|
|
|
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = $"【{curNozzle.NozzleIndex}】号排料吸嘴已运动到放料位下方";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
if (curNozzle.ToType== TurnoverType.Turnover)
|
|
|
{
|
|
|
/*打开周转盘真空吸*/
|
|
|
MessageQueue.Instance.Insert($"打开周转盘{curNozzle.ToIndex + 1}号穴位真空吸");
|
|
|
Ops.On($"周转盘{curNozzle.ToIndex + 1}号穴位真空吸");
|
|
|
Thread.Sleep(GlobalVar.TurnoverTrayOpenVacSuctionDelaytime);
|
|
|
/*关闭排料吸嘴真空吸*/
|
|
|
MessageQueue.Instance.Insert($"关闭{curNozzle.NozzleIndex}号排料吸嘴真空吸");
|
|
|
Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空吸电磁阀");//关闭真空
|
|
|
Thread.Sleep(GlobalVar.LoadNozzleCloseVacSuctionDelaytime);
|
|
|
/*打开排料吸嘴真空破*/
|
|
|
MessageQueue.Instance.Insert($"打开{curNozzle.NozzleIndex}号排料吸嘴真空破");
|
|
|
Ops.On($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
|
|
|
Thread.Sleep(GlobalVar.LoadNozzleOpenVacBreakDelaytime);
|
|
|
flowStep = EWorkFlowStep.到放料关破真空位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/*关闭排料吸嘴真空吸*/
|
|
|
MessageQueue.Instance.Insert($"关闭{curNozzle.NozzleIndex}号排料吸嘴真空吸");
|
|
|
Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空吸电磁阀");
|
|
|
Thread.Sleep(GlobalVar.LoadNozzleCloseVacSuctionDelaytime);
|
|
|
/*关闭排料吸嘴真空吸*/
|
|
|
MessageQueue.Instance.Insert($"打开{curNozzle.NozzleIndex}号排料吸嘴真空破");
|
|
|
Ops.On($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
|
|
|
Thread.Sleep(GlobalVar.LoadNozzleOpenVacBreakDelaytime);
|
|
|
/*关闭排料吸嘴真空吸*/
|
|
|
MessageQueue.Instance.Insert($"关闭{curNozzle.NozzleIndex}号排料吸嘴真空破");
|
|
|
Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
|
|
|
Thread.Sleep(GlobalVar.LoadNozzleCloseVacBreakDelaytime);
|
|
|
flowStep = EWorkFlowStep.放料完成抬起;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.到放料关破真空位:
|
|
|
targetPos = SysConfigParam.GetValue<double>($"TurnoverNozzle{curNozzle.NozzleIndex}TakeHeight");
|
|
|
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(targetPos + 1, GlobalVar.WholeSpeed);
|
|
|
if (errCode == ErrorCode.Ok)
|
|
|
{
|
|
|
MessageQueue.Instance.Insert($"{curNozzle.NozzleIndex}号排料吸嘴周转盘放料完成,准备微微抬起");
|
|
|
flowStep = EWorkFlowStep.等待到放料关破真空位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm($"NozzleZ{curNozzle.NozzleIndex}", errCode);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待到放料关破真空位:
|
|
|
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}"))
|
|
|
{
|
|
|
/*关闭排料吸嘴真空破*/
|
|
|
Ops.Off($"{curNozzle.NozzleIndex}号吸嘴真空破电磁阀");
|
|
|
Thread.Sleep(GlobalVar.LoadNozzleCloseVacBreakDelaytime);
|
|
|
MessageQueue.Instance.Insert($"{curNozzle.NozzleIndex}号排料吸嘴微微抬起后关闭破真空");
|
|
|
flowStep = EWorkFlowStep.放料完成抬起;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.放料完成抬起:
|
|
|
errCode = AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").MovePos(0, GlobalVar.WholeSpeed);
|
|
|
if (errCode == ErrorCode.Ok || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
if (GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
|
|
|
}
|
|
|
logInfo = $"{curNozzle.NozzleIndex}号排料吸嘴放料完成抬起";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.等待放料完成抬起;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm($"NozzleZ{curNozzle.NozzleIndex}", errCode);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待放料完成抬起:
|
|
|
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = $"{curNozzle.NozzleIndex}号排料吸嘴放料完成已起位,准备真空检测";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.放料真空检测;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.放料真空检测:
|
|
|
if (curNozzle.ToType == TurnoverType.Turnover)
|
|
|
{
|
|
|
if (Ops.IsOn($"周转盘{curNozzle.ToIndex + 1}号穴位真空吸检测") || GlobalVar.RunSpace)
|
|
|
{
|
|
|
logInfo = $"周转盘{curNozzle.ToIndex + 1}号穴位真空吸检测OK";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.放料任务完成;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
logInfo = $"周转盘{curNozzle.ToIndex + 1}号穴位真空吸异常";
|
|
|
MessageQueue.Instance.Warn(logInfo);
|
|
|
//DialogResult dr = Msg.ShowError($"周转盘{curNozzle.ToIndex + 1}号穴位真空吸异常,点击确定后跳过");
|
|
|
alarmInfo = $"周转盘{curNozzle.ToIndex + 1}号穴位真空吸异常";
|
|
|
TestCenterMessageBox.Show(AlarmConstID.TurnoverDumpFailAlarm, alarmInfo, ETipButton.Ok);
|
|
|
SchedulingMessageBox box = TestCenterMessageBox.WaitResult(AlarmConstID.TurnoverDumpFailAlarm);
|
|
|
if (box.Button== ETipButton.Ok)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.放料任务完成;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.放料任务完成;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.放料任务完成:
|
|
|
logInfo = "放料任务完成";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
//AxisControl.GetAxis($"NozzleZ{curNozzle.NozzleIndex}").Home();
|
|
|
//MessageQueue.Instance.Insert($"{curNozzle.NozzleIndex}号排料吸嘴回原");
|
|
|
//Ops.HomeAndGoStartPos($"NozzleR{NozzleIndex}");
|
|
|
if (curNozzle.ToType == TurnoverType.Turnover)
|
|
|
{
|
|
|
GlobalTray.TurnoverTray.ChangeStatus(curNozzle.ToIndex + 1, ESlotStatus.Have);
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.ToBeTested)
|
|
|
{
|
|
|
curNozzle.ToIndex = downSlot.Index-1;
|
|
|
curNozzle.ToFloor = StockManager.Instance.GetTray(EStockType.Input).GetFloor();
|
|
|
GlobalTray.InputTray.ChangeStatus(downSlot.Index, ESlotStatus.Have);
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.Passed)
|
|
|
{
|
|
|
curNozzle.ToIndex = downSlot.Index-1;
|
|
|
curNozzle.ToFloor = StockManager.Instance.GetTray(EStockType.Ok).GetFloor();
|
|
|
GlobalTray.OkTary.ChangeStatus(downSlot.Index, ESlotStatus.Have);
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.Failed)
|
|
|
{
|
|
|
curNozzle.ToIndex = downSlot.Index-1;
|
|
|
curNozzle.ToFloor = StockManager.Instance.GetTray(EStockType.Ng).GetFloor();
|
|
|
GlobalTray.NgTray.ChangeStatus(downSlot.Index, ESlotStatus.Have);
|
|
|
}
|
|
|
else if (curNozzle.ToType == TurnoverType.Multifunction)
|
|
|
{
|
|
|
curNozzle.ToIndex = downSlot.Index-1;
|
|
|
curNozzle.ToFloor = StockManager.Instance.GetTray(EStockType.Multi).GetFloor();
|
|
|
GlobalTray.MultiTray.ChangeStatus(downSlot.Index, ESlotStatus.Have);
|
|
|
}
|
|
|
curNozzle.Reset();
|
|
|
LoadAndUnloadTask.Instance.AddTurnoverResult(curNozzle);
|
|
|
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count > 0)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到放料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (LoadAndUnloadTask.Instance.GetUnDealedTask().Count > 0)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.到取料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.任务结束到安全位;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case EWorkFlowStep.任务结束到安全位:
|
|
|
|
|
|
errCode = AxisControl.LoadX.MovePos(SysConfigParam.GetValue<double>("LoadXStartPos"), GlobalVar.WholeSpeed);
|
|
|
if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
AxisControl.GetAxis($"NozzleZ1").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ2").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ3").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ4").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ5").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ6").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ7").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ8").Home();
|
|
|
AxisControl.GetAxis($"NozzleZ9").Home();
|
|
|
errCode = AxisControl.LoadY.MovePos(SysConfigParam.GetValue<double>("LoadYStartPos"), GlobalVar.WholeSpeed);
|
|
|
if(errCode== ErrorCode.Ok || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
if (GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
|
|
|
}
|
|
|
logInfo = "排料任务结束到安全位";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.等待任务结束到安全位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm(AxisAlias.LoadY, errCode);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MoveFailAlarm(AxisAlias.LoadX, errCode);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待任务结束到安全位:
|
|
|
if(Ops.IsStop("LoadX", "LoadY") || GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
logInfo = "任务结束已回到安全位";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
if (TestCenter.Instance.LoadResult())
|
|
|
{
|
|
|
logInfo = "通知中控任务完成";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
LoadAndUnloadTask.Instance.Clear();
|
|
|
logInfo = "任务完成,清除任务";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
MachineManage.Instance.SetLoadUnloadStatus(ERunState.Waiting);
|
|
|
flowStep = EWorkFlowStep.等待任务;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.测试工位上料:
|
|
|
testLoadList = LoadAndUnloadTask.Instance.GetTestLoadTasks();
|
|
|
TurnoverFlow.Instance.PressLoad(testLoadList);
|
|
|
flowStep = EWorkFlowStep.等待测试工位上料完成;
|
|
|
break;
|
|
|
case EWorkFlowStep.等待测试工位上料完成:
|
|
|
if (TurnoverFlow.Instance.LoadFinished())
|
|
|
{
|
|
|
TestCenter.Instance.LoadTestLoadResult();
|
|
|
//切换穴位状态
|
|
|
foreach (TurnoverInfo turnoverInfo in testLoadList)
|
|
|
{
|
|
|
GlobalTray.TurnoverTray.ChangeStatus(turnoverInfo.FromIndex+1, ESlotStatus.NotHave);
|
|
|
}
|
|
|
LoadAndUnloadTask.Instance.Clear();
|
|
|
MachineManage.Instance.SetLoadUnloadStatus(ERunState.Waiting);
|
|
|
|
|
|
//for (int i = 1; i < 9; i++)
|
|
|
//{
|
|
|
// GlobalTray.TurnoverTray.ChangeStatus(i, ESlotStatus.NotHave);
|
|
|
//}
|
|
|
//for (int i = 17; i < 25; i++)
|
|
|
//{
|
|
|
// GlobalTray.TurnoverTray.ChangeStatus(i, ESlotStatus.NotHave);
|
|
|
//}
|
|
|
flowStep = EWorkFlowStep.等待任务;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.测试工位下料:
|
|
|
testUnLoadList = LoadAndUnloadTask.Instance.GetTestUnLoadTasks();
|
|
|
TurnoverFlow.Instance.PressUnload(testUnLoadList);
|
|
|
flowStep = EWorkFlowStep.等待测试工位下料完成;
|
|
|
break;
|
|
|
case EWorkFlowStep.等待测试工位下料完成:
|
|
|
if (TurnoverFlow.Instance.UnloadFinished())
|
|
|
{
|
|
|
//logInfo = string.Join(",",testUnLoadList.Select(t=>t.ToIndex).ToList());
|
|
|
TestCenter.Instance.LoadTestUnLoadResult();
|
|
|
//切换穴位状态
|
|
|
foreach (TurnoverInfo turnoverInfo in testUnLoadList)
|
|
|
{
|
|
|
GlobalTray.TurnoverTray.ChangeStatus(turnoverInfo.ToIndex+1, ESlotStatus.Have);
|
|
|
}
|
|
|
LoadAndUnloadTask.Instance.Clear();
|
|
|
|
|
|
//for (int i = 9; i < 17; i++)
|
|
|
//{
|
|
|
// GlobalTray.TurnoverTray.ChangeStatus(i, ESlotStatus.Have);
|
|
|
//}
|
|
|
//for (int i = 25; i < 33; i++)
|
|
|
//{
|
|
|
// GlobalTray.TurnoverTray.ChangeStatus(i, ESlotStatus.Have);
|
|
|
//}
|
|
|
MachineManage.Instance.SetLoadUnloadStatus(ERunState.Waiting);
|
|
|
flowStep = EWorkFlowStep.等待任务;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Input料盘搬运完成:
|
|
|
if(TakeTrayFlow.Instance.TakeStatus== ETakeStatus.TakeOK)
|
|
|
{
|
|
|
StockManager.Instance.UnLoad(EStockType.Empty1);
|
|
|
StockManager.Instance.Load(EStockType.Input);
|
|
|
flowStep = EWorkFlowStep.等待Input料仓上料完成;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Input料仓上料完成:
|
|
|
if(StockManager.Instance.GetStockStatus(EStockType.Input)== ETrayStatus.Loaded)
|
|
|
{
|
|
|
flowStep = restoreFlowStep;
|
|
|
restoreFlowStep = EWorkFlowStep.IDLE;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Ok料仓收料完成:
|
|
|
if(StockManager.Instance.GetStockStatus( EStockType.Ok)== ETrayStatus.Unloaded)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.等待Ok料盘搬运完成;
|
|
|
TakeTrayFlow.Instance.Take(EStockType.Empty2, EStockType.Ok);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Ok料盘搬运完成:
|
|
|
if(TakeTrayFlow.Instance.TakeStatus== ETakeStatus.TakeOK && StockManager.Instance.GetStockStatus( EStockType.Ok)== ETrayStatus.Loaded)
|
|
|
{
|
|
|
flowStep = restoreFlowStep;
|
|
|
restoreFlowStep = EWorkFlowStep.IDLE;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Ng料仓收料完成:
|
|
|
if (StockManager.Instance.GetStockStatus(EStockType.Ng) == ETrayStatus.Unloaded)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.等待Ng料盘搬运完成;
|
|
|
TakeTrayFlow.Instance.Take(EStockType.Empty2, EStockType.Ng);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Ng料盘搬运完成:
|
|
|
if (TakeTrayFlow.Instance.TakeStatus == ETakeStatus.TakeOK && StockManager.Instance.GetStockStatus(EStockType.Ng) == ETrayStatus.Loaded)
|
|
|
{
|
|
|
flowStep = restoreFlowStep;
|
|
|
restoreFlowStep = EWorkFlowStep.IDLE;
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Multi料仓收料完成:
|
|
|
if (StockManager.Instance.GetStockStatus(EStockType.Multi) == ETrayStatus.Unloaded)
|
|
|
{
|
|
|
flowStep = EWorkFlowStep.等待Multi料盘搬运完成;
|
|
|
TakeTrayFlow.Instance.Take(EStockType.Empty2, EStockType.Multi);
|
|
|
}
|
|
|
break;
|
|
|
case EWorkFlowStep.等待Multi料盘搬运完成:
|
|
|
if (TakeTrayFlow.Instance.TakeStatus == ETakeStatus.TakeOK && StockManager.Instance.GetStockStatus(EStockType.Multi) == ETrayStatus.Loaded)
|
|
|
{
|
|
|
flowStep = restoreFlowStep;
|
|
|
restoreFlowStep = EWorkFlowStep.IDLE;
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 取料完成后更新吸嘴状态
|
|
|
/// </summary>
|
|
|
private void TakeFinishedUpdateNozzleStatus(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)
|
|
|
{
|
|
|
nozzle.FromFloor = turnoverInfo.FromFloor;
|
|
|
nozzle.SN = turnoverInfo.SN;
|
|
|
nozzle.FromIndex = turnoverInfo.FromIndex;
|
|
|
GlobalTray.TurnoverTray.ChangeStatus(turnoverInfo.FromIndex + 1, ESlotStatus.NotHave);
|
|
|
}
|
|
|
else if (turnoverInfo.FromType == TurnoverType.ToBeTested)
|
|
|
{
|
|
|
nozzle.FromFloor = StockManager.Instance.GetTray(EStockType.Input).GetFloor();
|
|
|
nozzle.SN = "";
|
|
|
nozzle.FromIndex = GlobalTray.InputTray.GetSlot(ESlotStatus.Have).Index - 1;
|
|
|
GlobalTray.InputTray.ChangeStatus(GlobalTray.InputTray.GetSlot(ESlotStatus.Have).Index, ESlotStatus.NotHave);
|
|
|
}
|
|
|
nozzle.Update();
|
|
|
turnoverInfo.Dealed = true;
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 等待任务
|
|
|
/// </summary>
|
|
|
private void WaitTask()
|
|
|
{
|
|
|
if (LoadAndUnloadTask.Instance.Count > 0 && WorkEnvironment.Instance.EnvironmentOk)
|
|
|
{
|
|
|
if (LoadAndUnloadTask.Instance.CanRunTask())
|
|
|
{
|
|
|
if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.TestLoad) > 0)
|
|
|
{
|
|
|
logInfo = $"接收到测试工位上料任务";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.测试工位上料;
|
|
|
}
|
|
|
else if (LoadAndUnloadTask.Instance.GetTaskNum(ETaskMode.TestUnload) > 0)
|
|
|
{
|
|
|
logInfo = $"接收到测试工位下料任务";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.测试工位下料;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
turnoverToTray = true;
|
|
|
logInfo = $"接收到排料任务";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EWorkFlowStep.到取料位上方;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取拍照点位
|
|
|
/// </summary>
|
|
|
private void GetGrabPoints()
|
|
|
{
|
|
|
|
|
|
}
|
|
|
private double GetVacOffsetHeight(int fetchNum)
|
|
|
{
|
|
|
switch (fetchNum)
|
|
|
{
|
|
|
case 0:
|
|
|
return 0;
|
|
|
case 1:
|
|
|
return -0.1;
|
|
|
case 2:
|
|
|
return -0.2;
|
|
|
case 3:
|
|
|
return -0.3;
|
|
|
case 4:
|
|
|
return 0.1;
|
|
|
case 5:
|
|
|
return 0.2;
|
|
|
case 6:
|
|
|
return 0.3;
|
|
|
default:
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
/// <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;
|
|
|
}
|
|
|
private bool XYCanMove()
|
|
|
{
|
|
|
if (!CanGoTurnoverTray())
|
|
|
return false;
|
|
|
//AxisControl.VacZ1.GetOrgStatus(out bool bOrgZ1);
|
|
|
//AxisControl.VacZ2.GetOrgStatus(out bool bOrgZ2);
|
|
|
//if (AxisControl.LoadX.HomeStatus == EHomeStatus.Finished
|
|
|
// && AxisControl.LoadY.HomeStatus == EHomeStatus.Finished
|
|
|
// && bOrgZ1 && bOrgZ2)
|
|
|
//{
|
|
|
// return true;
|
|
|
//}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private void MoveFailAlarm(string axisname,ErrorCode _errCode)
|
|
|
{
|
|
|
//string alarmStr = $"轴{axisname}运动异常,ret={_errCode}";
|
|
|
//TestCenterMessageBox.Show(AlarmConstID.MoveFailAlarm, alarmStr, ETipButton.Ok);
|
|
|
//SchedulingMessageBox box = TestCenterMessageBox.WaitResult(AlarmConstID.MoveFailAlarm);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 如果是虚拟轴,则模拟等待一下
|
|
|
/// </summary>
|
|
|
private void VirtualAxisSleep()
|
|
|
{
|
|
|
if (GlobalVar.VirtualAxis)
|
|
|
{
|
|
|
Thread.Sleep(GlobalVar.VirtualAxisMoveTime);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|