diff --git a/Machines/ILSOS_CCW_H52A/Sequences/ProcessObjects/ProcessManager.cs b/Machines/ILSOS_CCW_H52A/Sequences/ProcessObjects/ProcessManager.cs index af33138..be0a631 100644 --- a/Machines/ILSOS_CCW_H52A/Sequences/ProcessObjects/ProcessManager.cs +++ b/Machines/ILSOS_CCW_H52A/Sequences/ProcessObjects/ProcessManager.cs @@ -75,7 +75,21 @@ namespace ILSOS_CCW_H52A.Sequences.ProcessObjects lotId = lotId.Replace("\0", "").Trim(); cellId = cellId.Replace("\0", "").Trim(); ReceivedCellInfoQueue.Enqueue((lotId, cellId)); - _log.I($"Cell Tracker CallBack Received >> [LotId({lotId})] [CellId({cellId})]"); + _log.I($"Cell Tracker CallBack Received >> [LotId({lotId})] [CellId({cellId})] [QueueCount({ReceivedCellInfoQueue.Count})]"); + } + + /// + /// 재시작 시 큐 잔류 데이터 전량 폐기. + /// CellTracker는 투입 기준으로 선읽음하므로, 정지 시점에 큐에 남은 데이터는 + /// 이미 처리됐거나 이전 회차의 셀 정보일 수 있어 모두 버린다. + /// _pendingPrefetch1/2 는 이미 TryDequeue 이후 저장된 별도 슬롯이므로 영향 없음. + /// + public void DrainCellInfoQueue() + { + int count = 0; + while (ReceivedCellInfoQueue.TryDequeue(out _)) count++; + if (count > 0) + _log.W($"[QueueDrain] 재시작 시 잔류 데이터 {count}건 폐기"); } public IEnumerable CheckRotaryState() diff --git a/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs b/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs index 2b75844..696ecc6 100644 --- a/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs +++ b/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs @@ -450,6 +450,7 @@ namespace ILSOS_CCW_H52A.Sequences if (_CellScheduler.HasPendingPrefetch) Log.I("[PendingRestore] 미용접 셀 보존됨 >> 재시작 후 JigNo 매칭 시 복원 예정"); _CellScheduler.Reset(); + ProcessManager.Instance.DrainCellInfoQueue(); // 정지 전 미저장 APD 잔존 데이터 클리어 — 재시작 시 중복 누적 방지 Status.GetProcessingWeldingData().APD.Clear(); @@ -761,10 +762,18 @@ namespace ILSOS_CCW_H52A.Sequences Log.W($"[PendingRestore] Jig{_WeldingJigNo} canExist=false, 복원 데이터 폐기 >> CellId({rCell})"); } } - else if (canExist && ProcessManager.Instance.ReceivedCellInfoQueue.TryDequeue(out var cell)) { - recvInfo.LotId = cell.LotId; - recvInfo.CellId = cell.CellId; + else if (ProcessManager.Instance.ReceivedCellInfoQueue.TryDequeue(out var cell)) { + if (canExist) { + recvInfo.LotId = cell.LotId; + recvInfo.CellId = cell.CellId; + } else { + // 앞공정 NG 셀: CellTracker는 투입 시 이미 스캔했으므로 큐에서 소비 후 폐기. + // 소비하지 않으면 다음 정상 셀이 이 NG 데이터를 가져가 정합성 붕괴. + Log.W($"[NG Skip] Jig{_WeldingJigNo} canExist=false, 큐 데이터 폐기 >> CellId({cell.CellId})"); + } } else { + if (canExist) + Log.E($"[QueueEmpty] Jig{_WeldingJigNo} canExist=true 이지만 큐가 비어있음"); _CellTracker.getDummyData(out string lotId, out string cellId); recvInfo.LotId = lotId; recvInfo.CellId = cellId;