ACW 0300cb6ee0 Log 안나오는 부분 수정
실제 용접 전, Prefetch2가 null이라 로그 못찍고 죽는거 주석
2026-03-01 11:46:08 +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.Replace("\0", "").Trim()})] [CellId({cellId.Replace("\0", "").Trim()})]");
}
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);
}
}