Merge branch 'feature/unload-purge-param-to-sequence' into develop

This commit is contained in:
DESKTOP-GPE37UV\THINKAPD 2022-11-23 13:27:36 +08:00
commit ab054bca13
14 changed files with 141 additions and 65 deletions

View File

@ -751,6 +751,7 @@
CanUserDeleteRows="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
CanUserReorderColumns="False"
GridLinesVisibility="None"
HeadersVisibility="Column"
IsEnabled="{Binding IsPermission}"

View File

@ -192,7 +192,7 @@
<Style x:Key="TextBox_Top" TargetType="{x:Type TextBox}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Margin" Value="0,2,2,2" />
<Setter Property="BorderThickness" Value="0,1,1,1" />
<Setter Property="Background" Value="{DynamicResource TextBox_Top_BG}" />

View File

@ -101,6 +101,18 @@ namespace Mainframe.TMs.Routines
_useSettingValue = true;
}
public void Init(int purgeCount, int pumpDelayTime)
{
_purgeCount = purgeCount;
_pumpDelayTime = pumpDelayTime;
_pumpBasePressure = SC.GetValue<double>("TM.Purge.PumpBasePressure");
_ventBasePressure = SC.GetValue<double>("TM.Purge.VentBasePressure");
_ventDelayTime = SC.GetValue<int>("TM.Purge.PumpDelayTime");
_useSettingValue = true;
}
public override Result Start(params object[] objs)
{

View File

@ -934,6 +934,12 @@ namespace Mainframe.TMs
private bool FsmStartPurge(object[] param)
{
if (param != null && param.Length == 2
&& param[0] is int purgeLoop && param[1] is int purgePumpDelay)
{
_purgeRoutine.Init(purgeLoop, purgePumpDelay);
}
Result ret = StartRoutine(_purgeRoutine);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
@ -1022,6 +1028,14 @@ namespace Mainframe.TMs
return true;
}
public override int Purge(int loopCount, int pumpDelay)
{
if (CheckToPostMessage((int)MSG.Purge, loopCount, pumpDelay))
return (int)MSG.Purge;
return (int)FSM_MSG.NONE;
}
public override bool Goto(ModuleName target, Hand blade, int targetSlot, out string reason)
{
CheckToPostMessage((int)MSG.RobotGoto, target.ToString(), targetSlot, blade);
@ -1082,5 +1096,11 @@ namespace Mainframe.TMs
return (int)FSM_MSG.NONE;
}
public override bool CheckAcked(int fsmTaskToken)
{
return FsmState == (int)STATE.Idle && CheckAllMessageProcessed();
//return true;
}
}
}

View File

@ -32,9 +32,13 @@ namespace Mainframe.TMs
public abstract bool Home(out string reason);
//ITransferRobot
public abstract int Purge(int loopCount, int pumpDelay);
public abstract bool Pick(ModuleName target, Hand blade, int targetSlot, out string reason);
public abstract bool Place(ModuleName target, Hand blade, int targetSlot, out string reason);
public abstract bool PickAndPlace(ModuleName pickTarget, Hand pickHand, int pickSlot, ModuleName placeTarget, Hand placeHand, int placeSlot, out string reason);
public abstract bool Goto(ModuleName target, Hand blade, int targetSlot, out string reason);
public abstract bool CheckAcked(int entityTaskToken);
}
}

View File

@ -208,7 +208,11 @@ namespace Mainframe.UnLoads.Routines
public int GetRemainedTime()
{
if (_swCooling.IsRunning)
return _coolingTimeInSec - (int)(_swCooling.Elapsed.TotalSeconds);
{
var remain = _coolingTimeInSec - (int)(_swCooling.Elapsed.TotalSeconds);
return remain < 0 ? 0 : remain;
}
return 0;
}
}

View File

@ -4,10 +4,10 @@
<Catalog Type="Position">
<Item Name="Position" DisplayName="Position" InputType="ReadOnlySelection" >
<Selection Name="Sic" DisplayName="PM" Parameter="PMSelection,ProcessRecipe" />
<Selection Name="Buffer" DisplayName="Buffer" Parameter="SlotSelection,BufferType,SetValue" />
<Selection Name="Buffer" DisplayName="Buffer" Parameter="SlotSelection,BufferType,SetValue,PurgeCount,PumpDelayTime" />
<Selection Name="Aligner" DisplayName="Aligner" Parameter="" />
<Selection Name="Load" DisplayName="Load" Parameter="PurgeCount,PumpDelayTime" />
<Selection Name="UnLoad" DisplayName="UnLoad" Parameter="PurgeCount,PumpDelayTime,CoolingTime" />
<Selection Name="UnLoad" DisplayName="UnLoad" Parameter="PurgeCount,PumpDelayTime,PurgeCountBeforeWaferPicking,PumpDelayTimeBeforeWaferPicking,PurgeCountAfterWaferPicking,PumpDelayTimeAfterWaferPicking,CoolingTime" />
</Item>
</Catalog>
@ -28,9 +28,13 @@
<Selection Name="CoolingByTime" DisplayName="CoolingByTime"/>
</Item>
<Item Name="SetValue" DisplayName="SetValue" InputType="NumInput" Min="0" Max="10000" />
<Item Name="PurgeCount" DisplayName="PurgeCount" InputType="NumInput" Min="0" Max="1000" />
<Item Name="PumpDelayTime" DisplayName="PumpDelayTime" InputType="NumInput" Min="0" Max="1000" />
<Item Name="CoolingTime" DisplayName="Cooling Time(s)" InputType="NumInput" Min="0" Max="3600" />
<Item Name="PurgeCount" DisplayName="Purge Loop" InputType="NumInput" Min="0" Max="1000" />
<Item Name="PumpDelayTime" DisplayName="Pump Delay" InputType="NumInput" Min="0" Max="1000" />
<Item Name="PurgeCountBeforeWaferPicking" DisplayName="Purge Loop Before ATM" InputType="NumInput" Min="0" Max="1000" />
<Item Name="PumpDelayTimeBeforeWaferPicking" DisplayName="Pump Delay Before ATM" InputType="NumInput" Min="0" Max="1000" />
<Item Name="PurgeCountAfterWaferPicking" DisplayName="Purge Loop After ATM" InputType="NumInput" Min="0" Max="1000" />
<Item Name="PumpDelayTimeAfterWaferPicking" DisplayName="Pump Delay After ATM" InputType="NumInput" Min="0" Max="1000" />
<Item Name="CoolingTime" DisplayName="Cooling Time(s)" InputType="NumInput" Min="0" Max="3600" />
</Catalog>
</TableSequenceFormat>
<TableSequenceData RecipeVersion="Sic" CreatedBy="System" Barcode="" CreationTime="2016-05-13T13:56:44" LastRevisedBy="admin" LastRevisionTime="2015-10-13T13:56:44" Description="Empty">

View File

@ -1531,10 +1531,6 @@
<configs name="Purge">
<config default="3" name="CyclePurgeCount" description="吹扫的循环次数" max="1000" min="0" paramter="" tag="" unit="次" type="Integer" />
<config default="1" name="CyclePurgeCountBeforeWaferPicking" description="取Wafer前吹扫的循环次数设置为0表示不Purge" max="1000" min="0" paramter="" tag="" unit="次" type="Integer" />
<config default="10" name="PurgeDelayBeforeWaferPicking" description="取Wafer前吹扫时抽到底压后的持续抽气时间" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />
<config default="1" name="CyclePurgeCountAfterWaferPicked" description="取Wafer后吹扫的循环次数设置为0表示不Purge" max="1000" min="0" paramter="" tag="" unit="次" type="Integer" />
<config default="10" name="PurgeDelayAfterWaferPicked" description="取Wafer后吹扫时抽到底压后的持续抽气时间" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />
<config default="0" name="PumpBasePressure" description="抽气的底压" max="1000" min="0" paramter="" tag="" unit="mbar" type="Double" />
<config default="10" name="PumpDelayTime" description="抽气到底压后,继续抽气多长时间" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />
<config default="100" name="PumpTimeOut" description="抽气超时时间" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />

View File

@ -1514,6 +1514,14 @@ namespace SicRT.Modules
return;
}
if (_buffer.FirstDetectTrayArrive(0)
|| _buffer.FirstDetectTrayArrive(1)
|| _buffer.FirstDetectTrayArrive(2))
{
_buffer.ResetPurgeStatus();
}
for (int i = 0; i < 3; i++)
{
bool canExcute = _buffer.HasWafer(i) && _buffer.CheckWaferNextStepIsThis(_buffer.Module, i);
@ -1521,22 +1529,36 @@ namespace SicRT.Modules
{
WaferInfo bufferWafer = _buffer.GetWaferInfo(i);
int bufferSetValue = 0;
if (!GetWaferSequenceNextValue(ModuleName.Buffer, i, "BufferType", out string strBufferType))
#region Sequence中的参数
if (!GetWaferSequenceNextValue(ModuleName.Buffer, i, "BufferType", out var heatCoolingMode))
{
continue;
}
if (!GetWaferSequenceNextValue(ModuleName.Buffer, i, "SetValue", out string strBufferSetValue))
if (!GetWaferSequenceNextValue(ModuleName.Buffer, i, "SetValue", out var strSetPoint))
{
continue;
}
if (!Int32.TryParse(strBufferSetValue, out bufferSetValue))
if (!GetWaferSequenceNextValue(ModuleName.Buffer, i, "PurgeCount", out var strPurgeLoopCount))
{
continue;
}
if (!GetWaferSequenceNextValue(ModuleName.Buffer, i, "PumpDelayTime", out var strPurgePumpDelay))
{
continue;
}
if (!int.TryParse(strSetPoint, out var bufferSetValue)
|| !int.TryParse(strPurgeLoopCount, out var purgeLoopCount)
|| !int.TryParse(strPurgePumpDelay, out var purgePumpDelay))
{
continue;
}
#endregion
WaferInfo wafer = _buffer.GetWaferInfo(i);
//分别判断冷却和加热方式温度是否达到
if (strBufferType == "HeatByTemp")
if (heatCoolingMode == "HeatByTemp")
{
if (_bufferWaferInfo.ContainsKey(bufferWafer.InnerId.ToString()))
{
@ -1556,7 +1578,7 @@ namespace SicRT.Modules
_bufferWaferInfo.Add(bufferWafer.InnerId.ToString(), DateTime.Now);
}
}
else if (strBufferType == "HeatByTime")
else if (heatCoolingMode == "HeatByTime")
{
if (_bufferWaferInfo.ContainsKey(bufferWafer.InnerId.ToString()))
{
@ -1587,7 +1609,7 @@ namespace SicRT.Modules
_bufferWaferInfo.Add(bufferWafer.InnerId.ToString(), DateTime.Now);
}
}
else if (strBufferType == "CoolingByTime")
else if (heatCoolingMode == "CoolingByTime")
{
if (_bufferWaferInfo.ContainsKey(bufferWafer.InnerId.ToString()))
{
@ -1619,6 +1641,13 @@ namespace SicRT.Modules
}
}
// 如果TMRobot空闲并且Buffer收到新盘则根据Sequence配置进行Purge。
if (_tmRobot.IsAvailable && !_buffer.HasPurged)
{
_tmRobot.Purge(purgeLoopCount, purgePumpDelay);
_buffer.HasPurged = true;
}
return;
}
}
@ -1757,7 +1786,8 @@ namespace SicRT.Modules
GetWaferSequenceCoolingTime(_unload.Module, 0, out var coolingTime);
_unload.CoolingAndPurge(
true,
coolingTime, _unload.GetWaferPurgeCount(0),
coolingTime,
_unload.GetWaferPurgeCount(0),
_unload.GetWaferPumpDelayTime(0));
return;
}
@ -1778,7 +1808,8 @@ namespace SicRT.Modules
if (!_unload.CheckPurgedBeforeTrayPicking()
&& !_load.IsInPumping)
{
_unload.PurgeBeforeTrayPicking(_unload.GetWaferPurgeCount(0),
_unload.PurgeBeforeTrayPicking(
_unload.GetWaferPurgeCount(0),
_unload.GetWaferPumpDelayTime(0));
return;
}
@ -1805,8 +1836,8 @@ namespace SicRT.Modules
_unload.CheckWaferNextStepIsThis(ModuleName.UnLoad, 0)
&& !_load.IsInPumping)
{
var cycle = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.CyclePurgeCountBeforeWaferPicking");
var pumpDelay = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.PurgeDelayBeforeWaferPicking");
var cycle = _unload.GetWaferPurgeCount(0, "PurgeCountBeforeWaferPicking");
var pumpDelay = _unload.GetWaferPumpDelayTime(0, "PumpDelayTimeBeforeWaferPicking");
_unload.PurgeBeforeWaferPicking(cycle, pumpDelay);
_unload.GetWaferInfo(0).NextSequenceStep++;
return;
@ -1836,8 +1867,9 @@ namespace SicRT.Modules
// 如果Wafer取完后还没有Purge先Purge
if (!_unload.CheckPurgedAfterWaferPicked() && !_load.IsInPumping)
{
var cycle = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.CyclePurgeCountAfterWaferPicked");
var pumpDelay = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.PurgeDelayAfterWaferPicked");
var cycle = _unload.GetWaferPurgeCount(0, "PurgeCountAfterWaferPicking");
var pumpDelay= _unload.GetWaferPumpDelayTime(0, "PumpDelayTimeAfterWaferPicking");
_unload.PurgeAfterWaferPicked(cycle, pumpDelay);
}

View File

@ -728,8 +728,8 @@ namespace SicRT.Modules
if (!_unload.CheckPurgedBeforeWaferPicking()
&& !_load.IsInPumping)
{
var cycle = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.CyclePurgeCountBefWaferPicking");
var pumpDelay = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.PurgePumpDelayBefWaferPicking");
var cycle = _unload.GetWaferPurgeCount(0, "PurgeCountBeforeWaferPicking");
var pumpDelay = _unload.GetWaferPumpDelayTime(0, "PumpDelayTimeBeforeWaferPicking");
_unload.PurgeBeforeWaferPicking(cycle, pumpDelay);
return;
}

View File

@ -1,9 +1,6 @@
using Aitex.Core.RT.Fsm;
using Aitex.Core.Util;
using SicRT.Scheduler;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using SicRT.Equipments;
using SicRT.Equipments.Systems;
using Mainframe.Buffers;
using Aitex.Core.RT.Device;
@ -29,6 +26,8 @@ namespace SicRT.Modules.Schedulers
}
public bool HasPurged { get; set; }
private BufferModuleBase _buffer = null;
private int _entityTaskToken = (int)FSM_MSG.NONE;
@ -44,6 +43,11 @@ namespace SicRT.Modules.Schedulers
return true;
}
public void ResetPurgeStatus()
{
HasPurged = false;
}
internal float GetTemperature()
{
IoTempMeter deviceBufferTemp = DEVICE.GetDevice<IoTempMeter>($"Buffer.BufferTemp");

View File

@ -34,33 +34,8 @@ namespace SicRT.Modules.Schedulers
protected SchedulerModule GetModule(string name)
{
switch (ModuleHelper.Converter(name))
{
case ModuleName.Buffer:
return _buffer;
case ModuleName.TMRobot:
return _tmRobot;
case ModuleName.WaferRobot:
return _waferRobot;
case ModuleName.TrayRobot:
return _trayRobot;
case ModuleName.PM1:
return _pm1;
case ModuleName.CassAL:
return _cassetteAL;
case ModuleName.CassAR:
return _cassetteAR;
case ModuleName.CassBL:
return _cassetteBL;
case ModuleName.LoadLock:
return _load;
case ModuleName.UnLoad:
return _unload;
case ModuleName.Aligner:
return _aligner;
}
return null;
var module = ModuleHelper.Converter(name);
return GetModule(module);
}
protected SchedulerModule GetModule(ModuleName name)

View File

@ -11,12 +11,15 @@ using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using SicRT.Equipments.Systems;
using Mainframe.TMs;
using Aitex.Core.RT.Fsm;
namespace SicRT.Scheduler
{
public class SchedulerTMRobot : SchedulerModule
{
public override bool IsAvailable
private int _fsmTask = (int)FSM_MSG.NONE;
public override bool IsAvailable
{
get { return _tmRobot.IsIdle && _tmRobot.IsOnline && CheckTaskDone(); }
}
@ -56,10 +59,28 @@ namespace SicRT.Scheduler
return WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, (int)blade);
}
public bool Purge(int loopCount, int pumpDelayInSec)
{
if (loopCount <= 0)
{
LogTaskStart(_task, $"[{Module}] Purge ignored");
return true;
}
_fsmTask = _tmRobot.Purge(loopCount, pumpDelayInSec);
if (_fsmTask != (int)FSM_MSG.NONE)
{
_task = TaskType.Purge;
LogTaskStart(_task, $"[{Module}] Start to Purge");
}
return _fsmTask != (int)FSM_MSG.NONE;
}
public bool Pick(ModuleName target, int slot, Hand hand)
{
if (_tmRobot.Pick(target, hand, slot, out string reason))
if (_tmRobot.Pick(target, hand, slot, out var reason))
{
_task = TaskType.Pick;
_taskHand = hand;
@ -71,7 +92,7 @@ namespace SicRT.Scheduler
public bool Place(ModuleName target, int slot, Hand hand)
{
if (_tmRobot.Place(target, hand, slot, out string reason))
if (_tmRobot.Place(target, hand, slot, out var reason))
{
_task = TaskType.Place;
_taskHand = hand;
@ -99,6 +120,9 @@ namespace SicRT.Scheduler
case TaskType.None:
ret = true;
break;
case TaskType.Purge:
ret = _tmRobot.CheckAcked(_fsmTask);
break;
case TaskType.Pick:
ret = WaferManager.Instance.CheckHasTray(ModuleName.TMRobot, (int)_taskHand);
break;

View File

@ -401,7 +401,7 @@ namespace SicRT.Scheduler
}
}
public int GetWaferPurgeCount(int slot)
public int GetWaferPurgeCount(int slot, string whichPurge = "PurgeCount")
{
lock (SyncRoot)
{
@ -419,11 +419,11 @@ namespace SicRT.Scheduler
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module))
return 0;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey("PurgeCount"))
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey(whichPurge))
return 0;
if (int.TryParse(
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["PurgeCount"].ToString(),
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter[whichPurge].ToString(),
out int purgeCount))
{
return purgeCount;
@ -433,7 +433,7 @@ namespace SicRT.Scheduler
}
}
public int GetWaferPumpDelayTime(int slot)
public int GetWaferPumpDelayTime(int slot, string whichPumpDelay = "PumpDelayTime")
{
lock (SyncRoot)
{
@ -451,11 +451,11 @@ namespace SicRT.Scheduler
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module))
return 0;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey("PumpDelayTime"))
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey(whichPumpDelay))
return 0;
if (int.TryParse(
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["PumpDelayTime"]
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter[whichPumpDelay]
.ToString(), out int pumpDelayTime))
{
return pumpDelayTime;