280 lines
12 KiB
C#
280 lines
12 KiB
C#
/*
|
|
* 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 {
|
|
/// <summary>
|
|
/// 공정 중 취득한 이미지와 패턴 정보를 관리하기 위함.
|
|
/// </summary>
|
|
public class GrabFindSeqUtil {
|
|
private static Logger _Logger = new Logger("GrabFindSeqUtil");
|
|
private static readonly object _Lock = new object();
|
|
|
|
/// <summary>
|
|
/// 공정 조명 값이 동일할 때, 그랩을 스킵하고 재활용할 이미지 저장
|
|
/// </summary>
|
|
private static Dictionary<FovInfo, ProcGrabImageManager> _ProcGrabImageManagers
|
|
= new Dictionary<FovInfo, ProcGrabImageManager>();
|
|
/// <summary>
|
|
/// 공정 Fixture 패턴 저장
|
|
/// </summary>
|
|
private static Dictionary<FovInfo, PatternResult> _FixturePatternResults
|
|
= new Dictionary<FovInfo, PatternResult>();
|
|
|
|
#region Grab Image (조명 값이 동일할 경우 그랩을 스킵하는 용도)
|
|
/// <summary>
|
|
/// 등록 패턴의 조명 값이 마지막 조명 값과 동일한지 체크 (그랩 생략을 위함)
|
|
/// </summary>
|
|
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; // 조명 값이 같아서 그랩을 새로 안해도 됨
|
|
}
|
|
|
|
/// <summary>
|
|
/// 그랩 완료 여부를 체크한다.
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
/// <param name="lightInfo">조명 값</param>
|
|
/// <returns>그랩 완료 여부</returns>
|
|
public static bool IsProcGrabDone(FovInfo fovInfo, LightInfo lightInfo) {
|
|
var procGrabImageManager = GetProcGrabImageManager(fovInfo);
|
|
return procGrabImageManager.IsGrabDone(lightInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 그랩 완료된 공정 이미지를 등록한다.
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
/// <param name="lightInfo">조명 값</param>
|
|
/// <param name="image">공정 그랩 이미지</param>
|
|
public static void SetProcGrabImage(FovInfo fovInfo, LightInfo lightInfo, object image) {
|
|
var procGrabImageManager = GetProcGrabImageManager(fovInfo);
|
|
procGrabImageManager.SetGrabImage(lightInfo, image);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 그랩 완료된 공정 이미지를 얻어온다.
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
/// <param name="lightInfo">조명 값</param>
|
|
/// <returns>공정 이미지</returns>
|
|
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];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 공정 이미지들을 정리한다.
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
public static void ClearProcGrabImage(FovInfo fovInfo) {
|
|
var procGrabImageManager = GetProcGrabImageManager(fovInfo);
|
|
procGrabImageManager.Clear();
|
|
}
|
|
#endregion
|
|
|
|
#region Fixture Pattern
|
|
/// <summary>
|
|
/// Fixture 패턴의 검출 결과를 등록한다.
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
/// <param name="patternResult">패턴 검출 결과</param>
|
|
public static void SetFixturePatternResult(FovInfo fovInfo, PatternResult patternResult) {
|
|
if (!_FixturePatternResults.ContainsKey(fovInfo)) {
|
|
lock (_Lock) {
|
|
_FixturePatternResults.Add(fovInfo, patternResult);
|
|
}
|
|
}
|
|
else {
|
|
lock (_Lock) {
|
|
_FixturePatternResults[fovInfo] = patternResult;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fixture 패턴의 검출 결과를 얻어온다.
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
/// <returns>Fixture 패턴의 검출 결과</returns>
|
|
public static PatternResult GetFixturePatternResult(FovInfo fovInfo) {
|
|
if (_FixturePatternResults.ContainsKey(fovInfo)) {
|
|
return _FixturePatternResults[fovInfo];
|
|
}
|
|
else {
|
|
_Logger.FuncE("FixturePatternResult is null.");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fixture 패턴의 검출 결과를 정리한다.
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
/// </summary>
|
|
public static void ClearFixturePatternResult(FovInfo fovInfo) {
|
|
if (_FixturePatternResults.ContainsKey(fovInfo)) {
|
|
_FixturePatternResults.Remove(fovInfo);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Clear Images & Fixture Patterns
|
|
/// <summary>
|
|
/// 곻정 이미지, 패턴 정보 초기화
|
|
/// </summary>
|
|
/// <param name="subSysInfo">서브시스템 정보</param>
|
|
public static void Clear(SubSysInfo subSysInfo) {
|
|
lock (_Lock) {
|
|
foreach (var fovInfo in VisionRecipeManager.GetFovInfos(subSysInfo)) {
|
|
ClearProcGrabImage(fovInfo);
|
|
ClearFixturePatternResult(fovInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 곻정 이미지, 패턴 정보 초기화
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
public static void Clear(FovInfo fovInfo) {
|
|
lock (_Lock) {
|
|
ClearProcGrabImage(fovInfo);
|
|
ClearFixturePatternResult(fovInfo);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public static List<PatternResult> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 패턴 검출 결과의 이미지 좌표를 자재 좌표로 변환한다.
|
|
/// </summary>
|
|
/// <param name="calibrator">캘리브레이터 디바이스</param>
|
|
/// <param name="imageSize">이미지 사이즈 정보</param>
|
|
/// <param name="patternResult">패턴 검출 결과</param>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 강제 OK 이벤트 발생시키고 강제 OK 결과를 가져온다.
|
|
/// </summary>
|
|
/// <param name="forceOkReqParam">강제 OK 요청 파라미터</param>
|
|
/// <returns>강제 OK 패턴 검출 결과</returns>
|
|
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;
|
|
}
|
|
}
|
|
}
|