Sic05/Modules/Mainframe/EFEMs/TrayRobotPlaceRoutine.cs

208 lines
7.8 KiB
C#
Raw Normal View History

2022-09-26 14:39:17 +08:00
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Mainframe.Devices;
using Mainframe.LLs;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
using System;
namespace Mainframe.EFEMs
{
public class TrayRobotPlaceRoutine : EfemBaseRoutine
{
/* 1.Place to LoadLock()/Cassette
* 2.TrayRobot是否有Tray
* 3.
* 4.
* 5.
* 6.
* 7.
* 8.
*/
private LoadRotationHomeOffsetRoutine _loadRotationHomeRoutine = new LoadRotationHomeOffsetRoutine();
private EfemSlitValveRoutine _efemSlitValveOpenRoutine = new EfemSlitValveRoutine();
private EfemSlitValveRoutine _efemSlitValveCloseRoutine = new EfemSlitValveRoutine();
private LoadLockLiftRoutine _loadLockLiftDown = new LoadLockLiftRoutine();
//private LoadLockTrayAlignerRoutine _trayAligner = new LoadLockTrayAlignerRoutine();
private LoadLockTrayClawRoutine _trayClamp = new LoadLockTrayClawRoutine();
private LoadLockTrayClawRoutine _trayUnClamp = new LoadLockTrayClawRoutine();
private IoLoadRotation _llRotation = null;
private ModuleName _source;
private int _sourceSlot;
private int _placeTimeout;
private double _homeOffset;
private int _loadRotationTimeOut = 60;
enum RoutineStep
{
OpenSlitValve,
SetLiftUp,
CheckRobotReady,
PickComplete,
SetLiftDown,
Place,
TrayAligner,
TrayClamp,
TrayUnClamp,
CloseSlitValve,
TrayUnClamp1,
LoadRotationRelativeHome,
FindPositionSensor,
SetExtendToDo,
ClearRobortExtendToDo,
CheckTraySensor,
TimeDelay1,
TimeDelay2,
TimeDelay3,
TimeDelay4,
}
public TrayRobotPlaceRoutine()
{
Module = ModuleName.EFEM.ToString();
Name = "TrayRobortPlace";
_llRotation = DEVICE.GetDevice<IoLoadRotation>("Load.Rotation");
}
public void Init(ModuleName sourseMod,int sourceSlt)
{
_source = sourseMod;
_sourceSlot = sourceSlt;
}
public override Result Start(params object[] objs)
{
Reset();
if (!WaferManager.Instance.CheckHasTray(ModuleName.TrayRobot, 0))
{
Stop("Can not place,TrayRobot no tray");
return Result.FAIL;
}
//Place之前先,根据Sensor检测是否有盘
if (WaferManager.Instance.CheckHasTray(_source, _sourceSlot))
{
EV.PostWarningLog(Module, $"Can not place, {_source} slot {_sourceSlot} has tray");
return Result.FAIL;
}
if (TrayRobot.RobotState != RobotStateEnum.Idle)
{
EV.PostWarningLog(Module, $"Can not place, WaferRobot is not Idle");
EV.PostWarningLog(Module, $"Can not place, TrayRobot is not Idle");
return Result.FAIL;
}
//LoadLock传感器是否需要检测有Tray盘
if (_source == ModuleName.LoadLock || _source == ModuleName.Load)
{
if (_loadTrayPresence.Value)
{
EV.PostWarningLog(Module, $"Can not place,{_source} sensor[DI-32] check have tray");
return Result.FAIL;
}
if (!_llLift.IsDown)
{
EV.PostWarningLog(Module, $"Can not place,{_source} lift is not in down position!");
return Result.FAIL;
}
}
else if (_source == ModuleName.CassBL)
{
//检测凸片Sensor和有无Sensor
if (_cassBLWaferConvex.Value)
{
EV.PostWarningLog(Module, $"Can not place,{_source} check wafer convex");
return Result.FAIL;
}
if (!_cassBL6Inch.Value)
{
EV.PostWarningLog(Module, $"Can not place,{_source} sensor check no cassette");
return Result.FAIL;
}
}
_loadRotationTimeOut = SC.GetValue<int>("LoadLock.LoadRotation.RotationTimeOut");
_efemSlitValveOpenRoutine.Init(_source, ModuleName.TrayRobot, true);
_efemSlitValveCloseRoutine.Init(_source, ModuleName.TrayRobot, false);
_loadLockLiftDown.Init(false);
_trayClamp.Init(true);
_trayUnClamp.Init(false);
_placeTimeout = SC.GetConfigItem($"{ModuleName.TrayRobot}.MotionTimeout").IntValue;
_homeOffset = SC.GetConfigItem($"LoadLock.LoadRotation.HomeOffset").DoubleValue;
return Result.RUN;
}
public override Result Monitor()
{
try
{
/* DI_LoadTrayPresence
* DI_LoadWaferPlaced Wafer有无
* DI_LoadHomeTraySensor
*/
if (_source == ModuleName.LoadLock)
{
ExecuteRoutine((int)RoutineStep.TrayUnClamp1, _trayUnClamp); //夹爪打开
ExecuteRoutine((int)RoutineStep.OpenSlitValve, _efemSlitValveOpenRoutine); //打开闸板阀
SetTrayRobortExtendToDO((int)RoutineStep.SetExtendToDo, _source, 10); //设置ExtendToDO,用于检测InterLock
CheckRobotReady((int)RoutineStep.CheckRobotReady, TrayRobot, _placeTimeout); //判断机械手当前是否空闲
Place((int)RoutineStep.Place, TrayRobot, _source, _sourceSlot, _placeTimeout); //机械手
ClearRobortExtendToDO((int)RoutineStep.ClearRobortExtendToDo);
CheckTraySensor((int)RoutineStep.CheckTraySensor);
//对中
ExecuteRoutine((int)RoutineStep.TrayClamp, _trayClamp); //夹爪关闭
TimeDelay((int)RoutineStep.TimeDelay2, 1);//延迟1s
ExecuteRoutine((int)RoutineStep.TrayUnClamp, _trayUnClamp); //夹爪打开
//ExecuteRoutine((int)RoutineStep.LoadRotationRelativeHome, _loadRotationHomeRoutine); //Tray找原点
//TimeDelay((int)RoutineStep.TimeDelay1, 1);
ExecuteRoutine((int)RoutineStep.CloseSlitValve, _efemSlitValveCloseRoutine); //关闭闸板阀
}
else
{
CheckRobotReady((int)RoutineStep.CheckRobotReady, TrayRobot, _placeTimeout); //判断机械手当前是否空闲
SetTrayRobortExtendToDO((int)RoutineStep.SetExtendToDo, _source, 10); //设置ExtendToDO,用于检测InterLock
Place((int)RoutineStep.Place, TrayRobot, _source, _sourceSlot, _placeTimeout); //机械手
ClearRobortExtendToDO((int)RoutineStep.ClearRobortExtendToDo);
}
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException ex)
{
LOG.Error(ex.ToString());
return Result.FAIL;
}
Notify($"Finish");
return Result.DONE;
}
}
}