Sic08/Modules/Mainframe/EFEMs/Routines/TrayRobotPlaceRoutine.cs

208 lines
7.8 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 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 MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
using SicModules.Devices;
using SicModules.EFEMs.Routines.Base;
using SicModules.LLs.Routines;
namespace SicModules.EFEMs.Routines
{
public class TrayRobotPlaceRoutine : EfemBaseRoutine
{
/* 1.Place to LoadLock(需要开门)/Cassette
* 2.判断目标是否无Tray判断Robot是否有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 (!_cassBLInch.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;
}
}
}