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.LogicUnits; using System; using System.Collections.Generic; using FurnaceRT.Equipments.FIMSs; using FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.Stockers; using FurnaceRT.Equipments.Systems; namespace FurnaceRT.Equipments.WaferRobots { public class WaferRobotPick : ModuleRoutine, IRoutine { enum RoutineStep { Pick, RobotRequestWaferPresent, CheckCassetteInfoByRobotSensor, CheckBeforePick, SetRobotActionCommand, } private ModuleName _source; private int _sourceSlot; private Hand _blade; private WaferRobotModule _waferRobotModule; private int _timeout = 0; private RD_TRIG _holdTrig = new RD_TRIG(); private R_TRIG _emergencyStopTrig = new R_TRIG(); private R_TRIG _pauseTrig = new R_TRIG(); private R_TRIG _resumeTrig = new R_TRIG(); private RoutineStep _routineStep; private double _durationTime = 0; private bool _isHasAlarm = false; private bool _needStartCheck = true; public WaferRobotPick(WaferRobotModule waferRobotModule) { _waferRobotModule = waferRobotModule; Module = waferRobotModule.Module; Name = "Pick"; } public void Init(ModuleName source, int sourceSlot, Hand blade, bool isHasAlarm) { _source = source; _sourceSlot = sourceSlot; _blade = blade; var para = new List { _source, _sourceSlot, _blade, true };//增加参数true,表示执行过程中有alarm _waferRobotModule.PickWaferFailAlarm.RetryMessage = (int)WaferRobotModule.MSG.PickRetry; _waferRobotModule.PickWaferFailAlarm.RetryMessageParas = para.ToArray(); _waferRobotModule.PickWaferTimeoutAlarm.RetryMessage = (int)WaferRobotModule.MSG.PickRetry; _waferRobotModule.PickWaferTimeoutAlarm.RetryMessageParas = para.ToArray(); _waferRobotModule.RequestWaferPresentFailAlarm.RetryMessage = (int)WaferRobotModule.MSG.PickRetry; _waferRobotModule.RequestWaferPresentFailAlarm.RetryMessageParas = para.ToArray(); _waferRobotModule.RequestWaferPresentTimeoutAlarm.RetryMessage = (int)WaferRobotModule.MSG.PickRetry; _waferRobotModule.RequestWaferPresentTimeoutAlarm.RetryMessageParas = para.ToArray(); _waferRobotModule.RobotHasError.RetryMessage = (int)WaferRobotModule.MSG.PickRetry; _waferRobotModule.RobotHasError.RetryMessageParas = para.ToArray(); _isHasAlarm = isHasAlarm; if (!_isHasAlarm) _needStartCheck = true; } public Result Start(params object[] objs) { // 抛出过alarm就不reset if (!_isHasAlarm) { Reset(); } else { List stepLst = new List(Steps.ToArray()); stepLst.Remove((int)_routineStep); Steps = new Stack(stepLst); _isHasAlarm = false; ResetState(); } _holdTrig.RST = true; _emergencyStopTrig.RST = true; _pauseTrig.RST = true; _resumeTrig.RST = true; _timeout = SC.GetValue($"{Module}.PickTimeout"); if (_needStartCheck) { if (_blade == Hand.Blade1) { if (SC.GetValue("System.IsSimulatorMode")) { if (!WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 2)) { //_waferRobotModule.BladeWaferPresentWarning.Description = $"{ModuleName.WaferRobot} {_blade} wafer present"; _waferRobotModule.BladeWaferPresentWarning.Set($"{ModuleName.WaferRobot} {_blade} wafer present"); return Result.FAIL; } } else { if (_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade3 || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 2)) { //_waferRobotModule.BladeWaferPresentWarning.Description = $"{ModuleName.WaferRobot} {_blade} wafer present"; _waferRobotModule.BladeWaferPresentWarning.Set($"{ModuleName.WaferRobot} {_blade} wafer present"); return Result.FAIL; } } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 1} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 1} wafer not present"); return Result.FAIL; } } else if (_blade == Hand.Blade2) { if (SC.GetValue("System.IsSimulatorMode")) { if (!WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 1) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 2) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 3) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 4)) { //_waferRobotModule.BladeWaferPresentWarning.Description = $"{ModuleName.WaferRobot} {_blade} wafer present"; _waferRobotModule.BladeWaferPresentWarning.Set($"{ModuleName.WaferRobot} {_blade} wafer present"); return Result.FAIL; } } else { if (_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade2 || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 1) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 2) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 3) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 4)) { //_waferRobotModule.BladeWaferPresentWarning.Description = $"{ModuleName.WaferRobot} {_blade} wafer present"; _waferRobotModule.BladeWaferPresentWarning.Set($"{ModuleName.WaferRobot} {_blade} wafer present"); return Result.FAIL; } } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 1} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 1} wafer not present"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 1)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 2} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 2} wafer not present"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 2)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 3} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 3} wafer not present"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 3)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 4} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 4} wafer not present"); return Result.FAIL; } } else if (_blade == Hand.Both) { if (SC.GetValue("System.IsSimulatorMode")) { if (!WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 0) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 1) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 2) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 3) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 4)) { //_waferRobotModule.BladeWaferPresentWarning.Description = $"{ModuleName.WaferRobot} {_blade} wafer present"; _waferRobotModule.BladeWaferPresentWarning.Set($"{ModuleName.WaferRobot} {_blade} wafer present"); return Result.FAIL; } } else { if (_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade1 || _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade2 || _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade3 || _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade4 || _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade5 || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 0) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 1) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 2) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 3) || !WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 4)) { //_waferRobotModule.BladeWaferPresentWarning.Description = $"{ModuleName.WaferRobot} {_blade} wafer present"; _waferRobotModule.BladeWaferPresentWarning.Set($"{ModuleName.WaferRobot} {_blade} wafer present"); return Result.FAIL; } } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 1} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 1} wafer not present"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 1)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 2} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 2} wafer not present"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 2)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 3} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 3} wafer not present"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 3)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 4} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 4} wafer not present"); return Result.FAIL; } if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 4)) { //_waferRobotModule.TargetWaferNotPresentWarning.Description = $"{_source} {_sourceSlot + 5} wafer not present"; _waferRobotModule.TargetWaferNotPresentWarning.Set($"{_source} {_sourceSlot + 5} wafer not present"); return Result.FAIL; } } if (ModuleHelper.IsPm(_source)) { var pmModule = Singleton.Instance.Modules[_source] as PMModule; if (pmModule != null && !pmModule.CheckReadyForTransfer(ModuleHelper.Converter(_waferRobotModule.Module), _blade, _sourceSlot, EnumTransferType.Pick, out string reason)) { //_waferRobotModule.PickWaferFailAlarm.Description = reason; _waferRobotModule.PickWaferFailAlarm.Set(reason); return Result.FAIL; } } if (_source == ModuleName.FIMS1 || _source == ModuleName.FIMS2) { var fims = Singleton.Instance.Modules[_source] as FIMSModule; if (fims != null && !fims.CheckReadyForTransfer(ModuleHelper.Converter(Module), _blade, _sourceSlot, EnumTransferType.Pick, out string reason)) { //_waferRobotModule.PickWaferFailAlarm.Description = reason; _waferRobotModule.PickWaferFailAlarm.Set(reason); return Result.FAIL; } if (fims != null&&fims.IsWaferOnRobot) { _waferRobotModule.PickWaferFailAlarm.Set($"The wafer on {Module} has shifted"); } } } Notify($"Start"); return Result.RUN; } public void Abort() { _waferRobotModule.ResetRobotActionCommand(); _waferRobotModule.Stop(); (Singleton.Instance.Modules[_source] as ITransferTarget)?.NoteTransferStop(ModuleHelper.Converter(_waferRobotModule.Module), _blade, _sourceSlot, EnumTransferType.Pick); } public override Result Monitor() { try { PauseRountine(_waferRobotModule.WaferRobotDevice.IsPause); if (_waferRobotModule.WaferRobotDevice.IsPause) return Result.RUN; CheckBeforePick((int)RoutineStep.CheckBeforePick, _source, _sourceSlot, _blade); if (_waferRobotModule.TrigActionCommand != null) SetRobotActionCommand((int)RoutineStep.SetRobotActionCommand, _source, _timeout); Pick((int)RoutineStep.Pick, _source, _sourceSlot, _blade, _timeout); //RobotRequestWaferPresent((int)RoutineStep.RobotRequestWaferPresent, _blade, _timeout); CheckWaferInfoByRobotSensor((int)RoutineStep.CheckCassetteInfoByRobotSensor, _blade, true); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException ex) { _waferRobotModule.ResetRobotActionCommand(); (Singleton.Instance.Modules[_source] as ITransferTarget)?.NoteTransferStop(ModuleHelper.Converter(_waferRobotModule.Module), _blade, _sourceSlot, EnumTransferType.Pick); return Result.FAIL; } _waferRobotModule.ResetRobotActionCommand(); (Singleton.Instance.Modules[_source] as ITransferTarget)?.NoteTransferStop(ModuleHelper.Converter(_waferRobotModule.Module), _blade, _sourceSlot, EnumTransferType.Pick); Notify("Finished"); return Result.DONE; } private void PickStartInfo(ModuleName moduleName) { if (ModuleHelper.IsFIMS(moduleName)) { var fimsFoupInfo = CarrierManager.Instance.GetCarrier(_source); fimsFoupInfo.UICarrierStatusEnum = CarrierStatus.WCHARG; Singleton.Instance.SetVisibility(fimsFoupInfo, true); Singleton.Instance.SetUIWaferCount(fimsFoupInfo, moduleName, out var wafers); } if (ModuleHelper.IsPm(moduleName)) { var fims1 = Singleton.Instance.Modules[ModuleName.FIMS1] as FIMSModule; var fims2 = Singleton.Instance.Modules[ModuleName.FIMS2] as FIMSModule; if (fims1 != null && fims1.CheckReadyForTransfer(ModuleName.WaferRobot, _blade, 0, EnumTransferType.Place, out string reason)) { var fims1FoupInfo = CarrierManager.Instance.GetCarrier(ModuleName.FIMS1); fims1FoupInfo.UICarrierStatusEnum = CarrierStatus.WDCHRG; Singleton.Instance.SetUIWaferCount(fims1FoupInfo, ModuleName.FIMS1, out var wafers); Singleton.Instance.SetVisibility(fims1FoupInfo, true); } if (fims2 != null && fims2.CheckReadyForTransfer(ModuleName.WaferRobot, _blade, 0, EnumTransferType.Place, out reason)) { var fims2FoupInfo = CarrierManager.Instance.GetCarrier(ModuleName.FIMS2); fims2FoupInfo.UICarrierStatusEnum = CarrierStatus.WDCHRG; Singleton.Instance.SetUIWaferCount(fims2FoupInfo, ModuleName.FIMS2, out var wafers); Singleton.Instance.SetVisibility(fims2FoupInfo, true); } } } private void CheckBeforePick(int id, ModuleName source, int slot, Hand blade) { Tuple ret = Execute(id, () => { Notify("Check pick condition"); string reason = string.Empty; if (_waferRobotModule.WaferRobotDevice.IsError) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for robot error, error code={_waferRobotModule.WaferRobotDevice.ErrorCode}"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for robot error, error code={_waferRobotModule.WaferRobotDevice.ErrorCode}"); return false; } if (!_waferRobotModule.WaferRobotDevice.IsReady(out reason)) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for robot isn't Ready"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for robot isn't Ready {reason}"); return false; } if (ModuleHelper.IsPm(_source)) { var pmModule = Singleton.Instance.Modules[_source] as PMModule; if (pmModule != null && !pmModule.CheckReadyForTransfer(ModuleHelper.Converter(_waferRobotModule.Module), _blade, _sourceSlot, EnumTransferType.Pick, out reason)) { //_waferRobotModule.PickWaferFailAlarm.Description = reason; _waferRobotModule.PickWaferFailAlarm.Set(reason); return false; } PickStartInfo(_source); } if (source == ModuleName.FIMS1 || source == ModuleName.FIMS2) { var fims = Singleton.Instance.Modules[source] as FIMSModule; if (fims != null && !fims.CheckReadyForTransfer(ModuleHelper.Converter(Module), _blade, slot, EnumTransferType.Pick, out reason)) { //_waferRobotModule.PickWaferFailAlarm.Description = reason; _waferRobotModule.PickWaferFailAlarm.Set(reason); return false; } PickStartInfo(source); } if (blade == Hand.Blade1) { if (!WaferManager.Instance.CheckHasWafer(source, slot)) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for {source} no wafer"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for {source} no wafer"); return false; } if (!WaferManager.Instance.CheckNoWafer(Module, 2)) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for blade has wafer"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for blade has wafer"); return false; } } else if (blade == Hand.Blade2) { if (!WaferManager.Instance.CheckHasWafer(source, slot)) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for {source} no wafer"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for {source} no wafer"); return false; } if (!WaferManager.Instance.CheckNoWafer(Module, 1)) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for blade has wafer"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for blade has wafer"); return false; } } else { for (int i = 0; i < 5; i++) { if (!WaferManager.Instance.CheckHasWafer(source, slot + i)) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for {source} no wafer"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for {source} no wafer"); return false; } if (!WaferManager.Instance.CheckNoWafer(Module, i)) { //_waferRobotModule.PickWaferFailAlarm.Description = $"pick from {source} failed for blade has wafer"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for blade has wafer"); return false; } } } return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } _needStartCheck = false; } private void Pick(int id, ModuleName source, int slot, Hand hand, int timeout) { _routineStep = (RoutineStep)Enum.Parse(typeof(RoutineStep), id.ToString()); Tuple ret = ExecuteAndWait(id, () => { Notify("Pick"); string reason; (Singleton.Instance.Modules[source] as ITransferTarget)?.NoteTransferStart(ModuleHelper.Converter(_waferRobotModule.Module), hand, slot, EnumTransferType.Pick); if (!_waferRobotModule.RobotPick(source, slot, hand, out reason)) { //_waferRobotModule.PickWaferFailAlarm.Description = reason; _waferRobotModule.PickWaferFailAlarm.Set(reason); return false; } return true; }, () => { if (_waferRobotModule.WaferRobotDevice.IsReady() && !_waferRobotModule.WaferRobotDevice.IsError) { return true; } return false; }, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { //_waferRobotModule.PickWaferFailAlarm.Description = $"{_waferRobotModule.WaferRobotDevice.ErrorCode}"; _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for robot error, error code={_waferRobotModule.WaferRobotDevice.ErrorCode}"); throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { //_waferRobotModule.PickWaferTimeoutAlarm.Description = $"timeout over {timeout} seconds"; _waferRobotModule.PickWaferTimeoutAlarm.Set($"timeout over {timeout} seconds"); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } private void RobotRequestWaferPresent(int id, Hand hand, int timeout) { Tuple ret = ExecuteAndWait(id, () => { Notify("request wafer present"); if (!_waferRobotModule.RequestWaferPresent(hand, out string reason)) { //_waferRobotModule.RequestWaferPresentFailAlarm.Description = reason; _waferRobotModule.RequestWaferPresentFailAlarm.Set(reason); return false; } return true; }, () => { if (_waferRobotModule.WaferRobotDevice.IsReady() && !_waferRobotModule.WaferRobotDevice.IsError) { return true; } return false; }, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { //_waferRobotModule.RequestWaferPresentTimeoutAlarm.Description = $"timeout over {timeout} seconds"; _waferRobotModule.RequestWaferPresentTimeoutAlarm.Set($"timeout over {timeout} seconds"); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } private void CheckWaferInfoByRobotSensor(int id, Hand hand, bool isAfterPick) { Tuple ret = Execute(id, () => { Notify($"check wafer info by robot RQ present"); if (SC.GetValue("System.IsSimulatorMode")) return true; if (hand == Hand.Blade1 || hand == Hand.Both) { if (!isAfterPick && _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade3) { _waferRobotModule.RobotSensorFoundWaferOnBladeAfterPlaceAlarm.Set("Wafer Robot sensor found wafer on blade 3"); return false; } if (isAfterPick && !_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade3) { _waferRobotModule.RobotSensorNotFoundWaferOnBladeAfterPickAlarm.Set("Wafer Robot sensor no wafer on blade 3"); return false; } } if (hand == Hand.Blade2 || hand == Hand.Both) { if (!isAfterPick && _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade1) { _waferRobotModule.RobotSensorFoundWaferOnBladeAfterPlaceAlarm.Set("Wafer Robot sensor found wafer on blade 1"); return false; } if (isAfterPick && !_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade1) { _waferRobotModule.RobotSensorNotFoundWaferOnBladeAfterPickAlarm.Set("Wafer Robot sensor no wafer on blade 1"); return false; } if (!isAfterPick && _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade2) { _waferRobotModule.RobotSensorFoundWaferOnBladeAfterPlaceAlarm.Set("Wafer Robot sensor found wafer on blade 2"); return false; } if (isAfterPick && !_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade2) { _waferRobotModule.RobotSensorNotFoundWaferOnBladeAfterPickAlarm.Set("Wafer Robot sensor no wafer on blade 2"); return false; } if (!isAfterPick && _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade4) { _waferRobotModule.RobotSensorFoundWaferOnBladeAfterPlaceAlarm.Set("Wafer Robot sensor found wafer on blade 4"); return false; } if (isAfterPick && !_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade4) { _waferRobotModule.RobotSensorNotFoundWaferOnBladeAfterPickAlarm.Set("Wafer Robot sensor no wafer on blade 4"); return false; } if (!isAfterPick && _waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade5) { _waferRobotModule.RobotSensorFoundWaferOnBladeAfterPlaceAlarm.Set("Wafer Robot sensor found wafer on blade 5"); return false; } if (isAfterPick && !_waferRobotModule.WaferRobotDevice.IsWaferPresenceOnBlade5) { _waferRobotModule.RobotSensorNotFoundWaferOnBladeAfterPickAlarm.Set("Wafer Robot sensor no wafer on blade 5"); return false; } } return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { _waferRobotModule.CheckWaferInformationFailAlarm.Set(); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } private void SetRobotActionCommand(int id, ModuleName source, int timeout) { _routineStep = (RoutineStep)Enum.Parse(typeof(RoutineStep), id.ToString()); Tuple ret = ExecuteAndWait(id, () => { Notify($"Set robot action command target position {source}"); _waferRobotModule.SetRobotActionCommand(source, EnumTransferType.Pick); return true; }, () => { return _waferRobotModule.CheckRobotActionCommand(source, EnumTransferType.Pick); }, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { _waferRobotModule.PickWaferFailAlarm.Set($"pick from {source} failed for robot action command interlock"); throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { _waferRobotModule.PickWaferTimeoutAlarm.Set($"timeout over {timeout} seconds"); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } } }