choieigun 6279c02cd6 [bugfix] 재시작할때 미보고 발생하는 케이스 수정
- pending(보류) data 추가
- Reset을 해야하는 이유는 최초 2번의 WeldingListUpload를 하기 위해 필요함
- Reset을 하니까 pending data 영역이 필요해짐

자동 시퀀스 간소화
- Sub Sequence를 자동 시퀀스 내에 함수 단위로 변경함
 .receive / report..
2026-03-01 10:24:29 +09:00

154 lines
5.7 KiB
C#

using Aurora;
using Aurora.Api;
using Aurora.Util.HislogPlus;
using AuroraCellTracker;
using AuroraLaserScanner;
using AuroraPLC;
using ILSOS_CCW_H52A.Data;
using ILSOS_CCW_H52A.Device;
using OpenCvSharp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using WeldingCommon;
using WeldingCommon.Data;
using static ILSOS_CCW_H52A.Device.PLCControllerCCWH52A;
namespace ILSOS_CCW_H52A.Sequences.ProcessObjects
{
public class ProcessManager
{
private static ProcessManager _Instance;
public static ProcessManager Instance {
get {
if (_Instance is null) {
_Instance = new ProcessManager();
}
return _Instance;
}
}
private bool usedAnalyzerLog = false;
private readonly Logger _log = new Logger("ProcessManager");
private IAuroraEnvironment _env;
private PLCControllerCCWH52A _plc;
private ScannerCCWH52A _scanner;
private CellTracker _cellTracker;
public CellInfoScheduler cellScheduler { get; set; }
/// CellTracker 콜백에서 직접 수신한 (LotId, CellId) 큐.
/// DllSocket_ReceiveDataBuffer 발화 시 즉시 Enqueue — 시퀀스는 TryDequeue로 소비.
public ConcurrentQueue<(string LotId, string CellId)> ReceivedCellInfoQueue { get; }
= new ConcurrentQueue<(string, string)>();
public const double compensateEncoderReset = 0.015; // 엔코더 리셋 보상 각도 설정(70도/sec 기준 약 0.015도)
public const int RotaryJigCount = 16;
public const int RotaryMaxAngle = 360;
public double DegreePerJig { get => RotaryMaxAngle / RotaryJigCount; }
public double HalfDegreePerJig { get => DegreePerJig / 2; }
//public ConcurrentQueue<ReceivedCellInfo>
public void Init(IAuroraEnvironment env)
{
_env = env;
_plc = _env.DeviceManager[DeviceIds.PLCDevice] as PLCControllerCCWH52A;
_scanner = _env.DeviceManager[DeviceIds.Scanner] as ScannerCCWH52A;
_cellTracker = _env.DeviceManager[CommonDeviceIds.CellTracker] as CellTracker;
//CellTracker의 OnCellReceived 이벤트를 구독하여 콜백 수신 시 CellQueue에 직접 적재
if (_cellTracker._CellTracker != null)
_cellTracker._CellTracker.OnCellReceived += OnCellReceived;
cellScheduler = new CellInfoScheduler();
}
private void OnCellReceived(string lotId, string cellId)
{
ReceivedCellInfoQueue.Enqueue((lotId, cellId));
_log.I($"Cell Tracker CallBack Received >> LotId({lotId}) / CellId({cellId})");
}
public IEnumerable<bool> CheckRotaryState()
{
List<bool> rotaryStates = new List<bool>();
for (int i = 0; i < RotaryJigCount; i++) {
var rotaryProcessState = _plc.ReadBit(eBitInput.PLC_USE_WELD_JIG_1 + i).data;
rotaryStates.Add(rotaryProcessState);
//if (rotaryProcessState == false)
// _plc.ToggleBit(eBitInput.PLC_USE_WELD_JIG_1 + i, eBitOutput.PC_WELD_COMPLETE_1 + i);
}
if (usedAnalyzerLog) {
StringBuilder sb = new StringBuilder();
rotaryStates.ForEach(x => sb.Append($"{x} "));
_log.D($"Check Rotary State : {sb.ToString()}");
}
return rotaryStates;
}
public bool GetRotaryCanExist(int jigNo)
{
if (jigNo == 0)
jigNo = 1;
if (jigNo <= RotaryJigCount)
return _plc.ReadBit(eBitInput.PLC_USE_WELD_JIG_1 + (jigNo - 1)).data;
else
return false;
}
/// <summary>
/// Rotary의 현재 위치정보를 0~360로 전달함
/// </summary>
public double GetRotaryCurrentPosition(bool isView360 = true)
{
try {
double finalValue = Convert.ToDouble(_plc.ReadDWord(eWordInput.PLC_CURRENT_POS_1).data / 100_000f);
finalValue += _scanner.Config.RotaryEncoderOffset;
if (isView360) {
if (RotaryMaxAngle <= finalValue) {
while (RotaryMaxAngle <= finalValue) {
finalValue -= RotaryMaxAngle;
}
}
else if (finalValue < 0) {
while (finalValue < 0) {
finalValue += RotaryMaxAngle;
}
}
}
return finalValue;
}
catch {
return -9999.9999;
}
}
/// <summary>
/// 중심 기준 가장 가까운 지그 번호(내림 연산)
/// <param name="HalfDegreePerJig">내림 카운팅을 중심 기준 값</param>
/// </summary>
/// <returns></returns>
public int getCurrentJigNo() => (int)((GetRotaryCurrentPosition(isView360:true) + HalfDegreePerJig) / DegreePerJig) + 1;
/// <summary>
/// 360도 이상으로 준다고하면 Welding Count를 가져올 수 있음 2word = 2147483.647 / 3600 = 596 >> 596*16 = 9_536까지 카운팅 가능함
/// <param name="HalfDegreePerJig">내림 카운팅을 중심 기준 값</param>
/// </summary>
/// <returns></returns>
public int getWeldingCount() => (int)((GetRotaryCurrentPosition(isView360:false) + HalfDegreePerJig) / DegreePerJig);
}
}