2022-09-19 09:16:33 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2022-10-14 16:47:24 +08:00
|
|
|
|
using System.Threading;
|
2022-09-19 09:16:33 +08:00
|
|
|
|
using Aitex.Core.RT.Device;
|
2022-09-29 17:33:25 +08:00
|
|
|
|
using Aitex.Core.RT.Device.Unit;
|
2022-09-19 09:16:33 +08:00
|
|
|
|
using Aitex.Core.RT.Routine;
|
2022-09-29 17:33:25 +08:00
|
|
|
|
using Mainframe.Devices;
|
|
|
|
|
using Mainframe.TMs;
|
2022-09-19 09:16:33 +08:00
|
|
|
|
using MECF.Framework.Common.Equipment;
|
|
|
|
|
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
|
|
|
|
|
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.MachineVision.Keyence;
|
2022-09-29 17:33:25 +08:00
|
|
|
|
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
|
2022-09-19 09:16:33 +08:00
|
|
|
|
|
2022-09-29 17:33:25 +08:00
|
|
|
|
namespace Mainframe.LLs.Routines
|
2022-09-19 09:16:33 +08:00
|
|
|
|
{
|
|
|
|
|
public class LoadLockBaseRoutine : ModuleRoutine, IRoutine
|
|
|
|
|
{
|
|
|
|
|
protected LoadLock LoadLockDevice
|
|
|
|
|
{
|
|
|
|
|
get { return _ll; }
|
|
|
|
|
}
|
|
|
|
|
protected TM TMDevice
|
|
|
|
|
{
|
|
|
|
|
get { return _tm; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected IoLift4 Lift
|
|
|
|
|
{
|
|
|
|
|
get { return _llLift; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected IoLoadRotation Rotation
|
|
|
|
|
{
|
|
|
|
|
get { return _llRotation; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected IoClaw WaferClaw
|
|
|
|
|
{
|
|
|
|
|
get { return _llWaferClaw; }
|
|
|
|
|
}
|
|
|
|
|
protected IoClaw TrayClaw
|
|
|
|
|
{
|
|
|
|
|
get { return _llTrayClaw; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private LoadLock _ll = null;
|
|
|
|
|
private TM _tm = null;
|
|
|
|
|
private IoLift4 _llLift = null;
|
|
|
|
|
private IoLoadRotation _llRotation = null;
|
|
|
|
|
private IoClaw _llWaferClaw = null;
|
|
|
|
|
private IoClaw _llTrayClaw = null;
|
|
|
|
|
private KeyenceCVX300F _loadCCD = null;
|
|
|
|
|
public IoSensor _loadTrayHomeSensor; //Tray<61><79>λ
|
|
|
|
|
public IoSensor _loadWaferPlaced; //<2F><><EFBFBD>¶<EFBFBD><C2B6>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>Wafer<65><72><EFBFBD><EFBFBD>
|
|
|
|
|
public IoSensor _loadTrayPlaced; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public LoadLockBaseRoutine()
|
|
|
|
|
{
|
|
|
|
|
Module = ModuleName.LoadLock.ToString();
|
|
|
|
|
|
|
|
|
|
_ll = DEVICE.GetDevice<SicLoadLock>($"{Module}.{Module}");
|
|
|
|
|
_tm = DEVICE.GetDevice<SicTM>($"{ModuleName.System}.{ModuleName.TM}");
|
|
|
|
|
_llLift = DEVICE.GetDevice<IoLift4>($"{Module}.LLLift");
|
|
|
|
|
_llWaferClaw = DEVICE.GetDevice<IoClaw>($"{Module}.LLWaferClaw");
|
|
|
|
|
_llTrayClaw = DEVICE.GetDevice<IoClaw>($"{Module}.LLTrayClaw");
|
|
|
|
|
_llRotation = DEVICE.GetDevice<IoLoadRotation>("Load.Rotation");
|
|
|
|
|
_loadCCD = DEVICE.GetDevice<KeyenceCVX300F>($"TM.KeyenceCVX300F");
|
|
|
|
|
|
|
|
|
|
_loadTrayHomeSensor = DEVICE.GetDevice<IoSensor>($"TM.LoadTrayHomeSensor");
|
|
|
|
|
_loadWaferPlaced = DEVICE.GetDevice<IoSensor>($"TM.LLWaferPlaced");
|
|
|
|
|
_loadTrayPlaced = DEVICE.GetDevice<IoSensor>($"TM.LLTrayPresence");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual Result Start(params object[] objs)
|
|
|
|
|
{
|
|
|
|
|
return Result.DONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual Result Monitor()
|
|
|
|
|
{
|
|
|
|
|
return Result.DONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void Abort()
|
|
|
|
|
{
|
|
|
|
|
LoadLockDevice.SetSlowPumpValve(false, out _);
|
|
|
|
|
LoadLockDevice.SetFastPumpValve(false, out _);
|
|
|
|
|
LoadLockDevice.SetSlowVentValve(false, out _);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void LiftMove(int id, bool up, int timeout)
|
|
|
|
|
{
|
|
|
|
|
string note = up ? "Up" : "Down";
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Set {Module} Lift to {note}");
|
|
|
|
|
if(up)
|
|
|
|
|
{
|
|
|
|
|
if (!Lift.MoveUp(out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Lift to {note} failed:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!Lift.MoveDown(out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Lift to {note} failed:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
if(up)
|
|
|
|
|
{
|
|
|
|
|
return Lift.IsUp && !Lift.IsDown;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return !Lift.IsUp && Lift.IsDown;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Lift to {note} Timeout, over {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void MoveRelativeHome(int id, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Set {Module} Rotation move relative home");
|
|
|
|
|
if (!_llRotation.MoveRelativeHome(out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Rotation move relative home:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void MoveLoadRotationHomeOffset(int id, float offset, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Set {Module} Rotation move offset");
|
|
|
|
|
if (!_llRotation.JogCW(offset, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Rotation move offset:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void WaitLoadRotationDone(int id, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>κζ<CEBA><CEB6><EFBFBD>
|
|
|
|
|
return true;
|
|
|
|
|
},
|
|
|
|
|
() =>
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Rotation<6F><6E><EFBFBD><EFBFBD>Error
|
|
|
|
|
if (_llRotation.IsServoError)
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Rotation Servo Error");
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return !_llRotation.IsServoBusy;
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
Stop($"Wait Load Rotation Done timeout, over {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-14 16:47:24 +08:00
|
|
|
|
protected void TryResetServo(int id, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
var reason = "";
|
|
|
|
|
|
|
|
|
|
// <20><>tray mark<72><6B><EFBFBD>ŷ<EFBFBD><C5B7><EFBFBD><EFBFBD>ܱ<EFBFBD><DCB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ŷ<EFBFBD><C5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȳ<EFBFBD><C8B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (_llRotation.IsServoError)
|
|
|
|
|
{
|
|
|
|
|
Notify($"Resetting the {Module} Rotation...");
|
|
|
|
|
|
|
|
|
|
if (_llRotation.ServoReset(out reason) == false)
|
|
|
|
|
{
|
|
|
|
|
Notify($"Unable to perform 'ServoReset' of {Module} Rotation, {reason}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
|
|
|
|
if (_llRotation.ServoOn(out reason) == false)
|
|
|
|
|
{
|
|
|
|
|
Notify($"Unable to perform 'ServoOn' of {Module} Rotation, {reason}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
|
|
|
|
if (_llRotation.IsServoOn == false)
|
|
|
|
|
{
|
|
|
|
|
Notify($"Unable to servo on {Module} Rotation, 'ServoOn' performed but the PLC reports servo-off.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-19 09:16:33 +08:00
|
|
|
|
protected void MoveOneCircle(int id,int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
2022-10-14 16:47:24 +08:00
|
|
|
|
var reason = "";
|
|
|
|
|
|
2022-09-19 09:16:33 +08:00
|
|
|
|
Notify($"Set {Module} Rotation One Circle Wafter check sensor");
|
2022-10-14 16:47:24 +08:00
|
|
|
|
if (!_llRotation.MoveOneCircle(out reason))
|
2022-09-19 09:16:33 +08:00
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Rotation One Circle Wafter check sensor:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Result WaitMoveOneCircleDoneResult;
|
|
|
|
|
//protected Result WaitMoveOneCircleDone(int id, int timeout)
|
|
|
|
|
//{
|
|
|
|
|
// Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
// {
|
|
|
|
|
// Notify($"Wait {Module} Rotation One Circle Wafter check sensor");
|
|
|
|
|
// WaitMoveOneCircleDoneResult = Result.RUN;
|
|
|
|
|
// return true;
|
|
|
|
|
// }, () =>
|
|
|
|
|
// {
|
|
|
|
|
// //<2F><><EFBFBD>δ<E2B5BD>ź<EFBFBD>Sensor<6F>ź<EFBFBD>
|
|
|
|
|
// if (!_loadWaferPlaced.Value)
|
|
|
|
|
// {
|
|
|
|
|
// //ʧ<>ܺ<EFBFBD>Stop<6F><70><EFBFBD><EFBFBD>
|
|
|
|
|
// _llRotation.Stop(out _);
|
|
|
|
|
// Stop($"Set {Module} Rotation One Circle Wafter check sensor fail [TM DI-35]");
|
|
|
|
|
// WaitMoveOneCircleDoneResult = Result.VERIFYFAIL;
|
|
|
|
|
// return true;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// //<2F><><EFBFBD><EFBFBD>Rotation<6F><6E><EFBFBD><EFBFBD>Error
|
|
|
|
|
// if (_llRotation.IsServoError)
|
|
|
|
|
// {
|
|
|
|
|
// //ʧ<>ܺ<EFBFBD>Stop<6F><70><EFBFBD><EFBFBD>
|
|
|
|
|
// _llRotation.Stop(out _);
|
|
|
|
|
// Stop($"Set {Module} Rotation Servo Error");
|
|
|
|
|
// WaitMoveOneCircleDoneResult = Result.VERIFYFAIL;
|
|
|
|
|
// return true;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (!_llRotation.IsServoBusy)
|
|
|
|
|
// {
|
|
|
|
|
// Notify($"{Module} Rotation One Circle Wafter check result ok");
|
|
|
|
|
// WaitMoveOneCircleDoneResult = Result.Succeed;
|
|
|
|
|
// return true;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// return false;
|
|
|
|
|
// }, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
// if (ret.Item1)
|
|
|
|
|
// {
|
|
|
|
|
// if (ret.Item2 == Result.FAIL)
|
|
|
|
|
// {
|
|
|
|
|
// throw (new RoutineFaildException());
|
|
|
|
|
// }
|
|
|
|
|
// else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
// {
|
|
|
|
|
// Stop($"Set {Module}Rotation One Circle Wafter check sensor Timeout, over {timeout} seconds");
|
|
|
|
|
// throw (new RoutineFaildException());
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// throw (new RoutineBreakException());
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// return WaitMoveOneCircleDoneResult;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Result WaitMoveOneCircleDoneResult;
|
|
|
|
|
public Queue<bool> DISensroQueuen = new Queue<bool>();
|
|
|
|
|
protected Result WaitMoveOneCircleDone(int id, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Wait {Module} Rotation One Circle Wafter check sensor");
|
|
|
|
|
WaitMoveOneCircleDoneResult = Result.RUN;
|
|
|
|
|
DISensroQueuen = new Queue<bool>();
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
DISensroQueuen.Enqueue(_loadWaferPlaced.Value);
|
|
|
|
|
//<2F><><EFBFBD>δ<E2B5BD>ź<EFBFBD>Sensor<6F>ź<EFBFBD>
|
|
|
|
|
//if (!_loadWaferPlaced.Value)
|
|
|
|
|
//{
|
|
|
|
|
// //ʧ<>ܺ<EFBFBD>Stop<6F><70><EFBFBD><EFBFBD>
|
|
|
|
|
// _llRotation.Stop(out _);
|
|
|
|
|
// Stop($"Set {Module} Rotation One Circle Wafter check sensor fail [TM DI-35]");
|
|
|
|
|
// WaitMoveOneCircleDoneResult = Result.VERIFYFAIL;
|
|
|
|
|
// return true;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Rotation<6F><6E><EFBFBD><EFBFBD>Error
|
|
|
|
|
if (_llRotation.IsServoError)
|
|
|
|
|
{
|
|
|
|
|
//ʧ<>ܺ<EFBFBD>Stop<6F><70><EFBFBD><EFBFBD>
|
|
|
|
|
_llRotation.Stop(out _);
|
|
|
|
|
Stop($"Set {Module} Rotation Servo Error");
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_llRotation.IsServoBusy)
|
|
|
|
|
{
|
|
|
|
|
//Notify($"{Module} Rotation One Circle Wafter check finish");
|
|
|
|
|
WaitMoveOneCircleDoneResult = Result.Succeed;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module}Rotation One Circle Wafter check sensor Timeout, over {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return WaitMoveOneCircleDoneResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void MoveHomePos(int id)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"{Module} Rotation move Home Pos");
|
|
|
|
|
if (!_llRotation.MoveRelativeHome(out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"{Module} Rotation move Home Pos fail:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void MoveCCD1Pos(int id,int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"{Module} Rotation move CCD Pos1");
|
|
|
|
|
if (!_llRotation.MoveCCD1Pos(out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"{Module} Rotation move CCD Pos1 fail:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void MoveCCD2Pos(int id, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"{Module} Rotation move CCD Pos2");
|
|
|
|
|
if (!_llRotation.MoveCCD2Pos(out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"{Module} Rotation move CCD Pos2 fail:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
if (!_llRotation.IsServoBusy)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} Rotation move CCD Pos2 Timeout, over {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void ClawMove(int id, IoClaw _claw,bool claw, int timeout)
|
|
|
|
|
{
|
|
|
|
|
string note = claw ? "Clawing" : "Opening";
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Set {Module} {note}");
|
|
|
|
|
if (!_claw.SetValue(claw, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} {note} failed:" + reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
return _claw.State == (claw ? ClawStateEnum.Clamp : ClawStateEnum.Open);
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
Stop($"Set {Module} {note} Timeout, over {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CheckForelinePressure(int id,double basePressure, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Check {Module} foreline pressure under {basePressure} mbar");
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
return LoadLockDevice.ForelinePressure <= basePressure;
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
Stop($"{Module} foreline pressure can not lower than {basePressure} in {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SlowPump(int id, double switchPressure, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Open {Module} slow pump valve to {switchPressure} mbar");
|
|
|
|
|
|
|
|
|
|
if (!LoadLockDevice.SetSlowPumpValve(true, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop(reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
return LoadLockDevice.ChamberPressure <= switchPressure;
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
LoadLockDevice.SetSlowPumpValve(false, out string _);
|
|
|
|
|
|
|
|
|
|
Stop($"{Module} pressure can not pump to {switchPressure} in {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FastPump(int id, double basePressure, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Open {Module} fast pump valve to {basePressure} mbar");
|
|
|
|
|
|
|
|
|
|
if (!LoadLockDevice.SetFastPumpValve(true, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop(reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
return LoadLockDevice.ChamberPressure <= basePressure;
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
LoadLockDevice.SetSlowPumpValve(false, out string _);
|
|
|
|
|
LoadLockDevice.SetFastPumpValve(false, out string _);
|
|
|
|
|
|
|
|
|
|
Stop($"{Module} pressure can not pump to {basePressure} in {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CloseSlowPumpValve(int id)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Close {Module} slow pump valve");
|
|
|
|
|
|
|
|
|
|
if (!LoadLockDevice.SetSlowPumpValve(false, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop(reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CloseFastPumpValve(int id)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Close {Module} fast pump valve");
|
|
|
|
|
|
|
|
|
|
if (!LoadLockDevice.SetFastPumpValve(false, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop(reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SlowVent(int id,double switchPressure, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Open {Module} slow vent valve to {switchPressure} mbar");
|
|
|
|
|
|
|
|
|
|
if (!LoadLockDevice.SetSlowVentValve(true, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop(reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
return LoadLockDevice.ChamberPressure >= switchPressure;
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
LoadLockDevice.SetSlowVentValve(false, out string _);
|
|
|
|
|
|
|
|
|
|
Stop($"{Module} pressure can not vent to {switchPressure} mbar in {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SlowVent(int id,double switchPressure, double pressureDiff, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Open {Module} slow vent valve to {switchPressure} mbar");
|
|
|
|
|
|
|
|
|
|
if (!_ll.SetSlowVentValve(true, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop(reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
return LoadLockDevice.ChamberPressure >= switchPressure - pressureDiff;
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
_ll.SetSlowVentValve(false, out string _);
|
|
|
|
|
|
|
|
|
|
Stop($"{Module} pressure can not vent to {switchPressure} mbar in {timeout} seconds");
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CloseVentValve(int id)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Close {Module} slow vent valve");
|
|
|
|
|
|
|
|
|
|
if (!LoadLockDevice.SetSlowVentValve(false, out string reason))
|
|
|
|
|
{
|
|
|
|
|
Stop(reason);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CCDModeSet(int id)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = Execute(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Set CCD Mode to 0");
|
|
|
|
|
_loadCCD.RunR0();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Result CCDTriggerResult;
|
|
|
|
|
public Result CCDTrigger(int id,int timeout)
|
|
|
|
|
{
|
|
|
|
|
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
|
|
|
|
{
|
|
|
|
|
Notify($"Load CCD Check Trigger");
|
|
|
|
|
|
|
|
|
|
_loadCCD.ClearResult();
|
|
|
|
|
_loadCCD.GetResult(1);
|
|
|
|
|
CCDTriggerResult = Result.RUN;
|
|
|
|
|
return true;
|
|
|
|
|
}, () =>
|
|
|
|
|
{
|
|
|
|
|
if(_loadCCD._sResult != "")
|
|
|
|
|
{
|
|
|
|
|
if(_loadCCD._sResult.Contains("OK"))
|
|
|
|
|
{
|
|
|
|
|
//Notify($"Load CCD Check Result OK");
|
|
|
|
|
CCDTriggerResult = Result.Succeed;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Stop($"Load CCD Check Result NG");
|
|
|
|
|
CCDTriggerResult = Result.VERIFYFAIL;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
}, timeout * 1000);
|
|
|
|
|
|
|
|
|
|
if (ret.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (ret.Item2 == Result.FAIL)
|
|
|
|
|
{
|
|
|
|
|
return Result.VERIFYFAIL;
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
|
|
|
|
{
|
|
|
|
|
Stop($"Load CCD receive result in {timeout} seconds");
|
|
|
|
|
return Result.VERIFYFAIL;
|
|
|
|
|
throw (new RoutineFaildException());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw (new RoutineBreakException());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CCDTriggerResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|