This repository has been archived on 2023-03-29. You can view files and clone it, but cannot push or open issues or pull requests.
Sic02/Modules/Mainframe/TMs/TMRobotPickRoutine.cs

354 lines
12 KiB
C#

using System;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Sorter.Common;
using Mainframe.Devices;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Schedulers;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
using SicPM.Devices;
namespace Mainframe.TMs
{
public class TMRobotPickRoutine : TMBaseRoutine
{
enum RoutineStep
{
WaitOpenSlitValveInterlock,
OpenSlitValve,
CheckBeforePick,
PrepareTransfer,
PrepareTransferNotWait,
Pick,
QueryOffset,
Extend,
Handoff,
HandoffDelay,
Retract,
UpdateWaferInfoByHandoff,
RequestWaferPresent,
BeforePickRequestWaferPresent,
AfterPickRequestWaferPresent,
RequestAWCData,
CheckWaferInfoByRobotSensor,
BeforePickCheckWaferInfoByRobotSensor,
AfterPickCheckWaferInfoByRobotSensor,
WaitCloseSlitValveInterlock,
CloseSlitValve,
SetRobortExtendToDo,
ClearRobortExtendToDo,
WaitPMSensor,
PostTransfer,
OpenShutter,
CloseShutter,
Delay1,
Delay2,
VceMoveToSlot,
RobotGotoNotWait,
CheckRobotReady,
CheckTransferPrepared,
SetConfinementRingUp,
TimeDelay1,
TimeDelay20,
TimeDelay50,
}
private ModuleName _target;
private int _targetSlot;
private RobotArmEnum _blade;
private int _pickTimeout;
private bool _autoHand;
private int _postTransferTimeout;
private double _shutterAndSlitValveMotionInterval;
private bool _requestAWCData;
private SicTM _tm;
private TMSlitValveRoutine _openSlitValveRoutine = new TMSlitValveRoutine();
private TMSlitValveRoutine _closeSlitValveRoutine = new TMSlitValveRoutine();
// private VCEMoveToSlotRoutine _vceMoveToSlotRoutine;
private bool _isShutterAndSlitValveMotionOneByOne;
private bool _pmPostTrasferEnableHeat =true;
private IoConfinementRing _confinementRing;
public TMRobotPickRoutine()
{
Module = "TMRobot";
Name = "Pick";
_tm = DEVICE.GetDevice<SicTM>($"{ ModuleName.System.ToString()}.{ ModuleName.TM.ToString()}");
}
public void Init(ModuleName source, int sourceSlot, RobotArmEnum blade)
{
Init(source, sourceSlot, blade, false);
}
public void Init(ModuleName source, int sourceSlot, int blade)
{
Init(source, sourceSlot, blade == 0 ? RobotArmEnum.Blade1 : RobotArmEnum.Blade2, false);
}
public void Init(ModuleName source, int sourceSlot)
{
Init(source, sourceSlot, RobotArmEnum.Blade1, true);
}
private void Init(ModuleName source, int sourceSlot, RobotArmEnum blade, bool autoHand)
{
_autoHand = autoHand;
_target = source;
_targetSlot = sourceSlot;
_blade = blade;
_openSlitValveRoutine.Init(source.ToString(), true, _pmPostTrasferEnableHeat);
_closeSlitValveRoutine.Init(source.ToString(), false, _pmPostTrasferEnableHeat);
_confinementRing = DEVICE.GetDevice<IoConfinementRing>("PM1.ConfinementRing");
}
public void Init(ModuleName source, int sourceSlot, int blade, bool autoHand,bool pmPostTrasferEnableHeat)
{
_pmPostTrasferEnableHeat = pmPostTrasferEnableHeat;
Init(source, sourceSlot, RobotArmEnum.Blade1, autoHand);
}
public override Result Start(params object[] objs)
{
Reset();
if (RobotDevice.RobotState != RobotStateEnum.Idle)
{
EV.PostWarningLog(Module, $"Can not pick, TMRobot Is Not IDLE");
return Result.FAIL;
}
_pickTimeout = SC.GetValue<int>("TMRobot.PickTimeout");
//if (ModuleHelper.IsPm(_target))
//{
// _postTransferTimeout = SC.GetValue<int>($"{_target}.PostTransferTimeout");
// _shutterAndSlitValveMotionInterval = SC.GetValue<double>($"{_target}.ShutterAndSlitValveMotionInterval");
// _isShutterAndSlitValveMotionOneByOne = SC.GetValue<bool>($"{_target}.ShutterAndSlitValveMotionOneByOne");
// //CoralPM pm = DEVICE.GetDevice<CoralPM>(_target.ToString());
// if (!pm.PickPlaceCheck(out string reason, false))
// {
// EV.PostWarningLog(Module, $"Can not place, {reason}");
// return Result.FAIL;
// }
//}
_requestAWCData = SC.GetValue<bool>("System.RequestAWCDataAfterPick");
if (!WaferManager.Instance.CheckHasWafer(_target, _targetSlot))
{
EV.PostWarningLog(Module, $"Can not pick, No wafer at {_target}, {_targetSlot + 1}");
return Result.FAIL;
}
if (_autoHand)
{
if (WaferManager.Instance.CheckNoWafer(Module, 0))
{
_blade = RobotArmEnum.Blade1;
}
else if (WaferManager.Instance.CheckNoWafer(Module, 1))
{
_blade = RobotArmEnum.Blade2;
}
else
{
EV.PostWarningLog(Module, $"Can not pick, Robot both arm has wafer");
return Result.FAIL;
}
}
int slot = _blade == RobotArmEnum.Blade1 ? 0 : 1;
if (!WaferManager.Instance.CheckNoWafer(Module, slot))
{
EV.PostWarningLog(Module, $"Can not pick, Robot arm {slot + 1} has wafer");
return Result.FAIL;
}
//Pick之前先,根据Sensor检测是否有盘
if (!SC.GetValue<bool>("System.IsSimulatorMode"))
{
if (ModuleHelper.IsLoadLock(_target) && !SensorLLWaferPresence.Value)
{
EV.PostWarningLog(Module, $"Can not pick, LoadLock sensor check no wafer");
return Result.FAIL;
}
if (ModuleHelper.IsBuffer(_target) && !SensorBufferWaferPresence.Value)
{
EV.PostWarningLog(Module, $"Can not pick,Buffer sensor check no wafer");
return Result.FAIL;
}
}
//if (ModuleHelper.IsVCE(_target))
//{
// var vce = DEVICE.GetDevice<CoralVCE>(_target.ToString());
// if (!vce.CheckEnableTransfer(EnumTransferType.Pick))
// {
// EV.PostWarningLog(Module, $"can not pick, {_target} not ready for transfer");
// return Result.FAIL;
// }
// _vceMoveToSlotRoutine = new VCEMoveToSlotRoutine(_target.ToString());
// _vceMoveToSlotRoutine.Init(_targetSlot);
//}
//if (ModuleHelper.IsPm(_target))
//{
// SicPM pm = DEVICE.GetDevice<SicPM>(_target.ToString());
// if (!pm.CheckEnableTransfer(EnumTransferType.Pick, out string reason))
// {
// EV.PostWarningLog(Module, $"can not pick, {_target} not ready for transfer");
// return Result.FAIL;
// }
//}
Notify($"Start, Pick from {_target} slot {_targetSlot + 1}, by {(_blade == RobotArmEnum.Blade1 ? "Blade1" : "Blade2")}");
IsPicking = false;
return Result.RUN;
}
public override void Abort()
{
_tm.CloseAllVentPumpValue();
if (!IsPicking)
{
RobotDevice.Stop();
}
Notify("Abort");
}
public override Result Monitor()
{
try
{
WaitSlitValveOpenInterlock((int)RoutineStep.WaitOpenSlitValveInterlock, TMDevice.GetSlitValve(_target), _pickTimeout);
/// if (ModuleHelper.IsPm(_target))
{
RobotGotoNotWait((int)RoutineStep.RobotGotoNotWait, RobotDevice, _target, _targetSlot, _blade, _pickTimeout);
if (_isShutterAndSlitValveMotionOneByOne)
{
Delay((int)RoutineStep.Delay1, _shutterAndSlitValveMotionInterval);
ExecuteRoutine((int)RoutineStep.OpenSlitValve, _openSlitValveRoutine);
}
else
{
ExecuteRoutine((int)RoutineStep.OpenSlitValve, _openSlitValveRoutine);
}
CheckRobotReady((int)RoutineStep.CheckRobotReady, RobotDevice, _pickTimeout);
}
if (_target == ModuleName.VCEA || _target == ModuleName.VCEB)
ExecuteRoutine((int)RoutineStep.OpenSlitValve, _openSlitValveRoutine);
CheckBeforePick((int)RoutineStep.CheckBeforePick, _target, _targetSlot, _blade);
RobotRequestWaferPresent((int)RoutineStep.BeforePickRequestWaferPresent, RobotDevice, _blade, _pickTimeout);
CheckWaferInfoByRobotRQ((int)RoutineStep.AfterPickCheckWaferInfoByRobotSensor, RobotDevice, _blade, 1000);
WaitPMReadySensor((int)RoutineStep.WaitPMSensor, _target, 5);
SetRobortExtendToDO((int)RoutineStep.SetRobortExtendToDo, _target, 2);
CheckRobotReady((int)RoutineStep.CheckRobotReady, RobotDevice, _pickTimeout);
Pick((int)RoutineStep.Pick, RobotDevice, _target, _targetSlot, _blade, _pickTimeout);
IsPicking = false;
TimeDelay((int)RoutineStep.TimeDelay1, 1);
RobotRequestWaferPresent((int)RoutineStep.RequestWaferPresent, RobotDevice, _blade, _pickTimeout);
CheckWaferInfoByRobotRQ((int)RoutineStep.CheckWaferInfoByRobotSensor, RobotDevice, _blade, 1000);
if (_requestAWCData)
{
RobotRequestWaferAWCData((int)RoutineStep.RequestAWCData, RobotDevice, _pickTimeout);
}
ClearRobortExtendToDO((int)RoutineStep.ClearRobortExtendToDo);
ExecuteRoutine((int)RoutineStep.CloseSlitValve, _closeSlitValveRoutine);
//if (ModuleHelper.IsPm(_target))
//{
// PostTransfer((int)RoutineStep.PostTransfer, Singleton<RouteManager>.Instance.GetPMEntity(_target), DEVICE.GetDevice<PM>(_target.ToString()), EnumTransferType.Pick, _postTransferTimeout);
//}
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException ex)
{
LOG.Error(ex.ToString());
RobotDevice.Stop();
return Result.FAIL;
}
Notify($"Finished, Pick from {_target} slot {_targetSlot + 1}, by {_blade}");
return Result.DONE;
}
public void SetConfinementRingUp(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Set Confinement RingUp");
OP.DoOperation($"{_target}.ServoUp");
return true;
}, () =>
{
return _confinementRing.IsUp;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set Confinement RingUp timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
}
}