using System;
using System.Diagnostics;
using System.Collections.Generic;
using Aitex.Core.Common;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Utilities;
using Aitex.Core.Util;
using Aitex.Core.RT.Log;
using Aitex.Sorter.Common;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Schedulers;
using MECF.Framework.Common.SubstrateTrackings;
using CyberX8_Core;
using CyberX8_RT;
using CyberX8_RT.Devices;
using CyberX8_RT.Devices.YASKAWA;
using CyberX8_RT.Devices.EFEM;
using CyberX8_RT.Modules.LPs;
using CyberX8_RT.Modules.EFEM;
using System.Reflection;
using CyberX8_RT.Modules.Transporter;
using MECF.Framework.Common.Alarm;
using MECF.Framework.Common.CommonData;
using CyberX8_RT.Modules.Loader;
namespace CyberX8_RT.Modules
{
class EfemEntity : Entity, IEntity, IModuleEntity
{
//private int _bigWafer = 0;
//private int _midWafer = 0;
//private int _smallWafer = 0;
private bool _isVacuume = false;
public enum STATE
{
Unknown, // 0
Initializing, // 1
Idle, // 2
Error, // 3
Picking, // 4
Placing, // 5
Aligning, // 6
Mapping, // 7
Init, // 8
Orgshing, // 9
Lifting, // 10
InitingAL, // 11
InitingRB, // 12
Extending, // 13
Retracting, // 14
//SettingLamp, // 15
Swapping,
Gotoing,
Gripping,
Ungripping,
Fliping,
Vacuuming,
Retrying,
ConfirmCompleting,
ErrorPicking,
ErrorPlacing
}
public enum MSG
{
HomeAll, // 0
Pick, // 1
Place, // 2
Align, // 3
ActionDone, // 4
MoveCmd, // 6
Recover, // 8
Goto, // 9
Error, // 10
Online, // 11
CommReady, // 12
Lift, // 13
HomeAL, // 14
HomeRB, // 15
Extend, // 16
Retract, // 17
PMLiftPinUp, // 18
PMLiftPinDown, // 19
TurnOffBuzzer,
Abort,
GotoMap,
Map,
ToInit,
Cool,
Swap,
Grip,
Ungrip,
Flip,
LiftActionDone,
Offline,
SetRobotSpeed,
MapDummy,
Vacuum,
CloseBuzzer,
RobotPowerOn,
Retry,
ConfirmComplete,
BackroundCmd=999,
Load,
Unload,
Dock,
Undock,
Clamp,
Unclamp,
ReadCarrierId,
WriteCarrierID,
ReadTagData,
WriteTagData
}
public enum EfemType
{
FutureEfem = 1,
SunWayEFEM =2
}
public bool IsIdle
{
get { return fsm.State == (int)STATE.Idle; }
}
public bool IsError
{
get { return fsm.State == (int)STATE.Error; }
}
public bool IsInit
{
get { return fsm.State == (int)STATE.Unknown || fsm.State == (int)STATE.Init; }
}
public bool IsBusy
{
get { return !IsInit && !IsError && !IsIdle; }
}
public bool IsAuto { get; } = true;
///
/// 是否为工程模式
///
public bool IsEngineering { get; } = false;
///
/// 是否为产品模式
///
public bool IsProduction { get; } = true;
///
/// 模块名称
///
public ModuleName Module { get; private set; }
public bool IsHomed
{
get { return _isHomed; }
}
public bool IsOnline { get; internal set; }
public bool IsDisable { get; internal set; }
public RState RobotStatus
{
get
{
if (_efem.Status != RState.Running)
{
if (_robotWatch.ElapsedMilliseconds < 200)
return RState.Running;
else
return _efem.Status;
}
else
return RState.Running;
}
}
public bool Check(int msg, out string reason, params object[] args)
{
throw new NotImplementedException();
}
// Fields
private readonly string Name;
private readonly EfemBase _efem;
private readonly LoadPortModule[] _lpms = new LoadPortModule[3];
private readonly DummyDevice[] _dummies = new DummyDevice[2];
private readonly EfemType _efemType;
public EfemBase EfemDevice => _efem;
public EfemType EFEMType => _efemType;
// routine
private readonly EfemPickRoutine _pickRoutine;
private readonly EfemPlaceRoutine _placeRoutine;
private readonly EfemSwapRoutine _swapRoutine;
private readonly EfemHomeRoutine _homeRoutine;
private readonly EFEMAlignRoutine _alignRoutine;
private readonly EfemMapDummyRoutine _mapDummyRoutine;
private readonly EfemRobotMapRoutine _robotMapRoutine;
private readonly EfemVacuumRoutine _vacuumRoutine;
private string LiftMessage;
private Stopwatch _robotWatch = new Stopwatch();
private R_TRIG _robotIdleTrigger = new R_TRIG();
private bool _isHomed = false;
private EfemAutoMessageProcessor _autoMessageProcessor;
private STATE _errorPreState;
// Constructor
public EfemEntity()
{
Module = ModuleName.EFEM;
Name = ModuleName.EFEM.ToString();
InitFsmMap();
_efemType = (EfemType)SC.GetValue($"EFEM.EfemType");
_efem = new SunWayRobot();
_homeRoutine = new EfemHomeRoutine(_efem);
_pickRoutine = new EfemPickRoutine(_efem);
_placeRoutine = new EfemPlaceRoutine(_efem);
_swapRoutine = new EfemSwapRoutine(_efem);
_alignRoutine = new EFEMAlignRoutine(_efem);
_mapDummyRoutine = new EfemMapDummyRoutine(_efem);
_vacuumRoutine = new EfemVacuumRoutine(_efem);
_autoMessageProcessor =new EfemAutoMessageProcessor(_efem);
}
public LoadPortModule GetLoadportModule(int lpNumber)
{
if (lpNumber < 0|| _lpms.Length<=lpNumber)
{
return null;
}
return _lpms[lpNumber];
}
public DummyDevice GetDummyDevice(int dummyNumber)
{
if (dummyNumber < 0||_dummies.Length<=dummyNumber)
{
return null;
}
return _dummies[dummyNumber];
}
protected override bool Init()
{
_lpms[0] = new LoadPortModule(ModuleName.LP1, _efem);
_lpms[1] = new LoadPortModule(ModuleName.LP2, _efem);
_lpms[2] = new LoadPortModule(ModuleName.LP3, _efem);
_dummies[0] = new DummyDevice(ModuleName.Dummy1);
_dummies[1] = new DummyDevice(ModuleName.Dummy2);
_lpms[0].Initialize();
_lpms[1].Initialize();
_lpms[2].Initialize();
OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAll); return true; });
OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.ClearError}", (cmd, args) => { PostMsg(MSG.Recover); return true; });
OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.TurnOffBuzzer}", (cmd, args) => { PostMsg(MSG.CloseBuzzer); return true; });
OP.Subscribe($"{ModuleName.EFEM}.Online", (cmd, args) =>
{
PostMsg(MSG.Online, args[0]); return true;
});
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Pick}", (cmd, args) => { CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED,"EFEM",(int)MSG.Pick, args[0]); return true; });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Place}", (cmd, args) => { CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)MSG.Place, args[0]); return true; });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Swap}", (cmd, args) => { PostMsg(MSG.Swap, args[0]); return true; });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.DummyMap}", (cmd, args) => { CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)MSG.MapDummy); return true; });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Speed}", (cmd, args) => {
return _efem.SetRobotSpeed(ModuleName.EfemRobot, (int)args[0]); });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Vacuum}", (cmd, args) => {
return _efem.Vacuum(ModuleName.EfemRobot, (bool)args[1]); });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.PowerOn}", (cmd, args) => {
return _efem.RobotPowerOn(ModuleName.EfemRobot, (bool)args[0]); });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Abort}", (cmd, args) => { PostMsg(MSG.Abort); return true; });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeRB); return true; });
OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Grip}", (cmd, args) =>
{
bool isGrip = ((string)args[0]).ToLower() == "on";
PostMsg(isGrip ? MSG.Grip : MSG.Ungrip, args[1]);
return true;
});
//OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Flip}", (cmd, args) => { PostMsg(MSG.Flip, args[0]); return true; });
OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Aligner1); return true; });
OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Align}", (cmd, args) => { CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED,ModuleName.EFEM.ToString(),(int)MSG.Align, ModuleName.Aligner1, args[0], args[1]); return true; });
//OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Vacuum}", (cmd, args) => { CheckToPostMessage(eEvent.ERR_EFEM_COMMON_FAILED,ModuleName.EFEM.ToString(),(int)MSG.Vacuum, args); return true; });
OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Vacuum}", (cmd, args) => { return VacuumAction(args); });
DATA.Subscribe($"{Name}.FsmState", () => ((STATE)fsm.State).ToString(),SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.FsmPrevState", () => ((STATE)fsm.PrevState).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.FsmLastMessage", GetFsmLastMessage, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.RobotMoveAction", () => (_efem.TMRobotMoveInfo), SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.State", () => ((STATE)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.IsAlarm", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.IsInit", () => IsInit, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.IsIdle", () => IsIdle, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.IsBusy", () => IsBusy, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.IsOnline", () => IsOnline, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.IsHomed", () => _isHomed, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Name}.RobotSpeed",()=>IsIdle?SC.GetValue("EFEM.DefaultMoveSpeedInPercent"):0);
_robotWatch.Restart();
return true;
}
private void InitFsmMap()
{
fsm = new StateMachine("EFEM", (int)STATE.Unknown, 50);
fsm.EnableRepeatedMsg(true);
AnyStateTransition(FSM_MSG.TIMER, fnMonitor, FSM_STATE.SAME);
AnyStateTransition(MSG.TurnOffBuzzer, fnTurnOffBuzzer, FSM_STATE.SAME);
AnyStateTransition(MSG.Error, fnError, STATE.Error);
AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
AnyStateTransition(MSG.Abort, fnAbortRobot, FSM_STATE.SAME);
AnyStateTransition(MSG.ToInit, fnToInit, STATE.Init);
AnyStateTransition(MSG.BackroundCmd, fnBackroundCommand, FSM_STATE.SAME);
AnyStateTransition(MSG.CloseBuzzer, fnCloseBuzzer, FSM_STATE.SAME);
Transition(STATE.Unknown,MSG.CommReady, fnCommReady, STATE.Init);
//Error
Transition(STATE.Error, MSG.Recover, fnRecover, STATE.Idle);
// Home
Transition(STATE.Init, MSG.HomeAll, fnHomeAll, STATE.Initializing);
Transition(STATE.Idle, MSG.HomeAll, fnHomeAll, STATE.Initializing);
Transition(STATE.Error, MSG.HomeAll, fnHomeAll, STATE.Initializing);
Transition(STATE.Initializing, FSM_MSG.TIMER, fnHomingTimeout, STATE.Idle);
// Home Robot
Transition(STATE.Error, MSG.HomeRB, fnHomeRobot, STATE.InitingRB);
Transition(STATE.Idle, MSG.HomeRB, fnHomeRobot, STATE.InitingRB);
Transition(STATE.InitingRB, FSM_MSG.TIMER, fnHomingRobotTimeout, STATE.Idle);
// Home Aligner
Transition(STATE.Idle, MSG.HomeAL, fnHomeAligner, STATE.InitingAL);
Transition(STATE.InitingAL, FSM_MSG.TIMER, fnHomingAlignTimeout, STATE.Idle);
// Pick wafer
Transition(STATE.Idle, MSG.Pick, FnStartPick, STATE.Picking);
Transition(STATE.Picking, FSM_MSG.TIMER, FnPickTimeout, STATE.Idle);
Transition(STATE.Picking, MSG.Abort, FnAbortPick, STATE.Idle);
Transition(STATE.Error, MSG.Pick, FnErrorStartPick, STATE.ErrorPicking);
Transition(STATE.ErrorPicking, FSM_MSG.TIMER, FnErrorPickTimeout, STATE.Error);
Transition(STATE.ErrorPicking, MSG.Abort, FnErrorAbortPick, STATE.Error);
// Place wafer
Transition(STATE.Idle, MSG.Place, FnStartPlace, STATE.Placing);
Transition(STATE.Placing, FSM_MSG.TIMER, FnPlaceTimeout, STATE.Idle);
Transition(STATE.Placing, MSG.Abort, FnAbortPlace, STATE.Idle);
Transition(STATE.Error, MSG.Place, FnErrorStartPlace, STATE.ErrorPlacing);
Transition(STATE.ErrorPlacing, FSM_MSG.TIMER, FnErrorPlaceTimeout, STATE.Error);
Transition(STATE.ErrorPlacing, MSG.Abort, FnErrorAbortPlace, STATE.Error);
// Swap wafer with LL sequence
Transition(STATE.Idle, MSG.Swap, FnStartSwap, STATE.Swapping);
Transition(STATE.Swapping, FSM_MSG.TIMER, FnSwapTimeout, STATE.Idle);
Transition(STATE.Swapping, MSG.Abort, FnAbortSwap, STATE.Idle);
// Goto
Transition(STATE.Idle, MSG.Goto, fnGoto, STATE.Gotoing);
Transition(STATE.Gotoing, MSG.ActionDone, fnActionDone, STATE.Idle);
// Map
Transition(STATE.Idle, MSG.Map, fnMap, STATE.Mapping);
Transition(STATE.Mapping, MSG.ActionDone, fnActionDone, STATE.Idle);
// Grip
Transition(STATE.Idle, MSG.Grip, fnGrip, STATE.Gripping);
Transition(STATE.Gripping, MSG.ActionDone, fnActionDone, STATE.Idle);
// Ungrip
Transition(STATE.Idle, MSG.Ungrip, fnUngrip, STATE.Ungripping);
Transition(STATE.Ungripping, MSG.ActionDone, fnActionDone, STATE.Idle);
// Aligner
Transition(STATE.Idle, MSG.Lift, fnLift, STATE.Lifting);
//Transition(STATE.Lifting, MSG.LiftActionDone, fnActionDone, STATE.Idle);
Transition(STATE.Lifting, FSM_MSG.TIMER, fnLiftTimeout, STATE.Idle);
Transition(STATE.Idle, MSG.Align, fnAlign, STATE.Aligning);
Transition(STATE.Aligning, FSM_MSG.TIMER, fnAlignTimeout, STATE.Idle);
Transition(STATE.Aligning, MSG.ActionDone, fnActionDone, STATE.Idle);
//MapDummy
Transition(STATE.Idle, MSG.MapDummy, MapDummy, STATE.Mapping);
Transition(STATE.Mapping, FSM_MSG.TIMER, MapDummyTimeout, STATE.Idle);
//Vacuum
//Transition(STATE.Init, MSG.Vacuum, VacuumAction, STATE.Vacuuming);
//Transition(STATE.Idle, MSG.Vacuum, VacuumAction, STATE.Vacuuming);
//Transition(STATE.Error, MSG.Vacuum, VacuumAction, STATE.Vacuuming);
//Transition(STATE.Vacuuming, FSM_MSG.TIMER, VacuumActionTimeout, STATE.Idle);
//Retry
Transition(STATE.Error, MSG.Retry, NullFunc, STATE.Retrying);
Transition(STATE.Retrying, FSM_MSG.TIMER, EfemRetry, STATE.Retrying);
Transition(STATE.Retrying, MSG.Align, RetryAlign, STATE.Aligning);
Transition(STATE.Retrying, MSG.Pick, RetryPick, STATE.Picking);
Transition(STATE.Retrying, MSG.Place, RetryPlace, STATE.Placing);
//ConfirmComplete
Transition(STATE.Init, MSG.ConfirmComplete, ClearModuleAlarm, STATE.Init);
Transition(STATE.Idle, MSG.ConfirmComplete, ClearModuleAlarm, STATE.Idle);
Transition(STATE.Error, MSG.ConfirmComplete, NullFunc, STATE.ConfirmCompleting);
Transition(STATE.ConfirmCompleting, FSM_MSG.TIMER, ConfirmComplete, STATE.ConfirmCompleting);
Transition(STATE.ConfirmCompleting, MSG.Align, ConfirmAlign, STATE.Idle);
Transition(STATE.ConfirmCompleting, MSG.Pick, ConfirmPickup, STATE.Idle);
Transition(STATE.ConfirmCompleting, MSG.Place, ConfirmPlace, STATE.Idle);
EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
Running = true;
}
private bool fnCommReady(object[] param)
{
return true;
}
private bool fnCloseBuzzer(object[] param)
{
return _efem.CloseBuzzer();
}
private bool fnHomeAll(object[] param)
{
_isHomed = false;
return _homeRoutine.Start(ModuleName.EFEM) == RState.Running;
}
private bool fnHomingTimeout(object[] param)
{
RState ret = _homeRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error);
return false;
}
bool result= ret == RState.End;
if(result)
{
_isHomed= true;
RecoverLPStatus();
}
return result;
}
private void RecoverLPStatus()
{
_lpms[0].PostMsg(LoadPortModule.MSG.EnterIdle);
_lpms[1].PostMsg(LoadPortModule.MSG.EnterIdle);
_lpms[2].PostMsg(LoadPortModule.MSG.EnterIdle);
}
private bool fnHomeRobot(object[] param)
{
if (_isHomed)
{
return _homeRoutine.Start(ModuleName.EfemRobot) == RState.Running;
}
else
{
return false;
}
}
private bool fnHomingRobotTimeout(object[] param)
{
RState ret = _homeRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error);
return false;
}
bool result = ret == RState.End;
if (result)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Idle.ToString());
}
return result;
}
private bool fnHomeAligner(object[] param)
{
// module
ModuleName unit = ModuleName.EFEM;
if (param[0] is string s1)
unit = ModuleNameString.ToEnum(s1);
else if (param[0] is ModuleName mod)
unit = mod;
else
throw new ArgumentException("Argument error");
return _homeRoutine.Start(unit) == RState.Running;
}
private bool fnHomingAlignTimeout(object[] param)
{
RState ret = _homeRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error);
return false;
}
bool result = ret == RState.End;
if (result)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Idle.ToString());
}
return result;
}
private bool fnActionDone(object[] param)
{
return false;
}
public bool CheckToPostMessage(int msg, params object[] args)
{
if (!fsm.FindTransition(fsm.State, msg))
{
LOG.Write(eEvent.WARN_EFEM_COMMON_WARN, ModuleName.EFEM, $"{Name} is in {(STATE)fsm.State} state,can not do {(MSG)msg}");
return false;
}
Running = true;
fsm.PostMsg(msg, args);
return true;
}
private bool fnMonitor(object[] param)
{
if (_isVacuume)
{
VacuumActionTimeout();
_isVacuume = false;
}
// robot idle check
_robotIdleTrigger.CLK = _efem.Status != RState.Running;
if (_robotIdleTrigger.Q)
{
_robotWatch.Restart();
LOG.WriteLog(eEvent.EV_EFEM_ROBOT, Module.ToString(), $"robot status changed to {_efem.Status}");
}
_autoMessageProcessor.Monitor();
return true;
}
private bool fnOnline(object[] param)
{
bool bOnlineFlag = (bool)param[0];
if (_efem is EfemBase efem)
{
efem.SetOnline(bOnlineFlag);
}
IsOnline = bOnlineFlag;
return true;
}
private string GetFsmLastMessage()
{
int msg = fsm.LastMsg;
if (msg >= (int)MSG.HomeAll && msg <= (int)MSG.Error)
return ((MSG)msg).ToString();
if (msg == (int)FSM_MSG.TIMER)
return "Timer";
return msg.ToString();
}
private bool fnError(object[] param)
{
_errorPreState = (STATE)fsm.State;
string error = (param != null && param.Length != 0) ? param[0].ToString() : "";
if (Singleton.Instance.IsAutoRunning)
{
int msg = 0;
if (_errorPreState == STATE.Picking)
{
msg = (int)MSG.Pick;
}
else if (_errorPreState == STATE.Aligning)
{
msg= (int)MSG.Align;
}
else if (_errorPreState == STATE.Placing)
{
msg = (int)MSG.Place;
}
else
{
error = $"{error}\r\n Plase Home Robot back to idle state";
}
AlarmList alarmList = new AlarmList(Module.ToString(), ((STATE)fsm.State).ToString(), msg,
error, 0, (int)AlarmType.Error);
AlarmListManager.Instance.AddAlarm(alarmList);
}
return true;
}
private bool fnToInit(object[] param)
{
return true;
}
private bool fnRecover(object[] param)
{
bool result=_efem.ClearError();
if (result)
{
PostMsg(MSG.ToInit);
}
return result;
}
private bool fnAbortRobot(object[] param)
{
//_efem.ExecuteAction();
return true;
}
private bool fnBackroundCommand(object[] param)
{
_autoMessageProcessor.SendAutoCommandMessage(param);
return true;
}
private bool fnRobotPowerOn(object[] param)
{
return _efem.RobotPowerOn(ModuleName.EfemRobot, (bool)param[0]);
}
private bool fnSetLED(object[] param)
{
LightType light = (LightType)param[0];
LightStatus st = (LightStatus)param[1];
return _efem.SetLamp(light, st);
}
private bool fnTurnOffBuzzer(object[] param)
{
return false;
}
private bool FnStartPick(object[] param)
{
return _pickRoutine.Start(param) == RState.Running;
}
private bool FnErrorStartPick(object[] param)
{
if (!_isHomed)
{
LOG.WriteLog(eEvent.ERR_EFEM_ROBOT, Module.ToString(), "EFEM is not homed");
return false;
}
_efem.Reset();
return _pickRoutine.Start(param) == RState.Running;
}
///
/// Retry Pick
///
///
///
private bool RetryPick(object[] param)
{
int stepIndex = (int)param[0];
return _pickRoutine.Retry(stepIndex) == RState.Running;
}
private bool FnPickTimeout(object[] param)
{
RState ret = _pickRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error,_pickRoutine.ErrorMsg);
return false;
}
if (ret == RState.End)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Picking.ToString());
}
return ret == RState.End;
}
private bool FnErrorPickTimeout(object[] param)
{
RState ret = _pickRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error, _pickRoutine.ErrorMsg);
return false;
}
return ret == RState.End;
}
///
/// 确认Pick是否完成
///
///
///
private bool ConfirmPickup(object[] param)
{
int stepIdex = (int)param[0];
bool result = _pickRoutine.CheckCompleteCondition(stepIdex);
if (!result)
{
PostMsg(MSG.Error,_pickRoutine.ErrorMsg);
}
else
{
if (Singleton.Instance.IsAutoRunning)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Picking.ToString());
}
}
return result;
}
private bool FnAbortPick(object[] param)
{
_pickRoutine.Abort();
return true;
}
private bool FnErrorAbortPick(object[] param)
{
_pickRoutine.Abort();
return true;
}
private bool FnStartPlace(object[] param)
{
return _placeRoutine.Start(param) == RState.Running;
}
private bool FnErrorStartPlace(object[] param)
{
if(!_isHomed)
{
LOG.WriteLog(eEvent.ERR_EFEM_ROBOT, Module.ToString(), "EFEM is not homed");
return false;
}
_efem.Reset();
return _placeRoutine.Start(param) == RState.Running;
}
///
/// Retry Place
///
///
///
private bool RetryPlace(object[] param)
{
int stepIndex = (int)param[0];
return _placeRoutine.Retry(stepIndex) == RState.Running;
}
private bool FnPlaceTimeout(object[] param)
{
RState ret = _placeRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error,_placeRoutine.ErrorMsg);
return false;
}
if (ret == RState.End)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Placing.ToString());
}
return ret == RState.End;
}
private bool FnErrorPlaceTimeout(object[] param)
{
RState ret = _placeRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error, _placeRoutine.ErrorMsg);
return false;
}
return ret == RState.End;
}
///
/// 确认Place是否完成
///
///
///
private bool ConfirmPlace(object[] param)
{
int stepIdex = (int)param[0];
bool result = _placeRoutine.CheckCompleteCondition(stepIdex);
if (!result)
{
PostMsg(MSG.Error, _placeRoutine.ErrorMsg);
}
else
{
if (Singleton.Instance.IsAutoRunning)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Picking.ToString());
}
}
return result;
}
private bool FnAbortPlace(object[] param)
{
_placeRoutine.Abort();
return true;
}
private bool FnErrorAbortPlace(object[] param)
{
_placeRoutine.Abort();
return true;
}
private bool FnStartSwap(object[] param)
{
return _swapRoutine.Start(param) == RState.Running;
}
private bool FnSwapTimeout(object[] param)
{
RState ret = _swapRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error);
return false;
}
return ret == RState.End;
}
private bool FnAbortSwap(object[] param)
{
_swapRoutine.Abort();
return true;
}
private bool fnGoto(object[] param)
{
// module
ModuleName unit = ModuleName.EFEM;
if (param[0] is string s1)
unit = ModuleNameString.ToEnum(s1);
else if (param[0] is ModuleName mod)
unit = mod;
else
throw new ArgumentException("Argument error");
_efem.Goto(unit, Hand.Blade1);
return true;
}
private bool fnLift(object[] param)
{
// module
ModuleName unit = ModuleName.EFEM;
if (param[0] is string s1)
unit = ModuleNameString.ToEnum(s1);
else if (param[0] is ModuleName mod)
unit = mod;
else
throw new ArgumentException("Argument error");
bool isUp = true;
if (param.Length > 1)
{
isUp = (bool) param[1];
}
if (isUp)
{
if (!_efem.SetPinUp(unit))
return false;
}
else
{
if (!_efem.SetPinDown(unit))
return false;
}
LiftMessage = isUp ? "Up" : "Down";
return true;
}
private bool fnLiftTimeout(object[] param)
{
if (LiftMessage == "Up")
{
return _efem.LiftIsDown == false && _efem.LiftIsUp == true;
}
else if (LiftMessage == "Down")
{
return _efem.LiftIsDown == true && _efem.LiftIsUp == false;
}
return false;
}
private bool fnAlign(object[] param)
{
return _alignRoutine.Start(param) == RState.Running;
}
private bool fnAlignTimeout(object[] param)
{
RState ret = _alignRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error,_alignRoutine.ErrorMsg);
return false;
}
if (ret == RState.End)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Aligning.ToString());
}
return ret == RState.End;
}
///
/// Retry Align
///
///
///
private bool RetryAlign(object[] param)
{
int stepIndex = (int)param[0];
return _alignRoutine.Retry(stepIndex) == RState.Running;
}
///
/// 确认Align是否完成
///
///
///
private bool ConfirmAlign(object[] param)
{
int stepIdex = (int)param[0];
bool result = _alignRoutine.CheckCompleteCondition(stepIdex);
if (!result)
{
PostMsg(MSG.Error, _alignRoutine.ErrorMsg);
}
else
{
if (Singleton.Instance.IsAutoRunning)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Aligning.ToString());
}
}
return result;
}
private bool MapDummyTimeout(object[] param)
{
RState ret = _mapDummyRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
PostMsg(MSG.Error);
return false;
}
return ret == RState.End;
}
private bool VacuumActionTimeout()
{
RState ret = _vacuumRoutine.Monitor();
if (ret == RState.Failed || ret == RState.Timeout)
{
LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "Vacuum");
return false;
}
return ret == RState.End;
}
private bool fnMap(object[] param)
{
// module
ModuleName unit = ModuleName.EFEM;
if (param[0] is string s1)
unit = ModuleNameString.ToEnum(s1);
else if (param[0] is ModuleName mod)
unit = mod;
else
throw new ArgumentException("Argument error");
if (!_efem.Map(unit))
return false;
return true;
}
private bool MapDummy(object[] param)
{
return _mapDummyRoutine.Start()==RState.Running;
}
private bool VacuumAction(object[] param)
{
ModuleName vacuumModule = (ModuleName)param[0];
bool vacuum=(bool)param[1];
bool result = _vacuumRoutine.Start(vacuumModule, vacuum) == RState.Running;
if (result)
{
_isVacuume = true;
}
return result;
}
private bool fnGrip(object[] param)
{
Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[0]);
if (!_efem.Grip(arm, true))
return false;
return true;
}
public int SendEfemAutoCommand(params object[] args)
{
if (CheckToPostMessage((int)MSG.BackroundCmd, args))
return (int)MSG.BackroundCmd;
return (int)FSM_MSG.NONE;
}
private bool fnUngrip(object[] param)
{
Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[0]);
if (!_efem.Grip(arm, false))
return false;
return true;
}
#region EfemRetry
///
/// Retry
///
///
///
private bool EfemRetry(object[] param)
{
AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
if (alarmList != null)
{
CheckToPostMessage(eEvent.ERR_EFEM_ROBOT, Module.ToString(), alarmList.ModuleCmd,
alarmList.ModuleStep);
}
return false;
}
#endregion
#region ConfirmComplete
///
/// 确认是否完成
///
///
///
private bool ConfirmComplete(object[] param)
{
AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
if (alarmList != null)
{
if (alarmList.ModuleState == STATE.Picking.ToString())
{
CheckToPostMessage(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Pick, alarmList.ModuleStep);
}
else if (alarmList.ModuleState == STATE.Placing.ToString())
{
CheckToPostMessage(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Place, alarmList.ModuleStep);
}
else if (alarmList.ModuleState == STATE.Aligning.ToString())
{
CheckToPostMessage(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Align, alarmList.ModuleStep);
}
else
{
PostMsg(PUFSTATE.Error);
}
}
return false;
}
///
/// 清除报警
///
///
///
private bool ClearModuleAlarm(object[] param)
{
AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
if (alarmList != null)
{
AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), "");
}
return true;
}
#endregion
public int Invoke(string function, params object[] args)
{
switch (function)
{
case "HomeAll":
if (IsIdle)
{
return (int)FSM_MSG.NONE;
}
if (CheckToPostMessage((int)MSG.HomeAll))
{
return (int)MSG.HomeAll;
}
else
{
return (int)FSM_MSG.NONE;
}
case "Retry":
if (CheckToPostMessage(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Retry, args))
{
return (int)MSG.Retry;
}
else
{
return (int)FSM_MSG.NONE;
}
case "ConfirmComplete":
if (CheckToPostMessage(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.ConfirmComplete, args))
{
return (int)MSG.ConfirmComplete;
}
else
{
return (int)FSM_MSG.NONE;
}
}
return (int)FSM_MSG.NONE;
}
public bool CheckAcked(int msg)
{
return fsm.CheckExecuted(msg);
}
internal void InvokeReset()
{
if (fsm.State == (int) STATE.Error)
{
PostMsg((int)MSG.Recover);
}
}
public int InvokeAlign(string module, int reserv, float time)
{
if (CheckToPostMessage((int)MSG.Align, module, reserv, time))
return (int)MSG.Align;
return (int)FSM_MSG.NONE;
}
public int InvokeLiftDown(string module)
{
if (CheckToPostMessage((int)MSG.Lift, module, false))
return (int)MSG.Lift;
return (int)FSM_MSG.NONE;
}
public int InvokePick(ModuleName source, int slot, Hand hand, WaferSize size)
{
if (CheckToPostMessage((int)MSG.Pick, source, slot, hand, size))
return (int)MSG.Pick;
return (int)FSM_MSG.NONE;
}
public int InvokeGoto(ModuleName source, int slot)
{
if (CheckToPostMessage((int)MSG.Goto, source, slot))
return (int)MSG.Goto;
return (int)FSM_MSG.NONE;
}
public int InvokePlace(ModuleName target, int slot, Hand hand, WaferSize size)
{
if (CheckToPostMessage((int)MSG.Place, target, slot, hand, size))
return (int)MSG.Place;
return (int)FSM_MSG.NONE;
}
public int InvokePickAndPlace(ModuleName targetModule, Hand pickHand, int pickSlot, Hand placeHand, int placeSlot, WaferSize size)
{
if (CheckToPostMessage((int)MSG.Swap, targetModule, pickSlot, pickHand, placeHand, placeSlot, size))
return (int)MSG.Swap;
return (int)FSM_MSG.NONE;
}
public int InvokeMap(string target )
{
if (CheckToPostMessage((int)MSG.Map, target ))
return (int)MSG.Map;
return (int)FSM_MSG.NONE;
}
public int InvokeFlip(Hand hand)
{
if (CheckToPostMessage((int)MSG.Flip, hand))
return (int)MSG.Flip;
return (int)FSM_MSG.NONE;
}
public bool IsPrepareTransferReady(ModuleName module, EnumTransferType type, int slot)
{
//if (type == EnumTransferType.Pick)
//{
// //需要补充:判断LP 放好了,而且已经map过。
// return _efem[module].HasCassette && _efem[module].IsMapped;
//}
//else if (type == EnumTransferType.Place)
//{
// //需要补充:判断LP 放好了,而且已经map过。
// return _efem[module].HasCassette && _efem[module].IsMapped;
//}
return false;
}
internal bool CheckReadyRunNewJob(ModuleName module)
{
//???
return true;
}
internal bool CheckReadyTransfer(ModuleName module)
{
//return _efem[module].HasCassette && _efem[module].IsMapped;
return true;
}
internal bool CheckPlaced(ModuleName module)
{
//return _efem[module].HasCassette;
return true;
}
internal void NoteJobStart(ModuleName module)
{
//_efem[module].NoteJobStart();
}
internal void NoteJobComplete(ModuleName module)
{
//_efem[module].NoteJobComplete();
}
}
}