using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using athosRT.Devices; using athosRT.Devices.PA; using athosRT.FSM; using athosRT.Modules.EFEMs.Tasks; using athosRT.Modules.LPs; using athosRT.tool; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Text; using System.Threading.Tasks; using static MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase.RobotBaseDevice; namespace athosRT.Modules.EFEMs.Routine { public class PlaceExtendRoutine : ModuleRoutineBase, FSM.IRoutine { protected bool MultiWaferSize = Singleton.Instance.GetValue(nameof(MultiWaferSize)).GetValueOrDefault(); private SCConfigItem _scPlaceTimeout => SC.GetConfigItem("Robot.TimeLimitForPlaceWafer"); private int _timeout = 0; private int _axisTimeout = 0; private int _axisSpeed = 0; public LoadPort _lpDevice; protected readonly bool HaveMotionAxis = Singleton.Instance.GetValue("MotionAxisInstalled").GetValueOrDefault(); public ModuleName Station { get; set; } protected bool NeedRobotGripAndUngrip => SC.GetValue("System.EnableRobotGripAndUngrip"); private int _existInterval => SC.GetValue("Robot.Robot.ExistInterval"); public int Slot { get; set; } public Hand Blade { get; set; } public MpntTaskEnum TaskEnum { get; set; } protected Aligner aligner = null; RobotGoto robotgoto; WaitRobotMotion waitrobotmotion; UnGripRobotBlade UnGripRobotBlade; RobotBaseDevice robot; public PlaceExtendRoutine( ModuleName module ) : base(module) { robot = DEVICE.GetDevice("Robot"); if (HaveMotionAxis) { _axisTimeout = SC.GetValue("MotionAxis.MoveTimeout"); _axisSpeed = SC.GetValue("MotionAxis.AutoSpeed"); } aligner = DEVICE.GetDevice("Aligner"); } public void Abort() { } public RState Monitor() { switch (TaskEnum) { case MpntTaskEnum.P1: Runner .Run(PlaceExtendStep.CheckBeforePlace, CheckBeforePlace, fWaitRobotMotion, _timeout) .End(PlaceExtendStep.RobotGoto, fRobotGoto, fWaitRobotMotion, _timeout); break; case MpntTaskEnum.PB: Runner .Run(PlaceExtendStep.CheckBladeWaferIsExist,CheckBladeWaferIsExist, fWaitRobotMotion, _timeout) .Run(PlaceExtendStep.CheckBeforePlace,NullFun,CheckBeforePlace,_timeout) .Run(PlaceExtendStep.RobotGoto,fRobotGoto, fWaitRobotMotion, _timeout) .End(PlaceExtendStep.UnGripRobotBlade, fUnGripRobotBlade, fWaitRobotMotion, _timeout); break; case MpntTaskEnum.P4: Runner .Run(PlaceExtendStep.RobotGoto, fRobotGotoPlaceRetract, fWaitRobotMotion, _timeout) .Run(PlaceExtendStep.CheckBladeWaferIsExist,CheckBladeWaferIsExist, fWaitRobotMotion, _timeout) .End(PlaceExtendStep.CheckAfterPlace, NullFun, CheckAfterPlace,_timeout); break; } return Runner.Status; } private bool fUnGripRobotBlade() { if (NeedRobotGripAndUngrip) { if (robot.Release((RobotArmEnum)Blade)) { LogObject.Info("Robot","Release wafer"); return true; } else { LogObject.Error("Robot", "Cannot release wafer"); return false; } } return true; } private bool CheckAfterPlace() { switch (Blade) { case Hand.Blade1: if (!CheckSensorNoWafer(ModuleName.Robot, (int)Blade)) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend); return false; } break; case Hand.Blade2: for (int index = 0; index < robot.Blade2Slots; ++index) { if (!CheckSensorNoWafer(ModuleName.Robot, (int)(Blade + index))) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend); return false; } } break; default: for (int slot1 = 0; slot1 < robot.Blade2Slots + 1; ++slot1) { if (!CheckSensorNoWafer(ModuleName.Robot, slot1)) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend); return false; } } break; } return true; } private bool CheckBladeWaferIsExist() { //this.robot, this.Blade, this._timeout if (!robot.ReadParameter(new object[3] { "CheckWaferIsPresence", (Blade == Hand.Blade1 ? 0 : 1), _existInterval })) { //手臂上有wafer 无法pick return false; } return true; } private bool fWaitRobotMotion() { if (robot.IsReady()) { LogObject.Info("robot","is ready"); return true; } else { //LogObject.Error("robot", "is not ready"); return false; } } private bool CheckBeforePlace() { //this.Station, this.Slot, this.Blade if (!CheckRobotMotionInterlock(Station, Slot, out _)) { return false; } switch (Blade) { case Hand.Blade1 : if (!Singleton.Instance.CheckWafer(Station, Slot, WaferStatus.Empty)) { return false; } if (!Singleton.Instance.CheckWafer(ModuleName.Robot, (int)Blade, WaferStatus.Normal)) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } if (!CheckSeneorHasWafer(ModuleName.Robot, (int)Blade)) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } break; default: case Hand.Blade2 : bool flag1 = true; for (int index = 0; index < robot.Blade2Slots; ++index) { if (!Singleton.Instance.CheckWafer(Station, Slot + index, WaferStatus.Empty)) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferPresentWithRecord, (object)string.Format("Target {0}{1:D2}", (object)chamber.ToString(), (object)(slot + index + 1))); return false; } flag1 &= Singleton.Instance.CheckWafer(ModuleName.Robot, (int)(Blade + index), WaferStatus.Normal); if (!CheckSeneorHasWafer(ModuleName.Robot, (int)(Blade + index))) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } } if (!flag1) { //EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } break; } if (ModuleHelper.IsCoolingBuffer(Station)) { if (!DEVICE.GetDevice(Station.ToString()).CheckPinUp()) { //EV.PostWarningLog(chamber.ToString(), "Can not place wafer to buffer, buffer isn't pick position."); return false; } } else if (ModuleHelper.IsLoadPort(Station) && this.MultiWaferSize && Singleton.Instance.GetWaferSize(ModuleName.Robot, 0) != DEVICE.GetDevice(Station.ToString()).Size) { //EV.PostWarningLog(chamber.ToString(), "Can not place wafer to loadport, size is unmatch."); return false; } return true; } private bool fRobotGotoPlaceRetract() { bool flag = robot.GoTo(new object[4] { (RobotArmEnum)Blade, Station, Slot, RobotPostionEnum.PlaceRetract }); if (flag) { LogObject.Info("Robot", "RobotGotoPlaceRetract成功"); return true; } else { LogObject.Error("Robot", "RobotGotoPlaceRetract失败"); return false; } } private bool fRobotGoto() { bool flag = robot.GoTo(new object[4] { (RobotArmEnum) Blade, Station, Slot, RobotPostionEnum.PlaceExtend }); if (flag) { LogObject.Info("Robot", "RobotGoto成功"); return true; } else { LogObject.Error("Robot", "RobotGoto失败"); return false; } } public RState Start(params object[] objs) { Reset(); _timeout = _scPlaceTimeout.IntValue * 1000; if (!ModuleHelper.IsLoadLock(Station) || TaskEnum == MpntTaskEnum.ParamNg) { return RState.Failed; } else { return Runner.Start(ModuleName.System, "PlaceExtendRoutine"); } } protected bool CheckSensorNoWafer(ModuleName chamber, int slot) { if (SC.GetValue("System.IsSimulatorMode") || chamber != ModuleName.Robot) return Singleton.Instance.CheckNoWafer(chamber, slot); return slot == 0 ? !this.robot.IsWaferPresenceOnBlade1 : !this.robot.IsWaferPresenceOnBlade2; } protected bool CheckRobotMotionInterlock(ModuleName chamber, int slot, out string reason) { reason = string.Empty; if (robot.RobotState == RobotStateEnum.Error) { reason = "robot is error."; return false; } if (!robot.IsReady()) { reason = string.Format("robot isn't Ready."); return false; } if (chamber == ModuleName.Aligner) { if (aligner.Moving) { reason = string.Format("aligner is moving."); return false; } if (robot.IsReady()) return true; reason = string.Format("aligner isn't Ready."); return false; } if (ModuleHelper.IsLoadPort(chamber)) { LoadPortBaseDevice device = DEVICE.GetDevice(chamber.ToString()); if (!device.IsEnableTransferWafer(out reason)) { reason = string.Format($"{chamber} isn't Ready.The reason is {reason}"); return false; } if (device.MapError) { reason = string.Format("{0} Map has crossed error.", (object)chamber.ToString()); return false; } if (chamber.Equals(ModuleName.LP1)) { if (!DeviceModel.SensorSMIF1PODOPEN.Value) { reason = string.Format("{0} SMIF1PODOPEN signal is Off.", (object)chamber.ToString()); return false; } if (!DeviceModel.SensorSMIF1PODPRESENT.Value) { reason = string.Format("{0} SensorSMIF1PODPRESENT signal is Off,Foup is presence.", (object)chamber.ToString()); return false; } if (!DeviceModel.SensorSMIF1READY.Value) { reason = string.Format("{0} SensorSMIF1READY signal is Off.", (object)chamber.ToString()); return false; } } else if (chamber.Equals(ModuleName.LP2)) { if (!DeviceModel.SensorSMIF2PODOPEN.Value) { reason = string.Format("{0} SMIF2PODOPEN signal is Off.", (object)chamber.ToString()); return false; } if (!DeviceModel.SensorSMIF2PODPRESENT.Value) { reason = string.Format("{0} SensorSMIF2PODPRESENT signal is Off,Foup is not presence .", (object)chamber.ToString()); return false; } if (!DeviceModel.SensorSMIF2READY.Value) { reason = string.Format("{0} SensorSMIF2READY signal is Off.", (object)chamber.ToString()); return false; } } return true; } if (ModuleHelper.IsLoadLock(chamber)) return DEVICE.GetDevice(chamber.ToString()).IsEnableTransferWafer(out reason); if (ModuleHelper.IsCoolingBuffer(chamber)) { IoCoolingBuffer device = DEVICE.GetDevice(chamber.ToString()); if (device.Busy) { reason = "buffer is not idle"; return false; } if (device.CheckPinUp()) return true; reason = "buffer pin not up position"; return false; } if (ModuleHelper.IsAligner(chamber)) { PreAligner device = DEVICE.GetDevice(chamber.ToString()); if (device.Busy) { reason = "Aligner is not Idle"; return false; } return true; } reason = "error target"; return false; } protected bool CheckSeneorHasWafer(ModuleName chamber, int slot) { if (SC.GetValue("System.IsSimulatorMode") || chamber != ModuleName.Robot) return Singleton.Instance.CheckHasWafer(chamber, slot); return slot == 0 ? this.robot.IsWaferPresenceOnBlade1 : this.robot.IsWaferPresenceOnBlade2; } public enum PlaceExtendStep { CheckBladeWaferIsExist, CheckBeforePlace, RobotGoto, WaitRobotMotion, UnGripRobotBlade, CheckAfterPlace, WaitRobotReady, CheckRobotNoBusy } } }