179 lines
6.6 KiB
C#
179 lines
6.6 KiB
C#
using System.Linq;
|
||
using Aitex.Core.RT.Routine;
|
||
using Aitex.Core.RT.SCCore;
|
||
using MECF.Framework.Common.Equipment;
|
||
using SicModules.LLs.Routines.Base;
|
||
|
||
namespace SicModules.LLs.Routines
|
||
{
|
||
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();
|
||
|
||
Result MoveOneCircleResult;
|
||
Result CCDCheckResult;
|
||
|
||
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");
|
||
|
||
MoveOneCircleResult = Result.Succeed;
|
||
CCDCheckResult = Result.Succeed;
|
||
|
||
return Result.RUN;
|
||
}
|
||
|
||
|
||
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, 1);
|
||
|
||
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, 1);
|
||
|
||
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); //拍照
|
||
}
|
||
|
||
if(_enableDistanceSensorCheck)
|
||
{
|
||
double _distanceSensorOKRatio = SC.GetValue<double>("LoadLock.LoadRotation.DistanceSensorOKRatio");
|
||
int _calRatio = (int)(DISensroQueuen.Count(x => x) * 1.0 / DISensroQueuen.Count * 100);
|
||
if(_calRatio >= 0 && _calRatio <=100)
|
||
{
|
||
if (_calRatio < _distanceSensorOKRatio)
|
||
{
|
||
MoveOneCircleResult = Result.VERIFYFAIL;
|
||
Stop($"{Module} Rotation One Circle Wafter check sensor fail [TM DI-35],the OK Ratio is {_calRatio}%");
|
||
}
|
||
else
|
||
{
|
||
MoveOneCircleResult = Result.Succeed;
|
||
Notify($"{Module} Rotation One Circle Wafter check sensor Succeed [TM DI-35],the OK Ratio is {_calRatio}%");
|
||
}
|
||
}
|
||
}
|
||
|
||
if (CCDCheckResult == Result.TIMEOUT)
|
||
{
|
||
Stop($"Load CCD Check Result Timeout");
|
||
}
|
||
else if (CCDCheckResult == Result.VERIFYFAIL)
|
||
{
|
||
Stop($"Load CCD Check Result NG");
|
||
}
|
||
else if (_enableCCDCheck && CCDCheckResult == Result.Succeed)
|
||
{
|
||
Notify($"Load CCD Check Result OK");
|
||
}
|
||
|
||
if(MoveOneCircleResult != Result.Succeed || CCDCheckResult != Result.Succeed)
|
||
{
|
||
return Result.FAIL;
|
||
}
|
||
}
|
||
}
|
||
catch (RoutineBreakException)
|
||
{
|
||
return Result.RUN;
|
||
}
|
||
catch (RoutineFaildException)
|
||
{
|
||
return Result.FAIL;
|
||
}
|
||
|
||
Notify("Finished");
|
||
|
||
return Result.DONE;
|
||
}
|
||
|
||
public override void Abort()
|
||
{
|
||
|
||
}
|
||
|
||
}
|
||
}
|