2026-03-24 15:04:02 +08:00
using Aitex.Core.Common ;
using Aitex.Core.RT.DataCenter ;
using Aitex.Core.RT.Event ;
using Aitex.Core.RT.Key ;
using Aitex.Core.RT.Log ;
using Aitex.Core.RT.OperationCenter ;
using Aitex.Core.RT.Routine ;
using Aitex.Core.RT.SCCore ;
using Aitex.Core.Util ;
using Aitex.Sorter.Common ;
using Kxware.Common ;
using MECF.Framework.Common.DBCore ;
using MECF.Framework.Common.Equipment ;
using MECF.Framework.Common.Gem ;
using MECF.Framework.Common.Jobs ;
using MECF.Framework.Common.Schedulers ;
using MECF.Framework.Common.SubstrateTrackings ;
using OpenSEMI.Ctrlib.Controls ;
using SicRT.Equipments.Schedulers ;
using SicRT.Modules.Schedulers ;
using SicRT.Scheduler ;
using System ;
using System.Collections.Generic ;
using System.Linq ;
namespace SicRT.Modules
{
public partial class AutoTransfer : SchedulerModuleFactory
{
private List < ControlJobInfo > _controlJobList = new ( ) ;
private List < ProcessJobInfo > _processJobList = new ( ) ;
private int _maxTrayCount = 4 ; //可以同时运行的石墨盘总数
private const string LogSource = "Scheduler" ;
private SchedulerDBCallback _dbCallback = new ( ) ;
private bool _isCycleMode ;
private bool _isATMMode ;
private int _cycleSetPoint = 0 ;
private int _cycledCount = 0 ;
private int _cycledWafer = 0 ;
private string _curRecipeName = "" ;
private string _curSequenceName = "" ;
private bool _isModuleErrorPrevious ;
private bool [ ] _isPMErrorPrevious = new bool [ 2 ] ;
private double _timeBuffer1 { get ; set ; }
private double _timeBuffer2 { get ; set ; }
private double _timeBuffer3 { get ; set ; }
private double _timeLoad { get ; set ; }
2026-04-22 09:39:19 +08:00
private const int _bufferFloors = 1 ;
2026-03-24 15:04:02 +08:00
private Dictionary < string , DateTime > _loadWaferInfo = new ( ) ;
private Dictionary < string , DateTime > _bufferWaferInfo = new ( ) ;
private Queue < Action > tmRobotActions = new ( ) { } ;
private R_TRIG _updateAutoJobLocation = new ( ) ; //需要向数据库更新Wafer位置
public AutoTransfer ( )
{
DATA . Subscribe ( "Scheduler.IsCycleMode" , ( ) = > _isCycleMode ) ;
DATA . Subscribe ( "Scheduler.CycledCount" , ( ) = > _cycledCount ) ;
DATA . Subscribe ( "Scheduler.CycleSetPoint" , ( ) = > _cycleSetPoint ) ;
DATA . Subscribe ( "Scheduler.RecipeName" , ( ) = > _curRecipeName ) ;
DATA . Subscribe ( "Scheduler.SequenceName" , ( ) = > _curSequenceName ) ;
DATA . Subscribe ( "Scheduler.TimeBuffer1" , ( ) = > _timeBuffer1 ) ;
DATA . Subscribe ( "Scheduler.TimeBuffer2" , ( ) = > _timeBuffer2 ) ;
DATA . Subscribe ( "Scheduler.TimeBuffer3" , ( ) = > _timeBuffer3 ) ;
DATA . Subscribe ( "Scheduler.TimeLoad" , ( ) = > _timeLoad ) ;
DATA . Subscribe ( "LoadLock.LocalJobName" , ( ) = >
{
var jb = _controlJobList . Find ( x = > x . Module = = "LoadLock" ) ;
if ( jb ! = null )
return jb . Name ;
return "" ;
} ) ;
DATA . Subscribe ( "LoadLock.LocalJobStatus" , ( ) = >
{
var jb = _controlJobList . Find ( x = > x . Module = = "LoadLock" ) ;
if ( jb ! = null )
return jb . State . ToString ( ) ;
return "" ;
} ) ;
OP . Subscribe ( $"{ModuleName.TM}.ResetTask" , ( string cmd , object [ ] args ) = >
{
_tmRobot . ResetTask ( ) ;
return true ;
} ) ;
OP . Subscribe ( $"{ModuleName.EFEM}.ResetTask" , ( string cmd , object [ ] args ) = >
{
_waferRobot . ResetTask ( ) ;
_trayRobot . ResetTask ( ) ;
return true ;
} ) ;
OP . Subscribe ( $"{ModuleName.WaferRobot}.ResetTask" , ( string cmd , object [ ] args ) = >
{
_waferRobot . ResetTask ( ) ;
return true ;
} ) ;
OP . Subscribe ( $"{ModuleName.TrayRobot}.ResetTask" , ( string cmd , object [ ] args ) = >
{
_tmRobot . ResetTask ( ) ;
return true ;
} ) ;
tmRobotActions . Enqueue ( MonitorTmRobotLoadPlaceTask ) ;
tmRobotActions . Enqueue ( MonitorTmRobotLoadPickTask ) ;
tmRobotActions . Enqueue ( MonitorTmRobotPMPlaceTask ) ;
tmRobotActions . Enqueue ( MonitorTmRobotPMPickTask ) ;
tmRobotActions . Enqueue ( MonitorTmRobotBufferPlaceTask ) ;
tmRobotActions . Enqueue ( MonitorTmRobotBufferPickTask ) ;
}
public bool HasJobRunning
{
get { return _controlJobList . Count > 0 ; }
}
public void Clear ( )
{
_tmRobot . ResetTask ( ) ;
foreach ( var pm in _lstPms )
{
pm . ResetTask ( ) ;
}
_load . ResetTask ( ) ;
_buffer . ResetTask ( ) ;
_controlJobList . Clear ( ) ;
_processJobList . Clear ( ) ;
_loadWaferInfo . Clear ( ) ;
}
public void ResetTask ( )
{
if ( ! _load . IsOnline )
{
_load . ResetTask ( ) ;
}
if ( ! _buffer . IsOnline )
{
_buffer . ResetTask ( ) ;
}
if ( ! _tmRobot . IsOnline )
{
_tmRobot . ResetTask ( ) ;
}
foreach ( var pm in _lstPms )
{
if ( ! pm . IsOnline )
{
pm . ResetTask ( ) ;
}
}
}
#region Job Management
public bool CreateJob ( Dictionary < string , object > param )
{
var reason = "" ;
var slotSequence = ( string [ ] ) param [ "SlotSequence" ] ;
var jobId = ( string ) param [ "JobId" ] ;
var module = ( string ) param [ "Module" ] ;
var lotId = ( string ) param [ "LotId" ] ;
////检查Load腔Lock是否锁定
//if(!_load.CheckLocked())
//{
// EV.PostWarningLog(LogSource, $"The Load is Unlocked,do not start");
// return false;
//}
//检查所有Module里Tray的数量
if ( GetCurrentTrayCount ( ) > = _maxTrayCount )
{
EV . PostWarningLog ( LogSource , $"The machine has more than {_maxTrayCount} Tray" ) ;
return false ;
}
if ( slotSequence . Length ! = 1 )
{
reason = $"slot sequence parameter not valid, length is {slotSequence.Length}, should be 1" ;
EV . PostWarningLog ( LogSource , reason ) ;
return false ;
}
//拿到Recipe和ModuleName
var recipeName = "" ;
var pmModule = ModuleName . System ;
var seq = SequenceInfoHelper . GetInfo ( slotSequence [ 0 ] ) ;
for ( var i = 0 ; i < seq . Steps . Count ; i + + )
{
var stepInfo = seq . Steps [ i ] ;
foreach ( var m in stepInfo . StepModules )
{
if ( ModuleHelper . IsPm ( m ) )
{
recipeName = seq . Steps [ i ] . RecipeName ;
pmModule = m ;
}
}
}
//每个PM腔不能超过2个对应Wafer
if ( pmModule ! = ModuleName . System )
{
if ( GetRunWaferCount ( pmModule ) > = _maxTrayCount / 2 )
{
EV . PostWarningLog ( LogSource , $"Creating the job failed . There are already {_maxTrayCount / 2} job of the same pm in the system." ) ;
return false ;
}
}
if ( CheckModuleHaveWaferWithNoJob ( out reason ) )
{
EV . PostWarningLog ( LogSource , $"{reason}" ) ;
return false ;
}
if ( ! ValidateSequence ( slotSequence , out reason ) )
{
EV . PostWarningLog ( LogSource , $"{reason}" ) ;
return false ;
}
if ( string . IsNullOrEmpty ( jobId ) )
{
jobId = "CJ_Local_Load_" + DateTime . Now . ToString ( "yyyy-MM-dd HH:mm:ss" ) ;
}
if ( ! string . IsNullOrEmpty ( lotId ) )
{
if ( _controlJobList . Exists ( x = > x . LotName = = lotId ) )
{
reason = $"LotID : {lotId} already created" ;
EV . PostWarningLog ( LogSource , reason ) ;
return false ;
}
}
var cj = new ControlJobInfo ( ) ;
cj . Name = jobId ;
cj . Module = module ;
cj . LotName = lotId ;
cj . LotInnerId = Guid . NewGuid ( ) ;
cj . LotWafers = new List < WaferInfoRt > ( ) ;
cj . SetState ( EnumControlJobState . WaitingForStart ) ;
List < string > sequenceNameList = new List < string > ( ) ;
string WaferAssociationInfo = $"WaferAssociationInfo({module}):" ;
for ( int i = 0 ; i < 1 ; i + + )
{
//检查是否设置Sequence
string sequenceName = slotSequence [ i ] ;
if ( string . IsNullOrEmpty ( sequenceName ) )
{
reason = $"sequence name is empty" ;
EV . PostWarningLog ( LogSource , reason ) ;
return false ;
}
//检查是否有Normal Wafer
if ( ! WaferManager . Instance . CheckWafer ( ModuleHelper . Converter ( module ) , i , WaferStatus . Normal ) )
{
reason = $"{module} has no normal wafer" ;
EV . PostWarningLog ( LogSource , reason ) ;
return false ;
}
WaferInfoRt wafer = WaferManager . Instance . GetWafer ( ModuleHelper . Converter ( module ) , i ) ;
if ( wafer . ProcessState ! = WaferProcessStatus . Idle )
{
reason = $"specifies wafer: {module} slot {i + 1} process state is not idle" ;
EV . PostWarningLog ( LogSource , reason ) ;
return false ;
}
if ( wafer . ProcessJob ! = null )
{
reason = $"{module} wafer has processJob" ;
EV . PostWarningLog ( LogSource , reason ) ;
return false ;
}
WaferAssociationInfo = WaferAssociationInfo + string . Format ( " slot{0} -- {1};" , i + 1 , slotSequence [ i ] ) ;
wafer . NextSequenceStep = 0 ;
wafer . PPID = sequenceName ;
wafer . LotId = lotId ;
cj . LotWafers . Add ( wafer ) ;
_isATMMode = SC . GetValue < bool > ( "System.IsATMMode" ) ;
_isCycleMode = SC . GetValue < bool > ( "System.IsCycleMode" ) ;
//没有包含sequenceName,需新建
if ( ! sequenceNameList . Exists ( s = > s = = sequenceName ) )
{
sequenceNameList . Add ( sequenceName ) ;
ProcessJobInfo pj = new ProcessJobInfo ( ) ;
pj . Name = jobId + "_" + ( i + 1 ) ;
pj . ControlJobName = cj . Name ;
pj . Sequence = SequenceInfoHelper . GetInfo ( sequenceName ) ;
pj . SetState ( EnumProcessJobState . Queued ) ;
pj . SlotWafers = [ Tuple . Create ( ModuleHelper . Converter ( module ) , i ) ] ;
//不是CycleMode模式, 则CycleCount设为1
pj . CycleCount = _isATMMode & & _isCycleMode ? SC . GetValue < int > ( "System.CycleCount" ) : 1 ;
pj . CycleTime = 0 ;
//检查Sequence对应的PM腔状态
if ( ! CheckPMState ( sequenceName ) )
{
return false ;
}
wafer . ProcessJob = pj ;
_processJobList . Add ( pj ) ;
cj . ProcessJobNameList . Add ( pj . Name ) ;
}
//已包含sequenceName
else
{
ProcessJobInfo pj = _processJobList . Find ( p = > p . Sequence . Name = = sequenceName ) ;
wafer . ProcessJob = pj ;
pj . SlotWafers . Add ( Tuple . Create ( ModuleHelper . Converter ( module ) , i ) ) ;
}
}
_controlJobList . Add ( cj ) ;
int totalWafer = 0 ;
foreach ( string pjName in cj . ProcessJobNameList )
{
ProcessJobInfo tempPJ = _processJobList . First ( p = > p . Name = = pjName ) ;
foreach ( var pjSlotWafer in tempPJ . SlotWafers )
{
var wafer = WaferManager . Instance . GetWafer ( pjSlotWafer . Item1 , pjSlotWafer . Item2 ) ;
WaferDataRecorder . SetCjInfo ( wafer . WaferInnerID . ToString ( ) , cj . InnerId . ToString ( ) ) ;
WaferDataRecorder . SetWaferSequence ( wafer . WaferInnerID . ToString ( ) , tempPJ . Sequence . Name ) ;
WaferDataRecorder . SetWaferLotId ( wafer . WaferInnerID . ToString ( ) , jobId ) ;
WaferManager . Instance . UpdateWaferLotId ( pjSlotWafer . Item1 , pjSlotWafer . Item2 , jobId ) ;
totalWafer + + ;
}
}
CarrierManager . Instance . DeleteCarrier ( cj . Module ) ;
CarrierManager . Instance . CreateCarrier ( cj . Module ) ;
CarrierManager . Instance . UpdateCarrierId ( cj . Module , $"{cj.Module} {DateTime.Now}" ) ;
//此carrier为null
CarrierInfo carrier = CarrierManager . Instance . GetCarrier ( cj . Module ) ;
JobDataRecorder . StartCJ ( cj . InnerId . ToString ( ) , "" , cj . Name , cj . Module , cj . Module , totalWafer ) ;
EV . PostInfoLog ( LogSource , WaferAssociationInfo ) ;
//保存信息
var waferInfo = WaferManager . Instance . GetWafer ( ModuleName . LoadLock , 0 ) ;
if ( waferInfo ! = null )
{
waferInfo . LotId = cj . LotName ;
if ( recipeName . IndexOf ( @"\" ) > 0 )
{
recipeName = recipeName . Substring ( recipeName . LastIndexOf ( @"\" ) + 1 ) ;
}
AutoJobRecorder . Add ( waferInfo . WaferID . ToString ( ) , recipeName , cj . LotName , ModuleName . LoadLock . ToString ( ) , GetWaferStatue ( waferInfo ) , cj . Name ) ;
}
return true ;
}
public void StartJob ( string jobName )
{
_maxTrayCount = _lstPms . Count * 2 ;
var cj = _controlJobList . Find ( x = > x . Name = = jobName ) ;
if ( cj = = null )
{
EV . PostWarningLog ( LogSource , $"start job rejected, not found job with id {jobName}" ) ;
return ;
}
if ( cj . State = = EnumControlJobState . WaitingForStart )
{
cj . BeginTime = DateTime . Now ;
cj . LotInnerId = Guid . NewGuid ( ) ;
//_dbCallback.LotCreated(cj);
foreach ( var pjName in cj . ProcessJobNameList )
{
var pj = _processJobList . Find ( x = > x . Name = = pjName ) ;
if ( pj = = null )
{
LOG . Error ( $"Not find pj named {pjName} in {cj.Name}" ) ;
continue ;
}
if ( pj . State = = EnumProcessJobState . Queued )
{
ActiveProcessJob ( pj ) ;
}
}
cj . SetState ( EnumControlJobState . Executing ) ;
string squenceID = cj . LotWafers ! = null ? cj . LotWafers [ 0 ] . PPID : string . Empty ;
//补全路径
squenceID = $"Sequence\\{squenceID}.seq" ;
GemManager . Instance . Equipment ? . TriggerEvent ( "JobStart" , new string [ ] { "LotID" , "SequenceID" } , new object [ ] { cj . LotName , squenceID } ) ;
}
}
private string GetWaferStatue ( WaferInfoRt wafer )
{
if ( wafer . ProcessState = = WaferProcessStatus . InProcess )
{
return "InProcess" ;
}
else if ( wafer . ProcessState = = WaferProcessStatus . Completed )
{
return "Completed" ;
}
else if ( wafer . ProcessState = = WaferProcessStatus . Abort )
{
return "Aborted" ;
}
else
{
return "Idle" ;
}
}
private bool ValidateSequence ( string [ ] seqs , out string reason )
{
reason = string . Empty ;
//bool isAllSequenceNull = true;
//for (int i = 0; i < seqs.Length; i++)
//{
// if (string.IsNullOrEmpty(seqs[i]))
// continue;
// var sequence = SequenceInfoHelper.GetInfo(seqs[i]);
// if ((sequence == null || sequence.Steps == null || sequence.Steps.Count == 0) && !string.IsNullOrEmpty(sequence.Name))
// {
// reason = $"Invalid sequence {seqs[i]}";
// return false;
// }
// isAllSequenceNull = false;
// if (sequence.Steps != null)
// {
// int currentIndex = 0;
// if (sequence.Steps[currentIndex] == null || sequence.Steps[currentIndex].StepModules.Count <= 0 || sequence.Steps[currentIndex].StepModules[0] != ModuleName.Aligner)
// {
// reason = $"Invalid sequence {seqs[i]}, {currentIndex + 1}st step should be Aligner";
// return false;
// }
// else
// {
// if (sequence.Steps[currentIndex].AlignAngle < 0 || sequence.Steps[currentIndex].AlignAngle > 360)
// {
// reason = $"Invalid sequence {seqs[i]},{currentIndex + 1}st step Aligner angle parameter is not valid";
// return false;
// }
// }
// currentIndex++;
// if (sequence.Steps[currentIndex] == null || sequence.Steps[currentIndex].StepModules.Count <= 0 || sequence.Steps[currentIndex].StepModules[0] != ModuleName.Load)
// {
// reason = $"Invalid sequence {seqs[i]}, {currentIndex + 1}st step should be Load";
// return false;
// }
// currentIndex++;
// if (sequence.Steps[currentIndex] == null || sequence.Steps[currentIndex].StepModules.Count <= 0 || sequence.Steps[currentIndex].StepModules[0] != ModuleName.Buffer)
// {
// reason = $"Invalid sequence {seqs[i]}, {currentIndex + 1}st step should be Buffer";
// return false;
// }
// else
// {
// //if (!sequence.Steps[currentIndex].StepParameter.ContainsKey("SlotSelection")
// // || string.IsNullOrEmpty(sequence.Steps[currentIndex].StepParameter["SlotSelection"].ToString())
// // || sequence.Steps[currentIndex].StepParameter["SlotSelection"].ToString().Contains("3"))
// //{
// // reason = $"Invalid sequence {seqs[i]},{currentIndex + 1}st step Buffer SlotSelection parameter is not valid";
// // return false;
// //}
// if (!sequence.Steps[currentIndex].StepParameter.ContainsKey("BufferType") || !sequence.Steps[currentIndex].StepParameter["BufferType"].ToString().Contains("Heat"))
// {
// reason = $"Invalid sequence {seqs[i]},{currentIndex + 1}st step Buffer BufferType parameter is not valid";
// return false;
// }
// }
// currentIndex++;
// if (sequence.Steps[currentIndex] == null || sequence.Steps[currentIndex].StepModules.Count <= 0 || sequence.Steps[currentIndex].StepModules.Any(pm => !ModuleHelper.IsPm(pm)))
// {
// reason = $"Invalid sequence {seqs[i]}, {currentIndex + 1}st step should be PM";
// return false;
// }
// //if (sequence.Steps.Count == 7)
// //{
// // currentIndex++;
// // if (sequence.Steps[currentIndex] == null || sequence.Steps[currentIndex].StepModules.Count <= 0 || sequence.Steps[currentIndex].StepModules[0] != ModuleName.Buffer)
// // {
// // reason = $"Invalid sequence {seqs[i]}, {currentIndex + 1}st step should be Buffer";
// // return false;
// // }
// // else
// // {
// // if (!sequence.Steps[currentIndex].StepParameter.ContainsKey("SlotSelection")
// // || sequence.Steps[currentIndex].StepParameter["SlotSelection"].ToString() != "3")
// // {
// // reason = $"Invalid sequence {seqs[i]},{currentIndex + 1}st step Buffer SlotSelection parameter is not valid";
// // return false;
// // }
// // if (!sequence.Steps[currentIndex].StepParameter.ContainsKey("BufferType") || !sequence.Steps[currentIndex].StepParameter["BufferType"].ToString().Contains("Cooling"))
// // {
// // reason = $"Invalid sequence {seqs[i]},{currentIndex + 1}st step Buffer BufferType parameter is not valid";
// // return false;
// // }
// // }
// //}
// currentIndex++;
// if (sequence.Steps[currentIndex] == null || sequence.Steps[currentIndex].StepModules.Count <= 0 || sequence.Steps[currentIndex].StepModules[0] != ModuleName.UnLoad)
// {
// reason = $"Invalid sequence {seqs[i]}, {currentIndex + 1}st step should be Unload";
// return false;
// }
// currentIndex++;
// if (sequence.Steps[currentIndex] == null || sequence.Steps[currentIndex].StepModules.Count <= 0 || sequence.Steps[currentIndex].StepModules[0] != ModuleName.Aligner)
// {
// reason = $"Invalid sequence {seqs[i]}, {currentIndex + 1}st step should be Aligner";
// return false;
// }
// else
// {
// if (sequence.Steps[0].AlignAngle < 0 || sequence.Steps[0].AlignAngle > 360)
// {
// reason = $"Invalid sequence {seqs[i]}, Aligner angle parameter is not valid";
// return false;
// }
// }
// }
//}
//if (isAllSequenceNull)
//{
// reason = $"Invalid sequence, sequence are all null ";
// return false;
//}
return true ;
}
internal void StopJob ( string jobName )
{
//ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
//if (cj == null)
//{
// EV.PostWarningLog(LogSource, $"stop job rejected, not found job with id {jobName}");
// return;
//}
foreach ( var cj in _controlJobList )
{
foreach ( var pj in _processJobList )
{
if ( pj . ControlJobName = = cj . Name )
{
pj . SetState ( EnumProcessJobState . Stopping ) ;
}
}
if ( _cycleSetPoint > 0 )
{
_cycleSetPoint = _cycledCount ;
}
}
}
public void Abort ( )
{
try
{
var wafer = WaferManager . Instance . GetWafer ( ModuleName . PM1 , 0 ) ;
if ( wafer ! = null & & ! string . IsNullOrEmpty ( wafer . WaferID ) )
{
AutoJobRecorder . UpdatePosition ( wafer . WaferID . ToString ( ) , ModuleName . PM1 . ToString ( ) , "Aborted" ) ;
}
var wafer1 = WaferManager . Instance . GetWafer ( ModuleName . TMRobot , 0 ) ;
if ( wafer1 ! = null & & ! string . IsNullOrEmpty ( wafer1 . WaferID ) )
{
AutoJobRecorder . UpdatePosition ( wafer1 . WaferID . ToString ( ) , ModuleName . TM . ToString ( ) , "Aborted" ) ;
}
var wafer2 = WaferManager . Instance . GetWafer ( ModuleName . Buffer , 0 ) ;
if ( wafer2 ! = null & & ! string . IsNullOrEmpty ( wafer2 . WaferID ) )
{
AutoJobRecorder . UpdatePosition ( wafer2 . WaferID . ToString ( ) , ModuleName . Buffer . ToString ( ) , "Aborted" ) ;
}
var wafer3 = WaferManager . Instance . GetWafer ( ModuleName . LoadLock , 0 ) ;
if ( wafer3 ! = null & & ! string . IsNullOrEmpty ( wafer3 . WaferID ) )
{
AutoJobRecorder . UpdatePosition ( wafer3 . WaferID . ToString ( ) , ModuleName . LoadLock . ToString ( ) , "Aborted" ) ;
}
var cjList = _controlJobList . FindAll ( c = > c . State = = EnumControlJobState . Executing ) ;
if ( cjList ! = null )
{
foreach ( var cj in cjList )
{
string squenceID = cj . LotWafers ! = null ? cj . LotWafers [ 0 ] . PPID : string . Empty ;
//补全路径
squenceID = $"Sequence\\{squenceID}.seq" ;
GemManager . Instance . Equipment ? . TriggerEvent ( "JobAbort" , new string [ ] { "LotID" , "SequenceID" } , new object [ ] { cj . LotName , squenceID } ) ;
}
}
}
catch ( Exception ex )
{
LOG . Error ( ex . Message , ex ) ;
}
}
internal void AbortJob ( string jobName )
{
var cj = _controlJobList . Find ( x = > x . Name = = jobName ) ;
if ( cj = = null )
{
EV . PostWarningLog ( LogSource , $"abort job rejected, not found job with id {jobName}" ) ;
return ;
}
var unprocessed_cj = 0 ;
var aborted_cj = 0 ;
var pjAbortList = new List < ProcessJobInfo > ( ) ;
foreach ( var pj in _processJobList )
{
if ( pj . ControlJobName = = cj . Name )
{
pj . SetState ( EnumProcessJobState . Aborting ) ;
pjAbortList . Add ( pj ) ;
var unprocessed = 0 ;
var aborted = 0 ;
var wafers = WaferManager . Instance . GetWaferByProcessJob ( pj . Name ) ;
foreach ( var waferInfo in wafers )
{
waferInfo . ProcessJob = null ;
waferInfo . NextSequenceStep = 0 ;
if ( waferInfo . ProcessState ! = WaferProcessStatus . Completed )
{
unprocessed + + ;
unprocessed_cj + + ;
}
}
JobDataRecorder . EndPJ ( pj . InnerId . ToString ( ) , aborted , unprocessed ) ;
}
}
foreach ( var pj in pjAbortList )
{
_processJobList . Remove ( pj ) ;
}
_controlJobList . Remove ( cj ) ;
_dbCallback . LotFinished ( cj ) ;
JobDataRecorder . EndCJ ( cj . InnerId . ToString ( ) , aborted_cj , unprocessed_cj ) ;
}
public void AbortSingleJob ( string jobName , string waferID )
{
var cj = _controlJobList . Find ( x = > x . Name . ToString ( ) = = jobName ) ;
if ( cj = = null )
{
EV . PostWarningLog ( LogSource , $"abort job rejected, not found job with id {jobName}" ) ;
return ;
}
var pjAbortList = new List < ProcessJobInfo > ( ) ;
foreach ( var pj in _processJobList )
{
if ( pj . ControlJobName = = cj . Name )
{
var wafers = WaferManager . Instance . GetWaferByProcessJob ( pj . Name ) ;
foreach ( var waferInfo in wafers )
{
SkipWaferProcessStep ( waferInfo ) ;
waferInfo . WaferStatus = WaferStatus . Aborted ;
waferInfo . ProcessState = WaferProcessStatus . Abort ;
AutoJobRecorder . UpdateStatus ( waferInfo . WaferID . ToString ( ) , "Aborted" ) ;
}
}
}
}
public void ResumeJob ( string jobName )
{
//ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
//if (cj == null)
//{
// EV.PostWarningLog(LogSource, $"resume job rejected, not found job with id {jobName}");
// return;
//}
foreach ( var cj in _controlJobList )
{
if ( cj . State = = EnumControlJobState . Paused )
{
cj . SetState ( EnumControlJobState . Executing ) ;
}
}
}
internal void PauseJob ( string jobName )
{
//ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
//if (cj == null)
//{
// EV.PostWarningLog(LogSource, $"pause job rejected, not found job with id {jobName}");
// return;
//}
foreach ( var cj in _controlJobList )
{
if ( cj . State = = EnumControlJobState . Executing )
{
cj . SetState ( EnumControlJobState . Paused ) ;
}
}
}
internal bool CheckPMState ( string sequence )
{
var seqInfo = SequenceInfoHelper . GetInfo ( sequence ) ;
if ( seqInfo . Name ! = "" )
{
foreach ( var step in seqInfo . Steps )
{
foreach ( var moduleName in step . StepModules )
{
if ( ModuleHelper . IsPm ( moduleName ) )
{
var module = _lstPms . Find ( x = > x . Module = = moduleName ) ;
if ( module ! = null )
{
if ( module . IsError )
{
EV . PostWarningLog ( "Scheduler" , $"{moduleName} is not be error" ) ;
return false ;
}
if ( ! module . IsOnline )
{
EV . PostWarningLog ( "Scheduler" , $"{moduleName} is not be Online" ) ;
return false ;
}
if ( ! module . IsLineHeaterEnable )
{
EV . PostWarningLog ( "Scheduler" , $"{moduleName} LineHeater is not be Open" ) ;
return false ;
}
//if (module.IsService)
//{
// EV.PostWarningLog("Scheduler", $"can not start job, {moduleName} is Service Mode");
// return false;
//}
}
else
{
EV . PostWarningLog ( "Scheduler" , "Sequence PM can not be null!" ) ;
return false ;
}
}
}
}
}
else
{
EV . PostWarningLog ( "Scheduler" , "Sequence can not be null!" ) ;
return false ;
}
return true ;
}
#endregion
/// <summary>
/// Start Auto Transfer
/// </summary>
/// <param name="objs"></param>
/// <returns></returns>
public Result CheckAutoMode ( params object [ ] objs )
{
if ( ! _tmRobot . IsOnline | | _tmRobot . IsError )
{
EV . PostWarningLog ( "Scheduler" , "can not change to auto mode, TM robot should be online and no error" ) ;
return Result . FAIL ;
}
return Result . RUN ;
}
public Result Monitor ( )
{
MonitorModuleTasks ( ) ;
MonitorAutoJobStatus ( ) ;
MonitorModuleError ( ) ;
MonitorJobTasks ( ) ;
return Result . RUN ;
}
#region Job task
public Result MonitorJobTasks ( )
{
UpdateProcessJobStatus ( ) ;
UpdateControlJobStatus ( ) ;
return Result . RUN ;
}
/// <summary>
/// 检查PJ中的Wafer信息是否被清空。
/// <para>如果被清空, 则说明中间过程中Wafer被人工删除, 此时返回true, 通知相关Monitor可以改PJ。</para>
/// </summary>
/// <param name="pj"></param>
/// <returns></returns>
protected bool CheckAllWaferDeleted ( ProcessJobInfo pj )
{
var wi = WaferManager . Instance . GetWaferByProcessJob ( pj . Name ) ;
return wi = = null | | wi . Length < = 0 ;
}
protected bool CheckAllWaferReturned ( ProcessJobInfo pj , bool checkAllProcessed )
{
for ( var i = 0 ; i < pj . SlotWafers . Count ; + + i )
{
WaferInfoRt wafer = WaferManager . Instance . GetWafer ( pj . SlotWafers [ i ] . Item1 , pj . SlotWafers [ i ] . Item2 ) ;
if ( wafer . IsWaferEmpty )
return false ;
if ( checkAllProcessed & & CheckWaferNeedProcess ( pj . SlotWafers [ i ] . Item1 , pj . SlotWafers [ i ] . Item2 ) )
return false ;
if ( wafer . ProcessJob = = null | | wafer . ProcessJob . InnerId ! = pj . InnerId )
{
return false ;
}
}
return true ;
}
protected bool CheckAllDummyWaferReturned ( )
{
foreach ( var schedulerPm in _lstPms )
{
if ( WaferManager . Instance . CheckWaferIsDummy ( schedulerPm . Module , 0 ) )
return false ;
}
if ( WaferManager . Instance . CheckWaferIsDummy ( _tmRobot . Module , 0 ) )
return false ;
if ( WaferManager . Instance . CheckWaferIsDummy ( _tmRobot . Module , 1 ) )
return false ;
return true ;
}
protected bool CheckAllPmCleaned ( ProcessJobInfo pj )
{
foreach ( var schedulerPm in _lstPms )
{
if ( GetModule ( schedulerPm . Module ) . CheckNeedRunClean ( out _ , out _ ) )
{
foreach ( var sequenceStepInfo in pj . Sequence . Steps )
{
if ( sequenceStepInfo . StepModules . Contains ( schedulerPm . Module ) )
return false ;
}
}
}
return true ;
}
private void UpdateProcessJobStatus ( )
{
foreach ( var pj in _processJobList )
{
if ( pj . State = = EnumProcessJobState . Processing )
{
if ( CheckAllWaferReturned ( pj , true ) )
{
if ( CheckWaferSequenceStepDone ( ModuleName . LoadLock , 0 ) )
{
pj . CycleTime + + ;
if ( pj . CycleTime < pj . CycleCount )
{
//重新设置wafer
for ( int i = 0 ; i < pj . SlotWafers . Count ; + + i )
{
var wafer = GetModule ( pj . SlotWafers [ i ] . Item1 ) . GetWaferInfo ( pj . SlotWafers [ i ] . Item2 ) ;
wafer . NextSequenceStep = 0 ;
wafer . WaferStatus = WaferStatus . Normal ;
wafer . ProcessState = WaferProcessStatus . Idle ;
}
}
else
{
_load . SetJobStatue ( ) ;
pj . SetState ( EnumProcessJobState . ProcessingComplete ) ;
JobDataRecorder . EndPJ ( pj . InnerId . ToString ( ) , 0 , 0 ) ;
AutoJobRecorder . EndJob ( WaferManager . Instance . GetWafer ( ModuleName . LoadLock , 0 ) . WaferID . ToString ( ) ) ;
}
}
}
if ( CheckAllWaferDeleted ( pj ) )
{
_load . SetJobStatue ( ) ;
pj . SetState ( EnumProcessJobState . Complete ) ;
JobDataRecorder . EndPJ ( pj . InnerId . ToString ( ) , 0 , 0 ) ;
AutoJobRecorder . EndJob ( WaferManager . Instance . GetWafer ( ModuleName . LoadLock , 0 ) . WaferID . ToString ( ) ) ;
}
}
else if ( pj . State = = EnumProcessJobState . Stopping )
{
if ( CheckAllWaferReturned ( pj , false ) )
{
if ( CheckWaferSequenceStepDone ( ModuleName . LoadLock , 0 ) )
{
_load . SetJobStatue ( ) ;
pj . SetState ( EnumProcessJobState . Complete ) ;
JobDataRecorder . EndPJ ( pj . InnerId . ToString ( ) , 0 , 0 ) ;
AutoJobRecorder . EndJob ( WaferManager . Instance . GetWafer ( ModuleName . LoadLock , 0 ) . WaferID . ToString ( ) ) ;
}
}
}
}
}
private void UpdateControlJobStatus ( )
{
try
{
if ( _controlJobList . Count = = 0 )
{
return ;
}
foreach ( var cj in _controlJobList )
{
if ( cj . State = = EnumControlJobState . Executing )
{
bool allPjCompleted = true ;
foreach ( var pjName in cj . ProcessJobNameList )
{
var pj = _processJobList . Find ( x = > x . Name = = pjName ) ;
if ( pj ! = null )
{
if ( pj . State ! = EnumProcessJobState . ProcessingComplete & & pj . State ! = EnumProcessJobState . Complete )
{
allPjCompleted = false ;
break ;
}
}
}
if ( allPjCompleted )
{
foreach ( var pjName in cj . ProcessJobNameList )
{
var pj = _processJobList . Find ( x = > x . Name = = pjName ) ;
if ( pj ! = null )
{
_processJobList . Remove ( pj ) ;
}
}
var wafer = cj . LotWafers [ 0 ] ;
if ( wafer ! = null )
{
if ( wafer . WaferStatus = = WaferStatus . Aborted )
{
cj . SetState ( EnumControlJobState . Aborted ) ;
}
else
{
cj . SetState ( EnumControlJobState . Completed ) ;
}
AutoJobRecorder . UpdatePosition ( wafer . WaferID . ToString ( ) , ModuleName . LoadLock . ToString ( ) , cj . State . ToString ( ) ) ;
JobDataRecorder . EndCJ ( cj . InnerId . ToString ( ) , 0 , 0 ) ;
_dbCallback . LotFinished ( cj ) ;
}
}
}
}
for ( int i = 0 ; i < _controlJobList . Count ; i + + )
{
if ( _controlJobList [ i ] . State = = EnumControlJobState . Completed | | _controlJobList [ i ] . State = = EnumControlJobState . Aborted )
{
_controlJobList . RemoveAt ( i ) ;
}
}
}
catch ( Exception ex )
{
LOG . Error ( ex . Message , ex ) ;
}
}
public void MonitorAutoJobStatus ( )
{
try
{
_updateAutoJobLocation . CLK = _tmRobot . IsAvailable ;
if ( _updateAutoJobLocation . Q )
{
WaferInfoRt wafer = WaferManager . Instance . GetWafer ( ModuleName . PM1 , 0 ) ;
if ( wafer ! = null & & ! string . IsNullOrEmpty ( wafer . WaferID ) )
{
AutoJobRecorder . UpdateWaferPosition ( wafer . WaferID . ToString ( ) , ModuleName . PM1 . ToString ( ) ) ;
}
WaferInfoRt wafer1 = WaferManager . Instance . GetWafer ( ModuleName . TMRobot , 0 ) ;
if ( wafer1 ! = null & & ! string . IsNullOrEmpty ( wafer1 . WaferID ) )
{
AutoJobRecorder . UpdateWaferPosition ( wafer1 . WaferID . ToString ( ) , ModuleName . TM . ToString ( ) ) ;
}
WaferInfoRt wafer2 = WaferManager . Instance . GetWafer ( ModuleName . Buffer , 0 ) ;
if ( wafer2 ! = null & & ! string . IsNullOrEmpty ( wafer2 . WaferID ) )
{
AutoJobRecorder . UpdateWaferPosition ( wafer2 . WaferID . ToString ( ) , ModuleName . Buffer . ToString ( ) ) ;
}
WaferInfoRt wafer3 = WaferManager . Instance . GetWafer ( ModuleName . LoadLock , 0 ) ;
if ( wafer3 ! = null & & ! string . IsNullOrEmpty ( wafer3 . WaferID ) )
{
AutoJobRecorder . UpdateWaferPosition ( wafer3 . WaferID . ToString ( ) , ModuleName . LoadLock . ToString ( ) ) ;
}
}
}
catch ( Exception ex )
{
LOG . Error ( ex . Message , ex ) ;
}
}
public bool CheckAllJobDone ( )
{
//条件满足状态由AutoRunning切换到AutoIdle状态
if ( _load . IsAvailable & & _tmRobot . IsAvailable & & _tmRobot . NoWafer ( 0 ) & & _tmRobot . NoTray ( 0 ) & &
_buffer . NoWafer ( 0 ) & & _buffer . NoTray ( 0 ) & & _buffer . NoWafer ( 1 ) & & _buffer . NoTray ( 1 ) & & _buffer . NoWafer ( 2 ) & & _buffer . NoTray ( 2 ) & &
_pm1 . NoWafer ( 0 ) & & _pm1 . NoTray ( 0 ) & & _pm2 . NoWafer ( 0 ) & & _pm2 . NoTray ( 0 ) & & ! _controlJobList . Exists ( c = > c . State = = EnumControlJobState . Executing ) )
{
return true ;
}
return false ;
}
private bool ActiveProcessJob ( ProcessJobInfo pj )
{
foreach ( var pjSlotWafer in pj . SlotWafers )
{
WaferInfoRt wafer = GetModule ( pjSlotWafer . Item1 ) . GetWaferInfo ( pjSlotWafer . Item2 ) ;
wafer . ProcessJob = pj ;
wafer . NextSequenceStep = 0 ;
WaferDataRecorder . SetPjInfo ( wafer . WaferInnerID . ToString ( ) , pj . InnerId . ToString ( ) ) ;
}
var cj = _controlJobList . Find ( x = > x . Name = = pj . ControlJobName ) ;
var carrier = CarrierManager . Instance . GetCarrier ( cj . Module ) ;
JobDataRecorder . StartPJ ( pj . InnerId . ToString ( ) , null , cj . InnerId . ToString ( ) , pj . Name , cj . Module , cj . Module , pj . SlotWafers . Count ) ;
pj . SetState ( EnumProcessJobState . Processing ) ;
return true ;
}
#endregion
#region Module task
public Result MonitorModuleTasks ( )
{
MonitorPMTask ( ) ;
MonitorBufferTask ( ) ;
MonitorTmRobotTask ( ) ;
MonitorLoadTask ( ) ;
return Result . RUN ;
}
private void MonitorBufferTask ( )
{
if ( ! _buffer . IsAvailable )
{
return ;
}
2026-04-22 09:39:19 +08:00
for ( var i = 0 ; i < _bufferFloors ; i + + )
2026-03-24 15:04:02 +08:00
{
var canExcute = _buffer . HasWafer ( i ) & & _buffer . CheckWaferNextStepIsThis ( _buffer . Module , i ) ;
if ( canExcute )
{
WaferInfoRt bufferWafer = _buffer . GetWaferInfo ( i ) ;
if ( i = = 2 | | i = = 1 )
{
bufferWafer . NextSequenceStep + + ;
continue ;
}
var bufferSetValue = 0 ;
if ( ! GetWaferSequenceNextValue ( ModuleName . Buffer , i , "Type" , out var strBufferType ) )
{
continue ;
}
if ( ! GetWaferSequenceNextValue ( ModuleName . Buffer , i , "SetValue" , out var strBufferSetValue ) )
{
continue ;
}
if ( ! Int32 . TryParse ( strBufferSetValue , out bufferSetValue ) )
{
continue ;
}
//分别判断冷却和加热方式温度是否达到
if ( strBufferType = = "HeatByTemp" )
{
if ( _bufferWaferInfo . ContainsKey ( bufferWafer . WaferInnerID . ToString ( ) ) )
{
var dtStartTime = _bufferWaferInfo [ bufferWafer . WaferInnerID . ToString ( ) ] ;
var pastTime = ( DateTime . Now - dtStartTime ) . TotalSeconds ;
//选择By温度5秒后再判断温度
if ( pastTime > 5 )
{
if ( _buffer . GetTemperature ( ) > = bufferSetValue )
bufferWafer . NextSequenceStep + + ;
_bufferWaferInfo . Remove ( bufferWafer . WaferInnerID . ToString ( ) ) ;
}
}
else
{
_bufferWaferInfo . Add ( bufferWafer . WaferInnerID . ToString ( ) , DateTime . Now ) ;
}
}
else if ( strBufferType = = "HeatByTime" )
{
if ( _bufferWaferInfo . ContainsKey ( bufferWafer . WaferInnerID . ToString ( ) ) )
{
var dtStartTime = _bufferWaferInfo [ bufferWafer . WaferInnerID . ToString ( ) ] ;
var pastTime = ( DateTime . Now - dtStartTime ) . TotalSeconds ;
if ( i = = 0 )
{
_timeBuffer1 = pastTime > bufferSetValue ? 0 : ( bufferSetValue - pastTime ) ;
}
else if ( i = = 1 )
{
_timeBuffer2 = pastTime > bufferSetValue ? 0 : ( bufferSetValue - pastTime ) ;
}
else if ( i = = 2 )
{
_timeBuffer3 = pastTime > bufferSetValue ? 0 : ( bufferSetValue - pastTime ) ;
}
if ( pastTime > bufferSetValue )
{
bufferWafer . NextSequenceStep + + ;
_bufferWaferInfo . Remove ( bufferWafer . WaferInnerID . ToString ( ) ) ;
}
}
else
{
_bufferWaferInfo . Add ( bufferWafer . WaferInnerID . ToString ( ) , DateTime . Now ) ;
}
}
else if ( strBufferType = = "CoolingByTime" )
{
if ( _bufferWaferInfo . ContainsKey ( bufferWafer . WaferInnerID . ToString ( ) ) )
{
var dtStartTime = _bufferWaferInfo [ bufferWafer . WaferInnerID . ToString ( ) ] ;
var pastTime = ( DateTime . Now - dtStartTime ) . TotalSeconds ;
if ( i = = 0 )
{
_timeBuffer1 = pastTime > bufferSetValue ? 0 : ( bufferSetValue - pastTime ) ;
}
else if ( i = = 1 )
{
_timeBuffer2 = pastTime > bufferSetValue ? 0 : ( bufferSetValue - pastTime ) ;
}
else if ( i = = 2 )
{
_timeBuffer3 = pastTime > bufferSetValue ? 0 : ( bufferSetValue - pastTime ) ;
}
if ( pastTime > bufferSetValue )
{
bufferWafer . NextSequenceStep + + ;
_bufferWaferInfo . Remove ( bufferWafer . WaferInnerID . ToString ( ) ) ;
}
}
else
{
_bufferWaferInfo . Add ( bufferWafer . WaferInnerID . ToString ( ) , DateTime . Now ) ;
}
}
//return;
}
}
//Place和Pick条件都一样
if ( ! _buffer . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
{
_buffer . PrepareTransfer ( ModuleName . TMRobot , EnumTransferType . Place , 0 ) ;
}
}
/// <summary>
/// 检测到LL中的Wafer已完成Job。
/// </summary>
//private readonly R_TRIG _trigLLPjDone = new();
private void MonitorLoadTask ( )
{
if ( ! _load . IsAvailable )
{
return ;
}
if ( _load . FirstDetectWaferArrive ( 0 ) | | _load . FirstDetectWaferLeave ( 0 ) )
{
_load . ResetPurged ( ) ;
//_trigLLPjDone.RST = true;
}
var canExcute = _load . HasWafer ( 0 ) ;
if ( canExcute )
{
if ( _load . GetWaferInfo ( 0 ) . ProcessJob ! = null )
{
if ( _load . GetWaferInfo ( 0 ) . ProcessJob . State ! = EnumProcessJobState . Processing )
{
return ;
}
}
else
{
return ;
}
if ( ! _load . CheckWaferSequenceStepDone ( 0 ) )
{
if ( _load . CheckWaferNextStepIsThis ( ModuleName . LoadLock , 0 ) )
{
if ( _load . CheckWaferNeedProcess ( 0 ) )
{
_load . Purge ( _load . GetWaferPurgeCount ( 0 ) , _load . GetWaferPumpDelayTime ( 0 ) ) ;
_load . GetWaferInfo ( 0 ) . NextSequenceStep + + ;
return ;
}
else
{
if ( ! GetWaferSequenceNextValue ( ModuleName . Load , 0 , "Type" , out var strType ) )
{
return ;
}
if ( ! GetWaferSequenceNextValue ( ModuleName . Load , 0 , "SetValue" , out var strSetValue ) )
{
return ;
}
if ( ! Int32 . TryParse ( strSetValue , out var setValue ) )
{
return ;
}
//Load腔没有测温
//if (strType == "CoolingByTemp")
//{
// if (_load.GetTemperature() <= setValue)
// {
// _load.Purge(_load.GetWaferPurgeCount(0), _load.GetWaferPumpDelayTime(0));
// _load.Vent();
// _load.GetWaferInfo(0).NextSequenceStep++;
// }
//}
if ( strType = = "CoolingByTime" )
{
if ( _loadWaferInfo . ContainsKey ( _load . GetWaferInfo ( 0 ) . WaferInnerID . ToString ( ) ) )
{
var dtStartTime = _loadWaferInfo [ _load . GetWaferInfo ( 0 ) . WaferInnerID . ToString ( ) ] ;
var pastTime = ( DateTime . Now - dtStartTime ) . TotalSeconds ;
_timeLoad = pastTime > setValue ? 0 : ( setValue - pastTime ) ;
if ( pastTime > setValue )
{
if ( ! _load . CheckPurged ( ) )
{
_load . Purge ( _load . GetWaferPurgeCount ( 0 ) , _load . GetWaferPumpDelayTime ( 0 ) ) ;
return ;
}
_load . ResetPurged ( ) ;
_load . Vent ( ) ;
_load . GetWaferInfo ( 0 ) . NextSequenceStep + + ;
_loadWaferInfo . Remove ( _load . GetWaferInfo ( 0 ) . WaferInnerID . ToString ( ) ) ;
//补全路径
string squenceID = $"Sequence\\{_load.GetWaferInfo(0).PPID}.seq" ;
GemManager . Instance . Equipment ? . TriggerEvent ( "JobComplete" , new string [ ] { "LotID" , "SequenceID" } ,
new object [ ] { _load . GetWaferInfo ( 0 ) . LotId , squenceID } ) ;
return ;
}
}
else
{
_loadWaferInfo . Add ( _load . GetWaferInfo ( 0 ) . WaferInnerID . ToString ( ) , DateTime . Now ) ;
return ;
}
}
}
}
else if ( ! _load . IsReadyForPick ( ModuleName . TMRobot , 0 ) & & ! _tmRobot . IsInPumping )
{
_load . PrepareTransfer ( ModuleName . TMRobot , EnumTransferType . Pick , 0 ) ;
return ;
}
}
/ * else
{
// Job Done, 响蜂鸣器
_trigLLPjDone . CLK = true ;
if ( _trigLLPjDone . Q )
{
OP . DoOperation ( "System.AlertJobDone" , ModuleName . LoadLock . ToString ( ) , 0 ) ;
}
} * /
}
else
{
if ( _load . NoTray ( 0 ) )
{
if ( ! _load . IsReadyForPlace ( ModuleName . TMRobot , 0 ) & & ! _tmRobot . IsInPumping )
{
_load . PrepareTransfer ( ModuleName . TMRobot , EnumTransferType . Place , 0 ) ;
return ;
}
}
}
}
private void MonitorPMTask ( )
{
//if (_pm1.FirstDetectTrayArrive(0))
//{
// _pm1.GetWaferInfo(0).TrayUsedForWhichPM = (int)_pm1.Module;
//}
//if (_pm2.FirstDetectTrayArrive(1))
//{
// _pm2.GetWaferInfo(0).TrayUsedForWhichPM = (int)_pm2.Module;
//}
foreach ( var pm in _lstPms )
{
if ( ! pm . IsAvailable )
continue ;
if ( pm . HasWafer ( 0 ) )
{
if ( pm . CheckNeedRunClean ( out var withWafer , out var recipe ) & & withWafer
& & GetModule ( pm . Module ) . GetWaferInfo ( 0 ) . WaferStatus = = WaferStatus . Dummy
& & GetModule ( pm . Module ) . GetWaferInfo ( 0 ) . ProcessState = = WaferProcessStatus . Wait )
{
pm . Process ( recipe , true , withWafer ) ;
continue ;
}
if ( GetModule ( pm . Module ) . CheckWaferNeedProcess ( 0 , pm . Module ) )
{
WaferInfoRt wafer = GetModule ( pm . Module ) . GetWaferInfo ( 0 ) ;
if ( pm . Process ( wafer . ProcessJob . Sequence . Steps [ wafer . NextSequenceStep ] . RecipeName , false , true ) )
{
GetModule ( pm . Module ) . GetWaferInfo ( 0 ) . NextSequenceStep + + ;
continue ;
}
}
else
{
if ( ! pm . IsReadyForPick ( ModuleName . TMRobot , 0 ) )
{
pm . PrepareTransfer ( ModuleName . TMRobot , EnumTransferType . Pick , 0 ) ;
}
}
}
else
{
if ( GetModule ( pm . Module ) . CheckNeedRunClean ( out var withWafer , out var recipe ) & & ! withWafer )
{
pm . Process ( recipe , true , withWafer ) ;
continue ;
}
if ( ! pm . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
{
pm . PrepareTransfer ( ModuleName . TMRobot , EnumTransferType . Place , 0 ) ;
}
}
}
}
private void MonitorTmRobotTask ( )
{
// TMRobot Idle或者Error时, 清除被传盘对象的等待状态
if ( _tmRobot . CheckTaskDone ( ) )
{
foreach ( var pm in _lstPms . Where (
pm = > pm . IsWaitTransfer ( ModuleName . TMRobot ) & & _tmRobot . CheckTaskDone ( ) ) )
{
pm . StopWaitTransfer ( ModuleName . TMRobot ) ;
}
if ( _buffer . IsWaitTransfer ( ModuleName . TMRobot ) & & _tmRobot . CheckTaskDone ( ) )
_buffer . StopWaitTransfer ( ModuleName . TMRobot ) ;
if ( _load . IsWaitTransfer ( ModuleName . TMRobot ) & & _tmRobot . CheckTaskDone ( ) )
_load . StopWaitTransfer ( ModuleName . TMRobot ) ;
//if (_unload.IsWaitTransfer(ModuleName.TMRobot))
// _unload.StopWaitTransfer(ModuleName.TMRobot);
}
if ( ! _tmRobot . IsAvailable )
{
return ;
}
if ( ! _tmRobot . IsAvailable )
return ;
var act = tmRobotActions . Peek ( ) ;
act . Invoke ( ) ;
tmRobotActions . Enqueue ( tmRobotActions . Dequeue ( ) ) ;
}
#region TmRobotTask
private void MonitorTmRobotLoadPlaceTask ( )
{
if ( ! _load . IsAvailable | | ! _tmRobot . IsAvailable )
{
return ;
}
//place Robot有Tray有Wafer,Load无Tray,无Wafer
var canPlace = _tmRobot . HasTray ( 0 ) & & _load . NoTray ( 0 ) & & _load . NoWafer ( 0 )
& & ! _load . CheckTrayPlaced ( ) ;
if ( canPlace )
{
if ( ! _tmRobot . CheckWaferNeedProcess ( 0 ) | | _tmRobot . CheckWaferSequenceStepDone ( 0 ) | | _load . CheckWaferNextStepIsThis ( ModuleName . TMRobot , 0 ) )
{
if ( _load . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
{
if ( _tmRobot . Place ( _load . Module , 0 , Hand . Blade1 ) )
{
_load . WaitTransfer ( ModuleName . TMRobot , false , 0 ) ;
return ;
}
}
}
}
}
private void MonitorTmRobotLoadPickTask ( )
{
if ( ! _load . IsAvailable | | ! _tmRobot . IsAvailable )
{
return ;
}
//pick TM无Tray,需要Process
var canPick = _tmRobot . NoTray ( 0 ) & & _tmRobot . NoWafer ( 0 )
& & _load . HasTray ( 0 ) & & _load . HasWafer ( 0 )
& & _load . CheckWaferNeedProcess ( 0 )
& & ! _load . CheckWaferNextStepIsThis ( ModuleName . LoadLock , 0 )
& & _load . CheckWaferNextStepModuleNoTray ( 0 ) ;
if ( canPick )
{
//下一步如果去PM1, 判断PM1是否准备好
if ( _pm1 . CheckWaferNextStepIsThis ( ModuleName . LoadLock , 0 ) )
{
if ( ! _pm1 . IsAvailable | | _pm1 . HasTray ( 0 ) | | _pm1 . HasWafer ( 0 ) | | ! _pm1 . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
{
return ;
}
if ( ! _pm1 . CheckBufferToPMTemp ( ) )
{
return ;
}
}
//下一步如果去PM2, 判断PM2是否准备好
if ( _pm2 . CheckWaferNextStepIsThis ( ModuleName . LoadLock , 0 ) )
{
if ( ! _pm2 . IsAvailable | | _pm2 . HasTray ( 0 ) | | _pm2 . HasWafer ( 0 ) | | ! _pm2 . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
{
return ;
}
if ( ! _pm2 . CheckBufferToPMTemp ( ) )
{
return ;
}
}
if ( _load . IsReadyForPick ( ModuleName . TMRobot , 0 ) )
{
if ( _tmRobot . Pick ( _load . Module , 0 , Hand . Blade1 ) )
{
_load . WaitTransfer ( ModuleName . TMRobot , true , 0 ) ;
return ;
}
}
}
}
private void MonitorTmRobotBufferPlaceTask ( )
{
if ( ! _tmRobot . IsAvailable | | ! _buffer . IsAvailable )
{
return ;
}
//place Buffer位置没有Tray,Robot有Wafer,下一步骤是Buffer
var canPalce = _tmRobot . HasTray ( 0 ) ;
if ( canPalce )
{
SlotItem bufferEmptySlot = null ;
if ( _tmRobot . CheckWaferNeedProcess ( 0 , _pm1 . Module )
& & _buffer . NoTray ( 2 )
& & _buffer . NoWafer ( 2 )
& & _buffer . CheckWaferNextStepIsThis ( ModuleName . TMRobot , 0 ) )
{
bufferEmptySlot = new SlotItem ( ModuleName . Buffer , 2 ) ;
}
else if ( _tmRobot . CheckWaferNeedProcess ( 0 , _pm2 . Module )
& & _buffer . NoTray ( 1 )
& & _buffer . NoWafer ( 1 )
& & _buffer . CheckWaferNextStepIsThis ( ModuleName . TMRobot , 0 ) )
{
bufferEmptySlot = new SlotItem ( ModuleName . Buffer , 1 ) ;
}
//TMRobot的下一步是Buffer3
else if ( ! _tmRobot . CheckWaferNeedProcess ( 0 )
& & _buffer . NoTray ( 0 )
& & _buffer . NoWafer ( 0 )
& & _buffer . CheckWaferNextStepIsThis ( ModuleName . TMRobot , 0 ) )
{
bufferEmptySlot = new SlotItem ( ModuleName . Buffer , 0 ) ;
}
//Load里有Tray
else if ( ! _tmRobot . CheckWaferNeedProcess ( 0 )
& & _buffer . NoTray ( 0 )
& & _buffer . NoWafer ( 0 )
& & _load . HasTray ( 0 ) )
{
bufferEmptySlot = new SlotItem ( ModuleName . Buffer , 0 ) ;
}
if ( bufferEmptySlot = = null )
{
return ;
}
if ( _buffer . IsReadyForPlace ( ModuleName . TMRobot , bufferEmptySlot . Slot ) )
{
if ( _tmRobot . Place ( _buffer . Module , bufferEmptySlot . Slot , Hand . Blade1 ) )
{
_buffer . WaitTransfer ( ModuleName . TMRobot ) ;
return ;
}
}
return ;
}
}
private void MonitorTmRobotBufferPickTask ( )
{
if ( ! _tmRobot . IsAvailable | | ! _buffer . IsAvailable )
{
return ;
}
//pick,Buffer有Tray,机械手没有Tray
MonitorTmRobotBuffer1PickTask ( ) ;
MonitorTmRobotBuffer2PickTask ( ) ;
MonitorTmRobotBuffer3PickTask ( ) ;
}
private void MonitorTmRobotBuffer3PickTask ( )
{
if ( ! _tmRobot . IsAvailable | | ! _buffer . IsAvailable )
{
return ;
}
//pick,Buffer有Tray,机械手没有Tray
var canPick = _tmRobot . NoTray ( 0 ) ;
if ( canPick )
{
if ( _buffer . HasTray ( 2 ) & & _buffer . HasWafer ( 2 ) )
{
if ( _buffer . CheckWaferNextStepIsThis ( ModuleName . Buffer , 2 ) )
{
return ;
}
//下一步如果去PM1, 判断PM1是否准备好
if ( _pm1 . CheckWaferNextStepIsThis ( ModuleName . Buffer , 2 ) )
{
if ( ! _pm1 . IsAvailable | | _pm1 . HasTray ( 0 ) | | _pm1 . HasWafer ( 0 ) | | ! _pm1 . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
{
return ;
}
if ( ! _pm1 . CheckBufferToPMTemp ( ) )
{
return ;
}
}
if ( _buffer . IsReadyForPick ( ModuleName . TMRobot , 0 ) )
{
if ( _tmRobot . Pick ( _buffer . Module , 2 , Hand . Blade1 ) )
{
_buffer . WaitTransfer ( ModuleName . TMRobot ) ;
return ;
}
}
}
}
}
private void MonitorTmRobotBuffer2PickTask ( )
{
if ( ! _tmRobot . IsAvailable | | ! _buffer . IsAvailable )
{
return ;
}
//pick,Buffer有Tray,机械手没有Tray
var canPick = _tmRobot . NoTray ( 0 ) ;
if ( canPick )
{
if ( _buffer . HasTray ( 1 ) & & _buffer . HasWafer ( 1 ) )
{
if ( _buffer . CheckWaferNextStepIsThis ( ModuleName . Buffer , 1 ) )
{
return ;
}
//下一步如果去PM2, 判断PM2是否准备好
if ( _pm2 . CheckWaferNextStepIsThis ( ModuleName . Buffer , 1 ) )
{
if ( ! _pm2 . IsAvailable | | _pm2 . HasTray ( 0 ) | | _pm2 . HasWafer ( 0 ) | | ! _pm2 . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
{
return ;
}
if ( ! _pm2 . CheckBufferToPMTemp ( ) )
{
return ;
}
}
if ( _buffer . CheckWaferNextStepModuleNoTray ( 1 ) )
{
if ( _buffer . IsReadyForPick ( ModuleName . TMRobot , 0 ) )
{
if ( _tmRobot . Pick ( _buffer . Module , 1 , Hand . Blade1 ) )
{
_buffer . WaitTransfer ( ModuleName . TMRobot ) ;
return ;
}
}
}
}
}
}
private void MonitorTmRobotBuffer1PickTask ( )
{
if ( ! _tmRobot . IsAvailable | | ! _buffer . IsAvailable )
{
return ;
}
var canPick = _tmRobot . NoTray ( 0 ) & & _tmRobot . NoWafer ( 0 ) ;
if ( canPick )
{
if ( _buffer . HasTray ( 0 )
& & _load . NoTray ( 0 ) & & _load . NoWafer ( 0 )
& & ! _buffer . CheckWaferNextStepIsThis ( ModuleName . Buffer , 0 )
& & _load . IsReadyForPlace ( ModuleName . TMRobot , 0 )
& & _load . IsAvailable
& & _load . IsOnline )
{
if ( ! _buffer . CheckWaferNeedProcess ( 0 ) )
{
if ( _buffer . IsReadyForPick ( ModuleName . TMRobot , 0 ) )
{
if ( _tmRobot . Pick ( _buffer . Module , 0 , Hand . Blade1 ) )
{
_buffer . WaitTransfer ( ModuleName . TMRobot ) ;
return ;
}
}
}
}
}
}
private void MonitorTmRobotPMPlaceTask ( )
{
if ( ! _tmRobot . IsAvailable )
return ;
//place to pm
var blade0HasWaferAndNeedProcess = _tmRobot . HasWafer ( 0 ) & & _tmRobot . HasTray ( 0 ) & & _tmRobot . CheckWaferNeedProcess ( 0 ) ;
if ( blade0HasWaferAndNeedProcess )
{
foreach ( var pm in _lstPms )
{
if ( ! pm . IsAvailable
| | ! GetModule ( pm . Module ) . NoWafer ( 0 )
| | ! GetModule ( pm . Module ) . NoTray ( 0 )
| | ! pm . IsReadyForPlace ( ModuleName . TMRobot , 0 ) )
continue ;
var blade0Place = _tmRobot . HasWafer ( 0 ) & & _tmRobot . CheckWaferNeedProcess ( 0 , pm . Module ) & &
pm . CheckWaferNextStepIsThis ( ModuleName . TMRobot , 0 ) ;
if ( blade0Place )
{
if ( ! pm . CheckBufferToPMTemp ( ) )
{
continue ;
}
if ( _tmRobot . Place ( pm . Module , 0 , Hand . Blade1 ) )
{
pm . WaitTransfer ( ModuleName . TMRobot ) ;
return ;
}
}
}
}
}
private void MonitorTmRobotPMPickTask ( )
{
if ( ! _tmRobot . IsAvailable )
return ;
//TMRobot从PM取Wafer,Buffer1中不能有Tray,否则先去Buffer1中的Tray
if ( _tmRobot . NoWafer ( 0 ) & & _tmRobot . NoTray ( 0 ) )
{
var pickBlade = Hand . Blade1 ;
var pickPm = ModuleName . System ;
foreach ( var schedulerPm in _lstPms )
{
//增加温度低于900才能Pick的限制
if ( ! schedulerPm . IsAvailable
| | GetModule ( schedulerPm . Module ) . NoTray ( 0 )
| | GetModule ( schedulerPm . Module ) . CheckWaferNeedProcess ( 0 , schedulerPm . Module )
| | _tmRobot . HasWafer ( ( int ) pickBlade )
| | _tmRobot . HasTray ( ( int ) pickBlade ) )
continue ;
//如果下一步是Buffer,只能取出放Buffer1
if ( _buffer . CheckWaferNextStepIsThis ( schedulerPm . Module , 0 ) )
{
if ( _buffer . NoTray ( 0 ) & & _buffer . NoWafer ( 0 ) )
{
pickPm = schedulerPm . Module ;
break ;
}
}
else if ( ( _buffer . NoTray ( 0 ) & & _buffer . NoWafer ( 0 ) )
| | ( _load . NoTray ( 0 ) & & _load . NoWafer ( 0 ) ) )
{
pickPm = schedulerPm . Module ;
break ;
}
}
if ( pickPm ! = ModuleName . System )
{
var pmScheduler = _lstPms . Find ( scheduler = > scheduler . Module = = pickPm ) ;
if ( ! pmScheduler . CheckPMToTMRobotTemp ( ) )
{
return ;
}
var pm = GetModule ( pickPm . ToString ( ) ) ;
if ( pm . IsReadyForPick ( ModuleName . TMRobot , 0 ) )
{
if ( _tmRobot . Pick ( pm . Module , 0 , pickBlade ) )
{
pm . WaitTransfer ( ModuleName . TMRobot ) ;
return ;
}
}
}
}
}
#endregion
#endregion
#region Logic Check
/// <summary>
/// 获得Buffer的方式和数值
/// </summary>
/// <param name="module"></param>
/// <param name="slot"></param>
/// <param name="coolingType"></param>
/// <param name="setValue"></param>
/// <returns></returns>
private bool GetWaferSequenceNextValue ( ModuleName module , int slot , string nodeName , out string nodeValue )
{
nodeValue = "" ;
if ( ! GetModule ( module ) . HasWafer ( slot ) )
return false ;
WaferInfoRt wafer = GetModule ( module ) . GetWaferInfo ( slot ) ;
if ( wafer . ProcessJob = = null | | wafer . ProcessJob . Sequence = = null )
return false ;
if ( wafer . NextSequenceStep > = wafer . ProcessJob . Sequence . Steps . Count )
return false ;
if ( ! wafer . ProcessJob . Sequence . Steps [ wafer . NextSequenceStep ] . StepModules . Contains ( module ) )
return false ;
nodeValue = wafer . ProcessJob . Sequence . Steps [ wafer . NextSequenceStep ] . StepParameter [ nodeName ] . ToString ( ) ;
if ( String . IsNullOrEmpty ( nodeValue ) )
{
return false ;
}
return true ;
}
private bool GetWaferSequenceCurrentValue ( ModuleName module , int slot , string nodeName , out string nodeValue )
{
nodeValue = "" ;
if ( ! GetModule ( module ) . HasWafer ( slot ) )
return false ;
WaferInfoRt wafer = GetModule ( module ) . GetWaferInfo ( slot ) ;
if ( wafer . ProcessJob = = null | | wafer . ProcessJob . Sequence = = null )
return false ;
if ( wafer . NextSequenceStep > = wafer . ProcessJob . Sequence . Steps . Count )
return false ;
if ( ! wafer . ProcessJob . Sequence . Steps [ wafer . NextSequenceStep - 1 ] . StepModules . Contains ( module ) )
return false ;
nodeValue = wafer . ProcessJob . Sequence . Steps [ wafer . NextSequenceStep - 1 ] . StepParameter [ nodeName ] . ToString ( ) ;
if ( String . IsNullOrEmpty ( nodeValue ) )
{
return false ;
}
return true ;
}
public bool CheckBufferWaferHasJob ( )
{
WaferInfoRt wafer = _buffer . GetWaferInfo ( 0 ) ;
if ( wafer . IsWaferEmpty )
{
return false ;
}
if ( wafer . ProcessJob = = null )
{
return false ;
}
var pj = _processJobList . Find ( x = > x . InnerId = = wafer . ProcessJob . InnerId ) ;
if ( pj = = null )
{
return false ;
}
return true ;
}
public bool CheckWaferProcessModuleIsAvailable ( ModuleName waferModule , int waferSlot )
{
var wafer = GetModule ( waferModule ) . GetWaferInfo ( waferSlot ) ;
if ( wafer . IsWaferEmpty )
return false ;
if ( wafer . ProcessJob = = null | | wafer . ProcessJob . Sequence = = null )
return false ;
if ( wafer . NextSequenceStep > = wafer . ProcessJob . Sequence . Steps . Count )
return false ;
//foreach (var module in wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules)
//{
//if (GetModule(module).NoWafer(0)
// && _lstPms.Find(x => x.Module == module).IsAvailable
// && !CheckNeedRunClean(module, out bool _, out string _))
// return true;
//}
foreach ( var step in wafer . ProcessJob . Sequence . Steps )
{
foreach ( var module in step . StepModules )
{
if ( module . ToString ( ) . StartsWith ( "PM" )
& & GetModule ( module ) . NoWafer ( 0 )
& & _lstPms . Find ( x = > x . Module = = module ) . IsAvailable
& & ! GetModule ( module ) . CheckNeedRunClean ( out var _ , out var _ ) )
return true ;
}
}
return false ;
}
public bool CheckWaferSequenceStepDone ( ModuleName waferModule , int waferSlot )
{
var wafer = WaferManager . Instance . GetWafer ( waferModule , waferSlot ) ;
if ( wafer . IsWaferEmpty )
{
return false ;
}
if ( wafer . ProcessJob = = null | | wafer . ProcessJob . Sequence = = null )
{
return false ;
}
if ( wafer . NextSequenceStep > = wafer . ProcessJob . Sequence . Steps . Count & & wafer . ProcessJob . Sequence . Steps . Count > 0 )
{
return true ;
}
return false ;
}
private SlotItem SortBySerialMode ( List < Tuple < ModuleName , int > > processingWafers )
{
foreach ( var pjSlotWafer in processingWafers )
{
if ( pjSlotWafer . Item1 = = ModuleName . CassAL | | pjSlotWafer . Item1 = = ModuleName . CassAR )
{
if ( GetModule ( pjSlotWafer . Item1 ) . CheckWaferNeedProcess ( pjSlotWafer . Item2 , _pm1 . Module ) )
{
if ( GetRunWaferCount ( _pm1 . Module ) < 2 )
{
return new SlotItem ( pjSlotWafer . Item1 , pjSlotWafer . Item2 ) ;
}
else
{
return null ;
}
}
else if ( GetModule ( pjSlotWafer . Item1 ) . CheckWaferNeedProcess ( pjSlotWafer . Item2 , _pm2 . Module ) )
{
if ( GetRunWaferCount ( _pm2 . Module ) < 2 )
{
return new SlotItem ( pjSlotWafer . Item1 , pjSlotWafer . Item2 ) ;
}
else
{
return null ;
}
}
}
}
return null ;
}
private SlotItem SortByParallelMode ( List < Tuple < ModuleName , int > > processingWafers )
{
foreach ( var pjSlotWafer in processingWafers )
{
if ( pjSlotWafer . Item1 = = ModuleName . CassAL | | pjSlotWafer . Item1 = = ModuleName . CassAR )
{
if ( GetModule ( pjSlotWafer . Item1 ) . CheckWaferNeedProcess ( pjSlotWafer . Item2 , _pm1 . Module ) )
{
if ( GetRunWaferCount ( _pm1 . Module ) < 2 & & GetRunWaferCount ( _pm1 . Module ) < = GetRunWaferCount ( _pm2 . Module ) )
{
return new SlotItem ( pjSlotWafer . Item1 , pjSlotWafer . Item2 ) ;
}
}
else if ( GetModule ( pjSlotWafer . Item1 ) . CheckWaferNeedProcess ( pjSlotWafer . Item2 , _pm2 . Module ) )
{
if ( GetRunWaferCount ( _pm2 . Module ) < 2 & & GetRunWaferCount ( _pm2 . Module ) < = GetRunWaferCount ( _pm1 . Module ) )
{
return new SlotItem ( pjSlotWafer . Item1 , pjSlotWafer . Item2 ) ;
}
}
}
}
return SortBySerialMode ( processingWafers ) ;
}
/// <summary>
/// 获取各个模块的Wafer总数量
/// </summary>
/// <returns></returns>
private int GetRunWaferCount ( )
{
var waferCount = 0 ;
if ( _load . HasWafer ( 0 ) )
{
waferCount + + ;
}
if ( _unload . HasWafer ( 0 ) )
{
waferCount + + ;
}
if ( _tmRobot . HasWafer ( 0 ) )
{
waferCount + + ;
}
foreach ( var pm in _lstPms )
{
if ( GetModule ( pm . Module ) . HasWafer ( 0 ) )
{
waferCount + + ;
}
}
2026-04-22 09:39:19 +08:00
for ( var i = 0 ; i < _bufferFloors ; i + + )
2026-03-24 15:04:02 +08:00
{
if ( _buffer . HasWafer ( i ) )
{
waferCount + + ;
}
}
return waferCount ;
}
private int GetRunWaferCount ( ModuleName processIn )
{
var waferCount = 0 ;
if ( _tmRobot . HasWafer ( 0 ) & & ( _tmRobot . CheckWaferNeedProcess ( 0 , processIn ) | | _tmRobot . GetWaferInfo ( 0 ) . SubstHists . Select ( x = > x . locationID ) . Contains ( processIn . ToString ( ) ) ) )
{
waferCount + + ;
}
if ( GetModule ( processIn ) . HasWafer ( 0 ) & & ( GetModule ( processIn ) . CheckWaferNeedProcess ( 0 , processIn ) | | GetModule ( processIn ) . GetWaferInfo ( 0 ) . SubstHists . Select ( x = > x . locationID ) . Contains ( processIn . ToString ( ) ) ) )
{
waferCount + + ;
}
2026-04-22 09:39:19 +08:00
for ( var i = 0 ; i < _bufferFloors ; i + + )
2026-03-24 15:04:02 +08:00
{
if ( _buffer . HasWafer ( i ) & & ( _buffer . CheckWaferNeedProcess ( i , processIn ) | | _buffer . GetWaferInfo ( i ) . SubstHists . Select ( x = > x . locationID ) . Contains ( processIn . ToString ( ) ) ) )
{
waferCount + + ;
}
}
return waferCount ;
}
/// <summary>
/// 获取各个模块的石墨盘总数量
/// </summary>
/// <returns></returns>
private int GetCurrentTrayCount ( )
{
var trayCount = 0 ;
if ( _tmRobot . HasTray ( 0 ) )
{
trayCount + + ;
}
foreach ( var pm in _lstPms )
{
if ( GetModule ( pm . Module ) . HasTray ( 0 ) )
{
trayCount + + ;
}
}
2026-04-22 09:39:19 +08:00
for ( var i = 0 ; i < _bufferFloors ; i + + )
2026-03-24 15:04:02 +08:00
{
if ( _buffer . HasTray ( i ) )
{
trayCount + + ;
}
}
return trayCount ;
}
/// <summary>
/// 获取ProcessJob可以同时运行工艺的Wafer总数
/// </summary>
/// <returns></returns>
private int GetCurrentWaferCount ( )
{
var waferCountDiv = 0 ;
var cassWaferCount = 0 ;
foreach ( var cj in _controlJobList )
{
if ( cj . State = = EnumControlJobState . Executing )
{
foreach ( var pj in _processJobList )
{
if ( pj . ControlJobName = = cj . Name & & pj . State = = EnumProcessJobState . Processing )
{
cassWaferCount + = pj . SlotWafers . Count ;
foreach ( var pjSlotWafer in pj . SlotWafers )
{
var module = GetModule ( pjSlotWafer . Item1 ) ;
if ( module . HasWafer ( pjSlotWafer . Item2 ) & & ! module . CheckWaferNeedProcess ( pjSlotWafer . Item2 ) )
{
waferCountDiv + + ;
}
}
}
}
}
}
return cassWaferCount - waferCountDiv ;
//int waferCount = 0;
//if (_load.HasWafer(0))
//{
// waferCount++;
//}
//for (int i = 0; i < 3; i++)
//{
//if (_buffer.HasWafer(i))
// {
// waferCount++;
// }
//}
//if (_waferRobot.CheckWaferNeedProcess(0) )
//{
// waferCount++;
//}
//if (_aligner.CheckWaferNeedProcess(0) )
//{
// waferCount++;
//}
//for (int i=0;i<25;i++)
//{
// if (CheckWaferNeedProcess(ModuleName.CassAL, i))
// {
// waferCount++;
// }
// if (CheckWaferNeedProcess(ModuleName.CassAR, i))
// {
// waferCount++;
// }
//}
//return waferCount;
}
#endregion
#region Module error
public Result MonitorModuleError ( )
{
var isModuleError = false ;
var isPMError = new bool [ 2 ] ;
for ( var i = 0 ; i < isPMError . Length ; i + + )
{
isPMError [ i ] = false ;
}
if ( _tmRobot . IsError )
isModuleError = true ;
for ( var i = 0 ; i < _lstPms . Count ; i + + ) // PM出错, 不影响其他腔体的传片
{
if ( _lstPms [ i ] . IsError )
isPMError [ i ] = true ;
}
if ( isModuleError & & ! _isModuleErrorPrevious )
{
}
else if ( ! isModuleError & & _isModuleErrorPrevious )
{
Reset ( ) ;
}
for ( var i = 0 ; i < _lstPms . Count ; i + + )
{
if ( ! isPMError [ i ] & & _isPMErrorPrevious [ i ] )
{
_lstPms [ i ] . ResetTask ( ) ;
}
_isPMErrorPrevious [ i ] = isPMError [ i ] ;
}
_isModuleErrorPrevious = isModuleError ;
return Result . RUN ;
}
private bool CheckModuleHaveWaferWithNoJob ( out string reason )
{
reason = "" ;
if ( _controlJobList . Count > 0 )
{
reason = "lstControlJobs.Count > 0" ;
return false ;
}
else
{
if ( _buffer . HasWafer ( 0 ) | | _buffer . HasWafer ( 1 ) | | _buffer . HasWafer ( 2 ) )
{
reason = $"Buffer have wafer!" ;
EV . PostWarningLog ( LogSource , reason ) ;
return true ;
}
if ( _tmRobot . HasWafer ( 0 ) )
{
reason = $"TmRobot have wafer!" ;
EV . PostWarningLog ( LogSource , reason ) ;
return true ;
}
if ( ! _load . HasWafer ( 0 ) )
{
reason = $"Load have no wafer!" ;
EV . PostWarningLog ( LogSource , reason ) ;
return true ;
}
if ( ! _load . HasTray ( 0 ) )
{
reason = $"Load have no Tray!" ;
EV . PostWarningLog ( LogSource , reason ) ;
return true ;
}
return false ;
}
}
private bool CheckWaferNeedProcess ( ModuleName module , int waferSlot , ModuleName processIn = ModuleName . System )
{
WaferInfoRt wafer = WaferManager . Instance . GetWafer ( module , waferSlot ) ;
if ( wafer . IsWaferEmpty )
return false ;
if ( wafer . ProcessJob = = null | | wafer . ProcessJob . Sequence = = null | | wafer . ProcessJob . Sequence . Steps = = null )
return false ;
if ( wafer . NextSequenceStep > = wafer . ProcessJob . Sequence . Steps . Count | | wafer . ProcessJob . Sequence . Steps [ wafer . NextSequenceStep ] . StepModules = = null )
return false ;
//if (processIn != ModuleName.System && !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(processIn))
// return false;
var hasPm = false ;
for ( int i = wafer . NextSequenceStep ; i < wafer . ProcessJob . Sequence . Steps . Count ; i + + )
{
foreach ( var stepModule in wafer . ProcessJob . Sequence . Steps [ i ] . StepModules )
{
if ( ModuleHelper . IsPm ( stepModule ) )
{
hasPm = true ;
break ;
}
}
if ( hasPm )
break ;
}
if ( processIn = = ModuleName . System & & ! hasPm )
return false ;
return true ;
}
private bool SkipWaferProcessStep ( WaferInfoRt wafer )
{
if ( wafer . IsWaferEmpty )
return false ;
if ( wafer . ProcessJob = = null | | wafer . ProcessJob . Sequence = = null | | wafer . ProcessJob . Sequence . Steps = = null )
return false ;
if ( wafer . NextSequenceStep > = wafer . ProcessJob . Sequence . Steps . Count | | wafer . ProcessJob . Sequence . Steps [ wafer . NextSequenceStep ] . StepModules = = null )
return false ;
for ( int i = wafer . NextSequenceStep ; i < wafer . ProcessJob . Sequence . Steps . Count ; i + + )
{
foreach ( var stepModule in wafer . ProcessJob . Sequence . Steps [ i ] . StepModules )
{
if ( ModuleHelper . IsPm ( stepModule ) )
{
if ( wafer . NextSequenceStep = = 0 )
{
wafer . NextSequenceStep = wafer . ProcessJob . Sequence . Steps . Count - 1 ;
}
else
{
wafer . NextSequenceStep = i + 1 ;
}
break ;
}
}
}
return true ;
}
#endregion
}
}