using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Utilities; using MECF.Framework.Common.Beckhoff.AxisProvider; using MECF.Framework.Common.Utilities; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Devices.SRD; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Modules.SRD { internal class UnloadingStateMachine : Entity, IEntity { #region 常量 /// /// Arm Home最大retry次数 /// private const int MAX_ARM_HOME_RETRIES = 3; /// /// Rotation Home最大retry次数 /// private const int MAX_ROTATION_HOME_RETRIES = 3; /// /// 旋转增加时长 /// private const int ROTATION_PLUS_TIME = 10; #endregion #region 内部变量 /// /// 模块名称 /// private string _module; /// /// SRD Common /// private SrdCommonDevice _srdCommon; /// /// Arm Axis /// private JetAxisBase _armAxis; /// /// Rotation Axis /// private JetAxisBase _rotationAxis; /// /// Arm重试次数 /// private int _armRetryTimes = 0; /// /// Rotation重试次数 /// private int _rotationRetryTimes = 0; /// /// ARM正在执行Home /// private bool _armHoming = false; /// /// Rotation正在执行Home /// private bool _rotationHoming = false; #endregion #region 属性 /// /// 状态 /// public string State { get { return ((UnloadingState)fsm.State).ToString(); } } #endregion /// /// 构造函数 /// /// public UnloadingStateMachine(string module) { _module = module; this.fsm = new StateMachine($"{module}_UnloadingStateMachine", (int)UnloadingState.Unloading_Complete, 10); fsm.EnableRepeatedMsg(true); AnyStateTransition(UnloadingMsg.Init, EnterUnloadingStart, UnloadingState.Unloading_Start); AnyStateTransition(UnloadingMsg.Error, EnterError, UnloadingState.Error); //Transition(UnloadingState.Unloading_Complete, UnloadingMsg.Unloading_Start, EnterUnloadingStart, UnloadingState.Unloading_Start); Transition(UnloadingState.Unloading_Start, UnloadingMsg.Unloading_Start, UnloadingCheckStatus, UnloadingState.Unloading_CheckRotationStopped); Transition(UnloadingState.Unloading_CheckRotationStopped, FSM_MSG.TIMER, CheckRotationStopped, UnloadingState.Unloading_WaferPresent); Transition(UnloadingState.Unloading_WaferPresent, FSM_MSG.TIMER, CheckWaferPresent, UnloadingState.Unloading_OpenDoor); Transition(UnloadingState.Unloading_OpenDoor, FSM_MSG.TIMER, OpenDoor, UnloadingState.Unloading_CheckDoorOpened); Transition(UnloadingState.Unloading_CheckDoorOpened, FSM_MSG.TIMER, CheckDoorOpened, UnloadingState.Unloading_ReleaseChuckVacuum); Transition(UnloadingState.Unloading_ReleaseChuckVacuum, FSM_MSG.TIMER, ReleaseChuckVacuum, UnloadingState.Unloading_CheckVacuum); Transition(UnloadingState.Unloading_CheckVacuum, FSM_MSG.TIMER, CheckVacuum, UnloadingState.Unloading_Complete); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); } /// /// Enter Error /// /// /// private bool EnterError(object param) { return true; } /// /// Enter Unloading_Start /// /// /// private bool EnterUnloadingStart(object param) { return true; } #region 状态方法 /// /// 启动 /// /// /// private bool UnloadingCheckStatus(object param) { _armAxis = DEVICE.GetDevice($"{_module}.Arm"); _rotationAxis = DEVICE.GetDevice($"{_module}.Rotation"); _srdCommon = DEVICE.GetDevice($"{_module}.Common"); return true; } /// /// 检查Rotation与Arm是否home /// /// /// private bool CheckRotationStopped(object param) { CheckArmHome(); CheckRotationHome(); return _srdCommon.Status == RState.End; } /// /// 检验Arm home,发现失败则重试 /// /// /// private bool CheckArmHome() { if (_armAxis.IsHomed) { return true; } else { if (_armRetryTimes < MAX_ARM_HOME_RETRIES) { if (!_armHoming) { LOG.WriteLog(eEvent.INFO_SRD, _module, $"Arm Home Retry Home {_armRetryTimes + 1} times"); bool result = _armAxis.Home(false); if (result) { _armHoming = true; } _armRetryTimes++; return false; } else { if (_armAxis.IsHomed && _armAxis.Status == RState.End) { _armRetryTimes = 0; _armHoming = false; return true; } return false; } } else { LOG.WriteLog(eEvent.ERR_SRD, _module, $"Arm Home Retry Home {_armRetryTimes + 1} times is over {MAX_ARM_HOME_RETRIES}"); PostMsg(UnloadingMsg.Error); return false; } } } /// /// 检验Rotation home,发现失败则重试 /// /// /// private bool CheckRotationHome() { if (_rotationAxis.IsHomed) { return true; } else { if (_rotationRetryTimes < MAX_ROTATION_HOME_RETRIES) { if (!_rotationHoming) { LOG.WriteLog(eEvent.INFO_SRD, _module, $"Rotation Home Retry Home {_rotationRetryTimes + 1} times"); bool result = _rotationAxis.Home(false); if (result) { _rotationHoming = true; } _rotationRetryTimes++; return false; } else { if (_rotationAxis.IsHomed && _rotationAxis.Status == RState.End) { _rotationRetryTimes = 0; _rotationHoming = false; return true; } return false; } } else { LOG.WriteLog(eEvent.ERR_SRD, _module, $"Rotation Home Retry Home {_rotationRetryTimes + 1} times is over {MAX_ROTATION_HOME_RETRIES}"); PostMsg(UnloadingMsg.Error); return false; } } } /// /// Check Wafer Present /// /// /// private bool CheckWaferPresent(object param) { if (_srdCommon.IsWaferPresence) { if (_srdCommon.WaferPresence != "WellPlaced") { PostMsg(UnloadingMsg.Error); LOG.WriteLog(eEvent.ERR_SRD, _module, "Wafer Presence is not WellPlaced"); return false; } } else { LOG.WriteLog(eEvent.INFO_SRD, _module, "CheckWaferPresent has been ignored"); } return true; } /// /// Open Door /// /// /// private bool OpenDoor(object param) { bool result = _srdCommon.DoorOpenAction("", null); if (!result) { PostMsg(UnloadingMsg.Error); } return result; } /// /// 检验DoorOpened /// /// /// private bool CheckDoorOpened(object param) { if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout) { PostMsg(UnloadingMsg.Error); return false; } return _srdCommon.Status == RState.End && _srdCommon.CommonData.DoorOpened; } /// /// 关闭Chuck Vacuum,并检查Vacuum Level /// /// /// private bool ReleaseChuckVacuum(object param) { if (_srdCommon.IsWaferPresence) { bool result = _srdCommon.ChuckVacuumOffAction("", null); if (!result) { PostMsg(UnloadingMsg.Error); } return result; } else { LOG.WriteLog(eEvent.INFO_SRD, _module, "ReleaseChuckVacuum has been ignored"); return true; } } /// /// 检查真空状态 /// /// /// private bool CheckVacuum(object param) { if (_srdCommon.IsWaferPresence) { if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout) { PostMsg(UnloadingMsg.Error); return false; } bool result = _srdCommon.Status == RState.End && _srdCommon.CommonData.ChuckVacuum; return result; } else { LOG.WriteLog(eEvent.INFO_SRD, _module, "CheckVacuum has been ignored"); return true; } } #endregion /// /// 停止 /// public void Stop() { base.Terminate(); } public bool Check(int msg, out string reason, params object[] args) { reason = ""; return false; } #region State Msg枚举 public enum UnloadingState { None, Error, Unloading_Start, Unloading_Complete, Unloading_CheckRotationStopped, Unloading_WaferPresent, Unloading_OpenDoor, Unloading_CheckDoorOpened, Unloading_ReleaseChuckVacuum, Unloading_CheckVacuum } public enum UnloadingMsg { Init, Error, Unloading_Start, Unloading_Complete, CheckRoationStopped, WaferPresent, OpenDoor, ReleaseChuckVacuum, Abort } #endregion } }