Sic03-8inch/Modules/Mainframe/TMs/TMRobotPickRoutine.cs

305 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
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,
TimeDelay2,
TimeDelay20,
TimeDelay50,
}
private ModuleName _target;
private int _targetSlot;
private RobotArmEnum _blade;
private int _pickTimeout;
private bool _autoHand;
private bool _requestAWCData;
private SicTM _tm;
private TMSlitValveRoutine _openSlitValveRoutine = new TMSlitValveRoutine();
private TMSlitValveRoutine _closeSlitValveRoutine = new TMSlitValveRoutine();
private bool _pmPostTrasferEnableHeat = true;
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);
}
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.CheckHasTray(_target, _targetSlot))
{
EV.PostWarningLog(Module, $"Can not pick, No tray 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.CheckNoTray(ModuleHelper.Converter(Module), slot))
{
EV.PostWarningLog(Module, $"Can not pick, Robot arm {slot + 1} has tray");
return Result.FAIL;
}
//顶针必须在低位
if (_target == ModuleName.LoadLock || _target == ModuleName.Load)
{
if (!LoadLift.IsDown)
{
EV.PostWarningLog(Module, $"Can not place, Load Lift must in down Position!");
return Result.FAIL;
}
}
else if (_target == ModuleName.UnLoad)
{
if (!UnLoadLift.IsDown)
{
EV.PostWarningLog(Module, $"Can not place, UnLoad Lift must in down Position!");
return Result.FAIL;
}
}
//Pick之前先,根据Sensor检测是否有盘
if (!SC.GetValue<bool>("System.IsSimulatorMode"))
{
if (ModuleHelper.IsLoadLock(_target) && !SensorLLTrayPresence.Value)
{
EV.PostWarningLog(Module, $"Can not pick, LLTrayPresence sensor check no Tray");
return Result.FAIL;
}
if (_target==ModuleName.UnLoad && !SensorUnloadWaferPresence.Value)
{
EV.PostWarningLog(Module, $"Can not pick,UnloadWaferPresence sensor check no wafer");
return Result.FAIL;
}
if (ModuleHelper.IsBuffer(_target)&&_targetSlot==2 && !SensorBufferHighWaferPresence.Value)
{
EV.PostWarningLog(Module, $"Can not pick,BufferHighWaferPresence sensor check no wafer");
return Result.FAIL;
}
if (ModuleHelper.IsBuffer(_target) && _targetSlot == 1 && !SensorBufferMiddleWaferPresence.Value)
{
EV.PostWarningLog(Module, $"Can not pick,BufferMiddleWaferPresence sensor check no wafer");
return Result.FAIL;
}
if (ModuleHelper.IsBuffer(_target) && _targetSlot == 0 && !SensorBufferLowWaferPresence.Value)
{
EV.PostWarningLog(Module, $"Can not pick,BufferLowWaferPresence sensor check no wafer");
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);
RobotGotoNotWait((int)RoutineStep.RobotGotoNotWait, RobotDevice, _target, _targetSlot, _blade, _pickTimeout);
//如果是Buffer腔则不需要打开闸板阀动作
if (_target != ModuleName.Buffer)
{
ExecuteRoutine((int)RoutineStep.OpenSlitValve, _openSlitValveRoutine);
}
CheckRobotReady((int)RoutineStep.CheckRobotReady, RobotDevice, _pickTimeout);
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.TimeDelay2, 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);
TimeDelay((int)RoutineStep.TimeDelay1, 1);
//如果是Buffer腔则不需要关闭闸板阀动作
if (_target != ModuleName.Buffer)
{
ExecuteRoutine((int)RoutineStep.CloseSlitValve, _closeSlitValveRoutine);
}
}
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;
}
}
}