using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Aitex.Sorter.Common;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Schedulers;
using MECF.Framework.Common.SubstrateTrackings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Venus_Core;
using Venus_RT.Devices;
using Venus_RT.Devices.PreAligner;
using Venus_RT.Modules.VCE;
namespace Venus_RT.Modules.TM.VenusEntity
{
public class SEMFPickRoutine : ModuleRoutineBase, IRoutine
{
private enum PickStep
{
seWaitModuleReady,
sePrepareModule,
sePicking,
seNotifyDone,
}
private HongHuTM _tm;
private IPreAlign _vpa;
private ITransferRobot _robot;
private VceEntity _vceModule;
private ModuleName _targetModule;
private int _targetSlot;
private int _pickingTimeout;
public int currentStepNo;
Hand _hand;
///
/// 完整pick动作仅可vce vpa取片
///
///
///
///
public SEMFPickRoutine(HongHuTM tm, ITransferRobot robot, IPreAlign vpa) : base(ModuleName.SETM)
{
_tm = tm;
_robot = robot;
_vpa = vpa;
}
public RState Start(params object[] objs)
{
if (!_robot.IsHomed)
{
LOG.Write(eEvent.ERR_TM, Module, $"TM Robot is not homed, please home it first");
return RState.Failed;
}
//MoveItem pickItem = new MoveItem() { SourceModule = , };
var pickItem = (Queue)objs[0];
_targetModule = pickItem.Peek().SourceModule;
_targetSlot = pickItem.Peek().SourceSlot;
_hand = pickItem.Peek().RobotHand;
//如果目标是Vce 否则是vpa
if (ModuleHelper.IsVCE(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
{
_vceModule = Singleton.Instance.GetVCE(_targetModule);
//如果vce有错误 报错
if (_vceModule.IsError)
{
LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} is Error! Please solve Error first!");
return RState.Failed;
}
if (_targetSlot < 0)
{
LOG.Write(eEvent.ERR_TM, Module, $"VCE target slot cannot be {_targetSlot}. Please check it first.");
return RState.Failed;
}
if (_tm.VCESlitDoorClosed)
{
LOG.Write(eEvent.ERR_TM, Module, $"cannot pick cause vce slitdoor not open.");
return RState.Failed;
}
//如果VCE门是关闭的 说明还未进行pump 无法取片等
//if (_tm.VCESlitDoorClosed)
//{
// LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} slitdoor not open! Please pump down vce and open it first!");
// return RState.Failed;
//}
}
//如果目标又不是VPA 报错
else if (!ModuleHelper.IsVPA(_targetModule))
{
LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} for pick action");
return RState.Failed;
}
//检查目标手臂上没有wafer
if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, (int)_hand))
{
LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as TM Robot Arm: {_hand} already has a wafer");
return RState.Failed;
}
//检查目标槽位上有wafer
if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot))
{
LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as {_targetModule} Slot {_targetSlot + 1} has no wafer");
return RState.Failed;
}
//2023/10/13 朱永吉 atm mode的判断不允许自动pump vent 信号不满足手动pump vent
//if (RouteManager.IsATMMode && _targetModule == ModuleName.VCE1)
//{
// if (!_tm.IsVCEATM)
// {
// LOG.Write(eEvent.ERR_TM, Module, $"System in ATM Mode but VCE is not ATM!");
// return RState.Failed;
// }
//
// if (!_tm.IsTMATM)
// {
// LOG.Write(eEvent.ERR_TM, Module, $"System in ATM Mode but TM is not ATM!");
// return RState.Failed;
// }
//}
//else
//{
// if (_tm.IsVCEATM)
// {
// LOG.Write(eEvent.ERR_TM, Module, $"System not in ATM Mode but VCE is ATM!");
// return RState.Failed;
// }
//
// if (_tm.IsTMATM)
// {
// LOG.Write(eEvent.ERR_TM, Module, $"System not in ATM Mode but TM is ATM!");
// return RState.Failed;
// }
//}
Reset();
_pickingTimeout = SC.GetValue("SETM.PickTimeout") * 1000;
return Runner.Start(Module, $"Pick from {_targetModule}");
}
public RState Monitor()
{
Runner.Wait(PickStep.seWaitModuleReady, CheckModuleReady, _delay_60s)
.Run(PickStep.sePrepareModule, PrepareModule, CheckModuleReady)
.Run (PickStep.sePicking, Picking, WaitPickDone, _pickingTimeout)
.End (PickStep.seNotifyDone, NullFun, 500);
return Runner.Status;
}
private bool PrepareModule()
{
switch (_targetModule)
{
case ModuleName.VCE1:
return _vceModule.CheckToPostMessage((int)VceMSG.Goto, _targetSlot);//移动到目标槽位
case ModuleName.VPA:
return true;//10/17暂时为true 后可能要求旋转到0
default:
return false;
}
}
private bool WaitPickDone()
{
if (_robot.Status == RState.Running)
{
return false;
}
else if (_robot.Status == RState.End)
{
WaferManager.Instance.WaferMoved(_targetModule, _targetSlot, ModuleName.TMRobot, (int)_hand);
return true;
}
else
{
Runner.Stop($"TM Robot Picking failed, {_robot.Status}");
return true;
}
}
private bool Picking()
{
//到达目标点位 pick固定槽位点的wafer
return _robot.Pick(_targetModule, 0, _hand);
}
private bool CheckModuleReady()
{
switch (_targetModule)
{
case ModuleName.VCE1:
return _vceModule.IsIdle;
case ModuleName.VPA:
return _vpa.Status == RState.End;
default:
return false;
}
}
public void Abort() { }
}
}