using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aurora.Api; using AuroraLaserScanner; using Matrox.MatroxImagingLibrary; using MilCommon; using VisionCommon; using WeldingCommon.Alarm; using WeldingCommon.Data; using WeldingCommon.Settings; using WeldingCommon.Sequences; using WeldingCommon.Utils; using WeldingCommon; using System.Threading; namespace ILSOS_PrismaticScanner.Sequences { class SeqEventQTest { static readonly Logger Log = new Logger("SeqAutoRunPrismaticScanner"); #region 시퀸스 변수명 const string SEQ_ENTER = "SEQ_ENTER"; // inputParam 으로 받자. const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; // Check Init Condition const string SEQ_CHECK_SEQ_FINISH = "Check Seq Finish"; const string SEQ_MOVE_SCANNER = "Move Scanner"; const string SEQ_SEND_EVENT_SENDER = "Event Sender"; // Image Q 저장 const string SEQ_EVENT_Q_SAVE_FILE = "EventQ Save File"; const string SEQ_SAVE_IMAGES = "Save Images"; const string SEQ_COMPLETE = "Complete"; #endregion #region 변수 정의 // 디바이스 정의 private Scanner _Scanner; // 비전 정의 private CameraAgentBase _CameraAgent; private ICameraDisplay _CameraDisplay; private PatternAgentBase _PatternAgent; private PatternInfo _PatternInfo; private PatternResult _PatternResult; private FieldScanParams _FieldScanParams; private object _GrabImage; private MIL_ID _GrabImageMilId; private MIL_ID _ResultImageMilId; private bool _SuccessVisionCompension = false; private int _SeqCount = 0; private int _RetryCount = 0; private double _OffsetXfromModelFinder = 0; private double _OffsetYfromModelFinder = 0; // 시스템 및 용접 파라미터 정의 private SystemParameter _SystemParameter; private static SequenceSetting _SequenceSetting; public string EVENT_TRIGGER_SAVE_FILE = "EventTriggerSaveFile"; #endregion public SequenceBuilder Builder() { var sb = new SequenceBuilder(1000, true); ////var sb = new SequenceBuilder(1000, false); // With log sb.AddAction(SEQ_ENTER, Sequence_Enter); sb.AddDecision(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); //분기 ///// PLC_USE_PAGE_CHANGE_INTERFACE sb.AddDecision(SEQ_CHECK_SEQ_FINISH, CheckSeqFinish); sb.AddAction(SEQ_MOVE_SCANNER, MoveScanner); ///// Event Q sb.AddEventSender(SEQ_SEND_EVENT_SENDER, SendEvent); sb.AddEventQ(SEQ_EVENT_Q_SAVE_FILE, 2); sb.AddAction(SEQ_SAVE_IMAGES, SaveImagesEvent); sb.AddAction(SEQ_COMPLETE, Complete); // [Action] 초기 세팅 sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] // [Decision] SEQ 끝낼지 고민된다면 ! > sb[SEQ_CHECK_SEQ_FINISH] > sb[SEQ_MOVE_SCANNER] > sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_CHECK_SEQ_FINISH]); // Scout Image Save Event Seq sb.Flows(sb[SEQ_EVENT_Q_SAVE_FILE].On(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_SAVE_IMAGES]>sb.FlowFinal); // Complete sb.Flows(sb[SEQ_CHECK_SEQ_FINISH] > sb[SEQ_COMPLETE]>sb.Final); ///// Fork2 & Join sb.OnForceError(OnForceError); sb.OnStopped(OnStopped); //sb.Draw("SeqEventQ.pdf"); return sb; } private void OnStopped(SequenceContext context) { Log.I("SeqEventQ Stop"); } private void OnForceError(SequenceContext context, string arg2) { Log.I("SeqEventQ Force Error"); } private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) { Log.I("SeqEventQ Start"); _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); _SequenceSetting = context.GetSetting(CommonSettingIds.Sequence); _Scanner = context.GetLaserScanner(); if (!_Scanner.IsActivated) { AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_DeviceNotReady); Log.E("The devices are not active."); return null; } if (InitSequenceVariable(context) == false) { AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError); return null; } return SequenceAction.Ok(); } private bool InitSequenceVariable(SequenceContext context) { // TODO: [장비구현필요] Initialize Variable 추가 FovInfo _fovInfo = VisionRecipeManager.GetFovInfos().FirstOrDefault(); _PatternAgent = FovPatternAgentManager.GetAgent(_fovInfo.ToSubSysInfo()); List patterns = _PatternAgent.GetMainPatterns(_fovInfo); _PatternInfo = patterns[0]; _CameraDisplay = CameraDisplayManager.GetDisplay(_fovInfo, eDisplayType.Pattern); _CameraAgent = CameraAgentManager.GetCameraAgent(_fovInfo); _FieldScanParams = FieldScanParams.GetInstance(); _RetryCount = 3; _SeqCount = 0; var mainPage = CommonHelper.GetMainPage(); return true; } private string CheckInitCondition(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { return SEQ_CHECK_SEQ_FINISH; } private string CheckSeqFinish(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { if (_SeqCount > 20) return SEQ_COMPLETE; else return SEQ_MOVE_SCANNER; } private SequenceActionResult MoveScanner(SequenceContext context, string id, SequenceActionResult param) { if (_SeqCount % 2 == 1) _Scanner.JumpAbs(1, 5); else _Scanner.JumpAbs(-10, 5); Thread.Sleep(20); //// 테스트를 위한 변경 /// ClearAllGraphic으로 변경하였음. GC는 종종 생성해보임. _CameraDisplay.ClearMeasureGraphics(); _CameraDisplay.ClearTrainGraphics(); _CameraDisplay.ClearFindGraphics(); object image = null; Log.D($"Image Grab Start"); _CameraAgent.StopLive(); _CameraAgent.GrabSync(_CameraDisplay, ref image); Log.D($"Image Grab Complete"); Log.D($"Pattern Find Start"); _PatternResult = _PatternAgent.Find(_PatternInfo, image, _CameraDisplay); _PatternAgent.Draw(_PatternInfo, _PatternResult, _CameraDisplay); if (_PatternResult.Status == eFoundStatus.FoundOK) { _PatternAgent.Draw(_PatternInfo, _PatternResult, _CameraDisplay); _SuccessVisionCompension = true; Log.D($"Pattern Find Success!!"); } else { _SuccessVisionCompension = false; } Log.D($"Pattern Find Complete"); // 성공하든 아니든 이미지를 남겨보자. MIL_ID temp1 = MilEnvironment.CloneImage((MIL_ID)image); MIL_ID temp2 = MilEnvironment.GetOverlayImage((IMilCameraDisplay)_CameraDisplay, temp1); // Event로 넘겨줄 Param은 따로 없음. SeqVisionData_Param seqParam = new SeqVisionData_Param { originalImageID = temp1, overlayImageID = temp2, IsSuccess = _SuccessVisionCompension , VisionData_Foler = _SequenceSetting.VisionFolderName }; return SequenceAction.Ok(seqParam); } private object SendEvent(SequenceContext context, string id, SequenceActionResult param) { var seqInfoParam = param.Param as SeqVisionData_Param; _SeqCount++; return seqInfoParam; } private SequenceActionResult SaveImagesEvent(SequenceContext context, string id, SequenceActionResult param) { SeqVisionData_Param seqParam = param.Param as SeqVisionData_Param; string SequenceSettingFilePath = seqParam.VisionData_Foler; string SuccessStatus = seqParam.IsSuccess ? "OK" : "NG"; string CurrentTimeStamp = DateTime.Now.ToString("yyMMdd-HHmmss_fff"); string rawFileName = $"{SequenceSettingFilePath}\\Raw\\{SuccessStatus}\\{CurrentTimeStamp}.png"; string resultFileName = $"{SequenceSettingFilePath}\\Result\\{SuccessStatus}\\{CurrentTimeStamp}.png"; if (seqParam.originalImageID != MIL.M_NULL) { ImageUtil.SaveFieldScanImageJPG(seqParam.originalImageID, rawFileName, 10); Log.D($"Update Q Raw Image Complete;{rawFileName}"); MilEnvironment.FreeImage(seqParam.originalImageID); seqParam.originalImageID = MIL.M_NULL; } else { Log.E($"Update Q Raw Image Failed;{rawFileName};rawImage Is Null.."); } if (seqParam.overlayImageID != MIL.M_NULL) { ImageUtil.SaveFieldScanImageJPG(seqParam.overlayImageID, resultFileName, 10); Log.D($"Update Q Overlay Image Complete;{resultFileName}"); MilEnvironment.FreeImage(seqParam.overlayImageID); seqParam.overlayImageID = MIL.M_NULL; } else { Log.E($"Update Q Overlay Image Failed;{resultFileName};resultImage Is Null"); } return SequenceAction.Ok(); } private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param) { return SequenceAction.Ok(); } public class SeqVisionData_Param { public MIL_ID originalImageID; public MIL_ID overlayImageID; public bool IsSuccess; public string VisionData_Foler; } } }