using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Schedulers;
using CyberX8_Core;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.PUF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.SubstrateTrackings;
using CyberX8_RT.Modules.Loader;
using CyberX8_RT.Modules.SRD;
namespace CyberX8_RT.Schedulers.EfemRobot
{
public class SchedulerRobot : SchedulerModule
{
private enum SchedulerRobotOperation
{
None,
Pick,
PickWait,
Place,
PlaceWait
}
#region 内部变量
private EfemEntity _efemEntity;
private LoaderEntity _loaderEntity;
private PUFEntity _puf1Entity;
private PUFEntity _puf2Entity;
#endregion
#region 属性
///
/// 是否空闲
///
public override bool IsIdle
{
get { return _state == RState.End; }
}
///
/// 是否错误
///
public override bool IsError
{
get { return _state == RState.Failed || _state == RState.Timeout; }
}
#endregion
///
/// 构造函数
///
///
public SchedulerRobot(ModuleName module) : base(module.ToString())
{
_efemEntity = Singleton.Instance.EFEM;
_loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
_puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString());
_puf2Entity = Singleton.Instance.GetModule(ModuleName.PUF2.ToString());
}
///
/// 执行
///
///
///
public override bool RunProcess(object recipe, object parameter, List syncMessages)
{
if (_efemEntity.IsBusy)
{
return false;
}
MoveItem moveItem = (MoveItem)parameter;
if (moveItem.SourceModule != ModuleName.Unknown&&moveItem.DestinationModule!=ModuleName.Unknown)
{
SynchorinzeModuleMessages(syncMessages);
_state = RState.Running;
if (RobotMoveHelper.Instance.IsIdle)
{
RobotMoveHelper.Instance.Start(moveItem, Module.ToString());
return true;
}
}
return false;
}
///
/// 监控执行
///
///
public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
{
RobotMoveHelper.Instance.Monitor(Module.ToString());
if (RobotMoveHelper.Instance.IsIdle)
{
_state = RState.End;
}
return true;
}
///
/// 检验前置条件
///
///
///
///
public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter,string materialId, ref string reason)
{
if (parameter == null)
{
reason = "parameter is null";
return true;
}
if (_state == RState.Running)
{
reason = "scheduler module is already running";
return false;
}
if(_efemEntity.IsBusy)
{
reason = "efem is busy";
return false;
}
if(_efemEntity.IsError)
{
reason = "efem is error";
return false;
}
if(_loaderEntity.IsError||_puf1Entity.IsError || _puf2Entity.IsError)
{
reason = "loader or puf is error";
return false;
}
MoveItem moveItem = (MoveItem)parameter;
if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot,(int)moveItem.RobotHand))
{
reason = "robot has wafer";
return false;
}
if (moveItem.SourceModule == ModuleName.Unknown)
{
UpdateUnkownSourceModule(schedulerSequences, moveItem, sequenceIndex);
}
if (moveItem.DestinationModule == ModuleName.Unknown)
{
bool result= UpdateUnkownTargetModule(schedulerSequences, moveItem, sequenceIndex);
if (!result)
{
reason = "efem robot confirm target module failed";
return false;
}
}
if (ModuleHelper.IsPUF(moveItem.DestinationModule))
{
PUFEntity pufEntity = Singleton.Instance.GetModule(moveItem.DestinationModule.ToString());
if (pufEntity != null)
{
if (pufEntity.State == (int)PUFSTATE.WaitForRobotPlace)
{
return true;
}
else
{
if (pufEntity.IsIdle)
{
pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
(int)PUFMSG.ReadyForRobotPlace);
}
reason = $"{pufEntity.Module} state is not WaitForRobotPlace";
return false;
}
}
else
{
reason = $"{moveItem.DestinationModule} puf is null";
}
}
else if (ModuleHelper.IsPUF(moveItem.SourceModule))
{
PUFEntity pufEntity = Singleton.Instance.GetModule(moveItem.SourceModule.ToString());
if (pufEntity != null)
{
if (pufEntity.State == (int)PUFSTATE.WaitForRobotPick)
{
return true;
}
else
{
if (pufEntity.IsIdle)
{
pufEntity.CheckToPostMessage(eEvent.ERR_PUF, pufEntity.Module.ToString(),
(int)PUFMSG.ReadyForRobotPick);
}
reason = $"{pufEntity.Module} state is not WaitForRobotPick";
return false;
}
}
else
{
reason = $"{moveItem.SourceModule} puf is null";
return false;
}
}
return true;
}
///
/// 更新未知源模块
///
private void UpdateUnkownSourceModule(List schedulerSequences, MoveItem moveItem, int sequenceIndex)
{
if (moveItem.SourceModule == ModuleName.Unknown)
{
if (sequenceIndex >= 1 && sequenceIndex - 1 < schedulerSequences.Count)
{
SchedulerSequence preSchedulerSequence = schedulerSequences[sequenceIndex - 1];
if (preSchedulerSequence != null && preSchedulerSequence.SchedulerModule != null)
{
moveItem.SourceModule = preSchedulerSequence.SchedulerModule.Module;
}
}
}
}
///
/// 更新未知目标模块
///
private bool UpdateUnkownTargetModule(List schedulerSequences, MoveItem moveItem, int sequenceIndex)
{
SchedulerSequence currentSchedulerSequence= schedulerSequences[sequenceIndex];
ModuleName moduleName = ModuleName.Unknown;
if (moveItem.DestinationType == ModuleType.SRD)
{
SRDEntity srd1Entity = Singleton.Instance.GetModule(ModuleName.SRD1.ToString());
if (srd1Entity != null&&srd1Entity.IsIdle&&srd1Entity.IsAuto&&WaferManager.Instance.CheckNoWafer(ModuleName.SRD1.ToString(),0))
{
moduleName = ModuleName.SRD1;
}
else
{
SRDEntity srd2Entity= Singleton.Instance.GetModule(ModuleName.SRD2.ToString());
if (srd2Entity != null && srd2Entity.IsIdle&&srd2Entity.IsAuto && WaferManager.Instance.CheckNoWafer(ModuleName.SRD2.ToString(), 0))
{
moduleName=ModuleName.SRD2;
}
}
}
else
{
return false;
}
if (moduleName == ModuleName.Unknown)
{
return false;
}
else
{
if(WaferManager.Instance.CheckHasWafer(moduleName,0))
{
return false;
}
IModuleEntity moduleEntity = Singleton.Instance.GetModule(moduleName.ToString());
if (moduleEntity==null)
{
return false;
}
if (moduleEntity.IsBusy)
{
return false;
}
moveItem.DestinationModule = moduleName;
if (sequenceIndex + 1 < schedulerSequences.Count)
{
SchedulerSequence sequence = schedulerSequences[sequenceIndex + 1];
if (sequence.SchedulerModule == null)
{
sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);
sequence.ModuleName = moduleName;
}
}
}
return true;
}
public override void ResetTask()
{
base.ResetTask();
RobotMoveHelper.Instance.Reset();
}
}
}