You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1126 lines
62 KiB
C#

This file contains ambiguous Unicode characters!

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

using 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");
}
}
}
}