using System; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs; namespace Mainframe.TMs { public class TMRobotPickAndPlaceRoutine : TMBaseRoutine { enum RoutineStep { WaitOpenSlitValveInterlock, OpenSlitValve, CheckBeforePick, Pick, PickLiftMove, PickExtend, PickHandoff, PickHandoffDelay, PickRetract, PickUpdateWaferInfoByHandoff, PickRequestWaferPresent, PickCheckWaferInfoByRobotSensor, PickWaitCloseSlitValveInterlock, PickRequestAWCData, CheckBeforePlace, Place, PlaceLiftMove, PlaceExtend, PlaceHandoff, PlaceHandoffDelay, PlaceRetract, PlaceUpdateWaferInfoByHandoff, PlaceRequestWaferPresent, PlaceCheckWaferInfoByRobotSensor, PlaceWaitCloseSlitValveInterlock, PlaceRequestAWCData, CloseSlitValve, PostTransfer, } private Hand _pickBlade; private Hand _placeBlade; private ModuleName _targetModule; private int _pickSlot; private int _placeSlot; private int _pickTimeout; private int _placeTimeout; private int _postTransferTimeout; private TMSlitValveRoutine _openSlitValveRoutine = new TMSlitValveRoutine(); private TMSlitValveRoutine _closeSlitValveRoutine = new TMSlitValveRoutine(); private bool _requestAWCDataPick; private bool _requestAWCDataPlace; public TMRobotPickAndPlaceRoutine() { Module = "TMRobot"; Name = "Swap"; } public void Init(ModuleName targetModule, int pickSlot, int placeSlot, Hand pickBlade, Hand placeBlade) { _pickBlade = pickBlade; _placeBlade = placeBlade; _targetModule = targetModule; _pickSlot = pickSlot; _placeSlot = placeSlot; _openSlitValveRoutine.Init(targetModule.ToString(), true); _closeSlitValveRoutine.Init(targetModule.ToString(), false); } public override Result Start(params object[] objs) { Reset(); _pickTimeout = SC.GetValue("TMRobot.PickTimeout"); _placeTimeout = SC.GetValue("TMRobot.PlaceTimeout"); _postTransferTimeout = SC.GetValue($"{_targetModule}.PostTransferTimeout"); _requestAWCDataPick = SC.GetValue("System.RequestAWCDataAfterPick"); _requestAWCDataPlace = SC.GetValue("System.RequestAWCDataAfterPlace"); if (!WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, (int) _pickBlade)) { EV.PostWarningLog(Module, $"Can not pick by {_pickBlade}, found wafer on"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, (int)_placeBlade)) { EV.PostWarningLog(Module, $"Can not place by {_placeBlade}, no wafer on"); return Result.FAIL; } if (_pickSlot != _placeSlot) { if (!WaferManager.Instance.CheckHasWafer(_targetModule, _pickSlot)) { EV.PostWarningLog(Module, $"Can not pick from {_targetModule} slot {_pickSlot + 1}, no wafer on"); return Result.FAIL; } if (!WaferManager.Instance.CheckNoWafer(_targetModule, _placeSlot)) { EV.PostWarningLog(Module, $"Can not place to {_targetModule} slot {_placeSlot + 1}, found wafer on"); return Result.FAIL; } } else { if (!WaferManager.Instance.CheckHasWafer(_targetModule, _placeSlot)) { { EV.PostWarningLog(Module, $"Can not pick&place from {_targetModule} slot {_placeSlot + 1}, no wafer on"); return Result.FAIL; } } } Notify("Start"); return Result.RUN; } public override void Abort() { Notify("Abort"); } public override Result Monitor() { try { //Open slit valve //WaitSlitValveOpenInterlock((int)RoutineStep.WaitOpenSlitValveInterlock, TMDevice.GetSlitValve(_targetModule), _pickTimeout); //ExecuteRoutine((int)RoutineStep.OpenSlitValve, _openSlitValveRoutine); //if (ModuleHelper.IsLoadLock(_targetModule)) //{ // LLLiftMove((int)RoutineStep.PickLiftMove, DEVICE.GetDevice(_targetModule.ToString()), _pickSlot, _pickTimeout); //} ////Pick //CheckBeforePick((int)RoutineStep.CheckBeforePick, _targetModule, _pickSlot, _pickBlade); //if (ModuleHelper.IsPm(_targetModule) && DEVICE.GetDevice(_targetModule.ToString()).IsActiveHandoff) //{ // PickExtend((int)RoutineStep.PickExtend, RobotDevice, _targetModule, _pickSlot, _pickBlade, _pickTimeout); // TransferHandoff((int)RoutineStep.PickHandoff, DEVICE.GetDevice(_targetModule.ToString()), EnumTransferType.Pick, _pickTimeout); // Delay((int)RoutineStep.PickHandoffDelay, 2); // UpdateWaferInfoDueHandoff((int)RoutineStep.PickUpdateWaferInfoByHandoff, _targetModule, _pickSlot, ModuleHelper.Converter(Module), (int)_pickBlade); // PickRetract((int)RoutineStep.PickRetract, RobotDevice, _targetModule, _pickSlot, _pickBlade, _pickTimeout); //} //else //{ // Pick((int)RoutineStep.Pick, RobotDevice, _targetModule, _pickSlot, _pickBlade, _pickTimeout); //} //RobotRequestWaferPresent((int)RoutineStep.PickRequestWaferPresent, RobotDevice, _pickTimeout); //CheckWaferInfoByRobotSensor((int)RoutineStep.PickCheckWaferInfoByRobotSensor, RobotDevice, _pickBlade); //if (_requestAWCDataPick) //{ // RobotRequestWaferAWCData((int)RoutineStep.PickRequestAWCData, RobotDevice, _pickTimeout); //} ////Place //if (ModuleHelper.IsLoadLock(_targetModule)) //{ // LLLiftMove((int)RoutineStep.PlaceLiftMove, DEVICE.GetDevice(_targetModule.ToString()), _placeSlot, _placeTimeout); //} //CheckBeforePlace((int)RoutineStep.CheckBeforePlace, _targetModule, _placeSlot, _placeBlade); //if (ModuleHelper.IsPm(_targetModule) && DEVICE.GetDevice(_targetModule.ToString()).IsActiveHandoff) //{ // PlaceExtend((int)RoutineStep.PlaceExtend, RobotDevice, _targetModule, _placeSlot, _placeBlade, _placeTimeout); // TransferHandoff((int)RoutineStep.PlaceHandoff, DEVICE.GetDevice(_targetModule.ToString()), EnumTransferType.Place, _placeTimeout); // Delay((int)RoutineStep.PlaceHandoffDelay, 2); // UpdateWaferInfoDueHandoff((int)RoutineStep.PlaceUpdateWaferInfoByHandoff, ModuleHelper.Converter(Module), (int)_placeBlade, _targetModule, _placeSlot); // PlaceRetract((int)RoutineStep.PlaceRetract, RobotDevice, _targetModule, _placeSlot, _placeBlade, _placeTimeout); //} //else //{ // Place((int)RoutineStep.Place, RobotDevice, _targetModule, _placeSlot, _placeBlade, _placeTimeout); //} //RobotRequestWaferPresent((int)RoutineStep.PlaceRequestWaferPresent, RobotDevice, _placeTimeout); //CheckWaferInfoByRobotSensor((int)RoutineStep.PlaceCheckWaferInfoByRobotSensor, RobotDevice, _placeBlade); //if (_requestAWCDataPlace) //{ // RobotRequestWaferAWCData((int)RoutineStep.PlaceRequestAWCData, RobotDevice, _placeTimeout); //} ////Close slit valve //WaitSlitValveCloseInterlock((int)RoutineStep.PlaceWaitCloseSlitValveInterlock, TMDevice.GetSlitValve(_targetModule), _placeTimeout); //ExecuteRoutine((int)RoutineStep.CloseSlitValve, _closeSlitValveRoutine); //if (ModuleHelper.IsPm(_targetModule) && DEVICE.GetDevice(_targetModule.ToString()).IsNeedPostTransfer) //{ // PostTransfer((int)RoutineStep.PostTransfer, DEVICE.GetDevice(_targetModule.ToString()), EnumTransferType.Place, _postTransferTimeout); //} } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } Notify("Finished"); return Result.DONE; } protected void LLLiftMove(int id, LoadLock ll, int slot, int timeout) { Tuple ret = ExecuteAndWait(id, () => { Notify($"Move {ll.Name} Lift to {slot + 1}"); if (!ll.SetLift(slot, out string reason)) { Stop(reason); return false; } return true; }, () => { return ll.CheckLift(slot); }, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { Stop($"Timeout, over {timeout} seconds"); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } } }