using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; 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.Device.Bases; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Common; using Newtonsoft.Json; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using System.Threading; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using System.Text.RegularExpressions; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.Common.CommonData; using Aitex.Core.RT.IOCore; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Flipper.FlipperBase; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.JEL { public class JelC5000RobotFlippeV1 : JelC5000RobotFlippe { public JelC5000RobotFlippeV1(string module, string name, string scRoot, AOAccessor aoBladeRegulator, string robotModel = "") : base(module, name, scRoot, aoBladeRegulator, robotModel = "") { } private int _defaultRegulatorRatio { get { if (SC.ContainsItem($"Robot.{Name}.DefaultRegulatorRatio")) return SC.GetValue($"Robot.{Name}.DefaultRegulatorRatio"); return 0; } } protected override bool fStartInit(object[] param) { //string speedtype = string.Empty; //if (param != null && param.Length >0) // speedtype = Regex.Replace(param[0].ToString().Replace("(", "(").Replace(")", ")"), @"\([^\(]*\)", ""); //if (speedtype != "" && speedtype != "M" && speedtype != "L") return false; _dtActionStart = DateTime.Now; int compaundcmdNO = SC.GetValue($"Robot.{Name}.InitCmdNO"); int Robotspeed = SC.GetValue($"Robot.{Name}.RobotSpeed"); if (Robotspeed < 0) Robotspeed = 0; if (Robotspeed > 99) Robotspeed = 99; lock (_locker) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeCompaundCommandHandler(this, compaundcmdNO.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "G")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "BC")); // Read bank number _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "WCP")); // Read Cassette Number _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "1")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "2")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "3")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "4")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "X")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "Y")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "U")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "6", "Z")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "SPA", Robotspeed.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "SPA")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, $"C5", null, 2)); } _aoBladeRegulator.Value = (short)(_defaultRegulatorRatio*100); return true; } protected override bool fStartUnGrip(object[] param) { if (param == null || param.Length < 1) return false; RobotArmEnum arm = (RobotArmEnum)((int)param[0]); lock (_locker) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "DS", "10")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "WS", "0")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "")); } return true; } protected override bool fMonitorUnGrip(object[] param) { IsBusy = false; if (_lstMonitorHandler.Count == 0 && !_connection.IsBusy) { if (JelC5000RobotStatus != JelAxisStatus.NormalEnd || AxisStatus != JelAxisStatus.NormalEnd) { lock (_locker) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "")); //_lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, $"CS{_lowerArmWaferSensorIndex}")); } return false; } RobotArmEnum arm = (RobotArmEnum)((int)CurrentParamter[0]); //if(IsVacuumSensorON) // HandlerError("UnGrip wafer failed!"); IsBusy = false; return true; } return false; } protected override bool fStartGrip(object[] param) { if (param == null || param.Length < 1) return false; RobotArmEnum arm = (RobotArmEnum)((int)param[0]); lock (_locker) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "DS", "11")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "WS", "1")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "")); } return true; } protected override bool fMonitorGrip(object[] param) { IsBusy = false; if (_lstMonitorHandler.Count == 0 && !_connection.IsBusy) { if (JelC5000RobotStatus != JelAxisStatus.NormalEnd || AxisStatus != JelAxisStatus.NormalEnd) { lock (_locker) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "")); } return false; } //if (!IsVacuumSensorON) // HandlerError("UnGrip wafer failed!"); IsBusy = false; return true; } return false; } protected override bool fStartPickWafer(object[] param) { _dtActionStart = DateTime.Now; try { //RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); int slotindex = int.Parse(param[2].ToString()); //JelC5000RobotArm jelarm = (JelC5000RobotArm)(int)arm; var wz = WaferManager.Instance.GetWaferSize(tempmodule, slotindex); if (!GetBankAndCassetteNumber(tempmodule, wz, false, out int bankno, out int cassetteNO)) { EV.PostAlarmLog("Robot", $"{RobotModuleName} can't find the bankno or cassette no for {tempmodule}"); OnError("ParseStationError"); return false; } int compaundcmdNO = SC.GetValue($"Robot.{Name}.PickCmdNO"); int compaundcmdNOforSafe = SC.GetValue($"Robot.{Name}.SafeCmdNO"); if (!ModuleHelper.IsLoadPort(tempmodule) && Blade1ActionPosture == BladePostureEnum.Degree180) { if (!GetBankAndCassetteNumber(tempmodule, wz, true, out bankno, out cassetteNO)) { EV.PostAlarmLog("Robot", $"{RobotModuleName} can't find the bankno or cassette no for {tempmodule}"); OnError("ParseStationError"); return false; } compaundcmdNO = SC.GetValue($"Robot.{Name}.OverPickCmdNO"); compaundcmdNOforSafe = SC.GetValue($"Robot.{Name}.SafeCmdNO"); } if (ModuleHelper.IsLoadPort(tempmodule)) { var lp = DEVICE.GetDevice(tempmodule.ToString()); if (lp != null) lp.NoteTransferStart(); } lock (_locker) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "BC")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "WCP")); } DateTime readstarttime = DateTime.Now; while (_lstMonitorHandler.Count != 0 || _connection.IsBusy) { if (DateTime.Now - readstarttime > TimeSpan.FromSeconds(20)) { OnError("Read bankno and cassette no for pick Timeout."); return false; } } lock (_locker) { if (LastTargeModule != tempmodule)//(ReadBankNumber != bankno.ToString("X") || cassetteNO != ReadCassetNumber) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeCompaundCommandHandler(this, compaundcmdNOforSafe.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "G")); } _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "BC", bankno.ToString("X"))); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "WCP", cassetteNO.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "WCD", (slotindex + 1).ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "BC")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "WCP")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeCompaundCommandHandler(this, compaundcmdNO.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "G")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, $"C5",null,2)); } Blade1Target = tempmodule; Blade2Target = tempmodule; CmdTarget = tempmodule; LastTargeModule = tempmodule; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; } catch (Exception ex) { string reason = ""; if (param != null) { foreach (var strpara in param) reason += strpara.ToString(); } LOG.Write(ex); OnError($"{Name} Pick command valid:" + reason); return false; } return true; } protected override bool fStartPlaceWafer(object[] param) { _dtActionStart = DateTime.Now; try { RobotArmEnum arm = (RobotArmEnum)param[0]; ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString()); int slotindex = int.Parse(param[2].ToString()); //JelC5000RobotArm jelarm = (JelC5000RobotArm)(int)arm; var wz = WaferManager.Instance.GetWaferSize(RobotModuleName, arm == RobotArmEnum.Both ? 0 : (int)arm); int wzindex = 0; if (!GetBankAndCassetteNumber(tempmodule, wz, false, out int bankno, out int cassetteNO)) { EV.PostAlarmLog("Robot", $"{RobotModuleName} can't find the bankno or cassette no for {tempmodule}"); OnError("ParseStationError"); return false; } int compaundcmdNO = SC.GetValue($"Robot.{Name}.PlaceCmdNO"); int compaundcmdNOforSafe = SC.GetValue($"Robot.{Name}.SafeCmdNO"); if (!ModuleHelper.IsLoadPort(tempmodule) && Blade1ActionPosture == BladePostureEnum.Degree180) { if (!GetBankAndCassetteNumber(tempmodule, wz, true, out bankno, out cassetteNO)) { EV.PostAlarmLog("Robot", $"{RobotModuleName} can't find the bankno or cassette no for {tempmodule}"); OnError("ParseStationError"); return false; } compaundcmdNO = SC.GetValue($"Robot.{Name}.OverPlaceCmdNO"); compaundcmdNOforSafe = SC.GetValue($"Robot.{Name}.SafeCmdNO"); } lock (_locker) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "BC")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "WCP")); } DateTime readstarttime = DateTime.Now; while (_lstMonitorHandler.Count != 0 || _connection.IsBusy) { if (DateTime.Now - readstarttime > TimeSpan.FromSeconds(10)) { OnError("Read bankno and cassette no for place Timeout."); return false; } } if (ModuleHelper.IsLoadPort(tempmodule)) { var lp = DEVICE.GetDevice(tempmodule.ToString()); if (lp != null) lp.NoteTransferStart(); } lock (_locker) { if (LastTargeModule != tempmodule) //(ReadBankNumber != bankno.ToString("X") || cassetteNO != ReadCassetNumber) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeCompaundCommandHandler(this, compaundcmdNOforSafe.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "G")); } _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "BC", bankno.ToString("X"))); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "WCP", cassetteNO.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeSetHandler(this, "WCD", (slotindex + 1).ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "BC")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "WCP")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeCompaundCommandHandler(this, compaundcmdNO.ToString())); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "G")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, $"C5", null, 2)); } Blade1Target = tempmodule; Blade2Target = tempmodule; CmdTarget = tempmodule; LastTargeModule = tempmodule; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Placing, ArmTarget = RobotArm.Both, // CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; } catch (Exception ex) { string reason = ""; if (param != null) foreach (var strpara in param) reason += strpara.ToString(); OnError($"{Name} place command valid:" + reason); LOG.Write(ex); return false; } return true; } protected override bool fMonitorPlace(object[] param) { IsBusy = false; if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout)) { OnError("Place wafer timeout"); return true; } if (_lstMonitorHandler.Count == 0 && !_connection.IsBusy) { if (CurrentCompoundCommandStatus == JelCommandStatus.NormalEnd) { RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0]; ModuleName sourcemodule; if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false; int Sourceslotindex; if (!int.TryParse(CurrentParamter[2].ToString(), out Sourceslotindex)) return false; if (IsVacuumSensorON) { OnError("Vacuum sensor on blade is ON"); return false; } WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex); if(Blade1ActionPosture == BladePostureEnum.Degree180) WaferManager.Instance.UpdateWaferTurnOver(sourcemodule, Sourceslotindex); Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; if (ModuleHelper.IsLoadPort(sourcemodule)) { var lp = DEVICE.GetDevice(sourcemodule.ToString()); if (lp != null) lp.NoteTransferStop(); } IsBusy = false; CmdTarget = ModuleName.System; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } if (CurrentCompoundCommandStatus == JelCommandStatus.InError) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "GER")); HandlerError("PlaceFailed"); } } return false; } protected override bool fMonitorPick(object[] param) { IsBusy = false; if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout)) { OnError("Pick wafer timeout"); return true; } if (_lstMonitorHandler.Count == 0 && !_connection.IsBusy) { if (CurrentCompoundCommandStatus == JelCommandStatus.NormalEnd) { RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0]; ModuleName sourcemodule; if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false; int SourceslotIndex; if (!int.TryParse(CurrentParamter[2].ToString(), out SourceslotIndex)) return false; if (!IsVacuumSensorON) { OnError("Vacuum sensor is not ON"); return false; } WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0); if(Blade1ActionPosture == BladePostureEnum.Degree180) WaferManager.Instance.UpdateWaferTurnOver(RobotModuleName, 0); //if (arm == RobotArmEnum.Lower) //WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0); //if (arm == RobotArmEnum.Upper) // WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 1); //if (arm == RobotArmEnum.Both) //{ // WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0); // WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 1); //} Blade1Target = ModuleName.System; Blade2Target = ModuleName.System; if (ModuleHelper.IsLoadPort(sourcemodule)) { var lp = DEVICE.GetDevice(sourcemodule.ToString()); if (lp != null) lp.NoteTransferStop(); } IsBusy = false; CmdTarget = ModuleName.System; MoveInfo = new RobotMoveInfo() { Action = RobotAction.Picking, ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB, BladeTarget = BuildBladeTarget(), }; return true; } if (CurrentCompoundCommandStatus == JelCommandStatus.InError) { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "GER")); OnError("Compaund Comand execution failed"); } else { _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, "G")); _lstMonitorHandler.AddLast(new JelC5000RobotFlippeReadHandler(this, $"CS{_lowerArmWaferSensorIndex}")); } } return false; } public override void ParseData(string command, string parameter, string data) { try { string datavalue = data.Replace($"${BodyNumber}", "").Replace("\r", "").Replace($"$2", ""); if (command.Contains($"C5")) { IsVacuumSensorON = datavalue == "1"; } base.ParseData(command, parameter, data); } catch (Exception ex) { LOG.Write($"Parse {command}.{parameter ?? parameter} data {data} error:" + ex.ToString()); OnError($"Parse data error:{command}.{parameter ?? parameter} data {data}"); } } public override WaferSize GetCurrentWaferSize() { if (WaferManager.Instance.CheckHasWafer(RobotModuleName, 0)) return WaferManager.Instance.GetWaferSize(RobotModuleName, 0); return WaferSize.WS8; } } }