using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using athosRT.FSM; using athosRT.tool; using MECF.Framework.Common.Equipment; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace athosRT.Modules.EFEMs.Routine { public class WaferMappingRoutine : ModuleRoutineBase, FSM.IRoutine { private bool MultiWaferSize = Singleton.Instance.GetValue(nameof(MultiWaferSize)).GetValueOrDefault(); private SCConfigItem _scPickTimeout = (SCConfigItem)null; private int _timeout = 0; private LoadPortBaseDevice _lp; private WaferSize _waferSize; protected bool NeedSetParameter; private string _reason = string.Empty; public bool IsDeviceNull => _lp == null; public ModuleName Source { get; set; } public RobotBaseDevice robot; public WaferMappingRoutine(ModuleName Chamber) : base(Chamber) { robot = DEVICE.GetDevice("Robot"); Name = "Wafer Mapping"; _scPickTimeout = SC.GetConfigItem("Robot.TimeLimitForPickWafer"); } /// /// 千万注意 这里的objs 要传入LP的名字 原来获取LoadPort的 /// /// /// public RState Start(params object[] objs) { Reset(); Trace.WriteLine(objs); _timeout = SC.GetValue("Robot.TimeLimitForPickWafer")*1000; Name = "Wafer Mapping"; Reset(); NeedSetParameter = true; string str = (string)objs[0]; ModuleName result; if (string.IsNullOrEmpty(str) || !Enum.TryParse(str, out result)) { LogObject.Info("Wafer Mapping", "Start map wafer argument is not valid"); return RState.Failed; } Source = result; _lp = DEVICE.GetDevice(Source.ToString()); _waferSize = _lp.GetCurrentWaferSize(); return Runner.Start(result, "Wafer Mapping"); } public void Abort() { } /// /// WaferMap有两种逻辑 /// 一种是LP 一种是Robot /// 两种的GetWaferMap 是对robot和LP的状态做判断 同名不同参的函数 /// /// public RState Monitor() { bool? nullable = Singleton.Instance.GetValue("WAFSHEnable"); //两种扫片方式 if (nullable.GetValueOrDefault() == false & nullable.HasValue) { Runner .Wait(WaferMappingStep.CheckLoadPortReady, CheckLoadPortReady, _timeout) .Wait(WaferMappingStep.CheckRobotReady,CheckRobotReady, _timeout) .Run(WaferMappingStep.MapWafer,MapWafer, WaitRobotMotion, _timeout) .End(WaferMappingStep.GetWaferMap, GetRobotWaferMap, CheckRobotIdle, _timeout) ; } else { Runner .Wait(WaferMappingStep.CheckLoadPortReady, CheckLoadPortReady, _timeout) .End(WaferMappingStep.GetWaferMap, GetLPWaferMap, CheckLPIdle, _timeout) ; } return Runner.Status; } private bool CheckLPIdle() { if (!_lp.IsBusy) { LogObject.Info(Name, "LP 不忙"); return true; } else { //LogObject.Error(Name, "LP 忙"); return false; } } private bool GetLPWaferMap() { if (_lp.QueryWaferMap(out _reason)) { LogObject.Info(Name, "LP GetWaferMap"); return true; } else { //LogObject.Error(Name, "LP GetWaferMapping"); return false; } } private bool CheckRobotIdle() { if (robot.RobotState == RobotStateEnum.Idle) { LogObject.Info(Name, "Robot Idle"); return true; } else { //LogObject.Error(Name, "Robot not Idle"); return false; } } private bool GetRobotWaferMap() { if (robot.QueryWaferMap(Source, out _reason)) { LogObject.Info(Name, "Robot GetWaferMap"); return true; } else { //LogObject.Error(Name, "Robot GetWaferMapping"); return false; } } private bool WaitRobotMotion() { if (robot.IsReady()) { LogObject.Info(Name, "robot WaferMap"); return true; } else { //LogObject.Error(Name, "robot WaferMap"); return false; } } private bool MapWafer() { if (robot.WaferMapping(Source, out _reason)) { LogObject.Info(Name, "robot WaferMap"); return true; } else { //LogObject.Error(Name, "robot WaferMapping"); return false; } } private bool CheckRobotReady() { if (robot.RobotState == RobotStateEnum.Idle) { LogObject.Info(Name, "CheckRobotReady"); return true; } else { //LogObject.Error(Name, "Check Robot Not Ready"); return false; } } private bool CheckLoadPortReady() { //Trace.WriteLine($"DoorState:{_lp.DoorState}|Ready:{_lp.IsReady()}|"); if (_lp.IsEnableMapWafer(out _reason)) { LogObject.Info(Name, "LP ready to map wafer"); return true; } else { //LogObject.Error(Name, $"LP not ready to map wafer | ....{_reason}"); return false; } } private enum WaferMappingStep{ CheckLoadPortReady, CheckRobotReady, MapWafer, WaitRobotMotion, GetWaferMap, WaitMapStepOver } } }