|
@@ -3,8 +3,10 @@ using Aitex.Core.RT.Device;
|
|
|
using Aitex.Core.RT.Fsm;
|
|
|
using Aitex.Core.RT.Log;
|
|
|
using Aitex.Core.RT.OperationCenter;
|
|
|
+using Aitex.Core.RT.RecipeCenter;
|
|
|
using Aitex.Core.Util;
|
|
|
using Aitex.Core.Utilities;
|
|
|
+using CyberX12_RT.Modules.VpwCell;
|
|
|
using MECF.Framework.Common.Alarm;
|
|
|
using MECF.Framework.Common.CommonData;
|
|
|
using MECF.Framework.Common.Equipment;
|
|
@@ -16,6 +18,7 @@ using MECF.Framework.Common.Routine;
|
|
|
using MECF.Framework.Common.SubstrateTrackings;
|
|
|
using MECF.Framework.Common.ToolLayout;
|
|
|
using PunkHPX8_Core;
|
|
|
+using PunkHPX8_RT.Devices.LinMot;
|
|
|
using PunkHPX8_RT.Devices.VpwCell;
|
|
|
using PunkHPX8_RT.Modules.VpwCell;
|
|
|
using System;
|
|
@@ -72,9 +75,45 @@ namespace PunkHPX8_RT.Modules.VpwMain
|
|
|
/// </summary>
|
|
|
private VpwManualRecipeRoutine _manualRecipeRoutine;
|
|
|
/// <summary>
|
|
|
+ /// 循环routine
|
|
|
+ /// </summary>
|
|
|
+ private VpwCycleManualProcessRecipeRoutine _cycleManualProcessRoutine;
|
|
|
+ /// <summary>
|
|
|
/// recipe完成次数
|
|
|
/// </summary>
|
|
|
private int _achievedCycle;
|
|
|
+ /// <summary>
|
|
|
+ /// Cycle次数
|
|
|
+ /// </summary>
|
|
|
+ private int _cycle = 0;
|
|
|
+ /// <summary>
|
|
|
+ /// 是否Retry
|
|
|
+ /// </summary>
|
|
|
+ private bool _isRetry = false;
|
|
|
+ /// <summary>
|
|
|
+ /// recipe时长
|
|
|
+ /// </summary>
|
|
|
+ private int _recipeTime;
|
|
|
+ /// <summary>
|
|
|
+ /// 当前Recipe
|
|
|
+ /// </summary>
|
|
|
+ private VpwRecipe _currentRecipe;
|
|
|
+ /// <summary>
|
|
|
+ /// run recipe start time
|
|
|
+ /// </summary>
|
|
|
+ private DateTime _runRecipeStartTime;
|
|
|
+ /// <summary>
|
|
|
+ /// run recipe complete time
|
|
|
+ /// </summary>
|
|
|
+ private DateTime _runRecipeCompleteTime;
|
|
|
+ /// <summary>
|
|
|
+ /// 工艺当前执行小步骤
|
|
|
+ /// </summary>
|
|
|
+ private string _currentStateMachine = "Init";
|
|
|
+ /// <summary>
|
|
|
+ /// 工艺当前执行大步骤
|
|
|
+ /// </summary>
|
|
|
+ private string _currentStatus = "Init";
|
|
|
#endregion
|
|
|
|
|
|
#region 属性
|
|
@@ -132,6 +171,10 @@ namespace PunkHPX8_RT.Modules.VpwMain
|
|
|
/// 是否为产品模式
|
|
|
/// </summary>
|
|
|
public bool IsProduction { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == PRODUCTION; } }
|
|
|
+ /// <summary>
|
|
|
+ /// recipe时长
|
|
|
+ /// </summary>
|
|
|
+ public int RecipeTime { get { return _recipeTime; } }
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
@@ -199,6 +242,9 @@ namespace PunkHPX8_RT.Modules.VpwMain
|
|
|
//Manual Recipe
|
|
|
Transition(VPWCellState.Idle, VpwCellMsg.ManualRecipe, ManualRunRecipe, VPWCellState.ManualReciping);
|
|
|
Transition(VPWCellState.ManualReciping, FSM_MSG.TIMER, ManualRunRecipeMonitor, VPWCellState.Idle);
|
|
|
+ //Cycle Manual Process
|
|
|
+ Transition(VPWCellState.Idle, VpwCellMsg.CycleProcessRecipe, CycleManualProcess, VPWCellState.CycleManualProcessing);
|
|
|
+ Transition(VPWCellState.CycleManualProcessing, FSM_MSG.TIMER, CycleManualMonitor, VPWCellState.Idle);
|
|
|
//Prepare
|
|
|
Transition(VPWCellState.Idle, VpwCellMsg.Prepare, Prepare, VPWCellState.Preparing);
|
|
|
Transition(VPWCellState.Preparing, FSM_MSG.TIMER, PrepareMonitor, VPWCellState.WaitForRunRecipe);
|
|
@@ -243,6 +289,7 @@ namespace PunkHPX8_RT.Modules.VpwMain
|
|
|
_prepareRoutine=new VpwPrepareRoutine(Module.ToString());
|
|
|
_recipeRoutine=new VpwRecipeRoutine(Module.ToString());
|
|
|
_manualRecipeRoutine=new VpwManualRecipeRoutine(Module.ToString());
|
|
|
+ _cycleManualProcessRoutine = new VpwCycleManualProcessRecipeRoutine(Module.ToString());
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 初始化操作
|
|
@@ -251,6 +298,22 @@ namespace PunkHPX8_RT.Modules.VpwMain
|
|
|
{
|
|
|
OP.Subscribe($"{Module}.InitializeAll", (cmd, args) => { return CheckToPostMessage<VPWCellState, VpwCellMsg>(eEvent.ERR_VPW, Module.ToString(), (int)VpwCellMsg.Initialize); });
|
|
|
OP.Subscribe($"{Module}.Prepare", (cmd, args) => { return CheckToPostMessage<VPWCellState, VpwCellMsg>(eEvent.ERR_VPW, Module.ToString(), (int)VpwCellMsg.Prepare); });
|
|
|
+ OP.Subscribe($"{Module}.CycleManualProcessRecipe", (cmd, args) =>
|
|
|
+ {
|
|
|
+ VpwRecipe recipe = RecipeFileManager.Instance.LoadGenericityRecipe<VpwRecipe>(args[0].ToString());
|
|
|
+ if (recipe == null)
|
|
|
+ {
|
|
|
+ LOG.WriteLog(eEvent.ERR_VPW, Module.ToString(), $"{args[0]} recipe is null");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ object[] objects = new object[args.Length];
|
|
|
+ objects[0] = recipe;
|
|
|
+ for (int i = 1; i < args.Length; i++)
|
|
|
+ {
|
|
|
+ objects[i] = args[i];
|
|
|
+ }
|
|
|
+ return CheckToPostMessage<VPWCellState, VpwCellMsg>(eEvent.ERR_PREWET, Module.ToString(), (int)VpwCellMsg.CycleProcessRecipe, objects);
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
#region InitializeAll
|
|
@@ -412,6 +475,67 @@ namespace PunkHPX8_RT.Modules.VpwMain
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
+ #region cycle manual process
|
|
|
+ private bool CycleManualProcess(object[] param)
|
|
|
+ {
|
|
|
+ VpwRecipe recipe = param[0] as VpwRecipe;
|
|
|
+ _cycle = (int)param[1];
|
|
|
+
|
|
|
+ bool result = _cycleManualProcessRoutine.Start(param) == RState.Running;
|
|
|
+ if (result)
|
|
|
+ {
|
|
|
+ _isRetry = false;
|
|
|
+ if (CellItemRecipeTimeManager.Instance.ContainRecipe(recipe.Ppid))
|
|
|
+ {
|
|
|
+ _recipeTime = _cycle * CellItemRecipeTimeManager.Instance.GetRecipeTotalTime(recipe.Ppid);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _recipeTime = 0;
|
|
|
+ }
|
|
|
+ _currentRecipe = recipe;
|
|
|
+ _runRecipeStartTime = DateTime.Now;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool CycleManualMonitor(object[] param)
|
|
|
+ {
|
|
|
+ RState state = _cycleManualProcessRoutine.Monitor();
|
|
|
+ _currentStatus = _cycleManualProcessRoutine.CurrentStatus;
|
|
|
+ _currentStateMachine = _cycleManualProcessRoutine.CurrentStateMachine;
|
|
|
+ if (state == RState.Failed || state == RState.Timeout)
|
|
|
+ {
|
|
|
+ PostMsg(VpwCellMsg.Error);
|
|
|
+ _currentStateMachine = "Error";
|
|
|
+ _currentStatus = "Error";
|
|
|
+
|
|
|
+ _runRecipeCompleteTime = DateTime.Now;
|
|
|
+ _cycleManualProcessRoutine.VpwLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2");
|
|
|
+ //导出lotTrack数据
|
|
|
+ VpwLotTrackUtil.ExportVpwLotTrack(Module.ToString(), _cycleManualProcessRoutine.VpwLotTrackDatas,
|
|
|
+ _cycleManualProcessRoutine.VpwLotTrackHeaderDatas, IsAuto, _isRetry);
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ _achievedCycle = _cycleManualProcessRoutine.GetAchievedCycle();
|
|
|
+ bool result = state == RState.End;
|
|
|
+ if (result)
|
|
|
+ {
|
|
|
+ double elapsedMilliseconds = _cycleManualProcessRoutine.ElapsedMilliseconds;
|
|
|
+ int recipeTime = (int)Math.Floor(elapsedMilliseconds / _cycle / 1000);
|
|
|
+ CellItemRecipeTimeManager.Instance.UpdateRecipeTime(_currentRecipe.Ppid, recipeTime);
|
|
|
+ _runRecipeCompleteTime = DateTime.Now;
|
|
|
+ _cycleManualProcessRoutine.VpwLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2");
|
|
|
+ //导出lotTrack数据
|
|
|
+ VpwLotTrackUtil.ExportVpwLotTrack(Module.ToString(), _cycleManualProcessRoutine.VpwLotTrackDatas,
|
|
|
+ _cycleManualProcessRoutine.VpwLotTrackHeaderDatas, IsAuto, _isRetry);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
#region VpwCell Retry
|
|
|
/// <summary>
|
|
|
/// VpwCell
|