using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Utilities; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Fsm; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.HwinRobot; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.Sunway; using SicModules.EFEMs.Routines; namespace SicModules.EFEMs { public class WaferRobotModule : ModuleFsmDevice, IModuleDevice { #region Variables private enum STATE { NotInstall, Init, Idle, Homing, Error, Pick, Place, Map, RobotHoming, } private enum MSG { Home, Reset, Abort, Error, ToInit, SetOnline, SetOffline, RobotHome, Pick, Place, Map, } private WaferRobotHomeRoutine _waferRobotHomeRoutine; private WaferRobotPlaceRoutine _waferRobotPlaceRoutine; private WaferRobotPickRoutine _waferRobotPickRoutine; private WaferRobotMapRoutine _waferRobotMapRoutine; private bool _isInit; #endregion #region Constructors public WaferRobotModule(ModuleName module) { Module = module.ToString(); Name = module.ToString(); IsOnline = false; EnumLoop.ForEach((item) => { MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { MapMessage((int)item, item.ToString()); }); EnableFsm(50, IsInstalled ? STATE.Init : STATE.NotInstall); } #endregion #region Properties public RobotBaseDevice WaferRobotDevice { get; set; } public bool IsReady => FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); public bool IsError => FsmState == (int)STATE.Error; public bool IsInit => FsmState == (int)STATE.Init; public bool IsBusy => !IsInit && !IsError && !IsReady; public bool IsIdle => FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); public bool IsAlarm => FsmState == (int)STATE.Error; #endregion #region Methods public override bool Initialize() { InitRoutine(); InitDevice(); InitFsm(); InitOp(); InitData(); return base.Initialize(); } private void InitRoutine() { ModuleName module = ModuleHelper.Converter(Module); _waferRobotHomeRoutine = new WaferRobotHomeRoutine(); _waferRobotPlaceRoutine = new WaferRobotPlaceRoutine(); _waferRobotPickRoutine = new WaferRobotPickRoutine(); _waferRobotMapRoutine = new WaferRobotMapRoutine(); } private void InitDevice() { if (SC.GetStringValue("WaferRobot.RobotType") == "SunwayRobot") { WaferRobotDevice = DEVICE.GetDevice($"WaferRobot.WaferRobot"); } else { WaferRobotDevice = DEVICE.GetDevice($"WaferRobot.WaferRobot"); } } private void InitFsm() { //Error AnyStateTransition(MSG.Error, FsmOnError, STATE.Error); AnyStateTransition(FSM_MSG.ALARM, FsmOnError, STATE.Error); Transition(STATE.Error, MSG.Reset, FsmReset, STATE.Idle); EnterExitTransition(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError); //Home Transition(STATE.Init, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Error, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Idle, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Homing, FSM_MSG.TIMER, FsmMonitorHomeTask, STATE.Idle); Transition(STATE.Homing, MSG.Error, null, STATE.Init); Transition(STATE.Homing, MSG.Abort, FsmAbortTask, STATE.Init); EnterExitTransition((int)STATE.Homing, FsmEnterIdle, (int)FSM_MSG.NONE, FsmExitIdle); AnyStateTransition(MSG.ToInit, FsmToInit, STATE.Init); //Online Transition(STATE.Idle, MSG.SetOnline, FsmStartSetOnline, STATE.Idle); Transition(STATE.Idle, MSG.SetOffline, FsmStartSetOffline, STATE.Idle); Transition(STATE.Idle, MSG.Map, FsmStartWaferRobotMap, STATE.Map); Transition(STATE.Map, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Map, MSG.Abort, FsmAbortTask, STATE.Idle); Transition(STATE.Idle, MSG.Pick, FsmStartWaferRobotPick, STATE.Pick); Transition(STATE.Pick, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Pick, MSG.Abort, FsmAbortTask, STATE.Idle); Transition(STATE.Idle, MSG.Place, FsmStartWaferRobotPlace, STATE.Place); Transition(STATE.Place, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Place, MSG.Abort, FsmAbortTask, STATE.Idle); Transition(STATE.Idle, MSG.RobotHome, FsmStartRobotHome, STATE.RobotHoming); Transition(STATE.RobotHoming, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.RobotHoming, MSG.Abort, FsmAbortTask, STATE.Idle); } private void InitOp() { OP.Subscribe($"{Name}.Home", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Home)); OP.Subscribe($"{Name}.Reset", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Reset)); OP.Subscribe($"{Name}.Abort", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Abort)); OP.Subscribe($"{Module}.SetOnline", (string cmd, object[] args) => CheckToPostMessage((int)MSG.SetOnline)); OP.Subscribe($"{Module}.SetOffline", (string cmd, object[] args) => CheckToPostMessage((int)MSG.SetOffline)); OP.Subscribe($"{Module}.PickWafer", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Pick, args[0], args[1])); OP.Subscribe($"{Module}.PlaceWafer", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Place, args[0], args[1])); OP.Subscribe($"{Module}.MapWafer", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Map, args[0])); OP.Subscribe($"{Module}.RobotHome", (string cmd, object[] args) => CheckToPostMessage((int)MSG.RobotHome)); } private void InitData() { DATA.Subscribe($"{Module}.Status", () => StringFsmStatus); DATA.Subscribe($"{Module}.IsOnline", () => IsOnline); DATA.Subscribe($"{Module}.IsBusy", () => IsBusy); DATA.Subscribe($"{Module}.IsAlarm", () => IsAlarm); } private bool FsmOnError(object[] param) { IsOnline = false; if (FsmState == (int)STATE.Error) { return false; } if (FsmState == (int)STATE.Init) return false; return true; } private bool FsmReset(object[] param) { if (!_isInit) { PostMsg(MSG.ToInit); return false; } WaferRobotDevice.RobotReset(); return true; } private bool FsmExitError(object[] param) { return true; } private bool FsmEnterError(object[] param) { InvokeOnEnterError(Module); return true; } private bool FsmStartHome(object[] param) { Result ret = StartRoutine(_waferRobotHomeRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmMonitorHomeTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } if (ret == Result.DONE) { _isInit = true; OP.DoOperation($"{Module}.ResetTask"); return true; } return false; } private bool FsmAbortTask(object[] param) { AbortRoutine(); WaferRobotDevice.Abort(); return true; } private bool FsmExitIdle(object[] param) { return true; } private bool FsmEnterIdle(object[] param) { return true; } private bool FsmToInit(object[] param) { WaferRobotDevice.RobotReset(); return true; } private bool FsmStartSetOffline(object[] param) { IsOnline = false; return true; } private bool FsmStartSetOnline(object[] param) { IsOnline = true; return true; } private bool FsmMonitorTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } return ret == Result.DONE; } public bool Abort() { CheckToPostMessage((int)MSG.Abort); return true; } public bool Home(out string reason) { CheckToPostMessage((int)MSG.Home); reason = string.Empty; return true; } public bool CheckAcked(int entityTaskToken) { return FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); } public void InvokeOffline() { PostMsg((int)MSG.SetOffline); } public void InvokeOnline() { PostMsg((int)MSG.SetOnline); } public bool MapWafer(object[] objs) { if (CheckToPostMessage((int)MSG.Map, objs)) { return true; } return false; } public bool MapWafer(ModuleName target) { if(CheckToPostMessage((int)MSG.Map, target.ToString())) { return true; } return false; } public bool PickWafer(object[] objs) { if (CheckToPostMessage((int)MSG.Pick, objs)) return true; return false; } public bool PickWafer(ModuleName target, Hand blade, int targetSlot) { if (CheckToPostMessage((int)MSG.Pick, target.ToString(), targetSlot, blade)) return true; return false; } public bool PlaceWafer(object[] objs) { if (CheckToPostMessage((int)MSG.Place, objs)) return true; return false; } public bool PlaceWafer(ModuleName target, Hand blade, int targetSlot) { if (CheckToPostMessage((int)MSG.Place, target.ToString(), targetSlot, blade)) return true; return false; } private bool FsmStartWaferRobotMap(object[] param) { _waferRobotMapRoutine.Init(ModuleHelper.Converter((string)param[0])); Result ret = StartRoutine(_waferRobotMapRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartWaferRobotPick(object[] param) { _waferRobotPickRoutine.Init(ModuleHelper.Converter((string)param[0]), (int)param[1]); Result ret = StartRoutine(_waferRobotPickRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartWaferRobotPlace(object[] param) { _waferRobotPlaceRoutine.Init(ModuleHelper.Converter((string)param[0]), (int)param[1]); Result ret = StartRoutine(_waferRobotPlaceRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartRobotHome(object[] param) { Result ret = StartRoutine(_waferRobotHomeRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } public int InvokeError() { if (CheckToPostMessage((int)MSG.Error)) return (int)MSG.Error; return (int)FSM_MSG.NONE; } #endregion } }