using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Communications; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.Core.Extensions; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.Sunway.Errors; using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.Sunway { public class SunwayRobot : RobotBaseDevice, IConnection { #region Variables public object _locker = new object(); public PeriodicJob _thread; public readonly Dictionary _errorCodeReferenceDic = new Dictionary(); public readonly LinkedList _lstHandler = new LinkedList(); public readonly SCConfigItem _scHomeTimeout; public readonly SCConfigItem _scMotionTimeout; public readonly R_TRIG _trigCommunicationError = new R_TRIG(); public readonly R_TRIG _trigRetryConnect = new R_TRIG(); public List _disabledIntlkModules = new List(); public readonly bool _enableLog; public string _scRoot; public readonly R_TRIG _trigError = new R_TRIG(); public bool _isAlarm; #endregion #region Constructors public SunwayRobot(string module, string name, string endof = "\r\n") : base(module, name) { DATA.Subscribe($"{Module}.IsConnected", () => IsConnected); DATA.Subscribe($"{Module}.Address", () => Address); DATA.Subscribe($"{Module}.IsBobotReady", () => IsReady()); OP.Subscribe($"{Module}.Reconnect", (string cmd, object[] args) => { Disconnect(); Connect(); return true; }); OP.Subscribe($"{Module}.STAT", (string cmd, object[] args) => { RobotCheckStat(); return true; }); OP.Subscribe($"{Module}.ERR", (string cmd, object[] args) => { RobotCheckError(); return true; }); OP.Subscribe($"{Module}.MAP", (string cmd, object[] args) => { RobotMap(args); return true; }); OP.Subscribe($"{Module}.HOME", (string cmd, object[] args) => { RobotHome(); return true; }); OP.Subscribe($"{Module}.PUTSP", (string cmd, object[] args) => { RobotPlaceSP(args); return true; }); OP.Subscribe($"{Module}.GETSP", (string cmd, object[] args) => { RobotPickSP(args); return true; }); OP.Subscribe($"{Module}.InputA", (string cmd, object[] args) => { InputA(); return true; }); OP.Subscribe($"{Module}.GETA", (string cmd, object[] args) => { RobotPickA(args); return true; }); OP.Subscribe($"{Module}.PUTA", (string cmd, object[] args) => { RobotPlaceA(args); return true; }); OP.Subscribe($"{Module}.GETB", (string cmd, object[] args) => { RobotPickB(args); return true; }); OP.Subscribe($"{Module}.PUTB", (string cmd, object[] args) => { RobotPlaceB(args); return true; }); OP.Subscribe($"{Module}.RobotConnectHomeAll", (string cmd, object[] args) => { RobotConnectHomeAll(); return true; }); OP.Subscribe($"{Module}.RESP", (string cmd, object[] args) => { RobotRESP(); return true; }); OP.Subscribe($"{Module}.REMS", (string cmd, object[] args) => { RobotREMS(); return true; }); OP.Subscribe($"{Module}.SVON", (string cmd, object[] args) => { RobotSVON(); return true; }); OP.Subscribe($"{Module}.AbortAction", (string cmd, object[] args) => { fAbort(args); OnActionDone(args); return true; }); //开真空 OP.Subscribe($"{Module}.VacuumOn", (string cmd, object[] args) => { RobotVacuumOn(); return true; }); //关真空 OP.Subscribe($"{Module}.VacuumOff", (string cmd, object[] args) => { RobotVacuumOff(); return true; }); //开夹爪 OP.Subscribe($"{Module}.HandOn", (string cmd, object[] args) => { RobotGripOff(); return true; }); //关夹爪 OP.Subscribe($"{Module}.HandOff", (string cmd, object[] args) => { RobotGripOn(); return true; }); ModuleAssociateStationDic = new Dictionary() { {$"{ModuleName.PM1 }", 1 }, {$"{ModuleName.PM2}", 2 }, {$"{ModuleName.Buffer}1", 3}, {$"{ModuleName.Buffer}2", 4}, {$"{ModuleName.Buffer}3", 5}, {$"{ModuleName.Load}", 6}, {$"{ModuleName.LoadLock}", 6}, {$"{ModuleName.UnLoad}", 7}, {$"{ModuleName.Aligner}", 8}, {$"{ModuleName.CassAL}", 9}, {$"{ModuleName.CassAR}", 10}, {$"{ModuleName.CassBL}", 12}, }; try { string deviceIP = ""; deviceIP = SC.GetStringValue($"{Module}.Address"); _enableLog = SC.GetValue($"{Module}.EnableLogMessage"); _scHomeTimeout = SC.GetConfigItem($"{Module}.HomeTimeout"); _scMotionTimeout = SC.GetConfigItem($"{Module}.MotionTimeout"); WaferManager.Instance.SubscribeLocation(Module, 1); Connection = new SunwayRobotTCPConnection(deviceIP, endof); Connection.EnableLog(_enableLog); Status = new SunwayRobotStatus(); if (Connection.Connect()) { _trigConnection.CLK = true; PortStatus = "Open"; EV.PostInfoLog(Module, $"{Module}.{Name} connected"); } else { PortStatus = "Close"; EV.PostInfoLog(Module, $"{Module}.{Name} connect failed"); } _thread = new PeriodicJob(100, OnTimer, $"{Module}.{Name} MonitorHandler", true); } catch (Exception ex) { EV.PostAlarmLog(Module, ex.ToString()); } } #endregion #region Properties public string Address => Connection.Address; public bool IsConnected => Connection.IsConnected && !Connection.IsCommunicationError; public string PortStatus { get; set; } = "Closed"; public bool Connect() { return Connection.Connect(); } public bool Disconnect() { return Connection.Disconnect(); } public SunwayRobotTCPConnection Connection { get; } public Dictionary ModuleAssociateStationDic { get; set; } public R_TRIG _trigConnection = new R_TRIG(); public SunwayRobotStatus Status { get; private set; } public SunwayRobotAggregatedErrors Errors { get; private set; } #endregion #region Methods private void CheckStateThenDo(Action onCheckSucceed, Action onCheckFailed = null) { //// 检查Robot状态 //_lstHandler.AddLast(new SunwayRobotERRHandler(this, onHandlerEndTask: () => //{ // if (Errors.AggregateErrorMessages != null && Errors.AggregateErrorMessages.Count > 0) // { // try // { // onCheckFailed?.Invoke(); // } // catch (Exception ex) // { // EV.PostWarningLog(Module, "onCheckFailed action error"); // LOG.Error(ex.Message); // } // } // else // { // try // { // onCheckSucceed?.Invoke(); // } // catch (Exception ex) // { // EV.PostWarningLog(Module, "onCheckSucceed action error"); // LOG.Error(ex.Message); // } // } //})); } public override bool IsReady() { return !Connection.IsBusy && _lstHandler.Count == 0 && !Connection.IsCommunicationError && !IsBusy;// && !_isAlarm;//&& (RobotState == RobotStateEnum.Idle) } protected override bool Init() { return true; } private bool OnTimer() { try { Connection.MonitorTimeout(); if (!Connection.IsConnected || Connection.IsCommunicationError) { lock (_locker) { _lstHandler.Clear(); } _trigRetryConnect.CLK = !Connection.IsConnected; if (_trigRetryConnect.Q) { if (!Connection.Connect()) { EV.PostAlarmLog(Module, $"Can not connect with {Connection.Address}, {Module}.{Name}"); } else { _trigConnection.CLK = true; EV.PostInfoLog(Module, $"Retry connect succee with {Connection.Address}, {Module}.{Name}"); } } return true; } HandlerBase handler = null; if (!Connection.IsBusy) { lock (_locker) { if (_lstHandler.Count > 0) { Debug.WriteLine($"[Thread {Thread.CurrentThread.ManagedThreadId}] Handler Count before: {_lstHandler.Count}"); Debug.WriteLine($"Connection Busy = {Connection.IsBusy}"); handler = _lstHandler.First.Value; _lstHandler.RemoveFirst(); Debug.WriteLine($"[Thread {Thread.CurrentThread.ManagedThreadId}] Handler Removed: {handler?.GetType().FullName}"); Debug.WriteLine($"[Thread {Thread.CurrentThread.ManagedThreadId}] Handler Count after: {_lstHandler.Count}"); } } if (handler != null) { Debug.WriteLine($"[Thread {Thread.CurrentThread.ManagedThreadId}] Executing Handler: {handler?.GetType().FullName}"); Connection.Execute(handler); Debug.WriteLine($"Connection Busy = {Connection.IsBusy}"); } } } catch (Exception ex) { LOG.Write(ex); } return true; } public override void Monitor() { try { _trigCommunicationError.CLK = Connection.IsCommunicationError; if (_trigCommunicationError.Q) { EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {Connection.LastCommunicationError}"); } } catch (Exception ex) { LOG.Write(ex); } } protected override void SubscribeWaferLocation() { //do nothing } public override void Reset() { _trigError.RST = true; Connection.SetCommunicationError(false, ""); _trigCommunicationError.RST = true; _trigWarningMessage.RST = true; _trigRetryConnect.RST = true; base.Reset(); } #endregion #region Command Functions internal bool PraseGetWaferData() { if (CurrentParamter != null && CurrentParamter.Length >= 3) { ModuleName sourceModule; int sourceSlot; if (!int.TryParse(CurrentParamter[2].ToString(), out sourceSlot) || !Enum.TryParse(CurrentParamter[1].ToString(), out sourceModule)) { return false; } if (!WaferManager.Instance.CheckHasTray(RobotModuleName, 0)) { WaferManager.Instance.WaferMoved(sourceModule, sourceSlot, RobotModuleName, 0); return true; } } return false; } /// /// 解析STAT指令返回值。 /// /// /// public virtual bool ParseStatusData(string response) { try { if (!int.TryParse(response, out var status)) { EV.PostAlarmLog(Module, $"Incorrect format of STA Response, {response}"); return false; } var stat = status.ToBitTypeClass(4); Status = stat; var sInfo = Status.AggregateErrorMessages(); if (sInfo != null) { foreach (var s in sInfo) { EV.PostWarningLog(Module, s); } } return true; } catch (Exception ex) { EV.PostWarningLog(Module, $"{nameof(ParseStatusData)}() excepted, {ex.Message}"); return false; } } /// /// 从控制器获取错误代码。 /// 注意:如果控制器返回的字符串格式错误,则解析失败,Errors设置为null。 /// /// /// internal virtual bool ParseErrData(string response) { try { if (SunwayRobotAggregatedErrors.IsErrResponse(response, out _) == false) { EV.PostAlarmLog(Module, $"Incorrect format of ERR Response, {response}"); } else { Errors = null; Errors = new SunwayRobotAggregatedErrors(response); if (Errors.AggregateErrorMessages.Count > 0) { foreach (string errMsg in Errors.AggregateErrorMessages) { EV.PostAlarmLog(Module, errMsg); } } } return true; } catch (Exception ex) { return true; } } internal bool PrasePutWaferData() { if (CurrentParamter != null && CurrentParamter.Length >= 3) { ModuleName sourceModule; int sourceSlot; if (!int.TryParse(CurrentParamter[2].ToString(), out sourceSlot) || !Enum.TryParse(CurrentParamter[1].ToString(), out sourceModule)) { return false; } if (!WaferManager.Instance.CheckHasTray(sourceModule, sourceSlot)) { WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourceModule, sourceSlot); return true; } } return false; } public virtual void RobotPickB(object[] args) { if (args.Length >= 2) { lock (_locker) { _lstHandler.Clear(); CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotGETBHandler(this, args[0].ToString(), Convert.ToInt32(args[1]))); }); } } } public virtual void RobotPlaceB(object[] args) { if (args.Length >= 2) { lock (_locker) { _lstHandler.Clear(); CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotPUTBHandler(this, args[0].ToString(), Convert.ToInt32(args[1]))); }); } } } public void RobotPickA(object[] args) { if (args.Length >= 2) { lock (_locker) { _lstHandler.Clear(); CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotGETAHandler(this, args[0].ToString(), Convert.ToInt32(args[1]))); }); } } } public void RobotPlaceA(object[] args) { if (args.Length >= 2) { lock (_locker) { _lstHandler.Clear(); CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotPUTAHandler(this, args[0].ToString(), Convert.ToInt32(args[1]))); }); } } } public virtual void RobotPickSP(object[] args) { if (args.Length >= 3) { lock (_locker) { _lstHandler.Clear(); CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotGETSPHandler(this, args[0].ToString(), Convert.ToInt32(args[1]), Convert.ToInt32(args[2]))); }); } } } public void RobotPlaceSP(object[] args) { if (args.Length >= 3) { lock (_locker) { _lstHandler.Clear(); CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotPUTSPHandler(this, args[0].ToString(), Convert.ToInt32(args[1]), Convert.ToInt32(args[2]))); }); } } } public virtual void SetWaferData(string data) { //0:无片 1:单片 2:叠片 3:跨槽 ?:未知 string errorMessage = ""; int count = 1; if (CurrentInteractModule == ModuleName.CassAL || CurrentInteractModule == ModuleName.CassAR) { count = 25; } if (CurrentInteractModule == ModuleName.CassBL) { count = 8; } for (int i = 0; i < count; i++) { WaferManager.Instance.DeleteWafer(CurrentInteractModule, i); } if (data.Length == 53)//Wafer Cassette { data = data.Replace("MAP", "").Trim().Replace(" ", ""); for (int i = 0; i < count; i++) { string waferStatue = data.Substring(i, 1); if (waferStatue == "1") { if (!WaferManager.Instance.CheckHasWafer(CurrentInteractModule, i)) { WaferManager.Instance.CreateWafer(CurrentInteractModule, i, WaferStatus.Normal); } } else if (waferStatue == "0" || waferStatue == "?") { if (WaferManager.Instance.CheckHasWafer(CurrentInteractModule, i)) { WaferManager.Instance.DeleteWafer(CurrentInteractModule, i); } } else { string msg = ""; if (!WaferManager.Instance.CheckHasWafer(CurrentInteractModule, i)) { WaferManager.Instance.CreateWafer(CurrentInteractModule, i, GetWaferStarusByNum(waferStatue, out msg)); } else { WaferManager.Instance.GetWafer(CurrentInteractModule, i).WaferStatus = GetWaferStarusByNum(waferStatue, out msg);// Aitex.Core.Common.WaferStatus.Crossed; } errorMessage += $"slot {i + 1} has {msg}!" + "\r\n"; } } } //Wafer Cassette else if (data.Length == 19)//Tray Cassette { data = data.Replace("MAP", "").Trim().Replace(" ", ""); for (int i = 0; i < count; i++) { string tryaStatue = data.Substring(i, 1); if (tryaStatue == "1") { if (!WaferManager.Instance.CheckHasTray(CurrentInteractModule, i)) { WaferManager.Instance.CreateTray(CurrentInteractModule, i); } } else if (tryaStatue == "0" || tryaStatue == "?") { if (WaferManager.Instance.CheckHasTray(CurrentInteractModule, i)) { WaferManager.Instance.DeleteWafer(CurrentInteractModule, i); } } else { if (!WaferManager.Instance.CheckHasTray(CurrentInteractModule, i)) { WaferManager.Instance.CreateTray(CurrentInteractModule, i, Aitex.Core.Common.TrayStatus.Crossed); } errorMessage += $"slot {i + 1} has crossed wafer!" + "\r\n"; } } } else { if (data.Contains("LOAD A ON")) { if (Module=="WaferRobot" && !WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(Module), 0)) { WaferManager.Instance.CreateWafer(ModuleHelper.Converter(Module), 0, WaferStatus.Normal); } if (Module == "TrayRobot" && !WaferManager.Instance.CheckHasTray(ModuleHelper.Converter(Module), 0)) { WaferManager.Instance.CreateTray(ModuleHelper.Converter(Module), 0, TrayStatus.Normal); } } else if (data.Contains("LOAD A OFF")) { if (Module == "WaferRobot" && WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(Module), 0)) { WaferManager.Instance.DeleteWafer(ModuleHelper.Converter(Module), 0); } if (Module == "TrayRobot" && WaferManager.Instance.CheckHasTray(ModuleHelper.Converter(Module), 0)) { WaferManager.Instance.DeleteWafer(ModuleHelper.Converter(Module), 0); } } } if (!String.IsNullOrEmpty(errorMessage)) { EV.PostWarningLog(Module, $"Module {CurrentInteractModule} {errorMessage}"); } } //0:无片 1:单片 2:叠片 3:跨槽 ?:未知 private WaferStatus GetWaferStarusByNum(string num, out string msg) { switch (num) { case "2": msg = "crossed"; return WaferStatus.Crossed; case "3": msg = "double"; return WaferStatus.Double; case "?": msg = "unknow"; return WaferStatus.Double; default: msg = "crossed"; return WaferStatus.Crossed; } } public void RobotCheckStat() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotSTATHandler(this)); } } public virtual void RobotCheckError() { lock (_locker) { _lstHandler.Clear(); _lstHandler.AddLast(new SunwayRobotERRHandler(this)); } } public void RobotHome() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotHomeHandler(this)); } } public void RobotMap(object[] args) { lock (_locker) { _lstHandler.Clear(); _lstHandler.AddLast(new SunwayRobotGotoMapHandler(this, args[0].ToString(),false)); CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotMapHandler(this, args[0].ToString())); }); } } public virtual void InputA() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotOutpOpenHandler(this)); _lstHandler.AddLast(new SunwayRobotINPUTHandler(this)); _lstHandler.AddLast(new SunwayRobotOutpCloseHandler(this)); } } public virtual void RobotConnectHomeAll() { IsBusy = false; Connection.ForceClear(); _lstHandler.Clear(); lock (_locker) { //Robot Home指令包含了清除报警,电机使能,Home动作 _lstHandler.AddLast(new SunwayRobotSetEchoHandler(this, false)); _lstHandler.AddLast(new SunwayRobotHomeHandler(this, _scMotionTimeout.IntValue)); _lstHandler.AddLast(new SunwayRobotRQLoadHandler(this)); } } public void RobotRESP() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotRespHandler(this)); } } public void RobotREMS() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotRemsHandler(this)); } } public void RobotSVON() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotSVONHandler(this)); } } public void RobotVacuumOn() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotVacHandler(this,true,RobotArmEnum.Blade1)); } } public void RobotVacuumOff() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotVacHandler(this, false, RobotArmEnum.Blade1)); } } public void RobotGripOn() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotGripHandler(this, true, RobotArmEnum.Blade1)); } } public void RobotGripOff() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotGripHandler(this, false, RobotArmEnum.Blade1)); } } public void RobotHandOn() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotBOPTPHandler(this)); } } public void RobotHandOff() { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new SunwayRobotBOPTClosePHandler(this)); } } #endregion #region Note Functions public readonly R_TRIG _trigWarningMessage = new R_TRIG(); /// /// 查询并打印错误 /// ///当前指令的错误原因: 超时或返回? ///是否执行ERR指令 ///如果是E[指令本身返回“?,则不要再执行ERR指令,以免造成死循环。 public void NoteError(string reason, bool performErrCmd = true) { //确保传入的信息不能为空 if (string.IsNullOrEmpty(reason)) reason = "Unknown Error"; //重置TCPConnection对象,否则RobotCheckError函数中添加ERR指令到命令列队会造成TCPConnection失效 fAbort(null); EV.PostAlarmLog(Module, $"{Module}.{Name} error, {reason}"); // 查询机械手异常信息。 //if (performErrCmd)// 如果是ERR指令本身返回?,则不要再执行ERR指令,以免造成死循环 // RobotCheckError(); // if (reason != null) // { // fAbort(null); // // _trigWarningMessage.CLK = true; // var content = reason; // if (_errorCodeReferenceDic.ContainsKey(reason)) // { // content = _errorCodeReferenceDic[reason]; // } // if (_trigWarningMessage.Q) // { // EV.PostWarningLog(Module, $"{Module}.{Name} error, {reason} {content}"); // } // _isAlarm = true; // ErrorCode = reason; // } // else // { // _isAlarm = false; // } } public virtual void NoteActionCompleted() { //Blade1Target = ModuleName.System; //Blade2Target = ModuleName.System; IsBusy = false; CheckToPostMessage((int)RobotMsg.ActionDone); } internal void NotePickCompleted() { PostMessageWithoutCheck((int)RobotMsg.PickComplete, CurrentParamter); } internal void NotePlaceCompleted() { PostMessageWithoutCheck((int)RobotMsg.PlaceComplete, CurrentParamter); } protected override bool fStartHome(object[] param) { lock (_locker) { _lstHandler.AddLast(new SunwayRobotHomeHandler(this, _scHomeTimeout.IntValue)); } return true; } protected override bool fClear(object[] param) { return true; } public override bool ReadParameter(object[] param) { return CheckToPostMessage((int)RobotMsg.ReadData, param); } protected override bool fStartReadData(object[] param) { 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) { return true; } protected override bool fStartMapWafer(object[] param) { try { if (param.Length >= 1) { lock (_locker) { _lstHandler.AddLast(new SunwayRobotGotoMapHandler(this, param[0].ToString(), false)); _lstHandler.AddLast(new SunwayRobotMapHandler(this, param[0].ToString(), _scMotionTimeout.IntValue)); _lstHandler.AddLast(new SunwayRobotRSRHandler(this, param[0].ToString(), _scMotionTimeout.IntValue)); _lstHandler.AddLast(new SunwayRobotGotoMapHandler(this, param[0].ToString(), true)); } } } catch (Exception ex) { LOG.Write(ex); return false; } return true; } protected override bool fStartSwapWafer(object[] param) { return false; } protected override bool fPlaceComplete(object[] param) { //arm, station, slot Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; if (CurrentParamter.Length >= 3) { ModuleName sourceModule; int sourceSlot; if (!int.TryParse(CurrentParamter[2].ToString(), out sourceSlot) || !Enum.TryParse(CurrentParamter[1].ToString(), out sourceModule)) { return false; } if (RobotModuleName == ModuleName.WaferRobot) { if (WaferManager.Instance.CheckHasWafer(RobotModuleName, 0)) { WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourceModule, sourceSlot); } } else { if (WaferManager.Instance.CheckHasTray(RobotModuleName, 0)) { WaferManager.Instance.TrayMoved(RobotModuleName, 0, sourceModule, sourceSlot); } } } return base.fPlaceComplete(param); } protected override bool fPickComplete(object[] param) { //arm, station, slot Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; if (CurrentParamter.Length >= 3) { ModuleName sourceModule; int sourceSlot; if (!int.TryParse(CurrentParamter[2].ToString(), out sourceSlot) || !Enum.TryParse(CurrentParamter[1].ToString(), out sourceModule)) { return false; } if (RobotModuleName == ModuleName.WaferRobot) { if (WaferManager.Instance.CheckHasWafer(sourceModule, sourceSlot)) { WaferManager.Instance.WaferMoved(sourceModule, sourceSlot, RobotModuleName, 0); } } else { if (WaferManager.Instance.CheckHasTray(sourceModule, sourceSlot)) { WaferManager.Instance.TrayMoved(sourceModule, sourceSlot, RobotModuleName, 0); } } //lock (_locker) //{ // CheckStateThenDo(() => // { // _lstHandler.AddLast(new SunwayRobotGETSPHandler(this, CurrentParamter[1].ToString(), Convert.ToInt32(CurrentParamter[2]), 4, _scMotionTimeout.IntValue)); //缩回 // }); //} } return base.fPickComplete(param); } protected override bool fResetToReady(object[] param) { return true; } protected override bool fReset(object[] param) { _trigError.RST = true; Connection.SetCommunicationError(false, ""); _trigCommunicationError.RST = true; _trigRetryConnect.RST = true; if (_isAlarm) { lock (_locker) { //_lstHandler.AddLast(new SunwayRobotResetHandler(this)); } Thread.Sleep(100); CheckToPostMessage((int)RobotMsg.ActionDone); } IsBusy = false; return true; } protected override bool fMonitorReset(object[] param) { IsBusy = false; return true; } protected override bool fStartInit(object[] param) { RobotConnectHomeAll(); return true; } protected override bool fError(object[] param) { return true; } //[module][slot] 伸出手臂 protected override bool fStartExtendForPick(object[] param) { try { if (param.Length >= 3) { lock (_locker) { //初始位置和伸出 int slot = Convert.ToInt32(param[2]) + 1; _lstHandler.AddLast(new SunwayRobotGotoHandler(this, param[1].ToString(), slot, RobotArmEnum.Blade1, true, true, _scMotionTimeout.IntValue)); _lstHandler.AddLast(new SunwayRobotPickHandler(this, param[1].ToString(), slot, RobotArmEnum.Blade1, false, _scMotionTimeout.IntValue)); } } } catch (Exception ex) { LOG.Write(ex); return false; } return true; } //(module, slot) protected override bool fStartPickWafer(object[] param) { try { //arm, station, slot if (param.Length >= 3) { lock (_locker) { int slot = Convert.ToInt32(param[2]) + 1; _lstHandler.AddLast(new SunwayRobotPickHandler(this, param[1].ToString(), slot, RobotArmEnum.Blade1, true, _scMotionTimeout.IntValue)); } } } catch (Exception ex) { LOG.Write(ex); return false; } return true; } protected override bool fStartExtendForPlace(object[] param) { try { if (param.Length >= 3) { lock (_locker) { //初始位置和伸出 int slot = Convert.ToInt32(param[2]) + 1; _lstHandler.AddLast(new SunwayRobotGotoHandler(this, param[1].ToString(), slot, RobotArmEnum.Blade1, true, false, _scMotionTimeout.IntValue)); _lstHandler.AddLast(new SunwayRobotPlaceHandler(this, param[1].ToString(), slot, RobotArmEnum.Blade1, false, _scMotionTimeout.IntValue)); } } } catch (Exception ex) { LOG.Write(ex); return false; } return true; } //(module, slot) protected override bool fStartPlaceWafer(object[] param) { try { //arm, station, slot if (param.Length >= 3) { lock (_locker) { // 执行Place指令 int slot = Convert.ToInt32(param[2]) + 1; _lstHandler.AddLast(new SunwayRobotPlaceHandler(this, param[1].ToString(), slot, RobotArmEnum.Blade1, true, _scMotionTimeout.IntValue)); } } } catch (Exception ex) { LOG.Write(ex); return false; } return true; } /// /// 开始从Pick处缩回 /// /// /// protected override bool fStartRetractFromPick(object[] param) { try { if (param.Length >= 2) { lock (_locker) { CheckStateThenDo(() => { _lstHandler.AddLast(new SunwayRobotPUTSPHandler(this, param[0].ToString(), Convert.ToInt32(param[1]), 3, _scMotionTimeout.IntValue)); _lstHandler.AddLast(new SunwayRobotPUTSPHandler(this, param[0].ToString(), Convert.ToInt32(param[1]), 4, _scMotionTimeout.IntValue)); }); } } } catch (Exception ex) { LOG.Write(ex); return false; } return true; } /// /// 开始从Place处缩回 /// /// /// protected override bool fStartRetractFromPlace(object[] param) { try { if (param.Length >= 2) { lock (_locker) { _lstHandler.AddLast(new SunwayRobotPUTSPHandler(this, param[0].ToString(), Convert.ToInt32(param[1]), 3, _scMotionTimeout.IntValue)); _lstHandler.AddLast(new SunwayRobotPUTSPHandler(this, param[0].ToString(), Convert.ToInt32(param[1]), 4, _scMotionTimeout.IntValue)); } } } catch (Exception ex) { LOG.Write(ex); return false; } return true; } protected override bool fStartExecuteCommand(object[] param) { try { InputA(); } catch (Exception ex) { LOG.Write(ex); return false; } return true; } public override RobotArmWaferStateEnum GetWaferState(RobotArmEnum arm) { if (arm == RobotArmEnum.Blade1) { return IsWaferPresenceOnBlade1 ? RobotArmWaferStateEnum.Present : RobotArmWaferStateEnum.Absent; } return RobotArmWaferStateEnum.Unknown; } protected override bool fStop(object[] param) { lock (_locker) { IsBusy = false; Connection.ForceClear(); _lstHandler.Clear(); } return true; } protected override bool fAbort(object[] param) { lock (_locker) { IsBusy = false; Connection.ForceClear(); _lstHandler.Clear(); } return true; } #endregion internal void GetWaferData() { Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; IsBusy = false; if (CurrentParamter.Length >= 3) { ModuleName sourceModule; int sourceSlot = 0; if (!int.TryParse(CurrentParamter[2].ToString(), out sourceSlot) || !Enum.TryParse(CurrentParamter[1].ToString(), out sourceModule)) { return; } if (WaferManager.Instance.CheckNoTray(RobotModuleName, 0) && WaferManager.Instance.CheckHasTray(sourceModule, sourceSlot)) { WaferManager.Instance.TrayMoved(sourceModule, sourceSlot, RobotModuleName, 0); } } } internal void PutWaferData() { Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; IsBusy = false; if (CurrentParamter.Length >= 3) { ModuleName sourceModule; int sourceSlot = 0; if (!int.TryParse(CurrentParamter[2].ToString(), out sourceSlot) || !Enum.TryParse(CurrentParamter[1].ToString(), out sourceModule)) { return; } if (WaferManager.Instance.CheckHasTray(RobotModuleName, 0) && WaferManager.Instance.CheckNoTray(sourceModule, sourceSlot)) { WaferManager.Instance.TrayMoved(RobotModuleName, 0, sourceModule, sourceSlot); } } } } }