|
|
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.Common;
|
|
|
using Rs.MotionPlat.Flow.NormalFlow;
|
|
|
using Rs.MotionPlat.Flow.SafePosFlow;
|
|
|
using Rs.MotionPlat.Flow.SubFlow;
|
|
|
using Rs.MotionPlat.Vision;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Diagnostics;
|
|
|
using System.Diagnostics.Eventing.Reader;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Net.Http;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
using System.Text;
|
|
|
using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
namespace Rs.MotionPlat.Flow
|
|
|
{
|
|
|
public enum EDischargeFlowStep
|
|
|
{
|
|
|
//开始排料前准备
|
|
|
等待启动,
|
|
|
工作前准备,
|
|
|
//料仓取料
|
|
|
判断是否需要从料仓取料,
|
|
|
进料盘产品定位,
|
|
|
料仓取料,
|
|
|
//治具换料
|
|
|
到治具取料等待位,
|
|
|
等待到治具取料等待位,
|
|
|
等待治具测试完成换料,
|
|
|
治具取料,
|
|
|
治具放料,
|
|
|
//料仓放料
|
|
|
判断是否需要放料到料仓,
|
|
|
料仓放料,
|
|
|
//工作完成到安全位,
|
|
|
//等待工作完成到安全位,
|
|
|
工作完成收料,
|
|
|
等待收料完成
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 排料流程
|
|
|
/// </summary>
|
|
|
public class DischargeFlow
|
|
|
{
|
|
|
private Task mainTask;
|
|
|
private DischargeFlow() { }
|
|
|
|
|
|
private static DischargeFlow instance;
|
|
|
public static DischargeFlow Instance
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if (instance == null)
|
|
|
{
|
|
|
instance = new DischargeFlow();
|
|
|
}
|
|
|
return instance;
|
|
|
}
|
|
|
}
|
|
|
public event Action workFinishedEvent;
|
|
|
private AlarmEntity alarmEntity;
|
|
|
Stopwatch timeout = new Stopwatch();
|
|
|
EDischargeFlowStep flowStep = EDischargeFlowStep.等待启动;
|
|
|
public event Action CleanDataEvent;
|
|
|
|
|
|
int scanNum = 0;
|
|
|
string logInfo = string.Empty;
|
|
|
string alarmInfo = string.Empty;
|
|
|
|
|
|
private bool stop = true;
|
|
|
private bool run = true;
|
|
|
TargetPosition targetPosition = new TargetPosition();
|
|
|
ErrorCode errCode = ErrorCode.Ok;
|
|
|
TraySlot slot = null;
|
|
|
Nozzle curNozzle = null;
|
|
|
TestFixture curFixture = null;
|
|
|
//放料穴位
|
|
|
TraySlot curDumpSlot = null;
|
|
|
/// <summary>
|
|
|
/// 拍照的起始穴位
|
|
|
/// </summary>
|
|
|
TraySlot grabStartSlot = null;
|
|
|
/// <summary>
|
|
|
/// 拍照的结束穴位
|
|
|
/// </summary>
|
|
|
TraySlot grabEndSlot = null;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将要取料的穴位
|
|
|
/// </summary>
|
|
|
TraySlot waitTakeProductSlot = null;
|
|
|
|
|
|
Nozzle needPlaceNozzle = null;
|
|
|
/// <summary>
|
|
|
/// 取料学位索引
|
|
|
/// </summary>
|
|
|
int takeSlotIndex = 1;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 一拍十六定位结果
|
|
|
/// </summary>
|
|
|
ProductLocationResult[] productLocationResult;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 最后一次换料的治具编号
|
|
|
/// </summary>
|
|
|
//private int lastFixtureIndex = 0;
|
|
|
List<int> checkFixtureList = new List<int>();
|
|
|
/// <summary>
|
|
|
/// 从料仓到治具
|
|
|
/// </summary>
|
|
|
string acrossAnthorSide = "";
|
|
|
public void Init()
|
|
|
{
|
|
|
mainTask = new Task(Run);
|
|
|
mainTask.Start();
|
|
|
}
|
|
|
|
|
|
public void Deinit()
|
|
|
{
|
|
|
run = false;
|
|
|
}
|
|
|
private void Run()
|
|
|
{
|
|
|
while (run)
|
|
|
{
|
|
|
if (stop)
|
|
|
{
|
|
|
Thread.Sleep(10);
|
|
|
continue;
|
|
|
}
|
|
|
switch (flowStep)
|
|
|
{
|
|
|
case EDischargeFlowStep.等待启动:
|
|
|
{
|
|
|
//EButtonType button = Msgbox.ShowDialog(EButtonType.Ok | EButtonType.Cancel, "清除 NG料盘 数据 确定清除 选择OK 保留 选择否Cancel");
|
|
|
//if(button== EButtonType.Ok)
|
|
|
//{
|
|
|
// GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
//}
|
|
|
//button = Msgbox.ShowDialog(EButtonType.Ok | EButtonType.Cancel, "清除 OK料盘 数据 确定清除 选择OK 保留 选择否Cancel");
|
|
|
//if (button == EButtonType.Ok)
|
|
|
//{
|
|
|
// GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
//}
|
|
|
//EButtonType button = Msgbox.ShowDialog(EButtonType.Ok | EButtonType.Cancel, "请确认 LOT 信息 信息正确 选择OK 信息错误退出重写 选择Cancel");
|
|
|
List<TestFixture> enableList = TestFixtureManager.Instance.GetEnableFixtureList();
|
|
|
if(enableList!=null && enableList.Count>0)
|
|
|
{
|
|
|
LogHelper.Debug($"启用治具:{string.Join(",",enableList.Select(f=>f.Index))}");
|
|
|
EButtonType button = Msgbox.ShowTipDialog(EButtonType.Ok | EButtonType.Cancel, $"请确认LotName是否正确?\r\nCheck whether LotName is correct?");
|
|
|
if (button == EButtonType.Ok)
|
|
|
{
|
|
|
button = Msgbox.ShowTipDialog(EButtonType.Ok | EButtonType.Cancel, $"请确认MTCP版本并且是否已经被LOT END?\r\nPlease confirm the MTCP version and whether it has been LOT END?");
|
|
|
if (button == EButtonType.Ok)
|
|
|
{
|
|
|
button = Msgbox.ShowTipDialog(EButtonType.Ok | EButtonType.Cancel, $"请确认是否已选择正确的T0文件?\r\nCheck whether the correct T0 file is selected?");
|
|
|
if (button == EButtonType.Ok)
|
|
|
{
|
|
|
CreateCheckFixtureQueue(6);
|
|
|
List<TestFixture> enableFixtureList = TestFixtureManager.Instance.GetEnableFixtureList();
|
|
|
if (enableFixtureList.Count > 0)
|
|
|
{
|
|
|
int i = 0;
|
|
|
foreach (var fix in enableFixtureList)
|
|
|
{
|
|
|
if (i == 0)
|
|
|
fix.IsFirstFixture = true;
|
|
|
else
|
|
|
fix.IsFirstFixture = false;
|
|
|
i++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
button = Msgbox.ShowTipDialog(EButtonType.Ok | EButtonType.Cancel, "Are you sure you want to clear the data ?\r\n clear click OK\r\n not clear click Cancel");
|
|
|
if (button == EButtonType.Ok)
|
|
|
{
|
|
|
logInfo = GetClassName() + "选择了OK";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
CleanDataEvent?.Invoke();
|
|
|
//lastFixtureIndex = TestFixtureManager.Instance.GetEnableFixtureList().Select(f => f.Index).Min() - 1;
|
|
|
|
|
|
//lastFixtureIndex = checkFixtureList[0] - 1;
|
|
|
//TestFixtureManager.Instance.GetTestFixture(1).ClearData();
|
|
|
//TestFixtureManager.Instance.GetTestFixture(2).ClearData();
|
|
|
//TestFixtureManager.Instance.GetTestFixture(3).ClearData();
|
|
|
//TestFixtureManager.Instance.GetTestFixture(4).ClearData();
|
|
|
//TestFixtureManager.Instance.GetTestFixture(5).ClearData();
|
|
|
//TestFixtureManager.Instance.GetTestFixture(6).ClearData();
|
|
|
TestFixtureManager.Instance.ClearDataAll();
|
|
|
GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
GlobalTray.RetestTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
GlobalTray.OkTary.ChangeStatus(ESlotStatus.NotHave);
|
|
|
if (GlobalVar.RunSpace && !GlobalVar.EnableStock)
|
|
|
{
|
|
|
GlobalTray.InputTray.ChangeStatus(ESlotStatus.Have);
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
StockManager.ClampAfterReleaseAll();
|
|
|
flowStep = EDischargeFlowStep.工作前准备;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (button == EButtonType.Cancel)
|
|
|
{
|
|
|
logInfo = GetClassName() + "选择了Cancel";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
StockManager.ClampAfterReleaseAll();
|
|
|
flowStep = EDischargeFlowStep.工作前准备;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Ops.Stop();
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Ops.Stop();
|
|
|
}
|
|
|
}
|
|
|
else if (button == EButtonType.Cancel)
|
|
|
{
|
|
|
Ops.Stop();
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, $"请先启用治具再启动\r\nEnable TC first please");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
break;
|
|
|
#region 临时屏蔽
|
|
|
case EDischargeFlowStep.工作前准备:
|
|
|
if(!GlobalVar.RunSpace)
|
|
|
{
|
|
|
//lot start
|
|
|
DevLog.EventTracker("Start", 0, "", "Start");
|
|
|
EnvironmentPrepareFlow.Instance.Prepare();
|
|
|
}
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
break;
|
|
|
#endregion
|
|
|
|
|
|
#region 料仓取料
|
|
|
//料仓取料
|
|
|
case EDischargeFlowStep.判断是否需要从料仓取料:
|
|
|
//检测吸嘴有几个产品,少于3个产品则需要从料仓上料
|
|
|
int idelNozzleNum = NozzleManager.GetIdleNozzleCount();
|
|
|
if (idelNozzleNum == 1 || GlobalVar.Clear)
|
|
|
{
|
|
|
if(TestFixtureManager.Instance.GetHasProuctFixtureCount()>0 || NozzleManager.GetToTestNozzle()!=null)
|
|
|
{
|
|
|
logInfo = GetClassName() + $"空闲吸嘴的数量为{idelNozzleNum},没有空闲的吸嘴了,去治具换料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
flowStep = EDischargeFlowStep.到治具取料等待位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
flowStep = EDischargeFlowStep.工作完成收料;
|
|
|
}
|
|
|
|
|
|
//flowStep = EDischargeFlowStep.判断是否需要放料到料仓;
|
|
|
|
|
|
//NozzleManager.GetNozzle(1).VacSuction(EIoOperate.Close);
|
|
|
//NozzleManager.GetNozzle(2).VacSuction(EIoOperate.Close);
|
|
|
//NozzleManager.GetNozzle(3).VacSuction(EIoOperate.Close);
|
|
|
|
|
|
//NozzleManager.GetNozzle(1).Status = ENozzleStatus.IDLE;
|
|
|
//NozzleManager.GetNozzle(2).Status = ENozzleStatus.IDLE;
|
|
|
//NozzleManager.GetNozzle(3).Status = ENozzleStatus.IDLE;
|
|
|
|
|
|
//GlobalTray.NozzleTray.ChangeStatus(1, ESlotStatus.NotHave);
|
|
|
//GlobalTray.NozzleTray.ChangeStatus(2, ESlotStatus.NotHave);
|
|
|
//GlobalTray.NozzleTray.ChangeStatus(3, ESlotStatus.NotHave);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
logInfo = GetClassName() + $"空闲吸嘴的数量为{idelNozzleNum},继续取料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
//GlobalTray.InputTray.ChangeStatus(ESlotStatus.Have);
|
|
|
//检测料仓的拍照结果,如果还有未取的料则先取料,否则需要先拍照
|
|
|
//获取有料的穴位
|
|
|
//GlobalTray.InputTray.ChangeStatus(ESlotStatus.Have);
|
|
|
//TraySlot waitTakeProductSlot = GlobalTray.InputTray.GetSlot(ESlotStatus.Have);
|
|
|
TraySlot waitTakeProductSlot = GlobalTray.InputTray.GetSlot(takeSlotIndex);
|
|
|
if (waitTakeProductSlot!=null)
|
|
|
{
|
|
|
if (waitTakeProductSlot.Index % 16 == 1)
|
|
|
{
|
|
|
//没有可以取的穴位了,先拍照
|
|
|
flowStep = EDischargeFlowStep.进料盘产品定位;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.料仓取料;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if(GlobalVar.RunSpace&&!GlobalVar.EnableStock)
|
|
|
{
|
|
|
GlobalTray.InputTray.ChangeStatus(ESlotStatus.Have);
|
|
|
takeSlotIndex = 1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//换料盘
|
|
|
//GlobalTray.InputTray.ChangeStatus(ESlotStatus.Have);
|
|
|
//先判断是否时最后一盘料,如果时最后一盘料,则提示客户换料
|
|
|
//if(Stock2Flow.Instance.GetCurrentLayer()==1)
|
|
|
if (StockManager.GetCurrentLayer(2) == 1)
|
|
|
{
|
|
|
EButtonType btn = Msgbox.ShowTipDialog(EButtonType.Retry | EButtonType.EndInput, "Please change tray", "tip", true);
|
|
|
if (btn == EButtonType.Retry)
|
|
|
{
|
|
|
//先把轴移动到安全位
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
TakeTrayFlow.Instance.Take(ETrayType.Input, ETrayType.Empty);
|
|
|
//TakeTrayFlow.Instance.Take(ETrayType.Input, ETrayType.Empty);
|
|
|
//Stock2Flow.Instance.PrepareTray();
|
|
|
StockManager.PrepareTray(2);
|
|
|
TakeTrayFlow.Instance.Take(ETrayType.Input, ETrayType.Empty);
|
|
|
}
|
|
|
else if (btn == EButtonType.EndInput)
|
|
|
{
|
|
|
GlobalVar.Clear = true;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//先把轴移动到安全位
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
TakeTrayFlow.Instance.Take(ETrayType.Input, ETrayType.Empty);
|
|
|
//GlobalTray.InputTray.ChangeStatus(ESlotStatus.Have);
|
|
|
takeSlotIndex = 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case EDischargeFlowStep.进料盘产品定位:
|
|
|
ActionStart();
|
|
|
ProductLocationFlow.Instance.Grab(ETrayType.Input, takeSlotIndex);
|
|
|
productLocationResult = OneGrabSixteenManager.Instance.GetResults();
|
|
|
if (productLocationResult != null || GlobalVar.RunSpace)
|
|
|
{
|
|
|
ActionEnd("PnP 扫描 16 个 DUT 2DBC", "PrP scan 16 DUT 2DBC");
|
|
|
//对结果进行处理
|
|
|
flowStep = EDischargeFlowStep.料仓取料;
|
|
|
}
|
|
|
break;
|
|
|
case EDischargeFlowStep.料仓取料:
|
|
|
ProductLocationResult ret = productLocationResult.Where(r => r.SlotIndex == takeSlotIndex).FirstOrDefault();
|
|
|
if(ret != null || GlobalVar.RunSpace)
|
|
|
{
|
|
|
if((ret!= null && ret.Result== EOneGrabSixteenResult.Ok) ||(ret!=null &&ret.Result== EOneGrabSixteenResult.LocationOkScanBarcodeFail && GlobalVar.EnableVirtualBarCode) || GlobalVar.RunSpace)
|
|
|
{
|
|
|
StockTakeFlow.Instance.Take( ETrayType.Input, takeSlotIndex, NozzleManager.GetIdelNozzle().NozzleIndex);
|
|
|
takeSlotIndex++;
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bool exit = false;
|
|
|
while (!exit)
|
|
|
{
|
|
|
ProductLocationResult fixtureret = FixedGrabProductFlow.Instance.TakePicture(ETrayType.Input, ret.SlotIndex);
|
|
|
if (fixtureret.Result == EOneGrabSixteenResult.Ok)
|
|
|
{
|
|
|
if(fixtureret.SN.Length==GlobalVar.BarcodeLength)
|
|
|
{
|
|
|
ret.Change(fixtureret.SN, fixtureret.OffsetX, fixtureret.OffsetY);
|
|
|
//takeSlotIndex++;
|
|
|
StockTakeFlow.Instance.Take(ETrayType.Input, takeSlotIndex, NozzleManager.GetIdelNozzle().NozzleIndex);
|
|
|
takeSlotIndex++;
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
exit = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//报警弹框
|
|
|
alarmEntity = AlarmCollection.Get(AlarmConstID.二维码长度异常报警).Transform(ret.SlotIndex);
|
|
|
EButtonType buttonSelect = Msgbox.ShowDialog(alarmEntity, EButtonType.Retry, true);
|
|
|
if (buttonSelect == EButtonType.Retry)
|
|
|
{
|
|
|
logInfo = GetClassName() + "选择了重试";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (fixtureret.Result == EOneGrabSixteenResult.LocationOkScanBarcodeFail)
|
|
|
{
|
|
|
Nozzle idleNozzle = NozzleManager.GetIdelNozzle();
|
|
|
if(false)
|
|
|
{
|
|
|
StockTakeFlow.Instance.Take(ETrayType.Input, ret.SlotIndex, idleNozzle.NozzleIndex);
|
|
|
//放料
|
|
|
TraySlot noProductSlot = GlobalTray.RetestTray.GetSlot(ESlotStatus.NotHave);
|
|
|
if (noProductSlot != null)
|
|
|
{
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.ReTest, noProductSlot.Index, idleNozzle.NozzleIndex);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, "Retest tray full,please change tray and click ok button", "tip", true);
|
|
|
GlobalTray.RetestTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.ReTest);
|
|
|
//放料
|
|
|
noProductSlot = GlobalTray.RetestTray.GetSlot(ESlotStatus.NotHave);
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.ReTest, noProductSlot.Index, idleNozzle.NozzleIndex);
|
|
|
}
|
|
|
takeSlotIndex++;
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
exit = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
StockTakeFlow.Instance.Take(ETrayType.Input, ret.SlotIndex, idleNozzle.NozzleIndex);
|
|
|
if(NozzleManager.GetNozzle(idleNozzle.NozzleIndex).Product!=null)
|
|
|
{
|
|
|
NozzleManager.GetNozzle(idleNozzle.NozzleIndex).Product.SN = "SLK11111111PNK60X";
|
|
|
}
|
|
|
takeSlotIndex++;
|
|
|
exit = true;
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (fixtureret.Result == EOneGrabSixteenResult.Slant)
|
|
|
{
|
|
|
//报警弹框
|
|
|
alarmEntity = AlarmCollection.Get(AlarmConstID.取料定位失败报警).Transform(ret.SlotIndex);
|
|
|
EButtonType buttonSelect = Msgbox.ShowDialog(alarmEntity, EButtonType.Skip | EButtonType.Retry | EButtonType.EndInput, true);
|
|
|
//EButtonType buttonSelect = Msgbox.ShowDialog(EButtonType.Skip | EButtonType.Retry | EButtonType.EndInput, $"穴位{ret.SlotIndex}定位失败,请把产品手动取走后点击跳过","tip",true);
|
|
|
if(buttonSelect== EButtonType.Retry)
|
|
|
{
|
|
|
logInfo = GetClassName() + "选择了重试";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
else if (buttonSelect == EButtonType.Skip)
|
|
|
{
|
|
|
logInfo = GetClassName() + "选择了跳过";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
exit = true;
|
|
|
GlobalTray.InputTray.ChangeStatus(ret.SlotIndex, ESlotStatus.NotHave);
|
|
|
takeSlotIndex++;
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
}
|
|
|
else if (buttonSelect == EButtonType.EndInput)
|
|
|
{
|
|
|
logInfo = GetClassName() + "选择了结束上料";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
exit = true;
|
|
|
GlobalVar.Clear = true;
|
|
|
takeSlotIndex++;
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
}
|
|
|
}
|
|
|
else if(fixtureret.Result== EOneGrabSixteenResult.NoHaveProdut)
|
|
|
{
|
|
|
logInfo =GetClassName()+ $"视觉检测到穴位{ret.SlotIndex}无料,自动跳过";
|
|
|
exit = true;
|
|
|
GlobalTray.InputTray.ChangeStatus(ret.SlotIndex, ESlotStatus.NotHave);
|
|
|
takeSlotIndex++;
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
//if (GlobalTray.InputTray.GetSlot(takeSlotIndex).SlotStatus == ESlotStatus.Have)
|
|
|
//{
|
|
|
// StockTakeFlow.Instance.Take(takeSlotIndex, NozzleManager.GetIdelNozzle().NozzleIndex);
|
|
|
//}
|
|
|
//takeSlotIndex++;
|
|
|
//flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
break;
|
|
|
#endregion
|
|
|
|
|
|
#region 治具换料
|
|
|
//治具换料
|
|
|
case EDischargeFlowStep.到治具取料等待位:
|
|
|
//先去第一个治具拍照位上方等待
|
|
|
//if(TestFixtureManager.Instance.GetTestFixture(lastFixtureIndex+1).Product==null)
|
|
|
if (TestFixtureManager.Instance.GetTestFixture(checkFixtureList[0]).Product == null)
|
|
|
{
|
|
|
//targetPosition = FixtureManager.GetFixtureGrabPos(lastFixtureIndex + 1);
|
|
|
targetPosition = FixtureManager.GetFixtureGrabPos(checkFixtureList[0]);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//targetPosition = NozzleManager.GetNozzleToFixturePos(lastFixtureIndex + 1, NozzleManager.GetIdelNozzle().NozzleIndex);
|
|
|
//targetPosition.X += TestFixtureManager.Instance.GetTestFixture(lastFixtureIndex + 1).PlaceProductOffsetX;
|
|
|
//targetPosition.Y2 += TestFixtureManager.Instance.GetTestFixture(lastFixtureIndex + 1).PlaceProductOffsetY;
|
|
|
|
|
|
targetPosition = NozzleManager.GetNozzleToFixturePos(checkFixtureList[0], NozzleManager.GetIdelNozzle().NozzleIndex);
|
|
|
targetPosition.X += TestFixtureManager.Instance.GetTestFixture(checkFixtureList[0]).PlaceProductOffsetX;
|
|
|
targetPosition.Y2 += TestFixtureManager.Instance.GetTestFixture(checkFixtureList[0]).PlaceProductOffsetY;
|
|
|
}
|
|
|
//if (targetPosition.X-GlobalVar.FixtureSafePosX>50)
|
|
|
//{
|
|
|
// DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToFixture);
|
|
|
//}
|
|
|
ActionStart();
|
|
|
acrossAnthorSide = "";
|
|
|
if(Math.Abs(targetPosition.Y1-GlobalVar.FixtureSideY1)>50)
|
|
|
{
|
|
|
acrossAnthorSide = " (1)";
|
|
|
}
|
|
|
if(GroupAxisMove.XY1Y2MovePos(targetPosition, GlobalVar.WholeSpeed, EGoWhichSide.FixtureSide))
|
|
|
{
|
|
|
AxisPosPrint.PrintXY1Y2TargetPos("到治具放料缓冲位,", targetPosition, GetClassName());
|
|
|
flowStep = EDischargeFlowStep.等待到治具取料等待位;
|
|
|
}
|
|
|
break;
|
|
|
case EDischargeFlowStep.等待到治具取料等待位:
|
|
|
if(Ops.IsStop("LoadX","LoadY1","LoadY2"))
|
|
|
{
|
|
|
ActionEnd("拾取器移动到另一个治具", $"Picker move to another test cell{acrossAnthorSide}");
|
|
|
AxisPosPrint.PrintXY1Y2CurrentPos("轴loadx,loady1,loady2已停止运动,",GetClassName());
|
|
|
if(AxisArrived.LoadXY1Y2IsArrived(targetPosition.X, targetPosition.Y1, targetPosition.Y2))
|
|
|
{
|
|
|
//CreateCheckFixtureQueue();
|
|
|
AxisPosPrint.PrintXY1Y2CurrentPos("已运动到放料缓冲位,", GetClassName());
|
|
|
flowStep = EDischargeFlowStep.等待治具测试完成换料;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.到治具取料等待位;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case EDischargeFlowStep.等待治具测试完成换料:
|
|
|
if (NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count==3)
|
|
|
{
|
|
|
//double curXpos = Ops.GetCurPosition(AxisControl.LoadX);
|
|
|
//if(curXpos-GlobalVar.FixtureSafePosX>1)
|
|
|
//{
|
|
|
// DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock);
|
|
|
//}
|
|
|
flowStep = EDischargeFlowStep.判断是否需要放料到料仓;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
foreach (int i in checkFixtureList)
|
|
|
{
|
|
|
TestFixture fixture = TestFixtureManager.Instance.GetTestFixture(i);
|
|
|
if (fixture != null && fixture.Status == ETestFixtureStatus.IDLE)
|
|
|
{
|
|
|
//在这里检测吸嘴上有没有产品可以方到这个治具,如果有就把这个产品取起来,如果没有等待下一个就绪的治具
|
|
|
curFixture = fixture;
|
|
|
//判断治具是否有产品,没有产品则直接放料
|
|
|
if (curFixture.Product != null)
|
|
|
{
|
|
|
//curFixture.AddTestRecordToProduct();
|
|
|
//在这里判断这个治具上的产品,有没有吸嘴上的产品和它进行交换的,如果没有,则继续轮询下一个治具
|
|
|
needPlaceNozzle = GetPlaceNozzle(curFixture);
|
|
|
if (needPlaceNozzle != null)
|
|
|
{
|
|
|
MessageQueue.Instance.Insert($"{GetClassName()} 需要放料的吸嘴:{needPlaceNozzle.NozzleIndex}");
|
|
|
flowStep = EDischargeFlowStep.治具取料;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//治具里面有产品但是吸嘴已经没有可以产品可以交换
|
|
|
if (GlobalVar.Clear && NozzleManager.GetIdelNozzle() != null)
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.治具取料;
|
|
|
break;
|
|
|
//在这里先去把要放的产品给放下去,再回来取
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
needPlaceNozzle=GetPlaceNozzle(curFixture);
|
|
|
//needPlaceNozzle = NozzleManager.GetToTestNozzle();
|
|
|
if (needPlaceNozzle != null)
|
|
|
{
|
|
|
MessageQueue.Instance.Insert($"{GetClassName()} 治具中无产品,需要放料的吸嘴:{needPlaceNozzle.NozzleIndex}");
|
|
|
flowStep = EDischargeFlowStep.治具放料;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case EDischargeFlowStep.治具取料:
|
|
|
FixtureTakeFlow.Instance.Take(curFixture.Index);
|
|
|
if(needPlaceNozzle != null && needPlaceNozzle.Status== ENozzleStatus.ToTest)
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.治具放料;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
int num = TestFixtureManager.Instance.GetHaveProductFixtureList().Count();
|
|
|
int tounloadNum = NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count();
|
|
|
//if(GlobalVar.Clear && (
|
|
|
// (tounloadNum==3)
|
|
|
// || (num==0)
|
|
|
// ||(NozzleManager.GetToTestNozzle() == null)))
|
|
|
if(tounloadNum == 3
|
|
|
|| (num == 0 && NozzleManager.GetToTestNozzle() == null)
|
|
|
//|| NozzleManager.GetToTestNozzle() == null
|
|
|
)//吸嘴上有3个待下的料开始下料,治具中没有料同时吸嘴上没有待测的料开始下料
|
|
|
{
|
|
|
logInfo =GetClassName()+ $"clear:{GlobalVar.Clear},tounloadnum:{tounloadNum},num:{num}";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
//if(curFixture.Index==6)
|
|
|
//{
|
|
|
// DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock);
|
|
|
//}
|
|
|
CreateCheckFixtureQueue(curFixture.Index);
|
|
|
flowStep = EDischargeFlowStep.判断是否需要放料到料仓;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CreateCheckFixtureQueue(curFixture.Index);
|
|
|
flowStep = EDischargeFlowStep.到治具取料等待位;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case EDischargeFlowStep.治具放料:
|
|
|
//curNozzle = NozzleManager.GetToTestNozzle();
|
|
|
if(needPlaceNozzle!=null)
|
|
|
{
|
|
|
FixturePlaceFlow.Instance.Place(curFixture.Index, needPlaceNozzle.NozzleIndex);
|
|
|
CreateCheckFixtureQueue(curFixture.Index);
|
|
|
//lastFixtureIndex = checkFixtureList[0] - 1;
|
|
|
//lastFixtureIndex = curFixture.Index == checkFixtureList.Max() ? checkFixtureList.Min()-1 : curFixture.Index;
|
|
|
//lastFixtureIndex = curFixture.Index == 6 ? 0 : curFixture.Index;
|
|
|
|
|
|
int num = TestFixtureManager.Instance.GetHaveProductFixtureList().Count();
|
|
|
int tounloadNum = NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count();
|
|
|
if (
|
|
|
tounloadNum==3
|
|
|
|| num==0
|
|
|
|| NozzleManager.GetToTestNozzle() == null
|
|
|
)
|
|
|
//GlobalVar.Clear && (
|
|
|
//NozzleManager.GetToTestNozzle() == null
|
|
|
//|| (tounloadNum == 3)
|
|
|
//|| (num == 0)
|
|
|
//|| (NozzleManager.GetIdelNozzle() == null)))
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.判断是否需要放料到料仓;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.到治具取料等待位;
|
|
|
}
|
|
|
|
|
|
|
|
|
// if (NozzleManager.GetToTestNozzle() != null
|
|
|
// ||(GlobalVar.Clear && TestFixtureManager.Instance.GetHasProuctFixtureCount()>0 && NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToUnload).Count<3))
|
|
|
//{
|
|
|
// flowStep = EDischargeFlowStep.到治具取料等待位;
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
// //if (curFixture.Index == 6)
|
|
|
// //{
|
|
|
// // DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock);
|
|
|
// //}
|
|
|
// flowStep = EDischargeFlowStep.判断是否需要放料到料仓;
|
|
|
//}
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region 料仓放料
|
|
|
//料仓放料
|
|
|
case EDischargeFlowStep.判断是否需要放料到料仓:
|
|
|
//检测有没有需要放料到料仓的吸嘴
|
|
|
if(NozzleManager.GetToUnloadNozzle()!=null)
|
|
|
{
|
|
|
Nozzle placeNozzle = NozzleManager.GetToUnloadNozzle();
|
|
|
int placeNozzleIndex = placeNozzle.NozzleIndex;
|
|
|
logInfo = GetClassName() + $"检查到吸嘴{placeNozzle.NozzleIndex}号吸嘴产品检测结果{placeNozzle.Product.Result},bin:{placeNozzle.Product.Bin}";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
//placeNozzle.Product.Result
|
|
|
//这里先方到OK料仓
|
|
|
if (placeNozzle.Product.Result=="PASS")
|
|
|
{
|
|
|
if(GlobalVar.EnableBin)//需要分Bin
|
|
|
{
|
|
|
if(placeNozzle.Product.Bin== GlobalVar.BinToGrr)//最好的产品,放入grr盘
|
|
|
{
|
|
|
#region 最好的产品,放入GRR盘
|
|
|
TraySlot waitPlaceSlot = GlobalTray.GrrTray.GetSlot(ESlotStatus.NotHave);
|
|
|
if (waitPlaceSlot != null)
|
|
|
{
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.Grr, waitPlaceSlot.Index, placeNozzleIndex);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//提示更换料盘
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, "Grr tray full,please change tray and click ok button", "tip", true);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.Grr);
|
|
|
GlobalTray.GrrTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
#region OK产品,分BIN存放
|
|
|
int placeSlotIndex = BinManager.GetPlaceSlot(GlobalVar.CurrentUsedBin, ETrayType.Ok, placeNozzle.Product.Bin);
|
|
|
if (placeSlotIndex > 0)
|
|
|
{
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.Ok, placeSlotIndex, placeNozzleIndex);
|
|
|
|
|
|
}
|
|
|
else if (placeSlotIndex == 0)//此区域已经无穴位放产品
|
|
|
{
|
|
|
//料盘放满了,更换料盘
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
if (GlobalVar.EnableFullAlarm)
|
|
|
{
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, $"{placeNozzle.Product.Bin} area hasn't slot to place product,you can redraw ok tray bin area after click ok button,", "tip", true);
|
|
|
}
|
|
|
TakeTrayFlow.Instance.Take(ETrayType.Empty, ETrayType.Ok, true, true);
|
|
|
GlobalTray.OkTary.ChangeStatus(ESlotStatus.NotHave);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.Ok);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, $"cann't find {placeNozzle.Product.Bin} area,you can redraw ok tray area after click ok button", "tip", true);
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
TraySlot waitPlaceSlot = GlobalTray.OkTary.GetSlot(ESlotStatus.NotHave);
|
|
|
if (waitPlaceSlot != null)
|
|
|
{
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.Ok, waitPlaceSlot.Index, placeNozzleIndex);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//料盘放满了,更换料盘
|
|
|
//double curLoadX = Ops.GetCurPosition(AxisControl.LoadX);
|
|
|
//if (curLoadX - GlobalVar.FixtureSafePosX > 50)
|
|
|
//{
|
|
|
// DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock);
|
|
|
//}
|
|
|
if(GlobalVar.RunSpace&& !GlobalVar.EnableStock)
|
|
|
{
|
|
|
GlobalTray.OkTary.ChangeStatus(ESlotStatus.NotHave);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.Ok);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
TakeTrayFlow.Instance.Take(ETrayType.Empty, ETrayType.Ok, true, true);
|
|
|
GlobalTray.OkTary.ChangeStatus(ESlotStatus.NotHave);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.Ok);
|
|
|
}
|
|
|
|
|
|
//料盘已满
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if(placeNozzle.Product!=null && placeNozzle.Product.SN== "SLK11111111PNK60X")
|
|
|
{
|
|
|
TraySlot waitPlaceSlot = GlobalTray.RetestTray.GetSlot(ESlotStatus.NotHave);
|
|
|
if (waitPlaceSlot != null)
|
|
|
{
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.ReTest, waitPlaceSlot.Index, placeNozzleIndex);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (GlobalVar.RunSpace && !GlobalVar.EnableStock)
|
|
|
{
|
|
|
GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//提示更换料盘
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, "RetestTray full,please change tray and click ok button", "tip", true);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.ReTest);
|
|
|
GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (GlobalVar.EnableBin)
|
|
|
{
|
|
|
#region NG产品,分BIN存放
|
|
|
int placeSlotIndex = BinManager.GetPlaceSlot(GlobalVar.CurrentUsedBin, ETrayType.Ng, placeNozzle.Product.Bin);
|
|
|
if (placeSlotIndex > 0)
|
|
|
{
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.Ng, placeSlotIndex, placeNozzleIndex);
|
|
|
}
|
|
|
else if (placeSlotIndex == 0)//此区域已经无穴位放产品
|
|
|
{
|
|
|
//料盘放满了,更换料盘
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
if (GlobalVar.EnableFullAlarm)
|
|
|
{
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, $"{placeNozzle.Product.Bin} area hasn't slot to place product,you can redraw ok tray bin area after click ok button,", "tip", true);
|
|
|
}
|
|
|
//提示更换料盘
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, "NG tray full,please change tray and click ok button", "tip", true);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.Ng);
|
|
|
GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, $"cann't find {placeNozzle.Product.Bin} area,you can redraw ok tray area after click ok button", "tip", true);
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//logInfo = GetClassName() + $"检查到吸嘴{placeNozzle.NozzleIndex}号吸嘴产品检测结果{placeNozzle.Product.Result}";
|
|
|
//MessageQueue.Instance.Insert(logInfo);
|
|
|
TraySlot waitPlaceSlot = GlobalTray.NgTray.GetSlot(ESlotStatus.NotHave);
|
|
|
if (waitPlaceSlot != null)
|
|
|
{
|
|
|
StockPlaceFlow.Instance.Place(ETrayType.Ng, waitPlaceSlot.Index, placeNozzleIndex);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (GlobalVar.RunSpace && !GlobalVar.EnableStock)
|
|
|
{
|
|
|
GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//提示更换料盘
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, "NG tray full,please change tray and click ok button", "tip", true);
|
|
|
ThreePointLocationFlow.Instance.Location(ETrayType.Ng);
|
|
|
GlobalTray.NgTray.ChangeStatus(ESlotStatus.NotHave);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// flowStep = EDischargeFlowStep.到料仓放料位上方;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if(GlobalVar.Clear)
|
|
|
{
|
|
|
if(TestFixtureManager.Instance.GetHaveProductFixtureList().Count()==0)
|
|
|
{
|
|
|
//double curLoadX = Ops.GetCurPosition(AxisControl.LoadX);
|
|
|
//if (curLoadX - GlobalVar.FixtureSafePosX > 50)
|
|
|
//{
|
|
|
// DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock);
|
|
|
//}
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
flowStep = EDischargeFlowStep.工作完成收料;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.到治具取料等待位;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
//flowStep = EDischargeFlowStep.判断是否需要从料仓取料;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
//case EDischargeFlowStep.工作完成到安全位:
|
|
|
// targetPosition.X = GlobalVar.DischargeSafePostionX;
|
|
|
// targetPosition.Y1 = GlobalVar.StockSideY1;
|
|
|
// targetPosition.Y2 = GlobalVar.DischargeSafePostionY2;
|
|
|
|
|
|
// if(GroupAxisMove.XY1Y2MovePos(targetPosition, GlobalVar.WholeSpeed))
|
|
|
// {
|
|
|
// flowStep = EDischargeFlowStep.等待工作完成到安全位;
|
|
|
// }
|
|
|
// break;
|
|
|
//case EDischargeFlowStep.等待工作完成到安全位:
|
|
|
// if(Ops.IsStop("LoadX", "LoadY1", "LoadY2"))
|
|
|
// {
|
|
|
// AxisPosPrint.PrintXY1Y2CurrentPos("运动已停止,",GetClassName());
|
|
|
// if(AxisArrived.LoadXY1Y2IsArrived(targetPosition.X,targetPosition.Y1,targetPosition.Y2))
|
|
|
// {
|
|
|
// flowStep = EDischargeFlowStep.工作完成收料;
|
|
|
// }
|
|
|
// }
|
|
|
// break;
|
|
|
case EDischargeFlowStep.工作完成收料:
|
|
|
DischargeModuleGoSafePosFlow.Instance.GoSafePostion();
|
|
|
TakeTrayFlow.Instance.Take(ETrayType.Empty, ETrayType.Ok,true,true);
|
|
|
TakeTrayFlow.Instance.Take(ETrayType.Empty, ETrayType.Input);
|
|
|
Task.Run(() => {
|
|
|
StockManager.DischargeFinish(1);
|
|
|
});
|
|
|
Task.Run(() => {
|
|
|
StockManager.DischargeFinish(2);
|
|
|
});
|
|
|
Task.Run(() => {
|
|
|
StockManager.DischargeFinish(3);
|
|
|
});
|
|
|
flowStep = EDischargeFlowStep.等待收料完成;
|
|
|
break;
|
|
|
case EDischargeFlowStep.等待收料完成:
|
|
|
if(StockManager.AllReady())
|
|
|
{
|
|
|
StockManager.Reset(1);
|
|
|
StockManager.Reset(2);
|
|
|
StockManager.Reset(3);
|
|
|
Ops.Stop();
|
|
|
takeSlotIndex = 1;
|
|
|
GlobalVar.Clear = false;
|
|
|
workFinishedEvent?.Invoke();
|
|
|
flowStep = EDischargeFlowStep.等待启动;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
Thread.Sleep(5);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void Start()
|
|
|
{
|
|
|
stop = false;
|
|
|
}
|
|
|
public void Stop()
|
|
|
{
|
|
|
stop = true;
|
|
|
}
|
|
|
private string GetClassName()
|
|
|
{
|
|
|
return "DischargeFlow-";
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取吸嘴取料取不起来时,吸嘴在原取料位的偏移
|
|
|
/// 奇数向下偏移
|
|
|
/// 偶数向上偏移
|
|
|
/// </summary>
|
|
|
/// <param name="fetchNum"></param>
|
|
|
/// <returns></returns>
|
|
|
private double GetVacOffsetHeight(int fetchNum)
|
|
|
{
|
|
|
if (fetchNum == 0) return 0;
|
|
|
//先判断是奇数还是偶数
|
|
|
int count = 0;
|
|
|
int oddOrEven = fetchNum & 0x01;
|
|
|
|
|
|
double offsetDisct = 0.0;
|
|
|
if (oddOrEven == 1)
|
|
|
{
|
|
|
count = (fetchNum / 2) + 1;
|
|
|
offsetDisct = -0.1 * count;
|
|
|
}
|
|
|
|
|
|
else if (oddOrEven == 0)
|
|
|
{
|
|
|
count = (fetchNum / 2);
|
|
|
offsetDisct = 0.1 * count;
|
|
|
}
|
|
|
return offsetDisct;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断XY是否可以在本区域运动
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public bool XYCanGoLocalArea()
|
|
|
{
|
|
|
//获取周转Y轴的位置,当排料Y轴去周转盘的时候,检测是否安全
|
|
|
double turnoverYPos = Ops.GetCurPosition("TurnoverY");
|
|
|
if (turnoverYPos - SysConfigParam.GetValue<double>("TurnoverDumpY") < -0.5)
|
|
|
return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
public string GetCurStep()
|
|
|
{
|
|
|
return flowStep.ToString();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 生成检测治具状态的队列
|
|
|
/// </summary>
|
|
|
void CreateCheckFixtureQueue(int lastIndex)
|
|
|
{
|
|
|
checkFixtureList.Clear();
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
{
|
|
|
int number = ((lastIndex + 1) + i - 1) % 6 + 1;
|
|
|
if(TestFixtureManager.Instance.GetTestFixture(number).Enable)
|
|
|
{
|
|
|
checkFixtureList.Add(number);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据当前治具的产品判断吸嘴上的产品有没有交换的
|
|
|
/// </summary>
|
|
|
/// <param name="fixture"></param>
|
|
|
/// <returns></returns>
|
|
|
Nozzle GetPlaceNozzle(TestFixture fixture)
|
|
|
{
|
|
|
if(fixture!=null && fixture.Product!= null && fixture.Product.SN == "SLK11111111PNK60X")
|
|
|
{
|
|
|
foreach (Nozzle item in NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToTest))
|
|
|
{
|
|
|
if (item.Product != null)
|
|
|
{
|
|
|
return item;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//ABC模式
|
|
|
switch (GlobalVar.TestMethod)
|
|
|
{
|
|
|
|
|
|
case "A":
|
|
|
foreach (Nozzle item in NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToTest))
|
|
|
{
|
|
|
if (item.Product != null)
|
|
|
{
|
|
|
return item;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case "AAB":
|
|
|
if (fixture.Product != null && fixture.Product.TestNum == 1 && fixture.Product.Result == "NG")
|
|
|
{
|
|
|
return NozzleManager.GetIdelNozzle();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
foreach (Nozzle item in NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToTest))
|
|
|
{
|
|
|
if (item.Product != null && (item.Product.TestedFixtures == null || !item.Product.TestedFixtures.Contains(curFixture.Index)))
|
|
|
{
|
|
|
return item;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case "ABC"://必须更换治具
|
|
|
foreach (Nozzle item in NozzleManager.GetNozzlesByStatus(ENozzleStatus.ToTest))
|
|
|
{
|
|
|
if (item.Product != null)
|
|
|
{
|
|
|
if (item.Product.TestNum == 0)
|
|
|
return item;
|
|
|
if (!item.Product.TestedFixtures.Contains(fixture.Index))
|
|
|
return item;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
Stopwatch timeStatistics = new Stopwatch();
|
|
|
|
|
|
public void ActionStart()
|
|
|
{
|
|
|
if (GlobalVar.EnableIndexTimeStatistics)
|
|
|
timeStatistics.Restart();
|
|
|
}
|
|
|
|
|
|
public void ActionEnd(string actionCnName, string actionEnName)
|
|
|
{
|
|
|
if (GlobalVar.EnableIndexTimeStatistics)
|
|
|
{
|
|
|
timeStatistics.Stop();
|
|
|
string dirpath = $"d:\\data\\{DateTime.Now.ToString("yyyyMMdd")}";
|
|
|
if(!Directory.Exists(dirpath))
|
|
|
{
|
|
|
Directory.CreateDirectory(dirpath);
|
|
|
}
|
|
|
string filename = Path.Combine(dirpath, "breakdowntesttime.csv");
|
|
|
File.AppendAllText(filename, $"{actionCnName},{actionEnName},{timeStatistics.ElapsedMilliseconds}\r\n");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|