using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Communications; using MECF.Framework.Common.Equipment; using System; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.Sunway { public abstract class SunwayRobotHandler : HandlerBase { public SunwayRobot Device { get; } public bool HasResponse { get; set; } = true; protected string _command; protected string _parameter; protected string _target; protected RobotArmEnum _blade; /// /// Handler执行完毕后执行的任务。 /// protected Action _onHandlerEndTask; protected string _requestResponse = ""; protected SunwayRobotHandler(SunwayRobot device, string command, string parameter = null, Action onHandlerEndTask = null) : base(BuildMessage(command, parameter)) { Device = device; _command = command; _parameter = parameter; Name = command; _onHandlerEndTask = onHandlerEndTask; } private static string BuildMessage(string command, string parameter) { string msg = parameter == null ? $"{command}" : $"{command} {parameter}"; return msg + "\r\n"; } public override bool HandleMessage(MessageBase msg, out bool transactionComplete) { var response = msg as SunwayRobotMessage; ResponseMessage = msg; if (response.IsError) { Device.NoteError(response.Data); } if (response.IsComplete) { SetState(EnumHandlerState.Completed); transactionComplete = true; return true; } if (response.IsResponse) { _requestResponse = response.Data; } transactionComplete = false; return false; } } public class SunwayRobotHomeHandler : SunwayRobotHandler { //HOM public SunwayRobotHomeHandler(SunwayRobot device, int timeout = 60, Action onHandlerEndTask = null) : base(device, $"HOME ALL", onHandlerEndTask: onHandlerEndTask) { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.Both, BladeTarget = "ArmA.System", }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot HOM Timeout"); return true; } if (result.Data == "_RDY") { Device.IsBusy = false; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot HOME Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; handled = true; _onHandlerEndTask?.Invoke(); Device.NoteActionCompleted(); return true; } } public class SunwayRobotRQLoadHandler : SunwayRobotHandler { // RQ LOAD public SunwayRobotRQLoadHandler(SunwayRobot device, int timeout = 5) : base(device, "RQ LOAD A") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot RQ LOAD Timeout"); return true; } if (result.Data.Contains("ERR")) { Device.NoteError("Robot RQ LOAD Error"); return false; } else { Device.SetWaferData(result.Data); } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; Device.IsBusy = false; handled = true; return true; } } public class SunwayRobotGotoMapHandler : SunwayRobotHandler { //GOTO N station [MAP (EX|RE)] [[RX] R1|R2|R3] public SunwayRobotGotoMapHandler(SunwayRobot device, string module, bool isRetract,int timeout = 60) : base(device, "GOTO", $"N {device.ModuleAssociateStationDic[module]} MAP {(isRetract ? "RE" : "EX")}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.Both, BladeTarget = "ArmA.System", }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot Goto Map Timeout"); return true; } if (result.Data == "_RDY") { Device.IsBusy = false; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot Goto Map Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; handled = true; _onHandlerEndTask?.Invoke(); Device.NoteActionCompleted(); return true; } } public class SunwayRobotMapHandler : SunwayRobotHandler { //MAP station public SunwayRobotMapHandler(SunwayRobot device, string module, int timeout = 60) : base(device, $"MAP {device.ModuleAssociateStationDic[module]}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.Both, BladeTarget = "ArmA.System", }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot Goto Map Timeout"); return true; } if (result.Data == "_RDY") { Device.IsBusy = false; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot Goto Map Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; handled = true; _onHandlerEndTask?.Invoke(); Device.NoteActionCompleted(); return true; } } public class SunwayRobotRSRHandler : SunwayRobotHandler { //RSR station public SunwayRobotRSRHandler(SunwayRobot device, string module, int timeout = 60) : base(device, $"RSR {device.ModuleAssociateStationDic[module]}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot RSR Timeout"); return true; } if (result.Data.Length == 53 || result.Data.Length == 19) { Device.SetWaferData(result.Data); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot RSR Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; Device.NoteActionCompleted(); handled = true; return true; } } public class SunwayRobotGotoHandler : SunwayRobotHandler { //GOTO N station [R (EX|RE)] [Z (UP|DN)] [SLOT num] [[ARM] arm] public SunwayRobotGotoHandler(SunwayRobot device, string module, int slot, RobotArmEnum blade, bool isRetract = true, bool isZaxisDown = true, int timeout = 60) : base(device, "GOTO", $"N {device.ModuleAssociateStationDic[module]} R {(isRetract ? "RE" : "EX")}" + $" Z {(isZaxisDown ? "DN" : "UP")} SLOT {slot} ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot GoTo Command Timeout"); return true; } if (result.Data == "_RDY") { Device.IsBusy = false; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot Goto Command Error"); Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotPickHandler : SunwayRobotHandler { private bool isRetract; private string cModule; //PICK station [SLOT slot] [[ARM] arm] [ENRT|STRT NR] public SunwayRobotPickHandler(SunwayRobot device, string module, int slot, RobotArmEnum blade, bool isRetract = true, int timeout = 60) : base(device, "PICK", $"{device.ModuleAssociateStationDic[module]} SLOT {slot}" + $" ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}" + $" {(isRetract ? "STRT" : "ENRT")}" + " NR") { this.isRetract = isRetract; this.cModule = module; AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); //伸出时的动画 if (!isRetract) { device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot Pick Command Timeout"); return true; } if (result.Data == "_RDY") { if (!isRetract) { //将Robot的状态从ExtendingForPick转到Idle Device.NoteActionCompleted(); //伸出 Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = cModule, }; } else { //将Robot的状态从Picking转到Idle Device.NoteActionCompleted(); //缩回 Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot Pick Command Response Error"); if (!isRetract) // 伸出手臂 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Extending, ArmTarget = RobotArm.ArmA, BladeTarget = cModule, }; } else { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotPlaceHandler : SunwayRobotHandler { private bool isRetract; private string cModule; //Place station [SLOT slot] [[ARM] arm] [ENRT|STRT NR] public SunwayRobotPlaceHandler(SunwayRobot device, string module, int slot, RobotArmEnum blade, bool isRetract = true, int timeout = 60) : base(device, "PLACE", $"{device.ModuleAssociateStationDic[module]} SLOT {slot}" + $" ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}" + $" {(isRetract ? "STRT" : "ENRT")}" + " NR") { this.isRetract = isRetract; this.cModule = module; AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); //伸出时的动画 if (!isRetract) { device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot Place Command Timeout"); return true; } if (result.Data == "_RDY") { if (!isRetract) { //将Robot的状态从ExtendingForPlace转到Idle Device.NoteActionCompleted(); //伸出 Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = cModule, }; } else { //将Robot的状态从Placeing转到Idle Device.NotePlaceCompleted(); //缩回 Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot Place Command Response Error"); if (!isRetract) // 伸出手臂 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Extending, ArmTarget = RobotArm.ArmA, BladeTarget = cModule, }; } else { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotVacHandler : SunwayRobotHandler { //VAC ON|OFF ARM A|B public SunwayRobotVacHandler(SunwayRobot device,bool isOpen, RobotArmEnum blade,int timeout = 5) : base(device, $"VAC {(isOpen ? "ON" : "OFF")} ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot VAC Command Timeout"); return true; } if (result.Data.Contains("ERR")) { Device.NoteError("Robot VAC Command Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; Device.IsBusy = false; handled = true; return true; } } public class SunwayRobotGripHandler : SunwayRobotHandler { //GRIP ON|OFF ARM A|B public SunwayRobotGripHandler(SunwayRobot device, bool isOpen, RobotArmEnum blade, int timeout = 5) : base(device, $"GRIP {(isOpen ? "ON" : "OFF")} ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot GRIP Command Timeout"); return true; } if (result.Data.Contains("ERR")) { Device.NoteError("Robot GRIP Command Error"); return false; } ResponseMessage = msg; Device.IsBusy = false; handled = true; return true; } } public class SunwayRobotSetEchoHandler : SunwayRobotHandler { //SET IO ECHO Y|N public SunwayRobotSetEchoHandler(SunwayRobot device, bool isOpen, int timeout = 5) : base(device, $"SET IO ECHO {(isOpen ? "Y" : "N")}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot Set IO Echo Command Timeout"); return true; } if (result.Data.Contains("ERR")) { Device.NoteError("Robot Set IO Echo Command Error"); return false; } ResponseMessage = msg; Device.IsBusy = false; handled = true; return true; } } public class SunwayRobotSTATHandler : SunwayRobotHandler { // STAT public SunwayRobotSTATHandler(SunwayRobot device, int timeout = 5, Action onHandlerEndTask = null) : base(device, $"RQ STATE", onHandlerEndTask: onHandlerEndTask) { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot STAT Timeout"); return true; } if (result.Data.Contains("ERR")) { Device.NoteError("Robot STAT Response Error"); return false; } //Wafer位置从机械手和Station之间转换 if (Device.ParseStatusData(result.Data)) _onHandlerEndTask?.Invoke(); handled = true; return true; } } public class SunwayRobotERRHandler : SunwayRobotHandler { // STAT public SunwayRobotERRHandler(SunwayRobot device, int timeout = 5, Action onHandlerEndTask = null) : base(device, $"ERR 0", onHandlerEndTask: onHandlerEndTask) { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot ERR Timeout", false); return true; } if (result.Data.Contains("ERR")) { Device.NoteError("Robot ERR Response Error", false); return false; } if (Device.ParseErrData(result.Data)) _onHandlerEndTask?.Invoke(); handled = true; return true; } } public class SunwayRobotGETAHandler : SunwayRobotHandler { //GETA [module],[slot] public SunwayRobotGETAHandler(SunwayRobot device, string module, int slot, int timeout = 60) : base(device, $"GETA {device.ModuleAssociateStationDic[module]} {slot + 1}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot GETA Timeout"); return true; } if (result.Data == "_RDY") { //Wafer位置从机械手和Station之间转换 Device.PrasePutWaferData(); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot GETA Response Error"); return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotGETBHandler : SunwayRobotHandler { //GETB [module],[slot] public SunwayRobotGETBHandler(SunwayRobot device, string module, int slot, int timeout = 60) : base(device, $"GETB {device.ModuleAssociateStationDic[module]} {slot + 1}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot GETB Timeout"); return true; } if (result.Data == "_RDY") { //Wafer位置从机械手和Station之间转换 Device.PraseGetWaferData(); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot GETB Response Error"); return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotBGETBHandler : SunwayRobotHandler { //GETB [module],[slot] string cModule = ""; public SunwayRobotBGETBHandler(SunwayRobot device, string module, int slot, int timeout = 60) : base(device, $"GETB {device.ModuleAssociateStationDic[module]} {slot + 1}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); cModule = module; device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot GETB Timeout"); return true; } if (result.Data == "_RDY") { Device.GetWaferData(); Device.NotePickCompleted(); Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot GETB Response Error"); return true; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotPUTAHandler : SunwayRobotHandler { //PUTA [module],[slot] public SunwayRobotPUTAHandler(SunwayRobot device, string module, int slot, int timeout = 60) : base(device, $"PUTA {device.ModuleAssociateStationDic[module]} {slot + 1}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot PUTA Timeout"); return true; } if (result.Data == "_RDY") { //Wafer位置从机械手和Station之间转换 //Device.PraseWaferData(result.Data); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot PUTA Response Error"); return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotPUTBHandler : SunwayRobotHandler { //PUTA [module],[slot] public SunwayRobotPUTBHandler(SunwayRobot device, string module, int slot, int timeout = 60) : base(device, $"PUTB {device.ModuleAssociateStationDic[module]} {slot + 1}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot PUTB Timeout"); return true; } if (result.Data == "_RDY") { //Wafer位置从机械手和Station之间转换 //Device.PraseWaferData(result.Data); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot PUTB Response Error"); return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotBPUTBHandler : SunwayRobotHandler { //PUTA [module],[slot] string cModule = ""; public SunwayRobotBPUTBHandler(SunwayRobot device, string module, int slot, int timeout = 60) : base(device, $"PUTB {device.ModuleAssociateStationDic[module]} {slot + 1}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); cModule = module; device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot PUTB Timeout"); return true; } if (result.Data == "_RDY") { Device.PutWaferData(); Device.NotePlaceCompleted(); Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot PUTB Response Error"); return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotPUTSPHandler : SunwayRobotHandler { //PUTSP [module],[slot],[step] //step:1:初始化位置 2:伸出 3:开真空并抬升 4:到位回缩 string cModule = ""; int cSlot = 0; int cStep = 0; public SunwayRobotPUTSPHandler(SunwayRobot device, string module, int slot, int step, int timeout = 60) : base(device, $"PUTSP {device.ModuleAssociateStationDic[module]} {slot + 1} {step}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); cModule = module; cSlot = slot; cStep = step; if (cStep == 2) { device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot PUTSP Timeout"); return true; } if (result.Data == "_RDY") { if (cStep == 2) { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = cModule, }; } else if (cStep == 3) { Device.NoteActionCompleted(); } else if (cStep == 4) { Device.NotePlaceCompleted(); Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot PUTSP Response Error"); if (cStep == 2) // 伸出手臂 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Extending, ArmTarget = RobotArm.ArmA, BladeTarget = cModule, }; } else if (cStep == 3) // 開啟真空並抬升取片 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = RobotArm.ArmA, BladeTarget = cModule, }; } else // 1 = 縮回手臂至縮回位置並移動至取片的預備位置; 4 = 縮回手臂 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotGETSPHandler : SunwayRobotHandler { //PUTSP [module],[slot],[step] //step:1:初始化位置 2:伸出 3:关真空并抬升 4:到位回缩 string cModule = ""; int cSlot = 0; int cStep = 0; public SunwayRobotGETSPHandler(SunwayRobot device, string module, int slot, int step, int timeout = 60) : base(device, $"GETSP {device.ModuleAssociateStationDic[module]} {slot + 1} {step}") { cModule = module; cSlot = slot; cStep = step; AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); if (cStep == 2) { device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot GETSP Timeout"); return true; } if (result.Data == "_RDY") { if (cStep == 2) { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = cModule, }; Device.NoteActionCompleted(); } else if (cStep == 3) { Device.NotePickCompleted(); } else if (cStep == 4) { Device.NoteActionCompleted(); Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot GETSP Response Error"); if (cStep == 2) // 伸出手臂 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Extending, ArmTarget = RobotArm.ArmA, BladeTarget = cModule, }; } else if (cStep == 3) // 開啟真空並抬升取片 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = RobotArm.ArmA, BladeTarget = cModule, }; } else // 1 = 縮回手臂至縮回位置並移動至取片的預備位置; 4 = 縮回手臂 { Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; } return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotINPUTHandler : SunwayRobotHandler { // INPUT A 3 public SunwayRobotINPUTHandler(SunwayRobot device, int timeout = 5, string com = "INPUT A 1") : base(device, com) { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot INPUT Timeout"); return true; } if (result.Data.Length == 1) { Device.SetWaferData(result.Data); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot INPUT Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; //Device.NoteActionCompleted(); handled = true; return true; } } public class SunwayRobotBINPUTHandler : SunwayRobotHandler { // INPUT A 3 public SunwayRobotBINPUTHandler(SunwayRobot device, int timeout = 5) : base(device, $"INPUT A 6") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot INPUT Timeout"); return true; } if (result.Data.Length == 1) { Device.SetWaferData(result.Data); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot INPUT Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; Device.NoteActionCompleted(); handled = true; return true; } } public class SunwayRobotOutpOpenHandler : SunwayRobotHandler { //开真空 public SunwayRobotOutpOpenHandler(SunwayRobot device, int timeout = 5) : base(device, $"OUTP 1 1") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot OutP Timeout"); return true; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot OutP Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; //Device.NoteActionCompleted(); handled = true; return true; } } public class SunwayRobotBOPTClosePHandler : SunwayRobotHandler { //打开夹爪 public SunwayRobotBOPTClosePHandler(SunwayRobot device, int timeout = 60) : base(device, $"OUTP 1 1") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot OUTP Timeout"); return true; } if (result.Data == "_RDY") { } else if (result.Data.Contains("ERR")) { return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotOutpCloseHandler : SunwayRobotHandler { //关真空 public SunwayRobotOutpCloseHandler(SunwayRobot device, int timeout = 5) : base(device, $"OUTP 1 0") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot OutP Timeout"); return true; } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot OutP Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; Device.NoteActionCompleted(); handled = true; return true; } } public class SunwayRobotBOPTPHandler : SunwayRobotHandler { //打开夹爪 public SunwayRobotBOPTPHandler(SunwayRobot device, int timeout = 60) : base(device, $"OUTP 1 0") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot OUTP Timeout"); return true; } if (result.Data == "_RDY") { } else if (result.Data.Contains("ERR")) { return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotBRSRHandler : SunwayRobotHandler { //RSR public SunwayRobotBRSRHandler(SunwayRobot device, int timeout = 60) : base(device, $"RSR") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot RSR Timeout"); return true; } if (result.Data.Length > 5) { Device.SetWaferData(result.Data); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot RSR Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; Device.NoteActionCompleted(); handled = true; return true; } } public class SunwayRobotRespHandler : SunwayRobotHandler { //RESP 确认控制器是否成功建立与主控电脑的通信 public SunwayRobotRespHandler(SunwayRobot device, int timeout = 60) : base(device, $"RESP") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot RESP Timeout"); return true; } if (result.Data == "_RDY") { } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot RESP Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotRemsHandler : SunwayRobotHandler { //RESP 确认控制器是否成功建立与主控电脑的通信 public SunwayRobotRemsHandler(SunwayRobot device, int timeout = 60) : base(device, $"REMS") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot REMS Timeout"); return true; } if (result.Data == "_RDY") { } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot REMS Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotSVONHandler : SunwayRobotHandler { //SVON 用以激磁位于机械手臂内之伺服马达 public SunwayRobotSVONHandler(SunwayRobot device, int timeout = 60) : base(device, $"SET SERVOS ON") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot SVON Timeout"); return true; } if (result.Data == "_RDY") { } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot SVON Response Error"); return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotMTCSPHandler : SunwayRobotHandler { //前往位置 public SunwayRobotMTCSPHandler(SunwayRobot device, string module, string strAction, int timeout = 60) : base(device, $"MTCS {device.ModuleAssociateStationDic[$"{module}.{strAction}"]}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = module, }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot MTCS Timeout"); return true; } if (result.Data == "_RDY") { } else if (result.Data.Contains("ERR")) { return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotMOVRGHandler : SunwayRobotHandler { //抬升或下降 一定距离 public SunwayRobotMOVRGHandler(SunwayRobot device, int rDistance, int timeout = 60) : base(device, $"MOVR Z {rDistance}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot MOVR Z Timeout"); return true; } if (result.Data == "_RDY") { Device.GetWaferData(); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot MOVR Z Response Error"); return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotMOVRPHandler : SunwayRobotHandler { //抬升或下降 一定距离 public SunwayRobotMOVRPHandler(SunwayRobot device, int rDistance, int timeout = 60) : base(device, $"MOVR Z {rDistance}") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot MOVR Z Timeout"); return true; } if (result.Data == "_RDY") { Device.PutWaferData(); } else if (result.Data.Contains("ERR")) { Device.NoteError("Robot MOVR Z Response Error"); return false; } ResponseMessage = msg; handled = true; return true; } } public class SunwayRobotRETHHandler : SunwayRobotHandler { //缩回 public SunwayRobotRETHHandler(SunwayRobot device, int timeout = 60) : base(device, $"RETH") { AckTimeout = TimeSpan.FromSeconds(timeout); CompleteTimeout = TimeSpan.FromSeconds(timeout); device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = "ArmA.System", }; } public override bool HandleMessage(MessageBase msg, out bool handled) { var result = msg as SunwayRobotMessage; handled = false; if (!result.IsResponse) { Device.NoteError("Robot RETH Timeout"); return true; } if (result.Data == "_RDY") { Device.NotePickCompleted(); } else if (result.Data.Contains("ERR")) { return false; } Device.MoveInfo = new RobotMoveInfo() { Action = RobotAction.Moving, ArmTarget = RobotArm.ArmA, BladeTarget = ModuleName.System.ToString(), }; ResponseMessage = msg; handled = true; Device.NoteActionCompleted(); return true; } } }