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
}
}