using System; using System.Collections.Generic; using System.Xml; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Sorter.Common; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; namespace FutureEfemLib.Efems { public class FutureEfemRobot : RobotBaseDevice, IEfemRobotCallback { private ModuleName _module; private string _efemName; private IRorzeEfemController _efem; public string Address { get; } public bool IsConnected { get; } //EfemRobotHomeRoutine _homeRoutine; public FutureEfemRobot(string module, XmlElement node, string ioModule = "") : base("EfemRobot", "EfemRobot") { var attrModule = node.GetAttribute("module"); base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule; base.Name = node.GetAttribute("id"); _efemName = node.GetAttribute("efem"); _module = ModuleHelper.Converter(Module); } public FutureEfemRobot(string module, string name, string efemName) : base("EfemRobot", "EfemRobot") { _efemName = efemName; _module = ModuleHelper.Converter(module); } public bool Connect() { return true; } public bool Disconnect() { return true; } protected override bool Init() { if (_efem == null && !string.IsNullOrEmpty(_efemName)) { _efem = DEVICE.GetDevice(_efemName); _efem.SetRobotCallback(ModuleHelper.Converter(Module), this); } RorzeEfemHandler.ParameterModuleMap = new Dictionary() { {"SYSTEM", ModuleName.System}, {"System", ModuleName.System}, {"ROB", ModuleName.EfemRobot}, {"P1", ModuleName.LP1}, {"P2", ModuleName.LP2}, {"P3", ModuleName.LP3}, {"P4", ModuleName.LP4}, {"LLA", ModuleName.LLA}, {"LLB", ModuleName.LLB}, {"BF1", ModuleName.Buffer}, {"ALIGN", ModuleName.Aligner}, }; DATA.Subscribe($"{Module}1.WaferSize", () => WaferManager.Instance.GetWaferSize(_module, 0).ToString()); DATA.Subscribe($"{Module}2.WaferSize", () => WaferManager.Instance.GetWaferSize(_module, 1).ToString()); IsOnline = true; return true; } protected override bool fClear(object[] param) { return true; } protected override bool fStartReadData(object[] param) { ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[0].ToString()); _efem.QueryMapResult(tempmodule.ToString(), out string reason); return true; } protected override bool fStartSetParameters(object[] param) { return true; } protected override bool fStartTransferWafer(object[] param) { return true; } protected override bool fStartUnGrip(object[] param) { return true; } protected override bool fStartGrip(object[] param) { return true; } protected override bool fStartGoTo(object[] param) { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); int slot = int.Parse(param[2].ToString()); if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, arm == RobotArmEnum.Lower ? 0 : 1)) { if (!_efem.MoveToReadyPut(module, slot, arm == RobotArmEnum.Lower ? Hand.Blade1 : Hand.Blade2, out string reason)) { EV.PostAlarmLog(Module, $"Can not move to {module} slot {slot + 1}, " + reason); return false; } } else { if (!_efem.MoveToReadyGet(module, slot, arm == RobotArmEnum.Lower ? Hand.Blade1 : Hand.Blade2, out string reason)) { EV.PostAlarmLog(Module, $"Can not move to {module} slot {slot + 1}, " + reason); return false; } } CmdRobotArm = arm; CmdTarget = module; CmdTargetSlot = slot; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } protected override bool fGoToComplete(object[] param) { MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return base.fGoToComplete(param); } protected override bool fStartMapWafer(object[] param) { ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[0].ToString()); int thicknessIndex = int.Parse(param[1].ToString()); CmdRobotArm = RobotArmEnum.Lower; CmdTarget = tempmodule; CmdTargetSlot = 0; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; FutureEfem efem = _efem as FutureEfem; efem.MapCarrier(tempmodule.ToString(), thicknessIndex, out string _, out string reason); return true; } protected override bool fMapComplete(object[] param) { MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return base.fMapComplete(param); } protected override bool fStartSwapWafer(object[] param) { return true; } protected override bool fStartPlaceWafer(object[] param) { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); int slot = int.Parse(param[2].ToString()); if (!CheckEnablePlace(module, slot, arm, out string reason)) { EV.PostAlarmLog(Module, $"Can not place wafer to {module} slot {slot + 1}, " + reason); return false; } if (!_efem.PutWafer(module, slot, (Hand)(int)arm, out reason)) { EV.PostAlarmLog(Module, $"Can not place wafer to {module} slot {slot + 1}, " + reason); return false; } CmdRobotArm = arm; CmdTarget = module; CmdTargetSlot = slot; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } private bool CheckEnablePlace(ModuleName module, int slot, RobotArmEnum arm, out string reason) { if (arm == RobotArmEnum.Both) { if (!WaferManager.Instance.CheckNoWafer(module, slot) && !WaferManager.Instance.CheckNoWafer(module, slot + 1)) { reason = "target has wafer"; return false; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) && !WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { reason = "robot arm has no wafer"; return false; } } else { if (!WaferManager.Instance.CheckNoWafer(module, slot)) { reason = "target has wafer"; return false; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)arm)) { reason = "robot arm has no wafer"; return false; } } reason = string.Empty; return true; } protected override bool fPlaceComplete(object[] param) { if (CmdRobotArm == RobotArmEnum.Both) { WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade1, CmdTarget, CmdTargetSlot); WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade2, CmdTarget, CmdTargetSlot + 1); } else { WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)CmdRobotArm, CmdTarget, CmdTargetSlot); } MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return base.fPlaceComplete(param); } private string BuildBladeTarget() { return (CmdRobotArm == RobotArmEnum.Upper ? "ArmB" : "ArmA") + "." + CmdTarget; } protected override bool fStartPickWafer(object[] param) { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); int slot = int.Parse(param[2].ToString()); if (!CheckEnablePick(module, slot, arm, out string reason)) { EV.PostAlarmLog(Module, $"Can not pick wafer from {module} slot {slot + 1}, " + reason); return false; } if (!_efem.GetWafer(module, slot, (Hand)(int)arm, out reason)) { EV.PostAlarmLog(Module, $"Can not pick wafer from {module} slot {slot + 1}, " + reason); return false; } CmdRobotArm = arm; CmdTarget = module; CmdTargetSlot = slot; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } private bool CheckEnablePick(ModuleName module, int slot, RobotArmEnum arm, out string reason) { if (arm == RobotArmEnum.Both) { if (!WaferManager.Instance.CheckHasWafer(module, slot) && !WaferManager.Instance.CheckHasWafer(module, slot + 1)) { reason = "source has no wafer"; return false; } if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0) && !WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1)) { reason = "robot arm has wafer"; return false; } } else { if (!WaferManager.Instance.CheckHasWafer(module, slot)) { reason = "source has no wafer"; return false; } if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)arm)) { reason = "robot arm has wafer"; return false; } } reason = string.Empty; return true; } protected override bool fPickComplete(object[] param) { if (CmdRobotArm == RobotArmEnum.Both) { WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)Hand.Blade1); WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot + 1, ModuleHelper.Converter(Module), (int)Hand.Blade2); } else { WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)CmdRobotArm); } MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return base.fPickComplete(param); } protected override bool fResetToReady(object[] param) { return true; } protected override bool fReset(object[] param) { return true; } #region Init/Home public bool Home(out string reason) { if (!CheckToPostMessage((int)RobotMsg.StartInit)) { reason = $"Can not home at {(RobotStateEnum)fsm.State} state"; return false; } reason = string.Empty; return true; } protected override bool fStartInit(object[] param) { CmdRobotArm = RobotArmEnum.Lower; CmdTarget = ModuleName.System; CmdTargetSlot = 0; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Retracting, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } protected override bool fInitComplete(object[] param) { return base.fInitComplete(param); } protected override bool fMonitorInit(object[] param) { IsBusy = false; return true; } protected override bool fMonitorReadData(object[] param) { return base.fMonitorReadData(param); } #endregion public override bool HomeAllAxes(out string reason) { if (!_efem.HomeAllAxes(out reason)) return false; IsBusy = true; return true; } protected override bool fError(object[] param) { string errorInfo = param[0].ToString(); if (param.Length > 0) EV.PostAlarmLog(Module, errorInfo); if (fsm.State == (int)RobotStateEnum.Initializing) { } else if (fsm.State == (int)RobotStateEnum.Picking) { bool waferGot = errorInfo.Contains("|WAFER"); if (waferGot) { if (CmdRobotArm == RobotArmEnum.Both) { WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)Hand.Blade1); WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot + 1, ModuleHelper.Converter(Module), (int)Hand.Blade2); } else { WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)CmdRobotArm); } } } else if (fsm.State == (int)RobotStateEnum.Placing) { bool waferPut = errorInfo.Contains("|NONWAF"); if (waferPut) { if (CmdRobotArm == RobotArmEnum.Both) { WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade1, CmdTarget, CmdTargetSlot); WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade2, CmdTarget, CmdTargetSlot + 1); } else { WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)CmdRobotArm, CmdTarget, CmdTargetSlot); } } } MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } protected override bool fStartExtendForPick(object[] param) { return true; } protected override bool fStartExtendForPlace(object[] param) { return true; } protected override bool fStartRetractFromPick(object[] param) { return true; } protected override bool fStartRetractFromPlace(object[] param) { return true; } public override RobotArmWaferStateEnum GetWaferState(RobotArmEnum arm) { return RobotArmWaferStateEnum.Unknown; } public bool Pick(ModuleName target, Hand blade, int targetSlot, out string reason) { reason = string.Empty; return base.Pick((RobotArmEnum)(int)blade, target.ToString(), targetSlot); } public bool Place(ModuleName target, Hand blade, int targetSlot, out string reason) { reason = string.Empty; return base.Place((RobotArmEnum)(int)blade, target.ToString(), targetSlot); } public bool PickAndPlace(ModuleName pickTarget, Hand pickHand, int pickSlot, ModuleName placeTarget, Hand placeHand, int placeSlot, out string reason) { reason = string.Empty; return false; } public bool Goto(ModuleName target, Hand blade, int targetSlot, out string reason) { reason = string.Empty; return base.GoTo((RobotArmEnum)(int)blade, target.ToString(), targetSlot, RobotPostionEnum.PickReady); } public bool Map(ModuleName target, int thicknessIndex, out string reason) { reason = string.Empty; return base.WaferMapping(target, thicknessIndex); } public void NoteFailed(string error) { IsBusy = false; PostMsg(RobotMsg.ERROR, error); } public void NoteComplete() { if (fsm.State == (int)RobotStateEnum.Initializing) { IsBusy = false; return; } if (fsm.State == (int)RobotStateEnum.Mapping) { IsBusy = false; PostMsg(RobotMsg.ReadData, CmdTarget); } else { IsBusy = false; PostMsg(RobotMsg.ActionDone); } } public void NoteCancel(string error) { if (fsm.State == (int)RobotStateEnum.Initializing) { PostMsg(RobotMsg.ERROR, error); IsBusy = false; return; } IsBusy = false; PostMsg(RobotMsg.ERROR, error); } } }