123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- using Aitex.Core.RT.Fsm;
- 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.PUF;
- using CyberX8_RT.Modules;
- using CyberX8_RT.Schedulers.EfemRobot;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using CyberX8_RT.Modules.Loader;
- using Aitex.Core.RT.Log;
- using MECF.Framework.Common.SubstrateTrackings;
- using Aitex.Core.Common;
- using MECF.Framework.Common.Utilities;
- using CyberX8_RT.Devices.AXIS;
- using Aitex.Core.RT.Device;
- using CyberX8_RT.Dispatch;
- using MECF.Framework.Common.RecipeCenter;
- namespace CyberX8_RT.Schedulers.Puf
- {
- public class SchedulerPuf : SchedulerModule
- {
- private enum OperationStep
- {
- None,
- ReadyForSwap,
- WaitForLoaderUnloadComplete,
- Swap,
- CheckSwapComplete,
- GotoRobotForPick,
- WaitForRobotPick,
- PufBackToPark,
- CheckParkComplete
- }
- #region 内部变量
- private PUFEntity _pufEntity;
- private LoaderEntity _loaderEntity;
- private OperationStep _currentOperation;
- private EfemEntity _efemEntity;
- private bool _forward = false;
- private bool _isProductionWafer = false;
- #endregion
- #region 属性
- /// <summary>
- /// 是否空闲
- /// </summary>
- public override bool IsIdle
- {
- get { return _state == RState.End; }
- }
- /// <summary>
- /// 是否错误
- /// </summary>
- public override bool IsError
- {
- get { return _state == RState.Failed || _state == RState.Timeout; }
- }
- #endregion
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="module"></param>
- public SchedulerPuf(ModuleName moduleName) : base(moduleName.ToString())
- {
- _efemEntity = Singleton<RouteManager>.Instance.EFEM;
- _pufEntity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(moduleName.ToString());
- _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
- }
- /// <summary>
- /// 执行
- /// </summary>
- /// <param name="parameter"></param>
- /// <returns></returns>
- public override bool RunProcess(object recipe, object parameter, List<SchedulerSyncModuleMessage> syncMessages)
- {
- _isProductionWafer = false;
- _forward = (bool)parameter;
- if (_forward)
- {
- _currentOperation = OperationStep.ReadyForSwap;
- //B面是否有片
- if (WaferManager.Instance.CheckHasWafer(Module, 1))
- {
- _state = RState.Running;
- return _pufEntity.CheckToPostMessage<PUFSTATE, PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
- (int)PUFMSG.ReadyForSwap);
- }
- return false;
- }
- else
- {
- _currentOperation = OperationStep.None;
- return true;
- }
- }
- /// <summary>
- /// 监控执行
- /// </summary>
- /// <returns></returns>
- public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
- {
- //当前状态为ReadyForSwap
- if (_currentOperation == OperationStep.ReadyForSwap)
- {
- //若Puf已经完成ReadyForSwap动作,状态变更为WaitForSwap
- if (_pufEntity.State == (int)PUFSTATE.WaitForSwap)
- {
- //当前操作变量为WaitFor LoaderUnload Complete
- _currentOperation = OperationStep.WaitForLoaderUnloadComplete;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is WaitForLoaderUnloadComplete");
- }
- }
- else if (_currentOperation == OperationStep.WaitForLoaderUnloadComplete)
- {
- //Loader Entity Unload all
- if (CheckDualPufStateCanExecuteLoaderUnloadAll(hasMatchWafer))
- {
- PostLoaderEntityUnloadAllSide();
- }
- }
- //puf 进行Swap
- else if(_currentOperation==OperationStep.Swap)
- {
- bool result = _pufEntity.CheckToPostMessage<PUFSTATE,PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
- (int)PUFMSG.Swap);
- if(result)
- {
- _currentOperation = OperationStep.CheckSwapComplete;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is CheckSwapComplete");
- }
- }
- else if(_currentOperation==OperationStep.CheckSwapComplete)
- {
- //puf完成Swap后运动至Robot让Robot取片
- PostPufEntityGotoRobotForPick();
- }
- else if(_currentOperation==OperationStep.GotoRobotForPick)
- {
- //Efem 将Dummy片运输至Dummy Casstete
- PostEfemRobotTransferToDummyCassete();
- }
- else if(_currentOperation==OperationStep.WaitForRobotPick)
- {
- //等待Efem Robot完成传片
- if (RobotMoveHelper.Instance.IsBusy)
- {
- RobotMoveHelper.Instance.Monitor(Module.ToString());
- }
- if(RobotMoveHelper.Instance.IsPickCompleted)
- {
- _currentOperation = OperationStep.PufBackToPark;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is PufBackToBack");
- }
- }
- else if(_currentOperation==OperationStep.PufBackToPark)
- {
- if (RobotMoveHelper.Instance.IsBusy)
- {
- RobotMoveHelper.Instance.Monitor(Module.ToString());
- }
- //Puf运动至Park安全位置
- bool result = _pufEntity.CheckToPostMessage<PUFSTATE, PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
- (int)PUFMSG.RobotPickComplete);
- if (result)
- {
- _currentOperation = OperationStep.CheckParkComplete;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is CheckParkComplete");
- }
- }
- else if(_currentOperation==OperationStep.CheckParkComplete)
- {
- if (RobotMoveHelper.Instance.IsBusy)
- {
- RobotMoveHelper.Instance.Monitor(Module.ToString());
- }
- //判定Puf运动是否完成
- if (_pufEntity.IsIdle&&RobotMoveHelper.Instance.IsIdle)
- {
- _state = RState.End;
- }
- }
- return false;
- }
- /// <summary>
- /// 检验Dual puf 是不是都处于WaitForSwap 状态,保证Loader可以UnloadAll
- /// </summary>
- /// <returns></returns>
- private bool CheckDualPufStateCanExecuteLoaderUnloadAll(bool hasMatchWafer)
- {
- bool puf1ready = true;
- if(ModuleHelper.IsInstalled(ModuleName.PUF1))
- {
- PUFEntity puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());
- if(hasMatchWafer)
- {
- //B面有Wafer
- if (WaferManager.Instance.CheckHasWafer(ModuleName.PUF1,1))
- {
- puf1ready = puf1Entity.State == (int)PUFSTATE.WaitForSwap;
- }
- else
- {
- puf1ready = false;
- }
- }
- else
- {
- //任务仅一片Wafer,同时模块为PUF2
- if(Module==ModuleName.PUF2)
- {
- puf1ready = puf1Entity.IsIdle;
- }
- }
- }
- if(!puf1ready)
- {
- return false;
- }
- bool puf2ready = true;
- if (ModuleHelper.IsInstalled(ModuleName.PUF2))
- {
- PUFEntity puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());
- if(hasMatchWafer)
- {
- //B面有Wafer
- if (WaferManager.Instance.CheckHasWafer(ModuleName.PUF2, 1))
- {
- puf2ready = puf2Entity.State == (int)PUFSTATE.WaitForSwap;
- }
- else
- {
- puf2ready = false;
- }
- }
- else
- {
- //任务仅一片Wafer,同时模块为PUF1
- if (Module == ModuleName.PUF1)
- {
- puf2ready = puf2Entity.IsIdle;
- }
- }
- }
- if(!puf2ready)
- {
- return false;
- }
- //Loader中没有WaferHolder
- if(_loaderEntity.WaferHolderInfo==null)
- {
- return false;
- }
- if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload)
- {
- JetAxisBase _loadTransporterGantryAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Transporter2}.Gantry");
- if (_loadTransporterGantryAxis != null && !_loadTransporterGantryAxis.JudgeCompareTargetStation("Loader", "Right"))
- {
- return false;
- }
- }
- return true;
- }
- /// <summary>
- /// LoaderEntity Unload All
- /// </summary>
- private void PostLoaderEntityUnloadAllSide()
- {
- //当前loader状态机为WaitForUnload
- if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload&&_currentOperation==OperationStep.WaitForLoaderUnloadComplete)
- {
- //触发loaderEntity UnloadAll
- _loaderEntity.CheckToPostMessage<LOADERSTATE, LoaderMSG>(eEvent.WARN_LOADER, ModuleName.Loader1.ToString(),
- (int)LoaderMSG.UnloadAll);
- }
- //若Loader Unload操作完成,状态变更为WaitForLoad,puf操作变更为Swap
- else if (_loaderEntity.State == (int)LOADERSTATE.WaitForLoad)
- {
- _currentOperation = OperationStep.Swap;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is Swap");
- }
- else if (_loaderEntity.State == (int)LOADERSTATE.Unloading)
- {
- return;
- }
- //else
- //{
- // LOG.WriteLog(eEvent.ERR_PUF, Module.ToString(), $"Loader1 Current State {(LOADERSTATE)_loaderEntity.State} is not avaible");
- // _state = RState.Failed;
- //}
- }
- /// <summary>
- /// PUF Entity运动至Robot准备让robot pick
- /// </summary>
- private void PostPufEntityGotoRobotForPick()
- {
- if (_pufEntity.Module == ModuleName.PUF2)
- {
- if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
- {
- bool result = _pufEntity.CheckToPostMessage<PUFSTATE, PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
- (int)PUFMSG.ReadyForRobotPick);
- if (result)
- {
- NotifyWaferTaskSchedulerLoaderComplete();
- _currentOperation = OperationStep.GotoRobotForPick;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
- }
- }
- }
- else
- {
- if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
- {
- JetAxisBase loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
- if (loaderRotationAxis != null && loaderRotationAxis.CheckPositionIsInStation(loaderRotationAxis.MotionData.MotorPosition, "TRNPA"))
- {
- if (_loaderEntity.State == (int)LOADERSTATE.Loading || _loaderEntity.IsIdle)
- {
- bool result = _pufEntity.CheckToPostMessage<PUFSTATE, PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
- (int)PUFMSG.ReadyForRobotPick);
- if (result)
- {
- NotifyWaferTaskSchedulerLoaderComplete();
- _currentOperation = OperationStep.GotoRobotForPick;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
- }
- }
- }
- }
- }
- }
- /// <summary>
- /// 通知Wafer对应的SchedulerLoader工序已经完成
- /// </summary>
- private void NotifyWaferTaskSchedulerLoaderComplete()
- {
- //puf A面是否存在Wafer
- if (WaferManager.Instance.CheckHasWafer(_pufEntity.Module, 0))
- {
- WaferInfo waferInfo = WaferManager.Instance.GetWafer(_pufEntity.Module, 0);
- if (waferInfo!=null&&waferInfo.WaferType==WaferType.Production)
- {
- _isProductionWafer = true;
- WaferTask waferTask = WaferTaskManager.Instance.GetWaferTask(waferInfo.WaferID);
- if (waferTask!=null)
- {
- waferTask.UpdateLoaderSchedulerSequenceComplete();
- }
- }
- }
- }
- /// <summary>
- /// 将Dummy片移动至Dummy Cassete
- /// </summary>
- private void PostEfemRobotTransferToDummyCassete()
- {
- if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPick)
- {
- //生产片待EfemRobot取完片进行PufBackToPark状态
- if (_isProductionWafer)
- {
- bool hasWafer = WaferManager.Instance.CheckHasWafer(_pufEntity.Module, 0);
- if (!hasWafer)
- {
- _currentOperation = OperationStep.PufBackToPark;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is PufBackToPark");
- }
- }
- else
- {
- //A面Wafer
- WaferInfo waferInfo = WaferManager.Instance.GetWafer(_pufEntity.Module, 0);
- if (waferInfo == null)
- {
- return;
- }
- //Dummy片
- if (waferInfo.WaferType == WaferType.Assit)
- {
- if (_efemEntity.IsIdle)
- {
- var result = SchedulerSequenceManager.Instance.GetAvaibleDummySlots();
- if (result.moduleName != ModuleName.Unknown)
- {
- MoveItem moveItem = new MoveItem(_pufEntity.Module, 0, result.moduleName, result.slot, Aitex.Sorter.Common.Hand.Blade1);
- if(RobotMoveHelper.Instance.IsIdle)
- {
- RobotMoveHelper.Instance.Start(moveItem,Module.ToString());
- _currentOperation = OperationStep.WaitForRobotPick;
- LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is WaitForRobotPick");
- }
- }
- else
- {
- LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), "dummy slot is empty");
- }
- }
- else
- {
- LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), $"wafer {waferInfo.WaferID} efem is not idle");
- }
- }
- else
- {
- LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), $"wafer {waferInfo.WaferID} is not dummy wafer");
- }
- }
- }
- }
- /// <summary>
- /// 检验前置条件
- /// </summary>
- /// <param name="sequenceIndex"></param>
- /// <param name="parameter"></param>
- /// <returns></returns>
- public override bool CheckPrecondition(List<SchedulerSequence> schedulerSequences, int sequenceIndex, object parameter, string materialId, ref string reason)
- {
- if (_state == RState.Running)
- {
- reason = "scheduler module is already running";
- return false;
- }
- if (_pufEntity==null)
- {
- reason = "Puf entity is null";
- return false;
- }
- bool forward=(bool)parameter;
- if(forward)
- {
- if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPlace)
- {
- return true;
- }
- else
- {
- reason = $"{_pufEntity.Module} forward,but state is not WaitForRobotPlace";
- return false;
- }
- }
- else
- {
- if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPick)
- {
- return true;
- }
- else
- {
- reason = $"{_pufEntity.Module} backward,but state is not WaitForRobotPick";
- return false;
- }
- }
- }
- /// <summary>
- /// 获取可用资源
- /// </summary>
- /// <param name="sequenceIndex"></param>
- /// <param name="parameter"></param>
- /// <returns></returns>
- public override bool GetAvaibleMaterial(int sequenceIndex, object parameter)
- {
- return true;
- }
- }
- }
|