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.

333 lines
16 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 Rs.Controls;
using Rs.Framework;
using Rs.MotionPlat.Commom;
using Rs.MotionPlat.Entitys;
using Rs.MotionPlat.Flow.Common;
using Rs.MotionPlat.Flow.SafePosFlow;
using Rs.MotionPlat.Vision;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Rs.MotionPlat.Flow.SubFlow
{
enum EStockPlaceFlowStep
{
,
,
,
,
,
,
,
,
,
,
}
/// <summary>
/// 料仓放料流程
/// </summary>
public class StockPlaceFlow
{
public event Action<TestProduct> PlaceFinishedEvent;
bool finished = true;
double slotOffsetX = 0.0;
double slotOffsetY = 0.0;
EStockPlaceFlowStep flowStep = EStockPlaceFlowStep.;
public StockPlaceFlow()
{
}
private static StockPlaceFlow instance;
public static StockPlaceFlow Instance
{
get
{
if (instance == null)
instance = new StockPlaceFlow();
return instance;
}
}
public string GetCurStep()
{
return flowStep.ToString();
}
/// <summary>
/// 料仓放料
/// </summary>
/// <param name="tray">需要放入的料盘</param>
/// <param name="nozzleIndex">哪个吸嘴放</param>
/// <param name="className"></param>
public void Place(ETrayType trayType,int slotIndex,int nozzleIndex,bool needStop=true)
{
RsTray tray = null;
if (finished)
finished = false;
else
return;
switch (trayType)
{
case ETrayType.Ng:
tray = GlobalTray.NgTray;
break;
case ETrayType.ReTest:
tray = GlobalTray.RetestTray;
break;
case ETrayType.Grr:
tray = GlobalTray.GrrTray;
break;
case ETrayType.Ok:
tray = GlobalTray.OkTary;
break;
case ETrayType.Input:
tray = GlobalTray.InputTray;
break;
default:
break;
}
flowStep = EStockPlaceFlowStep.;
string logInfo = string.Empty;
TargetPosition targetPosition = new TargetPosition();
Nozzle curNozzle = NozzleManager.GetNozzle(nozzleIndex);
TraySlot curPlaceSlot = null;
DischargeFlow.Instance.ActionStart();
while (!finished)
{
if (MachineManage.Instance.MachineStatus == EMachineStatus.Stop && needStop)
{
Thread.Sleep(10);
continue;
}
switch (flowStep)
{
case EStockPlaceFlowStep.:
slotOffsetX = 0;
slotOffsetY = 0;
if (GlobalVar.EnableBeforePlaceProductGrab)
{
flowStep = EStockPlaceFlowStep.;
}
else
{
flowStep = EStockPlaceFlowStep.;
}
break;
case EStockPlaceFlowStep.:
curPlaceSlot = tray.GetSlot(slotIndex);
if(curPlaceSlot!=null)
{
SlotPoint sp = TrayPointManager.GetSlotPoint(trayType, curPlaceSlot.Index);
if(sp!=null)
{
targetPosition.X = sp.X;
targetPosition.Y1 = GlobalVar.StockSideY1;
targetPosition.Y2 = sp.Y;
//double curLoadX = Ops.GetCurPosition(AxisControl.LoadX);
//if (curLoadX - GlobalVar.FixtureSafePosX > 50)
//{
// DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock);
//}
if (GroupAxisMove.XY1Y2MovePos(targetPosition, GlobalVar.WholeSpeed, EGoWhichSide.StockSide))
{
AxisPosPrint.PrintXY1Y2TargetPos($"到{trayType}料仓拍照位上方,", targetPosition, GetClassName());
flowStep = EStockPlaceFlowStep.;
}
}
}
break;
case EStockPlaceFlowStep.:
if (Ops.IsStop("LoadX", "LoadY1", "LoadY2"))
{
AxisPosPrint.PrintXY1Y2CurrentPos("轴loadx,loady1,loady2已停止运动,", GetClassName());
if (AxisArrived.LoadXY1Y2IsArrived(targetPosition.X, targetPosition.Y1, targetPosition.Y2))
{
AxisPosPrint.PrintXY1Y2CurrentPos($"已运动到{trayType}料仓拍照位上方,", GetClassName());
flowStep = EStockPlaceFlowStep.;
}
else
{
flowStep = EStockPlaceFlowStep.;
}
}
break;
case EStockPlaceFlowStep.:
VisionHelper.trayLocationVision.ClearQueue();
UpCameraHelper.Grab();
VisionResult vr = VisionHelper.Grab(Vision.EVisionScene.TrayLocation);
if((vr!=null && vr.Result) || GlobalVar.RunSpace)
{
if(GlobalVar.RunSpace)
{
flowStep = EStockPlaceFlowStep.;
}
else
{
curNozzle = NozzleManager.GetNozzle(nozzleIndex);
slotOffsetX = vr.OffsetX;
slotOffsetY = vr.OffsetY;
string sn = "";
if (curNozzle != null && curNozzle.Product != null && !string.IsNullOrEmpty(curNozzle.Product.SN))
{
sn = curNozzle.Product.SN;
}
string title = "index,sn,offsetx,offsety,time\r\n";
string content = $"{slotIndex},{sn},{slotOffsetX},{slotOffsetY},{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}\r\n";
string dataDir = $"d://data/placestock//{DateTime.Now.ToString("yyyy-MM-dd")}";
if (!Directory.Exists(dataDir))
{
Directory.CreateDirectory(dataDir);
}
string dataFilePath = $"{dataDir}//{GlobalVar.LotName}_{trayType}.csv";
if (!File.Exists(dataFilePath))
{
File.AppendAllText(dataFilePath, title);
}
File.AppendAllText(dataFilePath, content);
flowStep = EStockPlaceFlowStep.;
}
}
else
{
Msgbox.ShowTipDialog(EButtonType.Retry, "stock slot location fail", "", true);
}
break;
case EStockPlaceFlowStep.:
//curNozzle = NozzleManager.GetToUnloadNozzle();
curNozzle = NozzleManager.GetNozzle(nozzleIndex);
if (curNozzle != null)
{
curPlaceSlot = tray.GetSlot(slotIndex);
if (curPlaceSlot != null)
{
targetPosition = NozzleManager.GetToTraySlot(trayType, curPlaceSlot.Index, curNozzle.NozzleIndex);
targetPosition.X += slotOffsetX;
targetPosition.Y2+= slotOffsetY;
//double curLoadX = Ops.GetCurPosition(AxisControl.LoadX);
//if (curLoadX - GlobalVar.FixtureSafePosX > 50)
//{
// DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock);
//}
if (GroupAxisMove.XY1Y2MovePos(targetPosition, GlobalVar.WholeSpeed, EGoWhichSide.StockSide))
{
AxisPosPrint.PrintXY1Y2TargetPos("到料仓放料位上方,", targetPosition, GetClassName());
flowStep = EStockPlaceFlowStep.;
}
}
else
{
}
}
break;
case EStockPlaceFlowStep.:
if (Ops.IsStop("LoadX", "LoadY1", "LoadY2"))
{
AxisPosPrint.PrintXY1Y2CurrentPos("轴loadx,loady1,loady2已停止运动,",GetClassName());
if (AxisArrived.LoadXY1Y2IsArrived(targetPosition.X, targetPosition.Y1, targetPosition.Y2))
{
AxisPosPrint.PrintXY1Y2CurrentPos("已运动到料仓放料位上方,", GetClassName());
flowStep = EStockPlaceFlowStep.;
}
else
{
flowStep = EStockPlaceFlowStep.;
}
}
break;
case EStockPlaceFlowStep.:
targetPosition.StockZ = NozzleManager.GetNozzleToTrayTakeProductPos(trayType, curNozzle.NozzleIndex)-GlobalVar.PlaceProdcutToStockTrayOffsetHeight;
if (NozzleManager.Go(curNozzle, targetPosition.StockZ, GlobalVar.WholeSpeed))
{
logInfo = $"{GetClassName()}到料仓放料位下方";
MessageQueue.Instance.Insert(logInfo);
flowStep = EStockPlaceFlowStep.;
}
break;
case EStockPlaceFlowStep.:
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}"))
{
logInfo = $"{GetClassName()}已运动到料仓放料位下方";
MessageQueue.Instance.Insert(logInfo);
//关闭真空吸
curNozzle.VacSuction(EIoOperate.Close, GetClassName());
//打开真空破
curNozzle.VacBreak(EIoOperate.Open, GetClassName());
//关闭真空
curNozzle.VacBreak(EIoOperate.Close, GetClassName());
flowStep = EStockPlaceFlowStep.;
}
break;
case EStockPlaceFlowStep.:
if (NozzleManager.GotoSafePos(curNozzle.NozzleIndex))
{
logInfo = $"{GetClassName()}料仓放料完成抬起";
MessageQueue.Instance.Insert(logInfo);
flowStep = EStockPlaceFlowStep.;
}
break;
case EStockPlaceFlowStep.:
if (Ops.IsStop($"NozzleZ{curNozzle.NozzleIndex}"))
{
logInfo = $"{GetClassName()}放料完成已抬起";
MessageQueue.Instance.Insert(logInfo);
flowStep = EStockPlaceFlowStep.;
}
break;
case EStockPlaceFlowStep.:
if (!curNozzle.HasProduct() || GlobalVar.RunSpace)
{
DischargeFlow.Instance.ActionEnd("拾取器将 1 个 DUT 卸载到output托盘OK/NG", "Picker unload 1 DUT to output trav (OK/NG)");
if(curNozzle.Product!=null)
{
curNozzle.Product.ToSlotIndex = curPlaceSlot.Index;
if (trayType != ETrayType.ReTest)
{
PlaceFinishedEvent?.Invoke(curNozzle.Product);
}
logInfo = $"{GetClassName()}检测到吸嘴{curNozzle.NozzleIndex}无粘料,吸嘴{curNozzle.NozzleIndex}把产品SN:{curNozzle.Product.SN}放入OK料盘{curPlaceSlot.Index}穴位";
MessageQueue.Instance.Insert(logInfo);
tray.ChangeStatus(curPlaceSlot.Index, ESlotStatus.Have);
curNozzle.Product.Save(trayType);
curNozzle.Product.ToString();
curNozzle.Clear();
}
else
{
curNozzle.Clear();
tray.ChangeStatus(curPlaceSlot.Index, ESlotStatus.Have);
}
finished = true;
flowStep = EStockPlaceFlowStep.;
}
else
{
AlarmEntity alarmEntity = AlarmCollection.Get(AlarmConstID.).Transform(curNozzle.NozzleIndex);
if(alarmEntity != null)
{
Msgbox.ShowDialog(alarmEntity, EButtonType.Retry);
}
else
{
Msg.ShowError("翻译文件中未找到 ‘排料吸嘴粘料报警’项");
}
}
break;
}
}
}
string GetClassName()
{
return $"{nameof(StockPlaceFlow)}-";
}
}
}