using Aurora.Api; using VisionCalibrator; using VisionCommon; using System.Collections.Generic; using VisionSequence.Camera; using System.Linq; using System.Windows.Documents; using Aurora.View; using System; namespace VisionSequence.Pattern { /// /// 카메라 그랩, 패턴 검출 시퀀스 파라미터 /// public class GrabFindSeqParams : GrabFindProcSeqParams { /// /// 생성자 /// /// FOV 키 정보 /// 패턴 정보 /// 메인 화면 타입 /// 시퀀스 모드 public GrabFindSeqParams( FovInfo fovInfo, PatternInfo patternInfo, eDisplayType displayType = eDisplayType.Main_1, eSeqMode seqMode = eSeqMode.Auto) : base(fovInfo, patternInfo, displayType, seqMode) { } } /// /// 카메라 그랩, 패턴 검출 시퀀스 /// public class GrabFindSeq : SubSeqBase { private readonly Logger _Logger; private TactTimeChecker _TactTimeChecker; private GrabFindSeqParams _Params; private FovRecipe _FovRecipe; private PatternAgentBase _PatternAgent; private Calibrator _Calibrator; private CameraAgentBase _CameraAgent; private ICameraDisplay _CameraDisplay; private ImageManager _ImageManager = new ImageManager(); private string _SeqName; // Get Context Key Values - Align에서 사용 할 때만 적용 private ProcParams _ProcParams; #region Sequence Id private const string SEQ_ID_INIT = "INIT"; private const string SEQ_ID_SET_GRAB_MAIN_SEQ_PARAMS = "SET_GRAB_MAIN_SEQ_PARAMS"; private const string SEQ_ID_GRAB_MAIN_SEQ = "GRAB_MAIN_SEQ"; private const string SEQ_ID_FIND_MAIN = "FIND_MAIN"; private const string SEQ_ID_CHECK_MAIN_FOUND = "CHECK_MAIN_FOUND"; private const string SEQ_ID_LIGHT_RETRY = "LIGHT_RETRY"; private const string SEQ_ID_FORCE_OK = "FORCE_OK"; private const string SEQ_ID_UPDATE_UI = "UPDATE_UI"; private const string SEQ_ID_SAVE_IMAGE = "SAVE_IMAGE"; private const string SEQ_ID_SEQ_COMPLETE = "SEQ_COMPLETE"; #endregion /// /// 생성자 /// public GrabFindSeq() { _Logger = new Logger($"{GetType().Name}"); } private void SetActions(SequenceBuilder sb) { var grabMainSeqBuilder = SubSeqManager.CreateSubSeqBuilder(new GrabSeq(), "GrabSeq"); sb.AddAction(SEQ_ID_INIT, Init); sb.AddAction(SEQ_ID_SET_GRAB_MAIN_SEQ_PARAMS, SetGrabMainSeqParams); sb.AddSubsequence(SEQ_ID_GRAB_MAIN_SEQ, grabMainSeqBuilder); sb.AddAction(SEQ_ID_FIND_MAIN, FindMain); sb.AddDecision(SEQ_ID_CHECK_MAIN_FOUND, CheckMainFound); sb.AddDecision(SEQ_ID_LIGHT_RETRY, LightRetry); sb.AddAction(SEQ_ID_FORCE_OK, ForceOK); sb.AddAction(SEQ_ID_UPDATE_UI, UpdateUI); sb.AddAction(SEQ_ID_SAVE_IMAGE, SaveImage); sb.AddAction(SEQ_ID_SEQ_COMPLETE, SeqComplete); } public override SequenceBuilder Builder(string seqName) { _SeqName = seqName; _TactTimeChecker = new TactTimeChecker(_SeqName); SequenceBuilder sb = new SequenceBuilder(1000); SetActions(sb); sb.OnStopped(OnStopped); sb.OnForceError(OnForceError); sb.Flows( sb.Init > sb[SEQ_ID_INIT] > sb[SEQ_ID_SET_GRAB_MAIN_SEQ_PARAMS] > sb[SEQ_ID_GRAB_MAIN_SEQ] > sb[SEQ_ID_FIND_MAIN] > sb[SEQ_ID_CHECK_MAIN_FOUND] > sb[SEQ_ID_UPDATE_UI] > sb[SEQ_ID_SAVE_IMAGE] > sb[SEQ_ID_SEQ_COMPLETE] > sb.Final ); sb.Flows( sb[SEQ_ID_CHECK_MAIN_FOUND] // Light Retry > sb[SEQ_ID_LIGHT_RETRY] > sb[SEQ_ID_SET_GRAB_MAIN_SEQ_PARAMS] ); sb.Flows( sb[SEQ_ID_LIGHT_RETRY] // Light Retry 모두 실패 > sb[SEQ_ID_FORCE_OK] ); sb.Flows( sb[SEQ_ID_CHECK_MAIN_FOUND] // Main Not Found > sb[SEQ_ID_FORCE_OK] ); sb.Flows( sb[SEQ_ID_FORCE_OK] > sb[SEQ_ID_UPDATE_UI] ); #if SEQ_DRAW sb.Draw($"{GetType().Name}.pdf"); #endif return sb; } private SequenceActionResult Init(SequenceContext context, string id, SequenceActionResult param) { if (param.Param != null) { _Params = param.Param as GrabFindSeqParams; context.TryGetValue(string.Format(VisionContextKeys.CNTXT_KEY_ALIGN_PROC_PARAMS, _Params.FovInfo.ToSubSysInfo()), out _ProcParams); } else { _Logger.E($"_Params is null."); return null; } _FovRecipe = VisionRecipeManager.GetFovRecipe(_Params.FovInfo); SetLightRetry(); SetPatternAgent(); SetCalibrator(); SetCameraAgent(); SetDisplay(); return SequenceAction.Ok(); } private void SetPatternAgent() { var patternIndex = _Params.PatternInfo.GetPatternIndex(); if (patternIndex is FovPatternIndex) { _PatternAgent = FovPatternAgentManager.GetAgent(_Params.FovInfo.ToSubSysInfo()); } else if (patternIndex is CamPatternIndex) { var camPatternIndex = patternIndex as CamPatternIndex; _PatternAgent = CamPatternAgentManager.GetAgent(camPatternIndex.CamId); } } private void SetCalibrator() { _Calibrator = CalibratorManager.GetCalibrator(_Params.FovInfo); } private void SetCameraAgent() { _CameraAgent = CameraAgentManager.GetCameraAgent(_Params.FovInfo); } private void SetDisplay() { _CameraDisplay = CameraDisplayManager.GetDisplay(_Params.FovInfo, _Params.DisplayType); } private SequenceActionResult SetGrabMainSeqParams(SequenceContext context, string id, SequenceActionResult param) { return SequenceAction.Ok( new GrabSeqParams(_Params.FovInfo, _Params.PatternInfo, _Params.DisplayType, _Params.SeqMode)); } private SequenceActionResult FindMain(SequenceContext context, string id, SequenceActionResult param) { var grabImage = context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_GRAB_IMAGE, _Params.FovInfo.GetKey())); var mainPatternResult = _PatternAgent.Find(_Params.PatternInfo, grabImage, _CameraDisplay); GrabFindSeqUtil.TransformCoord(_Calibrator, _CameraAgent.GetImageSize(), ref mainPatternResult); _PatternAgent.Draw(_Params.PatternInfo, mainPatternResult, _CameraDisplay, isFixturePattern: false); //_CameraDisplay.DrawRefCross(); mainPatternResult.PatternName = _Params.PatternInfo.PatternName; mainPatternResult.PatternType = _Params.PatternInfo.PatternType; mainPatternResult.FovId = _Params.FovInfo.FovId; context.PutValue(string.Format(VisionContextKeys.CNTXT_KEY_PATTERN_RESULT, _Params.FovInfo.GetKey()), mainPatternResult); return SequenceAction.Ok(); } private string CheckMainFound(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { var mainPatternResult = context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_PATTERN_RESULT, _Params.FovInfo.GetKey())); if (mainPatternResult.Status == eFoundStatus.FoundOK) { return SEQ_ID_UPDATE_UI; } else { if (_ProcParams != null && _ProcParams.LightRetryParams.LightRetryEnabled) { return SEQ_ID_LIGHT_RETRY; } else { return SEQ_ID_FORCE_OK; } } } private string LightRetry(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { if (_OriginalLightInfo == null) { _OriginalLightInfo = _Params.PatternInfo.LightInfo.Clone(); } _CurLightRetryCnt++; if (_CurLightRetryCnt <= _ProcParams.LightRetryParams.LightRetryCount) { var lightParams = _Params.PatternInfo.LightInfo.LightParams; var lightLevelMsg = string.Empty; for (int i = 0; i < lightParams.Count; i++) { var lightParam = lightParams[i]; lightParam.Level = IsLightRetryStepMode(_ProcParams.LightRetryParams.LightRetryMode) ? Convert.ToInt16(GetLightRetryValueStepMode(_CurLightRetryCnt, lightParam.Level, _ProcParams.LightRetryParams)) : Convert.ToInt16(GetLightRetryValueRatioMode(_CurLightRetryCnt, lightParam.Level, _OriginalLightInfo.LightParams[i].Level, _ProcParams.LightRetryParams)); lightLevelMsg += $"[{i} | {lightParam.Level}] "; } PrintLogAndShowToast(_Logger, $"[{_Params.FovInfo.SubSysName}][{_Params.FovInfo.FovName}] " + $"Grab retried at light step {_ProcParams.LightRetryParams.LightRetryStep}." + $"Mode is {_ProcParams.LightRetryParams.LightRetryMode.ToString()}. " + $"{lightLevelMsg} [{_CurLightRetryCnt}/{_ProcParams.LightRetryParams.LightRetryCount}]"); return SEQ_ID_SET_GRAB_MAIN_SEQ_PARAMS; // 조명 Retry 시도 } _Params.PatternInfo.LightInfo = _OriginalLightInfo.Clone(); // 기존 조명 원복 return SEQ_ID_FORCE_OK; // 조명 Retry 모두 실패시, 강제 OK 시도 } private SequenceActionResult ForceOK(SequenceContext context, string id, SequenceActionResult param) { if (_ProcParams != null && _ProcParams.ForceOkEnabled && PatternConstants.IsForceOkSupport(_Params.PatternInfo.PatternType)) { var patternResult = context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_PATTERN_RESULT, _Params.FovInfo.GetKey())); patternResult = GrabFindSeqUtil.DoForceOk(new ForceOkReqParam( _Params.FovInfo, patternResult.PatternIndex, context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_GRAB_IMAGE, _Params.FovInfo.GetKey())), patternResult)); if (patternResult.Status == eFoundStatus.FoundOK || patternResult.Status == eFoundStatus.ForceOK) { _CameraDisplay.ClearMeasureGraphics(); GrabFindSeqUtil.TransformCoord(_Calibrator, _CameraAgent.GetImageSize(), ref patternResult); DrawForceOkResult(patternResult); context.PutValue(string.Format(VisionContextKeys.CNTXT_KEY_PATTERN_RESULT, _Params.FovInfo.GetKey()), patternResult); } } return SequenceAction.Ok(); } private void DrawForceOkResult(PatternResult patternResult) { _PatternAgent.Draw(_Params.PatternInfo, patternResult, _CameraDisplay, isFixturePattern: false); var result = patternResult.Results.ToList()[0]; eColor color = eColor.Red; _CameraDisplay.AddCross(new Cross(result.ImagePosition, 80), color); } private SequenceActionResult UpdateUI(SequenceContext context, string id, SequenceActionResult param) { var mainPatternResult = context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_PATTERN_RESULT, _Params.FovInfo.GetKey())); VisionEnv.AuroraEnv.EventPublisher.Publish( new EventMessage(_Params.FovInfo.GetKey(), VisionEventId.UPDATE_PATTERN_RESULT, mainPatternResult)); return SequenceAction.Ok(); } private SequenceActionResult SaveImage(SequenceContext context, string id, SequenceActionResult param) { var grabImage = context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_GRAB_IMAGE, _Params.FovInfo.GetKey())); var mainPatternResult = context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_PATTERN_RESULT, _Params.FovInfo.GetKey())); var materialInfo = context.GetValue(VisionContextKeys.CNTXT_KEY_MATERIAL_INFO); if (mainPatternResult.Status == eFoundStatus.FoundOK) { if (VisionSettingManager.VisionSetting.SaveOkImage == false) { return SequenceAction.Ok(); } } _ImageManager.SaveImage(_Params.FovInfo, grabImage, mainPatternResult.Status.ToString(), materialInfo); return SequenceAction.Ok(); } private SequenceActionResult SeqComplete(SequenceContext context, string id, SequenceActionResult param) { var mainPatternResult = context.GetValue(string.Format(VisionContextKeys.CNTXT_KEY_PATTERN_RESULT, _Params.FovInfo.GetKey())); _TactTimeChecker.Stop(TactTimeType.ProcSeq, "Light/Grab/Find"); return SequenceAction.Ok(mainPatternResult); } void OnStopped( SequenceContext context) { _Logger.I($"{context.SequenceId} - STOP Handler"); HandleAbnormalFinish(context); } void OnForceError( SequenceContext context, string id) { _Logger.E($"{context.SequenceId} - FORCE ERROR Handler"); HandleAbnormalFinish(context); } void HandleAbnormalFinish( SequenceContext context) { _TactTimeChecker.Stop(TactTimeType.ProcSeq, "Light/Grab/Find"); if (_Params != null && _OriginalLightInfo != null) _Params.PatternInfo.LightInfo = _OriginalLightInfo.Clone(); // 기존 조명 원복 ( 방어코드 ) } } }