2022-09-29 17:33:25 +08:00
|
|
|
|
using System.Linq;
|
2022-09-19 09:16:33 +08:00
|
|
|
|
using Aitex.Core.RT.Routine;
|
|
|
|
|
using Aitex.Core.RT.SCCore;
|
|
|
|
|
using MECF.Framework.Common.Equipment;
|
|
|
|
|
|
2022-09-29 17:33:25 +08:00
|
|
|
|
namespace Mainframe.LLs.Routines
|
2022-09-19 09:16:33 +08:00
|
|
|
|
{
|
|
|
|
|
public class LoadLockGroupRoutine : LoadLockBaseRoutine
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* 8、顶升上升
|
|
|
|
|
9、夹爪打开
|
|
|
|
|
10、下降wafer
|
|
|
|
|
11、托盘旋转一周,进行距离判断
|
|
|
|
|
12、旋转到指定角度,视觉判断
|
|
|
|
|
13、抽真空
|
|
|
|
|
|
|
|
|
|
* 旋转一周,检测到未放好,报错,人为干预
|
|
|
|
|
* 拍照确认指令(Ok,NG)NG则报错,人为干预
|
|
|
|
|
*/
|
|
|
|
|
enum RoutineStep
|
|
|
|
|
{
|
|
|
|
|
CCDModeSet,
|
|
|
|
|
LiftUp,
|
|
|
|
|
ClawOpen,
|
|
|
|
|
LiftDown,
|
|
|
|
|
MoveOneCircle,//旋转一周检查上测距Sensor是否感应到
|
|
|
|
|
TimeDelay1,
|
|
|
|
|
WaitMoveOneCircleDone,
|
|
|
|
|
MoveCCD1Pos,//运动到CCDPos1
|
|
|
|
|
TimeDelay2,
|
|
|
|
|
TimeDelay3,
|
|
|
|
|
TimeDelay4,
|
|
|
|
|
TimeDelay5,
|
|
|
|
|
WaitMoveDone,
|
|
|
|
|
TrigCCD1Pos,//CCDPos1拍照
|
|
|
|
|
MoveCCD2Pos,//运动到CCDPos2
|
|
|
|
|
TrigCCD2Pos,//CCDPos2拍照
|
|
|
|
|
LoadRotationRelativeHome,
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private float _ccdPos1;
|
|
|
|
|
private float _ccdPos2;
|
|
|
|
|
private int _loadRatationMoveTimeout = 30;
|
|
|
|
|
private int _liftMoveTimeOut = 30;
|
|
|
|
|
private int _clawMoveTimeOut = 30;
|
|
|
|
|
|
|
|
|
|
private bool _isSimulator = false;
|
|
|
|
|
private bool _enableCCDCheck = false;
|
|
|
|
|
private bool _enableDistanceSensorCheck = false;
|
|
|
|
|
private LoadRotationHomeOffsetRoutine _loadRotationHomeRoutine = new LoadRotationHomeOffsetRoutine();
|
|
|
|
|
|
|
|
|
|
public LoadLockGroupRoutine(ModuleName module)
|
|
|
|
|
{
|
|
|
|
|
Module = module.ToString();
|
|
|
|
|
Name = "TrayGroup";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Result Start(params object[] objs)
|
|
|
|
|
{
|
|
|
|
|
Reset();
|
|
|
|
|
|
|
|
|
|
Notify("Start");
|
|
|
|
|
|
|
|
|
|
_liftMoveTimeOut = SC.GetValue<int>("LoadLock.LiftMoveTimeOut");
|
|
|
|
|
_clawMoveTimeOut = SC.GetValue<int>("LoadLock.ClawMoveTimeOut");
|
|
|
|
|
_loadRatationMoveTimeout = SC.GetValue<int>("LoadLock.LoadRotation.RotationTimeOut");
|
|
|
|
|
_ccdPos1 = (float)SC.GetValue<double>("LoadLock.LoadRotation.CCD1Pos");
|
|
|
|
|
_ccdPos2 = (float)SC.GetValue<double>("LoadLock.LoadRotation.CCD2Pos");
|
|
|
|
|
_isSimulator = SC.GetValue<bool>($"System.IsSimulatorMode");
|
|
|
|
|
_enableCCDCheck = SC.GetValue<bool>($"LoadLock.EnableCCDCheck");
|
|
|
|
|
_enableDistanceSensorCheck = SC.GetValue<bool>($"LoadLock.EnableDistanceSensorCheck");
|
|
|
|
|
|
|
|
|
|
return Result.RUN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Result MoveOneCircleResult;
|
|
|
|
|
Result CCDCheckResult;
|
|
|
|
|
public override Result Monitor()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//第一步Tray找原点
|
|
|
|
|
ExecuteRoutine((int)RoutineStep.LoadRotationRelativeHome, _loadRotationHomeRoutine);
|
|
|
|
|
TimeDelay((int)RoutineStep.TimeDelay1, 3);
|
|
|
|
|
LiftMove((int)RoutineStep.LiftUp, true, _liftMoveTimeOut);
|
|
|
|
|
ClawMove((int)RoutineStep.ClawOpen, WaferClaw, false, _clawMoveTimeOut);
|
|
|
|
|
LiftMove((int)RoutineStep.LiftDown, false, _liftMoveTimeOut);
|
|
|
|
|
TimeDelay((int)RoutineStep.TimeDelay2, 3);
|
|
|
|
|
|
|
|
|
|
if (!_isSimulator)
|
|
|
|
|
{
|
|
|
|
|
if (_enableDistanceSensorCheck)
|
|
|
|
|
{
|
|
|
|
|
MoveOneCircle((int)RoutineStep.MoveOneCircle, _loadRatationMoveTimeout); //旋转1周检查上方测距Sensor
|
|
|
|
|
TimeDelay((int)RoutineStep.TimeDelay3, 3);
|
|
|
|
|
MoveOneCircleResult = WaitMoveOneCircleDone((int)RoutineStep.WaitMoveOneCircleDone, _loadRatationMoveTimeout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TimeDelay((int)RoutineStep.TimeDelay4, 3);
|
|
|
|
|
|
|
|
|
|
if (_enableCCDCheck)
|
|
|
|
|
{
|
|
|
|
|
CCDModeSet((int)RoutineStep.CCDModeSet);
|
|
|
|
|
|
|
|
|
|
MoveCCD1Pos((int)RoutineStep.MoveCCD1Pos, _loadRatationMoveTimeout); //移动到CCD位置1
|
|
|
|
|
TimeDelay((int)RoutineStep.TimeDelay5, 3);
|
|
|
|
|
WaitLoadRotationDone((int)RoutineStep.WaitMoveDone, _loadRatationMoveTimeout);
|
|
|
|
|
|
|
|
|
|
CCDCheckResult = CCDTrigger((int)RoutineStep.TrigCCD1Pos, 10); //拍照
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double _distanceSensorOKRatio = SC.GetValue<double>("LoadLock.LoadRotation.DistanceSensorOKRatio");
|
|
|
|
|
int _calRatio = (int)(DISensroQueuen.Count(x => x) * 1.0 / DISensroQueuen.Count * 100);
|
|
|
|
|
|
|
|
|
|
if (_enableDistanceSensorCheck && _calRatio < _distanceSensorOKRatio)
|
|
|
|
|
{
|
|
|
|
|
Stop($"{Module} Rotation One Circle Wafter check sensor fail [TM DI-35],the OK Ratio is {_calRatio}%");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Notify($"{Module} Rotation One Circle Wafter check sensor Succeed [TM DI-35],the OK Ratio is {_calRatio}%");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_enableCCDCheck && CCDCheckResult == Result.VERIFYFAIL)
|
|
|
|
|
{
|
|
|
|
|
Stop($"Load CCD Check Result NG");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Notify($"Load CCD Check Result OK");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((_enableDistanceSensorCheck && _calRatio < _distanceSensorOKRatio) ||
|
|
|
|
|
(_enableCCDCheck && CCDCheckResult == Result.VERIFYFAIL))
|
|
|
|
|
{
|
|
|
|
|
return Result.FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (RoutineBreakException)
|
|
|
|
|
{
|
|
|
|
|
return Result.RUN;
|
|
|
|
|
}
|
|
|
|
|
catch (RoutineFaildException)
|
|
|
|
|
{
|
|
|
|
|
return Result.FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Notify("Finished");
|
|
|
|
|
|
|
|
|
|
return Result.DONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Abort()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|