/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.Api; using VisionLight; using VisionCommon; using System; using System.Collections.Generic; using VisionCalibrator; using Aurora.Api.DataType; using VisionSequence.Camera; using System.Threading; namespace VisionSequence.Pattern { /// /// 공정 중 취득한 이미지와 패턴 정보를 관리하기 위함. /// public class GrabFindSeqUtil { private static Logger _Logger = new Logger("GrabFindSeqUtil"); private static readonly object _Lock = new object(); /// /// 공정 조명 값이 동일할 때, 그랩을 스킵하고 재활용할 이미지 저장 /// private static Dictionary _ProcGrabImageManagers = new Dictionary(); /// /// 공정 Fixture 패턴 저장 /// private static Dictionary _FixturePatternResults = new Dictionary(); #region Grab Image (조명 값이 동일할 경우 그랩을 스킵하는 용도) /// /// 등록 패턴의 조명 값이 마지막 조명 값과 동일한지 체크 (그랩 생략을 위함) /// public static bool IsPatternAndLastLightSame(FovInfo fovInfo, PatternInfo patternInfo) { try { foreach (LightParam lightParam in patternInfo.LightInfo.LightParams) { int ch = lightParam.Ch; int lastLevel = LightHub.Instance.GetLightConfigInfo(lightParam.LightId, lightParam.Ch).ChConfig.Level; int patternLevel = lightParam.Level; bool patternOnOff = lightParam.OnOff; // 패턴 조명 값이 마지막 조명 값과 다른 경우 if (patternLevel != lastLevel) { if (!patternOnOff && lastLevel == 0) { continue; // 조명 값은 다르지만, 그랩을 새로 안해도 되는 경우 } else { return false; // 조명 값이 달라서 그랩을 새로 해야하는 경우 } } // 패턴 조명 값이 마지막 조명 값과 같은 경우 else { if (!patternOnOff && lastLevel != 0) { return false; // 조명 값은 같지만, 그랩을 새로 해야하는 경우 } else { continue; // 조명 값이 같아서 그랩을 새로 안해도 되는 경우 } } } } catch (Exception e) { _Logger.FuncE(e.Message); } return true; // 조명 값이 같아서 그랩을 새로 안해도 됨 } /// /// 그랩 완료 여부를 체크한다. /// /// FOV 키 정보 /// 조명 값 /// 그랩 완료 여부 public static bool IsProcGrabDone(FovInfo fovInfo, LightInfo lightInfo) { var procGrabImageManager = GetProcGrabImageManager(fovInfo); return procGrabImageManager.IsGrabDone(lightInfo); } /// /// 그랩 완료된 공정 이미지를 등록한다. /// /// FOV 키 정보 /// 조명 값 /// 공정 그랩 이미지 public static void SetProcGrabImage(FovInfo fovInfo, LightInfo lightInfo, object image) { var procGrabImageManager = GetProcGrabImageManager(fovInfo); procGrabImageManager.SetGrabImage(lightInfo, image); } /// /// 그랩 완료된 공정 이미지를 얻어온다. /// /// FOV 키 정보 /// 조명 값 /// 공정 이미지 public static object GetProcGrabImage(FovInfo fovInfo, LightInfo lightInfo) { var procGrabImageManager = GetProcGrabImageManager(fovInfo); return procGrabImageManager.GetGrabImage(lightInfo); } private static ProcGrabImageManager GetProcGrabImageManager(FovInfo fovInfo) { lock (_Lock) { if (!_ProcGrabImageManagers.ContainsKey(fovInfo)) { _ProcGrabImageManagers[fovInfo] = new ProcGrabImageManager( fovInfo, CameraAgentManager.GetCameraAgent(fovInfo)); } return _ProcGrabImageManagers[fovInfo]; } } /// /// 공정 이미지들을 정리한다. /// /// FOV 키 정보 public static void ClearProcGrabImage(FovInfo fovInfo) { var procGrabImageManager = GetProcGrabImageManager(fovInfo); procGrabImageManager.Clear(); } #endregion #region Fixture Pattern /// /// Fixture 패턴의 검출 결과를 등록한다. /// /// FOV 키 정보 /// 패턴 검출 결과 public static void SetFixturePatternResult(FovInfo fovInfo, PatternResult patternResult) { if (!_FixturePatternResults.ContainsKey(fovInfo)) { lock (_Lock) { _FixturePatternResults.Add(fovInfo, patternResult); } } else { lock (_Lock) { _FixturePatternResults[fovInfo] = patternResult; } } } /// /// Fixture 패턴의 검출 결과를 얻어온다. /// /// FOV 키 정보 /// Fixture 패턴의 검출 결과 public static PatternResult GetFixturePatternResult(FovInfo fovInfo) { if (_FixturePatternResults.ContainsKey(fovInfo)) { return _FixturePatternResults[fovInfo]; } else { _Logger.FuncE("FixturePatternResult is null."); return null; } } /// /// Fixture 패턴의 검출 결과를 정리한다. /// FOV 키 정보 /// public static void ClearFixturePatternResult(FovInfo fovInfo) { if (_FixturePatternResults.ContainsKey(fovInfo)) { _FixturePatternResults.Remove(fovInfo); } } #endregion #region Clear Images & Fixture Patterns /// /// 곻정 이미지, 패턴 정보 초기화 /// /// 서브시스템 정보 public static void Clear(SubSysInfo subSysInfo) { lock (_Lock) { foreach (var fovInfo in VisionRecipeManager.GetFovInfos(subSysInfo)) { ClearProcGrabImage(fovInfo); ClearFixturePatternResult(fovInfo); } } } /// /// 곻정 이미지, 패턴 정보 초기화 /// /// FOV 키 정보 public static void Clear(FovInfo fovInfo) { lock (_Lock) { ClearProcGrabImage(fovInfo); ClearFixturePatternResult(fovInfo); } } #endregion public static List FindMulti( FovInfo fovInfo, PatternInfo masterPatternInfo, PatternAgentBase patternAgent, Calibrator calibrator, CameraAgentBase cameraAgent, ICameraDisplay cameraDisplay, object grabImage, FixtureResult fixtureResult = null) { var patternResults = patternAgent.FindMulti(masterPatternInfo, grabImage, cameraDisplay, fixtureResult); for (int i = 1; i < patternResults.Count; i++) { PatternResult slavePatternResult = patternResults[i]; TransformCoord(calibrator, cameraAgent.GetImageSize(), ref slavePatternResult); var slavePatternInfo = patternAgent.GetPatternInfo(slavePatternResult.PatternIndex); patternAgent.Draw(slavePatternInfo, slavePatternResult, cameraDisplay, isFixturePattern: false); slavePatternResult.PatternName = slavePatternInfo.PatternName; slavePatternResult.PatternType = slavePatternInfo.PatternType; slavePatternResult.FovId = fovInfo.FovId; } return patternResults; } /// /// 패턴 검출 결과의 이미지 좌표를 자재 좌표로 변환한다. /// /// 캘리브레이터 디바이스 /// 이미지 사이즈 정보 /// 패턴 검출 결과 public static void TransformCoord( Calibrator calibrator, ImageSize imageSize, ref PatternResult patternResult) { try { lock (_Lock) { if (patternResult.Results == null) { _Logger.FuncE("patternResult.Results is null."); return; } foreach (BaseResult baseResult in patternResult.Results) { if(!(baseResult.ImagePosition is null)) { var calibratedPoint = calibrator.TransformToCalibratedSpace(baseResult.ImagePosition, imageSize); baseResult.MaterialPosition.X = calibratedPoint.X; baseResult.MaterialPosition.Y = calibratedPoint.Y; if (baseResult is CaliperResult) { var caliperResult = baseResult as CaliperResult; calibratedPoint = calibrator.TransformToCalibratedSpace(caliperResult.ImagePositionSecond, imageSize); caliperResult.MaterialPositionSecond.X = calibratedPoint.X; caliperResult.MaterialPositionSecond.Y = calibratedPoint.Y; calibratedPoint = calibrator.TransformToCalibratedSpace(caliperResult.ImagePositionSecond_VI, imageSize); caliperResult.MaterialPositionSecond_VI.X = calibratedPoint.X; caliperResult.MaterialPositionSecond_VI.Y = calibratedPoint.Y; caliperResult.SetWidthMm(patternResult.PatternType); } } } _Logger.I(patternResult.ToString()); } } catch (Exception e) { _Logger.FuncE(e.Message); } } /// /// 강제 OK 이벤트 발생시키고 강제 OK 결과를 가져온다. /// /// 강제 OK 요청 파라미터 /// 강제 OK 패턴 검출 결과 public static PatternResult DoForceOk(ForceOkReqParam forceOkReqParam) { VisionEnv.AuroraEnv.EventPublisher.Publish(new EventMessage( forceOkReqParam.FovInfo.GetKey(), VisionEventId.REQUEST_PATTERN_FORCE_OK, forceOkReqParam)); while (!forceOkReqParam.IsDone) { Thread.Sleep(100); } return forceOkReqParam.PatternResult; } } }