diff --git a/Machines/ILSOS_KS/Sequences/SeqAutoRunKS.cs b/Machines/ILSOS_KS/Sequences/SeqAutoRunKS.cs index 2788130..7f17e55 100644 --- a/Machines/ILSOS_KS/Sequences/SeqAutoRunKS.cs +++ b/Machines/ILSOS_KS/Sequences/SeqAutoRunKS.cs @@ -2280,7 +2280,7 @@ namespace ILSOS_KS.Sequences string LBADSendBcrId = _BcrID; if (LBADSendBcrId == "" || LBADSendBcrId.Equals(null)) - LBADSendBcrId = T1.ToString("HH:mm:ss"); + LBADSendBcrId = T1.ToString("HHmmss"); // 바코드가 안 읽히면 임의 값 보내기 int sendresult = _LBAD.SendCellData("LBM" + s1, LBADSendBcrId, recipeNo, _ModelNo); @@ -2293,7 +2293,7 @@ namespace ILSOS_KS.Sequences string LBADSendBcrId = _BcrID; if (LBADSendBcrId == "" || LBADSendBcrId.Equals(null)) - LBADSendBcrId = T1.ToString("HH:mm:ss"); + LBADSendBcrId = T1.ToString("HHmmss"); // PLC 에 바코드 값이 있으면 int sendresult = _LBAD.SendCellData("LBM" + s1, LBADSendBcrId, recipeNo, _ModelNo); @@ -3241,7 +3241,8 @@ namespace ILSOS_KS.Sequences if (result == E1.OK) { - stReceiveData tt = ResultList[0]; + Log.I($"before Clear >> Result Item Count[{ResultList.Count}]"); + stReceiveData tt = ResultList.Last(); // fixed double 배열에 접근하기 위해 unsafe 블록 사용 unsafe { @@ -3295,8 +3296,9 @@ namespace ILSOS_KS.Sequences judgeFlag = 3; judgeResult = "NG"; } - _LBAD.ClearResultDataList(); + Log.I($"after Clear >> Result Item Count[{ResultList.Count}]"); + // 경신 페이지 추가하여 검사 내용 추가 //LBADResultPage[_PageNo - 1] = judgeFlag; @@ -3415,15 +3417,15 @@ namespace ILSOS_KS.Sequences List recipe = Get_Recipe_Info(); // Recipe : 9 WeldingInfoSendPLC(recipe, StepLBAD, StepWELDING); - if (strLBADJudge == "4" || StepWELDING.Contains("NG")) + if (Status.GetProcessingWeldingData().LBAD_Judge == "4" || StepWELDING.Contains("NG")) { _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, true); - Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG True, LBAD Result : {strLBADJudge}")); + Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG True, LBAD Result : {Status.GetProcessingWeldingData().LBAD_Judge}")); } - else if (strLBADJudge != "4") + else if (Status.GetProcessingWeldingData().LBAD_Judge != "4" || recipeRequestId == 21) { _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, true); - Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK True, LBAD Result : {strLBADJudge}")); + Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK True, LBAD Result : {Status.GetProcessingWeldingData().LBAD_Judge}")); } bool[] Page = new bool[4]; @@ -3512,7 +3514,7 @@ namespace ILSOS_KS.Sequences DateTime T1 = DateTime.Now; string LBADSendBcrId = _BcrID; if (LBADSendBcrId == "" || LBADSendBcrId.Equals(null)) - LBADSendBcrId = T1.ToString("HH:mm:ss"); + LBADSendBcrId = T1.ToString("HHmmss"); Status.GetProcessingWeldingData().CellId = LBADSendBcrId; } diff --git a/Machines/ILSOS_KS/Sequences/SeqAutoRunKS.cs.bak b/Machines/ILSOS_KS/Sequences/SeqAutoRunKS.cs.bak deleted file mode 100644 index f96b250..0000000 --- a/Machines/ILSOS_KS/Sequences/SeqAutoRunKS.cs.bak +++ /dev/null @@ -1,2806 +0,0 @@ -using Aurora; -using Aurora.Api; -using Aurora.Api.Control; -using Aurora.Api.Devices; -using Aurora.Api.Manager; -using Aurora.Util.HislogPlus; -using Aurora.View; -using AuroraCellTracker; -using AuroraIO; -using AuroraLaser; -using AuroraLaserScanner; -using AuroraLBAD; -using AuroraLBAD.Service; -using AuroraOCT; -using AuroraPLC; -using CoreUnit.Control.UserControl.Canvas; -using CoreUnit.Scanner.UserControl.ScannerCanvas; -using DB; -using DB.Recipe; -using ExcelImageHelper; -using Hermes; -using ILSOS_KS.Models; -using ILSOS_KS.RMS; -using ILSOS_KS.Views.Dialog; -using ILSOS_KS.Views.PopUP; -using Matrox.MatroxImagingLibrary; -using MilUI; -using NPOI.Util; -using OpenCvSharp; -using OpenCvSharp.Dnn; -using OpenCvSharp.Text; -using OpenCvSharp.WpfExtensions; -using System; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Configuration; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Linq.Expressions; -using System.Runtime.InteropServices.ComTypes; -using System.Runtime.Remoting.Contexts; -using System.Runtime.Remoting.Metadata.W3cXsd2001; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls.Primitives; -using System.Windows.Forms; -using System.Windows.Forms.VisualStyles; -using System.Windows.Media.Imaging; -using System.Xml.Linq; -using VisionCommon; -using WeldingCommon; -using WeldingCommon.Alarm; -using WeldingCommon.Data; -using WeldingCommon.Devices; -using WeldingCommon.Recipes; -using WeldingCommon.Sequences; -using WeldingCommon.Settings; -using WeldingCommon.Utils; -using WeldingCommon.Views; -using WeldingCommon.Vision.WeldingObjectGenerator; -//using System.Windows.Shapes; -using WeldingCommon.Vision.WeldingObjectGenerator.GeometryLibrary; -using WeldingCommon.Vision.WeldingObjectGenerator.PathEditorLibrary; -using static Aurora.Api.SequenceBuilder; -using static AuroraIO.AJINEXTEK.AjinIO.IOModuleInfo; -using static AuroraLBAD.Service.StreamLightLBAD; -using static AuroraLBAD.Services.StreamLBADClient; -using static ILSOS_KS.Device.IOController_KS; -using static ILSOS_KS.Device.PLCControllerKS; -using Application = System.Windows.Application; -using Path = System.IO.Path; -using Point = OpenCvSharp.Point; -using SystemParameter = WeldingCommon.Settings.SystemParameter; - -namespace ILSOS_KS.Sequences -{ - class SeqAutoRunKS - { - static readonly Logger Log = new Logger("SeqAutoRunKS_New"); - - const string SEQ_ENTER = "[SeqAutoRunKS] SEQ_ENTER"; // inputParam 으로 받자. - const string SEQ_CHECK_INIT_CONDITION = "[SeqAutoRunKS] Check Init Condition"; // Check Init Condition - - // ADD jmj -> 메인페이지 레시피 넘버 확인하여 PLC에 전송후 메칭 확인 - // Page 번호 가져오기. - const string SEQ_CHECK_PAGENO = "[SeqAutoRunKS] CHECK PageNo"; - - const string SEQ_CHECK_LOAD_COMPLETE = "[SeqAutoRunKS] Check Load Complete"; - - // 양선전 사전검사 로직 추가(용접후 검사 결과를 보고 하구 나서 양산 시작) - const string SEQ_KS_WAIT_VISION = "[SeqAutoRunKS] Ks Wait Vision"; - const string SEQ_KS_COMPLETE_VISION = "[SeqAutoRunKS] Ks Complete Vision"; - - //const string SEQ_MEASURE_CELL_POSITION = "[SeqAutoRunKS] Measure CellPosition"; - - const string SEQ_SET_SCOUT_FLYING_VISION_SEQ = "[SeqAutoRunKS] Set Sequence Param (ScoutFlyingVision Seq)"; - const string SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ = "[SeqAutoRunKS] Process (ScoutFlyingVision Seq)"; - const string SEQ_GET_SCOUT_FLYING_VISION_SEQ = "[SeqAutoRunKS] Get Sequence Result (ScoutFlyingVision Seq)"; - - const string SEQ_SET_SCOUT_NORMAL_VISION_SEQ = "[SeqRCCTeachingRun] Set Sequence Param (ScoutNormalVision Seq)"; - const string SEQ_DO_ID_SCOUT_NORMAL_VISION_SEQ = "[SeqRCCTeachingRun] Process (ScoutNormalVision Seq)"; - const string SEQ_GET_SCOUT_NORMAL_VISION_SEQ = "[SeqRCCTeachingRun] Get Sequence Result (ScoutNormalVision Seq)"; - - const string SEQ_SEND_EVENT_SENDER = "[SeqAutoRunKS] Event Sender"; - const string SEQ_EVENT_Q_SAVE_FILE = "[SeqAutoRunKS] EventQ Save File"; - const string SEQ_SAVE_SCOUT_IMAGE = "[SeqAutoRunKS] Save ScoutImage"; - - const string SEQ_FIND_EDGE = "[SeqAutoRunKS] Find Edge"; - const string SEQ_DECISION_RCC_ALGORITHM_TYPE = "[SeqAutoRunKS] Decision RCC Algorithm Type"; - const string SEQ_APPLY_OFFSET_OBJECT = "[SeqAutoRunKS] Apply Offset Object"; - const string SEQ_GENERATE_WELDING_OBJECT = "[SeqAutoRunKS] Generate WeldingObject"; - - const string SEQ_READY_SCANNER_LIST = "[SeqAutoRunKS] Ready ScannerList"; - const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunKS] Set Sequence Param (UploadWeldingList Seq)"; - const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunKS] Process (UploadWeldingList Seq)"; - const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunKS] Get Sequence Result (UploadWeldingList Seq)"; - - const string SEQ_WAIT_WELDING_START = "[SeqAutoRunKS] Wait Welding Start"; - - const string SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunKS] Set Sequence Param (ReceiveCellInfo Seq)"; - const string SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunKS] Process (ReceiveCellInfo Seq)"; - const string SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ = "[SeqAutoRunKS] Get Sequence Result (ReceiveCellInfo Seq)"; - - const string SEQ_EXECUTE_WELDING = "[SeqAutoRunKS] Execute Welding"; - const string SEQ_REQUEST_UNLOAD_CELL = "[SeqAutoRunKS] Request Unload Cell"; - const string SEQ_WAIT_LBAD_JUDGE = "[SeqAutoRunKS] Wait LBAD Judge"; - - //const string SEQ_SET_PARAMS_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunKS] Set Sequence Param (ReportCellResult Seq)"; - //const string SEQ_DO_ID_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunKS] Process (ReportCellResult Seq)"; - //const string SEQ_GET_RESULT_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunKS] Get Sequence Result (ReportCellResult Seq)"; - - const string SEQ_REPORT_CELLINFO_TO_PLC = "[SeqAutoRunKS] ReportCellInfoToPLC"; - const string SEQ_CHECK_CYCLE_STOP = "[SeqAutoRunKS] Check Cycle Stop"; - - const string SEQ_SAVE_RESULT_DATA = "[SeqAutoRunKS] Save Result Data"; - - const string SEQ_WRITE_COMPLETION_PLC_BIT = "[SeqAutoRunKS] Write Completion PLC Bit"; - const string SEQ_COMPLETE = "[SeqAutoRunKS] SEQ_COMPLETE"; // 완료 - - const string SEQ_BEFORE_WELD_MOVE_OBJECT = "[SeqAutoRunKS] Before Weld Move Object"; - const string SEQ_AFTER_WELD_CHECK_BEAD = "[SeqAutoRunKS] After Weld Check Bead"; - const string SEQ_CHECK_RCC_MODE = "[SeqAutoRunKS] Check RCC Mode"; - const string SEQ_CHECK_BEFORE_OR_AFTER = "[SeqRCCTeachingRun] Check before or after"; - - static class ContextKey - { - public const string KEY_SEQUENCE_RESULT = "KEY_SEQUENCE_RESULT_SeqAutoRunKS"; - public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqAutoRunKS"; - } - - const int PLC_TIMEOUT = 60; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다 - - private SeqAutoRunKS_New_InitParam _InitParam; - - private Scanner _Scanner; - private LaserDevice _Laser; - //private OCT _OCT; - private PLCController _PLC; - private IODevice _IO; - private LBAD _LBAD; - //private StreamLightLBAD _StreamLightLBAD; - private SystemParameter _SystemParameter; - private IRecipeManager _RecipeManager; - private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; //스캐너 동작관련 객체 선언 - - private FovRecipe _FovRecipe; - private CameraAgentBase _CameraAgent; - private ICameraDisplay _CameraDisplay; - private CamConfig _CamConfig; - - private eListNo _WeldingScannerListNo; - private List _SelectedDrawObjectList; - - private MIL_ID _GrabImage = MIL.M_NULL; - private ObjectGenerator _ObjGenerator; - private Mat _ConvMatImage; - private Mat _ConvMatImage_after; - - private Mat[] _WeldingImage = new Mat[4]; - - private uint _TodayProduct; - private uint _TotalProduct; - private uint _OCT_QA_ERROR_COUNT; - - private DateTime _AutoRunStartTime; - private DateTime _WeldingStartTime; - private TimeSpan _WeldingSpanTime; - private DateTime _WeldEndTime; - private TimeSpan _InterfaceSpanTime; - private DateTime _InterfaceStartTime; - - private string _LotId = "N/A"; - private string _CellId = "N/A"; - - private bool _IncludeListStartEnd = false; // ==> local - - private int _SeqRunCount; - - // For RCC - private List _GeneratedDrawObjects; - private List _RecipeDrawObjects; // ==> local - - private Stopwatch _StopwatchGenObj; - - private int _Radius_Pixel; - // End For RCC - - private int _ModelNo; - - private int _PageNo = 0; - private int _PageNoRcc = 0; - private string _BcrID; - - private bool _IsRealTimeScout; - private double _CellMeasureCenterOffsetX; - private double _CellMeasureCenterOffsetY; - - public string EVENT_TRIGGER_SAVE_FILE = "EventTriggerSaveFile"; - private UnitPoint _DetectedContourCenter; - private Point[][] _MaxContour; - private List _Polygon; - private List _Paths; - private List _SelectedArcs; - private bool pre_welding = true; - private List bead_result_info; //상위보고를 위한 비드 사이즈 저장 리스트 (OK:0, NG:1) - private List[] result_info = new List[4]; - // 경신 검수용 LBAD 검사 결과 OK,NG 반전 .. - bool weldingResult = false; - - eScoutType _ScoutType; - - int[] LBADResultPage = new int[4]; - - IPopupService popup; - - List arcList = new List(); - List lineList = new List(); - List splineList = new List(); - List dotList = new List(); - - string StepLBAD = ""; - string StepWELDING = ""; - - public SeqAutoRunKS() - { - var systemParameterks = Application.Current.AuroraEnv().SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter; - _ScoutType = systemParameterks.ScoutType; - - Application.Current.AuroraEnv().EventObservable.AsObservable("Pre_Test").Subscribe(OnPre_Test); - - string Path = System.IO.Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "RealTimeScout"); - AsyncLog.Init(Path); - - PopupService.Init(); - popup = PopupService.Instance; - } - - public SequenceBuilder Builder() - { - var sb = new SequenceBuilder(50000, true); - ////var sb = new SequenceBuilder(1000, false); // With log - - sb.AddAction(SEQ_ENTER, Sequence_Enter); - sb.AddDecision(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); //분기 - - sb.AddAction(SEQ_CHECK_PAGENO, CheckPageNo); - - sb.AddDecision(SEQ_CHECK_LOAD_COMPLETE, CheckLoadComplete); - - sb.AddAction(SEQ_KS_WAIT_VISION, KSWaitVisionSquence); - sb.AddAction(SEQ_KS_COMPLETE_VISION, KSCompleteVisionSquence); - - // RCC FlyingVision - sb.AddAction(SEQ_SET_SCOUT_FLYING_VISION_SEQ, SetScoutFlyingVision_SeqParams); - sb.AddSubsequence(SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ, SequenceManager.GetSeqBuilder_SeqScoutFlyingVision()); - sb.AddAction(SEQ_GET_SCOUT_FLYING_VISION_SEQ, GetScoutFlyingVision_SeqResult); - //sb.AddDecision(SEQ_GET_SCOUT_FLYING_VISION_SEQ, GetScoutFlyingVision_SeqResult); - - - - - sb.AddEventSender(SEQ_SEND_EVENT_SENDER, SendEvent); - sb.AddEventQ(SEQ_EVENT_Q_SAVE_FILE, 2); - sb.AddAction(SEQ_SAVE_SCOUT_IMAGE, SaveScoutImageEvent); - - sb.AddAction(SEQ_FIND_EDGE, FindEdge); - sb.AddDecision(SEQ_DECISION_RCC_ALGORITHM_TYPE, DecisionRCCAlgorithmType); - sb.AddAction(SEQ_APPLY_OFFSET_OBJECT, ApplyOffsetObejct); - sb.AddAction(SEQ_GENERATE_WELDING_OBJECT, GenerateWeldingObject); - - //Image Processing - sb.AddAction(SEQ_BEFORE_WELD_MOVE_OBJECT, BeforeWeldMoveObject); - sb.AddAction(SEQ_AFTER_WELD_CHECK_BEAD, AfterWeldCheckBead); - sb.AddDecision(SEQ_CHECK_RCC_MODE, CheckRCCMode); - sb.AddDecision(SEQ_CHECK_BEFORE_OR_AFTER, CheckBeforeOrAfter); - - - // ALL (Normal & RCC & CellCenterOffset) - sb.AddAction(SEQ_READY_SCANNER_LIST, ReadyScannerList); - sb.AddAction(SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ, SetUploadWeldingList_SeqParams); - sb.AddSubsequence(SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ, SequenceManager.GetSeqBuilder_SeqUploadWeldingList()); - sb.AddAction(SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ, GetUploadWeldingList_SeqResult); - - sb.AddAction(SEQ_WAIT_WELDING_START, WaitWeldingStart); - - sb.AddAction(SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ, SetReceiveCellInfo_SeqParams); - sb.AddSubsequence(SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ, SequenceManager.GetSeqBuilder_SeqReceiveCellInfo()); - sb.AddAction(SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ, GetReceiveCellInfo_SeqResult); - - sb.AddAction(SEQ_EXECUTE_WELDING, ExecuteWelding); - sb.AddAction(SEQ_REQUEST_UNLOAD_CELL, RequestUnloadCell); - sb.AddAction(SEQ_WAIT_LBAD_JUDGE, WaitLBADJudge); - - sb.AddAction(SEQ_REPORT_CELLINFO_TO_PLC, ReportCellInfoToPLC); - - sb.AddDecision(SEQ_CHECK_CYCLE_STOP, CheckCycleStop); - - sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함. - sb.AddAction(SEQ_WRITE_COMPLETION_PLC_BIT, WriteCompletionPLCBit); // 정상적으로 종료 되면, complete bit write - sb.AddAction(SEQ_COMPLETE, Complete); - - - sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] - > sb[SEQ_CHECK_PAGENO] - > sb[SEQ_CHECK_LOAD_COMPLETE] > sb[SEQ_READY_SCANNER_LIST] - > sb[SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ] - > sb[SEQ_WAIT_WELDING_START] - > sb[SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ] - > sb[SEQ_EXECUTE_WELDING] - > sb[SEQ_CHECK_RCC_MODE] - > sb[SEQ_REQUEST_UNLOAD_CELL] > sb[SEQ_WAIT_LBAD_JUDGE] - // 상위 보고 추가 해야된다. - //> sb[SEQ_SET_PARAMS_REPORT_CELL_RESULT_SEQ] > sb[SEQ_DO_ID_REPORT_CELL_RESULT_SEQ] > sb[SEQ_GET_RESULT_REPORT_CELL_RESULT_SEQ] - - > sb[SEQ_REPORT_CELLINFO_TO_PLC] > sb[SEQ_CHECK_CYCLE_STOP] - > sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_WRITE_COMPLETION_PLC_BIT] > sb[SEQ_COMPLETE]); - - // CellCenterOffset - //sb.Flows(sb[SEQ_CHECK_LOAD_COMPLETE] > sb[SEQ_MEASURE_CELL_POSITION] > sb[SEQ_READY_SCANNER_LIST]); - - - // RCC - sb.Flows(sb[SEQ_CHECK_LOAD_COMPLETE] - // RCC FlyingVision - > sb[SEQ_SET_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_GET_SCOUT_FLYING_VISION_SEQ] - > sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_CHECK_BEFORE_OR_AFTER] - > sb[SEQ_BEFORE_WELD_MOVE_OBJECT] > sb[SEQ_READY_SCANNER_LIST]); - - sb.Flows(sb[SEQ_CHECK_RCC_MODE] - // RCC FlyingVision - > sb[SEQ_SET_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_GET_SCOUT_FLYING_VISION_SEQ] - > sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_CHECK_BEFORE_OR_AFTER] - > sb[SEQ_AFTER_WELD_CHECK_BEAD] > sb[SEQ_REQUEST_UNLOAD_CELL]); - - // 사전 검사 프로세스 추가 - sb.Flows(sb[SEQ_CHECK_LOAD_COMPLETE] - > sb[SEQ_KS_WAIT_VISION] - //> sb[SEQ_SET_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_DO_ID_SCOUT_FLYING_VISION_SEQ] > sb[SEQ_GET_SCOUT_FLYING_VISION_SEQ] - //> sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_CHECK_BEFORE_OR_AFTER] > sb[SEQ_AFTER_WELD_CHECK_BEAD] - > sb[SEQ_KS_COMPLETE_VISION] - > sb[SEQ_CHECK_PAGENO]); - - - // Scout Image Save Event Seq - sb.Flows(sb[SEQ_EVENT_Q_SAVE_FILE].On(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_SAVE_SCOUT_IMAGE] > sb.FlowFinal); - - //sb.Flows(sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_CHECK_LOAD_COMPLETE]); - sb.Flows(sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_CHECK_PAGENO]); - - sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_COMPLETE] > sb.Final); - - - sb.OnStopped(OnStopped); - sb.OnForceError(OnForceError); - - - sb.Draw("SeqAutoRunKS_New.pdf"); - - //popup.Generation(); - - return sb; - } - - #region 양선전 사전검사 로직 추가(용접후 검사 결과를 보고 하구 나서 양산 시작) - private void OnPre_Test(EventMessage message) - { - Log.I("OnPre_Test"); - } - - private SequenceActionResult KSWaitVisionSquence(SequenceContext context, string id, SequenceActionResult param) - { - _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, true); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY True")); - - Thread.Sleep(200); - - _InterfaceStartTime = DateTime.Now; - while (!context.Stopped) - { - if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data) - { - Log.I(string.Format($"[PLCInterface]GET PLC_WELD_REQEUST True")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, true); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK True")); - - break; - } - - _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - { - Log.E("TIMEOUT_PLC_WELD_REQEUST"); - _InterfaceStartTime = DateTime.Now; - } - Thread.Sleep(10); - } - - Thread.Sleep(200); - - _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK False")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False")); - - return SequenceAction.Ok(); - } - private SequenceActionResult KSCompleteVisionSquence(SequenceContext context, string id, SequenceActionResult param) - { - _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, true); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE True")); - - Thread.Sleep(200); - - _InterfaceStartTime = DateTime.Now; - while (!context.Stopped) - { - if (_PLC.ReadBit((int)eBitInput.PLC_WELD_COMPLETE_ACK).data) - { - Log.I(string.Format($"[PLCInterface]GET PLC_WELD_COMPLETE_ACK True")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE False")); - break; - } - _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - { - Log.E("TIMEOUT_PLC_WELD_COMPLETE_ACK"); - _InterfaceStartTime = DateTime.Now; - } - Thread.Sleep(10); - } - - while (!context.Stopped) - { - // 다음 페이지용 PLC 읽기 - _PageNo = GetPagePlc(); - SetPagePlc(_PageNo); - - // 다음 시퀀스 대기.. - Thread.Sleep(100); - - if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data) - { - Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True")); - - bool[] Page = new bool[4]; - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - Log.I(string.Format("[PLCInterface]Pgae Reset")); - - //UpdatePLCMemoryArea((int)eWordOutput.PC_WeldingInspection1, bead_result_info); - - break; - } - else - { - if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data) - { - Log.I(string.Format($"[IOInterface]Get PLC_RESULT_REQUEST True")); - - //UpdatePLCMemoryArea((int)eWordOutput.PC_WeldingInspection2, bead_result_info); - - bool[] Page = new bool[4]; - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - Log.I(string.Format("[PLCInterface]Pgae Reset")); - - break; - } - - Thread.Sleep(100); - } - } - - return SequenceAction.Ok(); - } - #endregion - - #region 경신 용접 RCC 추가 - private string CheckRCCMode(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - { - _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); - if (_SystemParameter.SequenceType == eSequenceType.Normal) - { - return SEQ_REQUEST_UNLOAD_CELL; - } - else - { - - return SEQ_SET_SCOUT_FLYING_VISION_SEQ; - - } - } - private SequenceActionResult BeforeWeldMoveObject(SequenceContext context, string id, SequenceActionResult param) - { - - - MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage; - - //RCC Error로 인해 시퀀스를 종료하고 있는데, NG배출해야 될지 확인 필요 - _StopwatchGenObj = Stopwatch.StartNew(); - double dPixelResolution = ((_SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0; - - _ObjGenerator = new ObjectGenerator(dPixelResolution); - int arc_cnt = 6 * (_PageNoRcc / 2); - - _ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage); - //_ConvMatImage = Cv2.ImRead("D:\\RCC\\6_KS\\2025_7_3\\before1.PNG"); - - - //string baseDir = @"D:\ImagesTT"; - ////// 원본 이미지 저장 - //string origFileName = $"Before{_PageNoRcc}_{DateTime.Now:HHmmss}.png"; - //string origPath = Path.Combine(baseDir, origFileName); - //Cv2.ImWrite(origPath, _ConvMatImage); - - - // 4 Page 시퀀스 사용으로 spiral 페이지 사용시 RCC 사용안함 - if (_PageNoRcc % 2 == 1) - return SequenceAction.Ok(); - - _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); - var mainPage = WeldingRecipeManager.GetWeldingPage(); - _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; - UnitPoint offset = new UnitPoint(0, 0); - for (int i = 0; i < _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects.Count; i += 2) - { - int[] threshold_array = new int[] { _SystemParameter.CVThresholdCircle1, _SystemParameter.CVThresholdCircle2, _SystemParameter.CVThresholdCircle3, _SystemParameter.CVThresholdCircle4, _SystemParameter.CVThresholdCircle5, _SystemParameter.CVThresholdCircle6 }; - //if (_ScannerCanvasUserCtrl.Model.Layers[0].Objects.Count < 13) return; - //if (!(_ScannerCanvasUserCtrl.Model.Layers[0].Objects[12] is Spline)) return; - //if (((Spline)_ScannerCanvasUserCtrl.Model.Layers[0].Objects[12]).Center.Y < 0) - // threshold_array = new int[] { _SystemParameter.CVThresholdCircle2_1, _SystemParameter.CVThresholdCircle2_2, _SystemParameter.CVThresholdCircle2_3, _SystemParameter.CVThresholdCircle2_4, _SystemParameter.CVThresholdCircle2_5, _SystemParameter.CVThresholdCircle2_6 }; - FovInfo _FovInfo = VisionRecipeManager.GetFovInfos().FirstOrDefault(); - PatternAgentBase _PatternAgent = PatternAgentManager.GetAgent(_FovInfo); - var item = _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i]; - _ObjGenerator = new ObjectGenerator(dPixelResolution); - - if (item is Arc) - { - arc_cnt += 1; - var procPatternInfo = VisionRecipeManager.GetProcPatternInfo(_FovInfo, $"Arc{(_PageNoRcc / 2) + 1}_{arc_cnt - 6 * (_PageNoRcc/2)}", (eProcPatternId)arc_cnt - 1); - var patternInfo = _PatternAgent.GetPatternInfo(_FovInfo, procPatternInfo.PatternId); - UnitPoint center = ((Arc)item).Center; - double my_radius = ((Arc)item).Radius; - int roi_height = _PatternAgent.GetFindROI(patternInfo).Height; - int roi_width = _PatternAgent.GetFindROI(patternInfo).Width; - OpenCvSharp.Rect my_ROI = new OpenCvSharp.Rect((int)(center.X / dPixelResolution + _ConvMatImage.Width / 2 - roi_width / 2), (int)(_ConvMatImage.Height / 2 - center.Y / dPixelResolution - roi_height / 2), roi_width, roi_height); - Mat roi_img = new Mat(_ConvMatImage, my_ROI); - Cv2.CvtColor(roi_img, roi_img, ColorConversionCodes.GRAY2BGR); - Cv2.CvtColor(roi_img, roi_img, ColorConversionCodes.BGR2GRAY); - //MIL.MbufAllocColor(MilEnvironment.Instance.GetSystem(_cameraAgent._CamConfig.CamConnConfig.BoardSlotPos), 3, loadImg.Width, loadImg.Height, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_DISP + MIL.M_PROC, ref mil_roi_img); - MIL_ID mil_roi_img = _ObjGenerator.ConvertMatToMilID(roi_img); - - //MIL.MbufLoad($"D:/test_{arc_cnt}.png", mil_roi_img); - //Mat roi_img_img; - //_ObjGenerator.ConvertMILToMat(mil_roi_img, out roi_img_img); - //Cv2.ImWrite($"D:/test_convert_{arc_cnt}.png", roi_img_img); - Point2d found_center_pixel, found_center_pixel_mm; - var cameraDisplay = CameraDisplayManager.GetDisplay(_FovInfo, eDisplayType.Pattern) as CameraDisplay; - - PatternResult _PatternResult = _PatternAgent.Find(patternInfo, mil_roi_img, _CameraDisplay); - MIL.MbufFree(mil_roi_img); - if (_PatternResult.Status == eFoundStatus.FoundOK) - { - Log.W("Pattern is found."); - var resultsList = _PatternResult.Results.ToList(); - found_center_pixel = new Point2d(resultsList[0].ImagePosition.X + my_ROI.X, resultsList[0].ImagePosition.Y + my_ROI.Y); - found_center_pixel_mm = new Point2d((found_center_pixel.X - _ConvMatImage.Width / 2) * dPixelResolution, (_ConvMatImage.Height / 2 - found_center_pixel.Y) * dPixelResolution); - offset = new UnitPoint(found_center_pixel_mm.X - center.X, found_center_pixel_mm.Y - center.Y); - } - else - { - Log.W("Pattern is not found."); - } - - - //var ROI_X = (center.X - my_radius * 2) / dPixelResolution + _ConvMatImage.Width / 2; - //var ROI_Y = -(center.Y + my_radius * 2) / dPixelResolution + _ConvMatImage.Height / 2; - //var ROI_size = my_radius * 4 / dPixelResolution; - //Point2f circle = _ObjGenerator.find_circle_center(_ConvMatImage, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, (int)ROI_size, (int)ROI_size), threshold_array[circle_cnt], _SystemParameter.CVRadiusMargin, my_radius / dPixelResolution); - //circle_cnt += 1; - //circle = new Point2f((float)(circle.X + ROI_X), (float)(circle.Y + ROI_Y)); - ////Point2f circle = _ObjectGenerator.find_circle_center(_DetectImageMat, new OpenCvSharp.Rect(3325, 4250, 500, 500), threshold, my_radius, my_radius / dPixelResolution); - ////Cv2.Circle(_DetectImageMat, new Point(circle.X, circle.Y), (int)(my_radius / dPixelResolution), Scalar.Red, 8); - //circle = new Point2f((float)((circle.X - _ConvMatImage.Width / 2) * dPixelResolution), (float)((-circle.Y + _ConvMatImage.Height / 2) * dPixelResolution)); - - Log.I($"Offset : {offset.X},{offset.Y}"); - IDrawObject objclone = item.Clone(); - objclone.Move(offset); - //_ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i] = objclone; - _SelectedDrawObjectList[i] = objclone; - //IDrawObject objclone_line = _ScannerCanvasUserCtrl.Model.Layers[0].Objects[i + 1].Clone(); - IDrawObject objclone_line = _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i + 1].Clone(); - objclone_line.Move(offset);/// - //_ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i + 1] = objclone_line; - _SelectedDrawObjectList[i + 1] = objclone_line; - } - else if (item is Line) - { - //var line_length = Math.Abs(((Line)item).PF1.Y - ((Line)item).PF2.Y); - //if (line_length < 2) continue; - //int ROI_size = (int)(line_length * 1.5 / dPixelResolution); - //int ROI_X = (int)(((Line)item).PF1.X / dPixelResolution + _ConvMatImage.Width / 2) - ROI_size / 2; - //int ROI_Y = (int)(-Math.Max(((Line)item).PF1.Y, ((Line)item).PF2.Y) / dPixelResolution + _ConvMatImage.Height / 2) - ROI_size / 4; - //RotatedRect r = _ObjGenerator.find_line_center(_ConvMatImage, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, (int)ROI_size, (int)ROI_size), - // _SystemParameter.CVThresholdLine1, _SystemParameter.CVThresholdLine2); - //Point[] intVertices = new Point[4]; - //for (int j = 0; j < 4; j++) - //{ - // intVertices[j] = new Point(r.Points()[j].X + ROI_X, r.Points()[j].Y + ROI_Y); - //} - //UnitPoint LineCenter = new UnitPoint((r.Center.X + ROI_X - _ConvMatImage.Width / 2) * dPixelResolution, (-r.Center.Y - ROI_Y + _ConvMatImage.Height / 2) * dPixelResolution); - - //UnitPoint offset = new UnitPoint(LineCenter.X - (((Line)item).PF1.X + ((Line)item).PF2.X) / 2, LineCenter.Y - (((Line)item).PF1.Y + ((Line)item).PF2.Y) / 2); - //IDrawObject objclone = item.Clone(); - //float angle = Math.Min(r.Angle, 90 - r.Angle); - //objclone.Rotate(angle, LineCenter); - //objclone.Move(offset); - //_ScannerCanvasUserCtrl.Model.Layers[0].Objects[i] = objclone; - } - } - - return SequenceAction.Ok(); - } - private SequenceActionResult AfterWeldCheckBead(SequenceContext context, string id, SequenceActionResult param) - { - - //if (_SystemParameter.SequenceType == eSequenceType.Normal) return SequenceAction.Ok(); - MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage; - //RCC Error로 인해 시퀀스를 종료하고 있는데, NG배출해야 될지 확인 필요 - if (_ConvMatImage.Type() == MatType.CV_8UC1) - Cv2.CvtColor(_ConvMatImage, _ConvMatImage, ColorConversionCodes.GRAY2BGR); - - _StopwatchGenObj = Stopwatch.StartNew(); - _ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage_after); - if (_ConvMatImage_after.Type() == MatType.CV_8UC1) - Cv2.CvtColor(_ConvMatImage_after, _ConvMatImage_after, ColorConversionCodes.GRAY2BGR); - _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); - double dPixelResolution = ((_SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0; - _ObjGenerator = new ObjectGenerator(dPixelResolution); - var mainPage = WeldingRecipeManager.GetWeldingPage(); - _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; - bead_result_info = new List(); - for (int i = 0; i < _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects.Count; i++) - { - var item = _ScannerCanvasUserCtrl.Model.Layers[_PageNoRcc].Objects[i]; - double my_radius = 0; - int ROI_X = 0; - int ROI_Y = 0; - int ROI_W = 0; - int ROI_H = 0; - double bead_size1 = 0; - double bead_size2 = 0; - int search_size = 0; - UnitPoint center = new UnitPoint(0, 0); - OpenCvSharp.Point p1 = new OpenCvSharp.Point(); - OpenCvSharp.Point p2 = new OpenCvSharp.Point(); - Point[][] contour; - int type = -1; - if (item is Arc) - { - bead_result_info.Add(_SystemParameter.ArcBeadSizeMin); - bead_result_info.Add(_SystemParameter.ArcBeadSizeMax); - center = ((Arc)item).Center; - my_radius = ((Arc)item).Radius; - type = 0; - ROI_W = (int)(my_radius * 2 / dPixelResolution); - ROI_H = (int)(my_radius * 0.5 / dPixelResolution); - ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W; - ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_H / 2; - search_size = (int)(ROI_W / 10); - //double size_margin = 10000; - (bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_H), type, _SystemParameter.CVSearchSize); - Cv2.Line(_ConvMatImage_after, p1, p2, Scalar.LimeGreen, 10); - Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + 10), new Point(p1.X, p1.Y - 10), Scalar.LimeGreen, 10); - Cv2.Line(_ConvMatImage_after, new Point(p2.X, p2.Y + 10), new Point(p2.X, p2.Y - 10), Scalar.LimeGreen, 10); - Cv2.PutText(_ConvMatImage_after, $"{Math.Round(bead_size1 * dPixelResolution, 3)} mm", new Point(p1.X + 10, p1.Y + 220), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25); - bead_size1 = bead_size1 * dPixelResolution; - Log.I($"arc length : {bead_size1}"); - bead_result_info.Add(bead_size1); - - if (bead_size1 <= _SystemParameter.ArcBeadSizeMax && bead_size1 >= _SystemParameter.ArcBeadSizeMin) - { - bead_result_info.Add(1); // OK -> 1 - if (!weldingResult) weldingResult = true; - } - else - { - bead_result_info.Add(2); // NG -> 2 - weldingResult = false; - } - - - } - else if (item is Spline) - { - bead_result_info.Add(_SystemParameter.SpiralBeadWidthMin); - bead_result_info.Add(_SystemParameter.SpiralBeadWidthMax); - bead_result_info.Add(_SystemParameter.SpiralBeadHeightMin); - bead_result_info.Add(_SystemParameter.SpiralBeadHeightMax); - center = ((Spline)item).Center; - my_radius = ((Spline)item).Radius; - type = 1; - ROI_W = (int)(my_radius * 4 / dPixelResolution); - ROI_X = (int)(center.X / dPixelResolution) + _ConvMatImage.Width / 2 - ROI_W / 2; - ROI_Y = -(int)(center.Y / dPixelResolution) + _ConvMatImage.Height / 2 - ROI_W / 2; - (bead_size1, bead_size2, p1, p2, contour) = _ObjGenerator.check_bead_size(_ConvMatImage, _ConvMatImage_after, new OpenCvSharp.Rect((int)ROI_X, (int)ROI_Y, ROI_W, ROI_W), type, 0); - - Cv2.Line(_ConvMatImage_after, new Point(p1.X - bead_size1 / 2, p1.Y), new Point(p1.X + bead_size1 / 2, p1.Y), Scalar.LimeGreen, 10); - Cv2.Line(_ConvMatImage_after, new Point(p1.X, p1.Y + bead_size2 / 2), new Point(p1.X, p1.Y - bead_size2 / 2), Scalar.LimeGreen, 10); - Cv2.Line(_ConvMatImage_after, new Point(p1.X - bead_size1 / 2, p1.Y + 10), new Point(p1.X - bead_size1 / 2, p1.Y - 10), Scalar.LimeGreen, 10); - Cv2.Line(_ConvMatImage_after, new Point(p1.X + bead_size1 / 2, p1.Y + 10), new Point(p1.X + bead_size1 / 2, p1.Y - 10), Scalar.LimeGreen, 10); - - Cv2.Line(_ConvMatImage_after, new Point(p1.X - 10, p1.Y - bead_size2 / 2), new Point(p1.X + 10 / 2, p1.Y - bead_size2 / 2), Scalar.LimeGreen, 10); - Cv2.Line(_ConvMatImage_after, new Point(p1.X - 10, p1.Y + bead_size2 / 2), new Point(p1.X + 10 / 2, p1.Y + bead_size2 / 2), Scalar.LimeGreen, 10); - - Cv2.PutText(_ConvMatImage_after, $"W : {Math.Round(bead_size1 * dPixelResolution, 3)} mm", new Point(p1.X + bead_size1 / 2, p1.Y), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25); - Cv2.PutText(_ConvMatImage_after, $"H : {Math.Round(bead_size2 * dPixelResolution, 3)} mm", new Point(p1.X + bead_size1 / 2, p1.Y + bead_size2 / 2 + 50), HersheyFonts.HersheyComplexSmall, 10, Scalar.LimeGreen, 25); - bead_size1 = bead_size1 * dPixelResolution; - bead_size2 = bead_size2 * dPixelResolution; - Log.I($"spiral length : {bead_size1}, {bead_size2}"); - - ScannerParam _SplineParam = ScannerCanvasUserCtrl.ScannerParams[((Spline)item).ScannerParamNo]; - Log.I($"ScannerParam ->{_SplineParam.LaserPower1}, {_SplineParam.LaserPower2}"); - bead_result_info.Add(bead_size1); - bead_result_info.Add(bead_size2); - - if (bead_size1 <= _SystemParameter.SpiralBeadWidthMax && bead_size1 >= _SystemParameter.SpiralBeadWidthMin - && bead_size2 <= _SystemParameter.SpiralBeadHeightMax && bead_size2 >= _SystemParameter.SpiralBeadHeightMin) - { - bead_result_info.Add(1); // OK -> 1 - if (!weldingResult)weldingResult = true; - } - else - { - bead_result_info.Add(2); // NG -> 2 - weldingResult = false; - } - } - } - return SequenceAction.Ok(); - } - #endregion - - Mat matLeftTop; - Mat matRightTop; - Mat matLeftBottom; - Mat matRightBottom; - - OpenCvSharp.Rect rectT; - private void TestopupWin() - { - // OpenCV Version 4.9.0 - //D:\ILSOSConfig\_vision\Def - string Png1 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\1.png"); - string Png2 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\2.png"); - string Png3 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\3.png"); - string Png4 = string.Format("D:\\ILSOSConfig\\_vision\\Def\\4.png"); - matLeftTop = Cv2.ImRead(Png1); - matRightTop = Cv2.ImRead(Png2); - matLeftBottom = Cv2.ImRead(Png3); - matRightBottom = Cv2.ImRead(Png4); - - // Width 10368, Height 9856 // 1153 896 6918 8056 - rectT = new OpenCvSharp.Rect(1153, 896, 6918, 8056); - popup.Show(); - - popup.UpdateImages1(matLeftTop, rectT); - popup.UpdateImages2(matRightTop, rectT); - popup.UpdateImages3(matLeftBottom, rectT); - popup.UpdateImages4(matRightBottom, rectT); - - List info = Init_info(); - - popup.SetParameters1(info); - popup.SetParameters2(info); - - popup.SetStepLBAD("OK"); - popup.SetStepWELDING("OK"); - - - while (true) - { - Thread.Sleep(100); - } - } - - private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) - { - - //UpdatePLCMemoryArea((int)eWordOutput.STEP1_Arc, Init_info()); - //string version = Cv2.GetVersionString(); - //TestopupWin(); - - Log.I("SeqAutoRunKS_New Start"); - Status.SetWorkingPosition(eWorkingPosition.CHECKING_CONDITION); - - _InitParam = param.Param as SeqAutoRunKS_New_InitParam; - _RecipeManager = Application.Current.AuroraEnv().RecipeManager; - _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); - - InitDev(context); - if (!CheckDeviceReady(context)) - { //Check Device - 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) - { - _AutoRunStartTime = DateTime.Now; - _SeqRunCount = 0; - _TodayProduct = _SystemParameter.TodayProductCount; - _TotalProduct = _SystemParameter.TotalProductCount; - //_SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; - - if (_SystemParameter.SequenceType == eSequenceType.Normal) - { - _IsRealTimeScout = false; - } - else if (_SystemParameter.SequenceType == eSequenceType.RCC) - { - double dPixelResolution = ((_SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0; - //ConvEdgeObjectViewModel에서도 생성되지만.. Seq에서 재생성하고 쓰고 버리자 - _ObjGenerator = new ObjectGenerator(dPixelResolution); - - if (_SystemParameter.OffsetType == eOffsetType.manual) - _ObjGenerator.SetOffsetType("Manual"); - else - { - _ObjGenerator.SetOffsetType("CSV"); - _ObjGenerator.SetOffsetTable(_SystemParameter.OffsetCSVFile, _SystemParameter.LensMagnification, _SystemParameter.CameraPixelSize); - } - _ObjGenerator.SetInterlockProperties(_SystemParameter.DrawObjectDistanceRange, _SystemParameter.DrawObjectArcLengthMax, _SystemParameter.DrawObjectLengthSumDiffRange, _SystemParameter.DrawObjectCenterXYDiffRange, _SystemParameter.MaxMinDiffHigh, _SystemParameter.MaxMinDiffLow, _SystemParameter.CheckCenterDiff, _SystemParameter.DistortionCenterDiff, _SystemParameter.AutoMissAlignHigh, _SystemParameter.AutoMissAlignLow); - - //if (!_ObjGenerator.GetArcInfoFromRecipe(_RecipeDrawObjects, out _SelectedArcs)) { - // Log.E(string.Format("Recipe Infomation Register Error")); - // return false; - //} - - _IsRealTimeScout = true; - - } - else if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset) - { - // VisionDevice 추가 - // InitializeCameraDevice - _FovRecipe = VisionRecipeManager.GetFovRecipe(_InitParam.ScoutSeqParams.FovInfo); - _CameraAgent = CameraAgentManager.GetCameraAgent(_InitParam.ScoutSeqParams.FovInfo); - _CameraDisplay = CameraDisplayManager.GetDisplay(_InitParam.ScoutSeqParams.FovInfo, _InitParam.ScoutSeqParams.DisplayType); - - // InitGrabImageBuffer 함수 - try - { - IpAdapter.Instance.IpEnvironment.FreeImage(_GrabImage); - _GrabImage = (MIL_ID)_CameraAgent.CloneImageBuffer(); - } - catch (Exception e) - { - Log.E(e.Message); - } - - _IsRealTimeScout = false; - - } - else - { - Log.E("Invalid SequenceType."); - return false; - } - - var mainPage = WeldingRecipeManager.GetWeldingPage(); - _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; - _RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; - _WeldingScannerListNo = eListNo.LIST1; - - _CellMeasureCenterOffsetX = 0.0; - _CellMeasureCenterOffsetY = 0.0; - - var currentModelName = context.Recipes.ActivatedModelName(); - var modelItem = context.GetModel(currentModelName, CommonModelIds.EquipmentSpecificModel); - _ModelNo = modelItem.Model_No; - - return true; - } - private void InitDev(SequenceContext context) - { - //Device Init - _Scanner = context.GetLaserScanner(); - _Laser = context.GetLaser(); - - //_StreamLightLBAD._Client = context.GetStreamLightClient(); - - _PLC = context.GetPLC(); - _IO = context.GetIOUnit(); - - _LBAD = context.GetLBAD(); - } - - private bool CheckDeviceReady(SequenceContext context) - { - List deviceListToCheck = new List() { CommonDeviceIds.Scanner, CommonDeviceIds.Laser, - CommonDeviceIds.PLCDevice, CommonDeviceIds.IODevice, CommonDeviceIds.LBAD }; - bool isAllDeviceActivated = true; - foreach (string item in deviceListToCheck) - { - if (!context.Devices[item].IsActivated) - { - isAllDeviceActivated = isAllDeviceActivated && false; - } - } - - return isAllDeviceActivated; - } - - private bool CheckCondition(SequenceContext context) - { - if (CheckCondition_Interlock()) - { - if (InitializeDeviceStatus(context)) - { - return true; - } - } - return false; - } - - private bool CheckCondition_Interlock() - { - // PLC, Data, IO 등 Interlock checking - return true; - } - - private bool InitializeDeviceStatus(SequenceContext context) - { - // PLC Interface AutoStatus Start - InitAutoRunBit(); - - // Laser Initialize - _Laser.PilotLaserOff(); - _Laser.LaserOn(); - Thread.Sleep(100); - if (!_Laser.GetLaserReady()) - { - Log.E("ERROR Initialize Laser"); - return false; - } - - // Scanner Initialize - // Scanner 없음. - - // OCT Initialize - // TODO: EnterSequenceModeOCT 와 함께 Initialize 하는 것을 재구현 필요함. 초반에 한번만 check 하고 돌아 갈수 있도록 - - // PLC Initialize - if (_PLC.ReadBit((int)eBitInput.PLC_AUTO_STATUS).data == false) - { - Log.E(string.Format("ERROR Initialize PLC, Bit Off PLC_AUTO_STATUS")); - return false; - } - - // LBAD Initialize - // LBAD 는 server 이기 때문에, 만약 끊어졌으면 다시 접속이 필요함 - if (!_LBAD.GetConnected()) - { - _LBAD.DisConnect(); - Thread.Sleep(500); - int ret = _LBAD.Open(_LBAD.Config); - if (ret == -1) - { - Log.E($"LBAD Open Error : {ret}"); - return false; - } - } - - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), true); - Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus true")); - - if (_SystemParameter.SequenceType == eSequenceType.Normal) - { - _Scanner.SelectCorrectionTable(2); - Log.I(string.Format("Normal, Select Laser Correction File")); - } - else if (_SystemParameter.SequenceType == eSequenceType.RCC) - { - _Scanner.SelectCorrectionTable(1); - Log.I(string.Format("RCC, Select Vision Correction File")); - } - else if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset) - { - _Scanner.SelectCorrectionTable(1); - Log.I(string.Format("CellCenterOffset, Select Vision Correction File")); - } - else - { - Log.I(string.Format("Invalid SequenceType.")); - } - - return true; - } - - private void InitAutoRunBit() - { - Log.I(string.Format($"[PLCInterface] Start AutoRun PLC Bit Initialize")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK False")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE False")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False")); - _PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, true); - Log.I(string.Format($"[PLCInterface]SET PC_AUTO_STATUS True")); - // Page Rrset - bool[] Page = new bool[4]; - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - Log.I(string.Format("[PLCInterface]Pgae Reset")); - - _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, false); - Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG False")); - - _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, false); - Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK False")); - - - _PLC.WriteBit((int)eBitOutput.PC_RECIPE_PARAM_UPLOAD_COMPLETE, false); - Log.I(string.Format($"[PLCInterface]SET PC_RECIPE_PARAM_UPLOAD_COMPLETE false")); - - Log.I(string.Format($"[IOInterface] Start AutoRun IO Bit Initialize")); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false); - Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus False")); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false); - Log.I(string.Format($"[IOInterface]SET PCLBADWeldingTrigger False")); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false); - Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop False")); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); - Log.I(string.Format($"[IOInterface]SET PCLBADJudgementCompleteAck False")); - Log.I(string.Format($"[IOInterface] Complete AutoRun IO Bit Initialize")); - } - - private string CheckBeforeOrAfter(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - { - _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); - - var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam; - //return SequenceAction.Ok(); - - if (pre_welding) - { - pre_welding = !pre_welding; - return SEQ_BEFORE_WELD_MOVE_OBJECT; - - } - else - { - pre_welding = !pre_welding; - return SEQ_AFTER_WELD_CHECK_BEAD; - } - - } - - private string CheckInitCondition(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - { - if (!CheckCondition(context)) - { - AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition); - Log.E("Condition is not in state to start sequence."); - context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false); - return SEQ_COMPLETE; - } - - var startTime = DateTime.Now; - context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime); - - Log.D("ReceiveCellInfo Sequence CheckInitCondition"); - //return SEQ_CHECK_LOAD_COMPLETE; - - return SEQ_CHECK_PAGENO; - } - - private string GetPLC_WordDataToString(short[] rawData) - { - byte[] bytes = new byte[rawData.Length * 2]; - for (int i = 0; i < rawData.Length; i++) - { - bytes[i * 2] = (byte)(rawData[i] & 0xFF); // 하위 바이트 - bytes[i * 2 + 1] = (byte)((rawData[i] >> 8) & 0xFF); // 상위 바이트 - } - - string result = Encoding.ASCII.GetString(bytes); - - return result; - } - - private short[] SetPLC_StringDataToWord(string dataString) - { - List shorts = new List(); - - for (int i = 0; i < dataString.Length; i += 2) - { - byte first = (byte)dataString[i]; - byte second = (i + 1 < dataString.Length) ? (byte)dataString[i + 1] : (byte)0; - - // 반전하여 저장: second first - short combined = (short)((second << 8) | first); - shorts.Add(combined); - } - - - return shorts.ToArray(); - } - - public static short[] IntArrayToShortArray(int[] intArray) - { - // short 범위 -> -32768 ~ 32767 - short[] shortArray = new short[intArray.Length * 2]; - for (int i = 0; i < intArray.Length; i++) - { - shortArray[i * 2] = (short)((intArray[i] >> 16) & 0xFFFF); // 상위 16비트 - shortArray[i * 2 + 1] = (short)(intArray[i] & 0xFFFF); // 하위 16비트 - } - return shortArray; - } - - public static int[] ShortArrayToIntArray(short[] shortArray) - { - if (shortArray.Length % 2 != 0) - throw new ArgumentException("short 배열 길이는 반드시 짝수여야 합니다."); - - int[] intArray = new int[shortArray.Length / 2]; - for (int i = 0; i < intArray.Length; i++) - { - int high = (ushort)shortArray[i * 2]; // 부호 없는 16비트로 캐스팅 - int low = (ushort)shortArray[i * 2 + 1]; - intArray[i] = (high << 16) | low; - } - return intArray; - } - - - - - public void GETDATA_TEST() - { - var mainPage = WeldingRecipeManager.GetWeldingPage(); - _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; - _RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; - - var activatedRecipeId = Application.Current.AuroraEnv().RecipeManager.ActivatedRecipe().Id; - - var scannerObjects = new List(); - - foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects) - { - ScannerParam param = null; - - if (item is Arc arc) - { - param = ScannerCanvasUserCtrl.ScannerParams[arc.ScannerParamNo]; - } - else if (item is Line line) - { - param = ScannerCanvasUserCtrl.ScannerParams[line.ScannerParamNo]; - } - else if (item is Spline spline) - { - param = ScannerCanvasUserCtrl.ScannerParams[spline.ScannerParamNo]; - } - else if (item is Dot dot) - { - param = ScannerCanvasUserCtrl.ScannerParams[dot.ScannerParamNo]; - } - - if (param != null) - { - scannerObjects.Add(new ScannerObjectInfo - { - Object = item, - LaserPower1 = param.LaserPower1, - LaserPower2 = param.LaserPower2, - JumpSpeed = param.JumpSpeed, - MarkSpeed = param.MarkSpeed - }); - } - } - - foreach (var info in scannerObjects) - { - Console.WriteLine($"{info.Object.GetType().Name} -> Power1: {info.LaserPower1}, Power2: {info.LaserPower2}, Jump: {info.JumpSpeed}, Mark: {info.MarkSpeed}"); - } - } - - public void SetBCRID(string id) - { - //string TestString = "ABCDEFG"; - //short[] data = SetPLC_StringDataToWord(TestString); - //string hexString1 = string.Join(" ", Array.ConvertAll(data, s => s.ToString("X4"))); - - ////short[] WordData = new short[] { 0x00A0, 0x00B0 }; - //_PLC.WriteWordBlock((int)eWordOutput.PC_RECIPE_NO, 2, data); - //var Red = _PLC.ReadWordBlock((int)eWordOutput.PC_RECIPE_NO, 2).data; - //Log.I(string.Format($"[PLCInterface]SET PLC_BCR_ID {0}", _BcrID)); - } - - public string GetBCRID() - { - string id = ""; - - var bcrid = _PLC.ReadWordBlock((int)eWordInput.PLC_BCR_ID, 16).data; - - string hexString = string.Join(" ", Array.ConvertAll(bcrid, s => s.ToString("X4"))); - // 4241 4443 4645 4847 4A49 4C4B 4E4D 504F 5251 5453 3130 3332 3534 3736 3938 0000 - id = GetPLC_WordDataToString(bcrid); - Log.I(string.Format($"[PLCInterface]GET PLC_BCR_ID {0}", id)); - - return id; - } - - public void SetPagePlc(int num) - { - bool[] Page = new bool[4]; - - switch (num) - { - case 0: - { - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - } - break; - - case 1: - { - Page = new bool[4] { true, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - } - break; - - case 2: - { - Page = new bool[4] { false, true, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - } - break; - - case 3: - { - Page = new bool[4] { false, false, true, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - } - break; - - case 4: - { - Page = new bool[4] { false, false, false, true }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - } - break; - } - } - - public int GetPagePlc() - { - int num = 0; - - bool[] page = _PLC.ReadBitBlock((int)eBitInput.PLC_SET_WELD_PAGE_1, 4).data; - if (page[0]) num = 1; - if (page[1]) num = 2; - if (page[2]) num = 3; - if (page[3]) num = 4; - - return num; - } - - // Add jmj -> - private SequenceActionResult CheckPageNo(SequenceContext context, string id, SequenceActionResult param) - { - Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL); - - #region ex - //UpdatePLCMemoryArea_test(); - - //int nRecipeNo = _RecipeManager.ActivatedRecipe().Id; - //int recipeRequestId = 18; - - //if (nRecipeNo != recipeRequestId) - //{ - // var recipeName = WeldingRecipeManager.SearchRecipeItem(recipeRequestId); - - // if (recipeName != string.Empty) - // { - // Application.Current.AuroraEnv().EventPublisher.Publish(new EventMessage(SequenceIds.SeqAutoRunKS_New, "Autorun_Recipe_Change", (recipeRequestId, recipeName))); - // Thread.Sleep(500); - // } - - // nRecipeNo = _RecipeManager.ActivatedRecipe().Id; - //} - #endregion - - - - - // Cell 이 Load 완료되어서 Scout 가 가능한 상태인지 확인 - #region Whie -> PLC_JIG_LOAD_COMPLETE - _InterfaceStartTime = DateTime.Now; - while (!context.Stopped) - { - if (_PLC.ReadBit((int)eBitInput.PLC_JIG_LOAD_COMPLETE).data) - { - Log.I(string.Format("Cell Loading is completed.")); - - break; - } - _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - - if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - { - Log.E("TIMEOUT_PLC_JIG_LOAD_COMPLETE"); - _InterfaceStartTime = DateTime.Now; - } - Thread.Sleep(10); - } - #endregion - - _InterfaceStartTime = DateTime.Now; - while (!context.Stopped) - { - #region PLC 에서 PAGE 정보 가져오기 ( BIT 영역 ) - _PageNo = GetPagePlc(); - #endregion - - if (_PageNo != 0) break; - - _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - - if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - { - Log.E("TIMEOUT_PLC_PAGENO"); - _InterfaceStartTime = DateTime.Now; - } - Thread.Sleep(10); - } - - if (_PageNo != 0) - { - #region 제품 BCR ID 가져오기 ( WORD ARR 영역 ) - _BcrID = GetBCRID(); - #endregion - - // RCC 들어가기전에 1로 바꿔있어야된다... - _Scanner.SelectCorrectionTable(1); - - var mainPage = WeldingRecipeManager.GetWeldingPage(); - _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; - _RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[_PageNo - 1].Objects; - _SelectedDrawObjectList = _RecipeDrawObjects; - _WeldingScannerListNo = eListNo.LIST1; - - SetPagePlc(_PageNo); - - _PageNoRcc = _PageNo - 1; - } - - return SequenceAction.Ok(); - } - - // 지그 상태 확인 - private string CheckLoadComplete(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - { - Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL); - - TimeSpan spanTime; - DateTime startTime = DateTime.Now; - - if (_SystemParameter.SequenceType == eSequenceType.Normal) - { - // CorrectionTable ==> 2 - return SEQ_READY_SCANNER_LIST; - } - else - { - _CamConfig = Application.Current.AuroraEnv().DeviceManager.GetDeviceConfig(eCamId.CAM1.ToString()) as CamConfig; - // RCC, CellCenterOffset - // RCC의 경우 LoadCompleteCheck 전 Scout 첫번째 위치로 스캐너 이동 해놓는게 시간을 벌듯.. - // CellCenterOffset은 중심위치에서 그랩하니깐 해당 기능 필요없을 것이라 우선 여기서 if문 처리하자 - // 즉 정리하면, RCC 만 이동하고, CellCenterOffset은 이동 하지 않음. - if (_SystemParameter.SequenceType == eSequenceType.RCC) - { - int scoutNo = 0; - if (_CamConfig.ChildImage.ChildBufRowCols[scoutNo].Enabled) - { - double XPos = _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPos.X + _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPosOffset.X; //카메라 위치에 대한 보정값 입력 - double YPos = _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPos.Y + _CamConfig.ChildImage.ChildBufRowCols[scoutNo].MotorPosOffset.Y; //카메라 위치에 대한 보정값 입력 - Log.I(string.Format($"Move No.{scoutNo + 1} Field Scan Pos(X,Y:{XPos},{YPos})")); - - //1.스캐너 필드 위치 이동(Jump) - _Scanner.JumpAbs(XPos, YPos, eFunctionType.COMMAND); - } - - - return SEQ_SET_SCOUT_FLYING_VISION_SEQ; - - } - - return SEQ_READY_SCANNER_LIST; - } - } - - private SequenceActionResult SetReceiveCellInfo_SeqParams(SequenceContext context, string id, SequenceActionResult param) - { - SeqReceiveCellInfo_InitParam seqParams = new SeqReceiveCellInfo_InitParam() - { - }; - - return SequenceAction.Ok(seqParams); - } - - private SequenceActionResult GetReceiveCellInfo_SeqResult(SequenceContext context, string id, SequenceActionResult param) - { - var resultOutParam = param.Param as SeqReceiveCellInfo_OutParam; - if (resultOutParam.Success == false) - { - return null; - } - - return SequenceAction.Ok(); - } - - public MIL_ID DoGrab() - { - var image = (object)_GrabImage; - _CameraAgent.GrabSync(_CameraDisplay, ref image); - _GrabImage = (MIL_ID)image; - - return _GrabImage; - } - - // RCC FlyingVision - #region RCC FlyingVision - private SequenceActionResult SetScoutFlyingVision_SeqParams(SequenceContext context, string id, SequenceActionResult param) - { - Log.I($"AutoRun Seq Run Count : {_SeqRunCount}"); - var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B); - - SeqScoutFlyingVision_InitParam seqParams = new SeqScoutFlyingVision_InitParam() - { - IsRealTimeScout = _IsRealTimeScout, - ScoutSeqParams = scoutSeqParams, - SequenceAutoRunCount = _SeqRunCount, - WeldingScannerListNo = eListNo.LIST2, - }; - - return SequenceAction.Ok(seqParams); - } - - //private string GetScoutFlyingVision_SeqResult(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - //{ - // var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam; - // if (pre_welding) - // { - // pre_welding = !pre_welding; - // return SEQ_BEFORE_WELD_MOVE_OBJECT; - - // } - // else - // { - // pre_welding = !pre_welding; - // return SEQ_AFTER_WELD_CHECK_BEAD; - // } - - // if (resultOutParam.Success == false) - // { - // return null; - // } - //} - private SequenceActionResult GetScoutFlyingVision_SeqResult(SequenceContext context, string id, SequenceActionResult param) - { - - var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam; - return SequenceAction.Ok(); - - //if (pre_welding) - //{ - // pre_welding = !pre_welding; - // return SEQ_BEFORE_WELD_MOVE_OBJECT; - - //} - //else - //{ - // pre_welding = !pre_welding; - // return SEQ_AFTER_WELD_CHECK_BEAD; - //} - - if (resultOutParam.Success == false) - { - return null; - } - } - #endregion - - // RCC Normal Vision - #region RCC Normal Vision - private SequenceActionResult SetScoutNORMALVision_SeqParams(SequenceContext context, string id, SequenceActionResult param) - { - Log.I($"AutoRun Seq Run Count : {_SeqRunCount}"); - var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B); - - SeqScoutFlyingVision_InitParam seqParams = new SeqScoutFlyingVision_InitParam() - { - IsRealTimeScout = _IsRealTimeScout, - ScoutSeqParams = scoutSeqParams, - SequenceAutoRunCount = _SeqRunCount, - WeldingScannerListNo = eListNo.LIST2, - }; - - return SequenceAction.Ok(seqParams); - } - - private SequenceActionResult GetScoutNORMALVision_SeqResult(SequenceContext context, string id, SequenceActionResult param) - { - var resultOutParam = param.Param as SeqScoutFlyingVision_OutParam; - if (resultOutParam.Success == false) - { - return null; - } - - return SequenceAction.Ok(); - } - #endregion - - // For RCC Only - private SequenceActionResult SaveScoutImageEvent(SequenceContext context, string id, SequenceActionResult param) - { - MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage; - if (ScannerFieldImage != null) - { - SaveScoutImage(ScannerFieldImage); - } - else - { - Log.E("ScannerFieldImage is Null"); - } - return SequenceAction.Ok(); - } - private object SendEvent(SequenceContext context, string id, SequenceActionResult param) - { - //Event로 넘겨줄 Param은 따로 없다. - return null; - } - private SequenceActionResult FindEdge(SequenceContext context, string id, SequenceActionResult param) - { - MIL_ID ScannerFieldImage = Status.GetProcessingWeldingData().ScannerFiledImage; - - //RCC Error로 인해 시퀀스를 종료하고 있는데, NG배출해야 될지 확인 필요 - _StopwatchGenObj = Stopwatch.StartNew(); - #region Find Edge - _ObjGenerator.ConvertMILToMat(ScannerFieldImage, out _ConvMatImage); - if (_ConvMatImage == null) - { - Log.E(string.Format("[GenerateWeldingObject] Scout Image is empty. Check Camera or Cell.")); - return null; - } - var (centerX, centerY) = FindCenterReicpeSingleArc(_ConvMatImage); - if (_ObjGenerator.FindEdge(_ConvMatImage, _Radius_Pixel, _SystemParameter.Margin, _SystemParameter.PointNum, _SystemParameter.CVThreshold, centerX, centerY, _SystemParameter.DetectPointPercent, _SystemParameter.CVJigSize, out Point[][] maxContour, out _DetectedContourCenter) == false) - { - Log.E(string.Format("[GenerateWeldingObject] Edge Detection Interlock.")); - return null; - } - if (maxContour[0].Count() < 1 || maxContour == null) - { - Log.E(string.Format("[GenerateWeldingObject] MaxContour is Null. Check Scout Image.")); - return null; - } - context.PutValue("MAX_CONTOUR_FIND_EDGE", maxContour); - _StopwatchGenObj.Stop(); - Log.I(string.Format($"[GenerateWeldingObject] Find Edge Complete Time : {_StopwatchGenObj.ElapsedMilliseconds} msec")); - #endregion - - return SequenceAction.Ok(); - } - private (int centerX, int centerY) FindCenterReicpeSingleArc(Mat image) - { - int centerX = 0, centerY = 0; - foreach (var item in _RecipeDrawObjects) - { - if (item is Arc) - { - Arc arc = (Arc)item; - centerX = (int)(arc.Center.X * 1000.0 / _SystemParameter.CameraPixelSize * _SystemParameter.LensMagnification + image.Width / 2); - centerY = (int)(-arc.Center.Y * 1000.0 / _SystemParameter.CameraPixelSize * _SystemParameter.LensMagnification + image.Height / 2); - break; - } - } - return (centerX, centerY); - } - private string DecisionRCCAlgorithmType(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - { - // FindEdge의 maxContour를 param으로 받아오기 - Point[][] maxContour = context.GetValue("MAX_CONTOUR_FIND_EDGE"); - // CheckEdge의 Return 결과를 param 으로 받아와서 현재 노드에서 4가지 경우로 분류하자 - var (centerX, centerY) = FindCenterReicpeSingleArc(_ConvMatImage); - int[] shrinkList = new int[] { _SystemParameter.CVShrinkPixel, _SystemParameter.CVShrinkPixel2, _SystemParameter.CVShrinkPixel3, _SystemParameter.CVShrinkPixel4 }; - int resultCheckEdge = _ObjGenerator.CheckEdge(maxContour, shrinkList, _ConvMatImage.Height, _ConvMatImage.Width, centerX, centerY, _SystemParameter.EnableAutoMissAlign, out _MaxContour); - if (resultCheckEdge == 3) - { - Log.E("Error Check Edge. Check EdgeDetect Center or Over LocalMaxMinDiff Upper"); - return null; - } - - if (_SystemParameter.RCCAlgorithmType == eRCCAlgorithmType.OnlyGenObject) - { - return SEQ_GENERATE_WELDING_OBJECT; - } - else if (_SystemParameter.RCCAlgorithmType == eRCCAlgorithmType.OnlyOffsetObject) - { - return SEQ_APPLY_OFFSET_OBJECT; - } - else - { - if (resultCheckEdge == 0) - { - return SEQ_READY_SCANNER_LIST; - } - else if (resultCheckEdge == 1) - { - return SEQ_APPLY_OFFSET_OBJECT; - } - else if (resultCheckEdge == 2) - { - return SEQ_GENERATE_WELDING_OBJECT; - } - else - { - Log.E("Error Check Edge. Check EdgeDetect Center or Over LocalMaxMinDiff Upper"); - return null; - } - } - } - private SequenceActionResult ApplyOffsetObejct(SequenceContext context, string id, SequenceActionResult param) - { - var (centerX, centerY) = FindCenterReicpeSingleArc(_ConvMatImage); - // Recipe 객체는 그대로 사용하고 CetnerOffset 값을 SeqUploadWeldingList에서 사용할 수 있도록 넣어준다 - double centerOffsetX = _DetectedContourCenter.X - centerX; - double centerOffsetY = _DetectedContourCenter.Y - centerY; - - _CellMeasureCenterOffsetX = centerOffsetX; - _CellMeasureCenterOffsetY = centerOffsetY; - Log.I(string.Format($"Object CenterOffsetX : {centerOffsetX}, CenterOffsetY : {centerOffsetY}")); - - return SequenceAction.Ok(); - } - private SequenceActionResult GenerateWeldingObject(SequenceContext context, string id, SequenceActionResult param) - { - #region Generate Object - _StopwatchGenObj.Restart(); - _ObjGenerator.SetPolygonFromList(_MaxContour, out _Polygon); - if (_SystemParameter.ObjectGenType == eObjectGenType.FitArcsAndLines) - { - _ObjGenerator.CalculateAutoPath(_ConvMatImage, _SelectedArcs[0], _Polygon, _SystemParameter.dMergeDist, _SystemParameter.nMaxArcRadius, _SystemParameter.nLineTolerance, _SystemParameter.nArcTolerance, _DetectedContourCenter, out _Paths); - } - else - { - _ObjGenerator.CalculateAutoPathAngle(_ConvMatImage, _SelectedArcs[0], _Polygon, _SystemParameter.dMergeDist, _SystemParameter.ObjectNumber, _DetectedContourCenter, out _Paths); - } - //Generate 한 object 를 SelectedDrawObjects 에 넣어두고 쓴다. - _ObjGenerator.ConvertPathItemToDrawingObjects(_Paths, _SystemParameter.fLineDefualtWidth, _ConvMatImage, _SelectedArcs[0], out _GeneratedDrawObjects); - //objGenerator.SaveDrawingObjectsToCSV(GeneratedDrawObjects, "SeqAutoRunKS_RCC_before"); - if (_ObjGenerator.CheckInterlockDrawingObjectPosition(_GeneratedDrawObjects, _DetectedContourCenter, _SelectedArcs[0]) == false) - { - Log.E(string.Format("[GenerateWeldingObject]Interlock DrawingObject.")); - return null; - } - List tempobject = new List(); - int startindex = 0; int nCount = _RecipeDrawObjects.Count; - for (int i = startindex; i < _RecipeDrawObjects.Count; i++) - { - if (i >= startindex + nCount) - break; - tempobject.Add(_RecipeDrawObjects[i]); - } - _SelectedDrawObjectList = tempobject; - - //현재 Recipe의 Arc객체를 RCC로 생성된 객체로 대체하면서 Group화 해준다 - _ObjGenerator.ReplaceRCCObject(eArcCount.FirstArc, _SelectedDrawObjectList, _GeneratedDrawObjects, _DetectedContourCenter); - - _ObjGenerator.SaveDrawingObjectsToCSV(_GeneratedDrawObjects, "SeqAutoRunKS_RCC"); - - _StopwatchGenObj.Stop(); - Log.I(string.Format($"[GenerateWeldingObject] Generate Object Complete Time : {_StopwatchGenObj.ElapsedMilliseconds} msec")); - #endregion - return SequenceAction.Ok(); - } - - private SequenceActionResult ReadyScannerList(SequenceContext context, string id, SequenceActionResult param) - { - Status.SetWorkingPosition(eWorkingPosition.UPLOADING_WELD_LIST); - - return SequenceAction.Ok(); - } - - private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param) - { - Log.I("SeqDryRun SetUploadWeldingList_SeqParams"); - SeqUploadWeldingList_InitParam seqParams = new SeqUploadWeldingList_InitParam() - { - NeedSetLaserTiming = false, - IncludeListStartEnd = true, - CellMeasureCenterOffsetX = _CellMeasureCenterOffsetX, - CellMeasureCenterOffsetY = _CellMeasureCenterOffsetY, - SelectedDrawObjectList = _RecipeDrawObjects, - WeldingScannerListNo = _WeldingScannerListNo, - }; - - return SequenceAction.Ok(seqParams); - } - - private SequenceActionResult GetUploadWeldingList_SeqResult(SequenceContext context, string id, SequenceActionResult param) - { - var resultOutParam = param.Param as SeqUploadWeldingList_OutParam; - if (resultOutParam.Success == false) - { - AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_UploadWeldingList_ResultFailed); - return null; - } - - return SequenceAction.Ok(); - } - - private SequenceActionResult WaitWeldingStart(SequenceContext context, string id, SequenceActionResult param) - { - _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, true); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY True")); - - Thread.Sleep(500); - - #region PLC_WELD_REQEUST 채크로직 - _InterfaceStartTime = DateTime.Now; - while (!context.Stopped) - { - if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data) - { - Log.I(string.Format($"[PLCInterface]GET PLC_WELD_REQEUST True")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, true); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK True")); - - break; - } - - _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - { - Log.E("TIMEOUT_PLC_WELD_REQEUST"); - _InterfaceStartTime = DateTime.Now; - } - Thread.Sleep(10); - } - #endregion - - return SequenceAction.Ok(); - } - - private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param) - { - Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD); - - // Laser Correction 파일로 변경, 레이저를 사용해야 하므로 2 - _Scanner.SelectCorrectionTable(2); - _CellId = Status.GetProcessingWeldingData().WorkCellId; - _LotId = Status.GetProcessingWeldingData().WorkLotId; - - int recipeNo = _RecipeManager.ActivatedRecipe().Id; - - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), true); - int sendresult = _LBAD.SendCellData(_LotId, _CellId, recipeNo, _ModelNo); - Log.I(string.Format($"SendCellData result :{sendresult}")); - - - - - - _WeldingStartTime = DateTime.Now; - Status.GetProcessingWeldingData().WeldStartTime = _WeldingStartTime.ToString("yyyyMMddHHmmss"); - - //_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND); - //_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND); - _Scanner.ExecuteList(_WeldingScannerListNo); - Log.I(string.Format($"START Welding : ExecuteList_{_WeldingScannerListNo}")); - - //WaitForListTaskCompleted 함수에서 List 완료 여부를 Check함, List실행이 끝나면 while문을 빠져나옴 - _Scanner.WaitForListTaskCompleted(_SystemParameter.WeldLinesTaskTimeOut, context); - _WeldEndTime = DateTime.Now; - _WeldingSpanTime = DateTime.Now.Subtract(_WeldingStartTime); - Log.I(string.Format($"Welding Complete Time : {_WeldingSpanTime.TotalMilliseconds} msec")); - Status.GetProcessingWeldingData().WeldTime = _WeldingSpanTime.TotalSeconds.ToString(); - - double dExecuteListTime = _Scanner.GetTime(); - Log.I(string.Format($"ExecuteList Time : {dExecuteListTime * 1000} msec")); - - - _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_REQEUST_ACK False")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False")); - - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false); - Log.I(string.Format($"[IOInterface]SET PCWeldingTrigger false")); - - - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), true); - Log.I(string.Format($"[IOInterface]{_PageNo} setp --> SET PCWeldingStop true")); - - return SequenceAction.Ok(); - } - - private SequenceActionResult RequestUnloadCell(SequenceContext context, string id, SequenceActionResult param) - { - Status.SetWorkingPosition(eWorkingPosition.UNLOADING_CELL); - - // PC → PLC , Unload Cell Request - _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, true); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE True")); - - _InterfaceStartTime = DateTime.Now; - while (!context.Stopped) - { - if (_PLC.ReadBit((int)eBitInput.PLC_WELD_COMPLETE_ACK).data) - { - Log.I(string.Format($"[PLCInterface]GET PLC_WELD_COMPLETE_ACK True")); - _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false); - Log.I(string.Format($"[PLCInterface]SET PC_WELD_COMPLETE False")); - break; - } - _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - { - Log.E("TIMEOUT_PLC_WELD_COMPLETE_ACK"); - _InterfaceStartTime = DateTime.Now; - } - Thread.Sleep(10); - } - - UpdateProductCount(context); - UpdateProductInfoForView(); - - return SequenceAction.Ok(); - } - - private SequenceActionResult WaitLBADJudge(SequenceContext context, string id, SequenceActionResult param) - { - - - - // 1. LBAD 결과 수신, 확인 & 처리 - //LBAD 결과 받아오는 부분 우선 여기서 추가하여 테스트하고 Sub 시퀀스로 빼자 - if (_LBAD.IsSimul) - { - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false); - Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop false, LBAD is Simul")); - } - else - { - - } - - return SequenceAction.Ok(); - } - - /// - /// 소수점 3제자리 까지 int 반환 - /// - /// - /// 소수점 3제자리까지만 int 변환 - public static int ToIntThousand(double value) - { - decimal decValue = (decimal)value; - return (int)Math.Round(decValue * 100m, MidpointRounding.AwayFromZero); - } - - public List Init_info() - { - List info = new List(); - //Ring #1 _ bead 폭 하한 - info.Add(1.234); - //Ring #1 _ bead 폭 상한 - info.Add(-1.234); - //Ring #1 _ bead 폭 OK/NG 0 OK 1 Ng - info.Add(1); - - //Ring #2 _ bead 폭 하한 - info.Add(2.234); - //Ring #2 _ bead 폭 상한 - info.Add(2.234); - //Ring #2 _ bead 폭 OK/N - info.Add(1); - - //Ring #3 _ bead 폭 하한 - info.Add(2.234); - //Ring #3 _ bead 폭 상한 - info.Add(2.234); - //Ring #3 _ bead 폭 OK/NG - info.Add(1); - - //Ring #4 _ bead 폭 하한 - info.Add(2.234); - //Ring #4 _ bead 폭 상한 - info.Add(2.234); - //Ring #4 _ bead 폭 OK/NG - info.Add(1); - - //Ring #5 _ bead 폭 하한 - info.Add(2.234); - //Ring #5 _ bead 폭 상한 - info.Add(2.234); - //Ring #5 _ bead 폭 OK/NG - info.Add(1); - - //Ring #6 _ bead 폭 하한 - info.Add(2.234); - //Ring #6 _ bead 폭 상한 - info.Add(2.234); - //Ring #6 _ bead 폭 OK/NG - info.Add(1); - - //Spiral #1 _ 가로 하한 - info.Add(2.234); - //Spiral #1 _ 가로 상한 - info.Add(2.234); - //Spiral #1 _ 세로 하한 - info.Add(2.234); - //Spiral #1 _ 세로 상한 - info.Add(2.234); - //Spiral #1 _ bead 폭 OK/NG - info.Add(1); - - //Spiral #2 _ 가로 하한 - info.Add(2.234); - //Spiral #2 _ 가로 상한 - info.Add(2.234); - //Spiral #2 _ 세로 하한 - info.Add(2.234); - //Spiral #2 _ 세로 상한 - info.Add(2.234); - //Spiral #2 _ bead 폭 OK/NG - info.Add(1); - - //Spiral #3 _ 가로 하한 - info.Add(2.234); - //Spiral #3 _ 가로 상한 - info.Add(2.234); - //Spiral #3 _ 세로 하한 - info.Add(2.234); - //Spiral #3 _ 세로 상한 - info.Add(2.234); - //Spiral #3 _ bead 폭 OK/NG - info.Add(1); - - - return info; - } - public static short[] IntArrayToCatShortArray(int[] intArray) - { - short[] shortArray = new short[intArray.Length]; - - for (int i = 0; i < intArray.Length; i++) - { - shortArray[i] = (short)intArray[i]; - } - - return shortArray; - } - - private void UpdatePLCMemoryArea(int startAddress, List result_info) - { - Log.I($"[INFO]bead_result_info: " + string.Join(", ", result_info)); - - - Log.I(string.Format("[PLCInterface]Start Plc Write ...... Map {0:X4}", 0x2500 + startAddress)); - - List resultList = new List(); - - foreach (double info in result_info) - { - resultList.Add(ToIntThousand(info)); - } - - short[] resultShort = IntArrayToCatShortArray(resultList.ToArray()); - Log.I($"[PLCInterface]SET resultShort: " + string.Join(", ", resultShort)); - - int start = 0; - - for (int i = 0; i < resultShort.Length; i++) - { - start = startAddress + i; - - //_PLC.WriteWord(start, resultShort[i]); - Log.I(string.Format("[PLCInterface]SET {0:X4} -> {1:X4} : {2}", 0x2500 + start, resultShort[i], resultShort[i])); - Thread.Sleep(5); - } - - Log.I(string.Format("[PLCInterface]End Plc Write ...... Map {0:X4} / Lenght {1}", 0x2500 + start, resultShort.Length)); - } - - - private SequenceActionResult ReportCellInfoToPLC(SequenceContext context, string id, SequenceActionResult param) - { - - - return SequenceAction.Ok(); - } - - private void UpdatePLCMemoryAreaRecipe(int startAddress, List result_info) - { - Log.I($"[INFO]Recipe_Info: " + string.Join(", ", result_info)); - - short[] info = result_info.ToArray(); - - Log.I(string.Format("[PLCInterface]Start Plc Write ...... Map {0:X4}", 0x2500 + startAddress)); - - int start = 0; - - for (int i = 0; i < info.Length; i++) - { - //_PLC.WriteWord(start, info[i]); - Log.I(string.Format("[PLCInterface]SET {0:X4} -> {1:X4} : {2}", 0x2500 + start, info[i], info[i])); - start = startAddress + i; - Thread.Sleep(5); - } - - Log.I(string.Format("[PLCInterface]End Plc Write ...... Map {0:X4} / Lenght {1}", 0x2500 + start, info.Length)); - } - - public List Get_Recipe_Info() - { - var mainPage = WeldingRecipeManager.GetWeldingPage(); - _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; - _RecipeDrawObjects = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; - - var activatedRecipeId = Application.Current.AuroraEnv().RecipeManager.ActivatedRecipe().Id; - - var scannerObjects = new List(); - - foreach (var item in _ScannerCanvasUserCtrl.Model.Layers[0].Objects) - { - ScannerParam param = null; - - if (item is Arc arc) - { - param = ScannerCanvasUserCtrl.ScannerParams[arc.ScannerParamNo]; - if (param != null) - arcList.Add(new ScannerObjectInfo - { - Object = arc, - LaserPower1 = param.LaserPower1, - LaserPower2 = param.LaserPower2, - JumpSpeed = param.JumpSpeed, - MarkSpeed = param.MarkSpeed - }); - } - else if (item is Line line) - { - param = ScannerCanvasUserCtrl.ScannerParams[line.ScannerParamNo]; - if (param != null) - lineList.Add(new ScannerObjectInfo - { - Object = line, - LaserPower1 = param.LaserPower1, - LaserPower2 = param.LaserPower2, - JumpSpeed = param.JumpSpeed, - MarkSpeed = param.MarkSpeed - }); - } - else if (item is Spline spline) - { - param = ScannerCanvasUserCtrl.ScannerParams[spline.ScannerParamNo]; - if (param != null) - splineList.Add(new ScannerObjectInfo - { - Object = spline, - LaserPower1 = param.LaserPower1, - LaserPower2 = param.LaserPower2, - JumpSpeed = param.JumpSpeed, - MarkSpeed = param.MarkSpeed - }); - } - else if (item is Dot dot) - { - param = ScannerCanvasUserCtrl.ScannerParams[dot.ScannerParamNo]; - if (param != null) - dotList.Add(new ScannerObjectInfo - { - Object = dot, - LaserPower1 = param.LaserPower1, - LaserPower2 = param.LaserPower2, - JumpSpeed = param.JumpSpeed, - MarkSpeed = param.MarkSpeed - }); - } - } - - - List Recipe = new List(); - - Recipe.Add((short)lineList[0].LaserPower1); - Recipe.Add((short)lineList[0].LaserPower2); - Recipe.Add((short)lineList[0].MarkSpeed); - - Recipe.Add((short)arcList[0].LaserPower1); - Recipe.Add((short)arcList[0].LaserPower2); - Recipe.Add((short)arcList[0].MarkSpeed); - - Recipe.Add((short)splineList[0].LaserPower1); - Recipe.Add((short)splineList[0].LaserPower2); - Recipe.Add((short)splineList[0].MarkSpeed); - - return Recipe; - } - - private void WeldingInfoSendPLC(string LBAD, string WELDING) - { - // PLC 영역쓰기 - UpdatePLCMemoryArea((int)eWordOutput.STEP1_Arc1_LowerLimit, result_info[0]); - UpdatePLCMemoryArea((int)eWordOutput.STEP2_Spiral1_HorizontalLowerLimit, result_info[1]); - UpdatePLCMemoryArea((int)eWordOutput.STEP3_Arc1_LowerLimit, result_info[2]); - UpdatePLCMemoryArea((int)eWordOutput.STEP4_Spiral1_HorizontalLowerLimit, result_info[3]); - - // 레시피 값 가져오기 - List recipe = Get_Recipe_Info(); - UpdatePLCMemoryAreaRecipe((int)eWordOutput.Line_LaserPower1, recipe); - - // LBAD 검사 결과 확인 - if (string.Equals(LBAD, "OK")) - { - _PLC.WriteWord((int)eWordOutput.LBADOK_NG, 1); - } - else - { - _PLC.WriteWord((int)eWordOutput.LBADOK_NG, 2); - } - - // 용접후 검사 결과 확인 - if (string.Equals(WELDING, "OK")) - { - _PLC.WriteWord((int)eWordOutput.WeldingOK_NG, 1); - } - else - { - _PLC.WriteWord((int)eWordOutput.WeldingOK_NG, 2); - } - } - - private void SaveExcelFile(Mat img, string ExcelFile) - { - //string ImgFile = string.Format("D:\\ILSOSConfig\\_vision\\Def\\1.png"); - //Mat img = Cv2.ImRead(ImgFile); - //string ExcelFile = string.Format("D:\\ILSOSConfig\\_vision\\Def\\Test.xlsx"); - - var inserter = new ExcelImageInserter(ExcelFile); - - var entry = new ExcelEntry - { - Name = "그림1", - Image = img, - ParametersSets = new List> - { - new List { "파라A", "파라B" }, // 1행 - new List { "뉴욕A", "뉴욕B" } // 2행 - }, - Content = "추가 내용" - }; - - inserter.AddEntry(entry, "MySheet", widthCm: 8, heightCm: 8); - - inserter.Save(); - } - - private string CheckCycleStop(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - { - Status.SetWorkingPosition(eWorkingPosition.CHECKING_CYCLE); - - string strLBADJudge = Status.GetProcessingWeldingData().LBAD_Judge; - Int16 judgeFlag = 0; - string judgeResult = ""; - - _WeldingImage[_PageNoRcc] = _ConvMatImage_after; - - while (!context.Stopped) - { - // 다음 페이지용 PLC 읽기 - _PageNo = GetPagePlc(); - - //Log.I(string.Format($"[PLCInterface]GET PLC_SET_WELD_PAGE {0}", _PageNo)); - - // PLC 에 페이지 써줘야 넘어간다. - SetPagePlc(_PageNo); - - // 다음 시퀀스 대기.. - Thread.Sleep(100); - - if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data) - { - Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True")); - - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false); - Log.I(string.Format($"[IOInterface]LBAD {_PageNo} setp --> SET PCWeldingStop false")); - - if (_ConvMatImage_after != null && !_ConvMatImage_after.Empty()) - { - //string baseDir = @"D:\ImagesTT"; - ////// 원본 이미지 저장 - //string origFileName = $"After{_PageNoRcc}_{DateTime.Now:HHmmss}.png"; - //string origPath = Path.Combine(baseDir, origFileName); - //Cv2.ImWrite(origPath, _ConvMatImage_after); - } - else - { - Log.I(string.Format($"ConvMatImage : {1} _ConvMatImage_after Not............")); - } - - //WeldingInfoSendPLC("OK","OK"); - - bool[] Page = new bool[4]; - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - Log.I(string.Format("[PLCInterface]Pgae Reset")); - - return SEQ_CHECK_PAGENO; - } - else - { - if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data) - { - Log.I(string.Format($"[IOInterface]Get PLC_RESULT_REQUEST True")); - - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false); - Log.I(string.Format($"[IOInterface]LBAD {_PageNo} setp --> SET PCWeldingStop false")); - - _InterfaceStartTime = DateTime.Now; - while (!context.Stopped) - { - if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LBADJudgementComplete))) - { - Log.I(string.Format($"[IOInterface]SET LBADJudgementComplete true")); - - int result = _LBAD.GetResult(out judgeFlag); - if (result == E1.OK) - { - switch (judgeFlag) - { - case 0: - judgeResult = "OK"; - break; - case 1: - judgeResult = "WARNING"; - break; - case 2: - judgeResult = "NA"; - break; - case 3: - judgeResult = "NG"; - break; - case 4: - judgeResult = "ERROR"; - break; - default: - judgeResult = "NG"; - break; - } - } - else - { - // TODO: LBAD 가 not Activated 인 상황이다. error 로 보내야 할꺼 같음. - judgeFlag = 3; - judgeResult = "NG"; - } - - // 경신 페이지 추가하여 검사 내용 추가 - //LBADResultPage[_PageNo - 1] = judgeFlag; - - Log.I(string.Format($"LBAD Judge Flag [kS] : {judgeFlag} PageResult : {judgeResult}")); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), true); - Status.GetProcessingWeldingData().LBAD_Judge = (judgeFlag + 1).ToString(); - Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck true")); - break; - } - - _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - { - Log.E("TIMEOUT_DI_LBADJudgementComplete_TRUE"); - _InterfaceStartTime = DateTime.Now; - } - Thread.Sleep(10); - } - - if (strLBADJudge == "4") - { - _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, true); - Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG True, LBAD Result : {strLBADJudge}")); - } - else if (strLBADJudge != "4") - { - _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, true); - Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK True, LBAD Result : {strLBADJudge}")); - } - - - //WeldingInfoSendPLC("OK","OK"); - - if (_ConvMatImage_after != null && !_ConvMatImage_after.Empty()) - { - //string baseDir = @"D:\ImagesTT"; - ////// 원본 이미지 저장 - //string origFileName = $"After{_PageNoRcc}_{DateTime.Now:HHmmss}.png"; - //string origPath = Path.Combine(baseDir, origFileName); - //Cv2.ImWrite(origPath, _ConvMatImage_after); - - - popup.Show(); - popup.UpdateImages1(_WeldingImage[0], new OpenCvSharp.Rect(1153, 896, 6918, 8056)); - popup.UpdateImages2(_WeldingImage[1], new OpenCvSharp.Rect(1153, 896, 6918, 8056)); - popup.UpdateImages3(_WeldingImage[2], new OpenCvSharp.Rect(1153, 896, 6918, 8056)); - popup.UpdateImages4(_WeldingImage[3], new OpenCvSharp.Rect(1153, 896, 6918, 8056)); - - //popup.SetParameters1(result_info[0]); - //popup.SetParameters2(result_info[1]); - //popup.SetParameters3(result_info[2]); - //popup.SetParameters4(result_info[3]); - - Log.I(string.Format($"ConvMatImage : {2} _ConvMatImage_after End Yes............")); - } - else - { - Log.I(string.Format($"ConvMatImage : {2} _ConvMatImage_after Not............")); - } - - switch (judgeFlag) - { - case 0: - popup.SetStepLBAD("OK"); - break; - - case 3: - popup.SetStepLBAD("NG"); - break; - - default: - popup.SetStepLBAD("NG"); - break; - } - - if (weldingResult) popup.SetStepWELDING("OK"); - else popup.SetStepWELDING("NG"); - - string ExcelFile = string.Format("D:\\ILSOSConfig\\_vision\\Def\\Test.xlsx"); - - SaveExcelFile(_WeldingImage[0], ExcelFile); - SaveExcelFile(_WeldingImage[1], ExcelFile); - SaveExcelFile(_WeldingImage[2], ExcelFile); - SaveExcelFile(_WeldingImage[3], ExcelFile); - - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); - Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck false")); - - bool[] Page = new bool[4]; - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - Log.I(string.Format("[PLCInterface]Pgae Reset")); - - - - return SEQ_CHECK_PAGENO; - } - - Thread.Sleep(100); - } - } - - return SEQ_CHECK_PAGENO; - } - - - //private SequenceActionResult ReportCellInfoToPLC(SequenceContext context, string id, SequenceActionResult param) - //{ - // while (!context.Stopped) - // { - // _PageNo = GetPagePlc(); - - // Thread.Sleep(10); - // if (_PageNo != 0) break; - // } - - // Log.I(string.Format($"[PLCInterface]GET PLC_SET_WELD_PAGE {0}", _PageNo)); - // // PLC 에 페이지 써줘야 넘어간다. - // SetPagePlc(_PageNo); - - // return SequenceAction.Ok(); - //} - - //private string CheckCycleStop(SequenceContext context, string id, ICollection branches, SequenceActionResult param) - //{ - // Status.SetWorkingPosition(eWorkingPosition.CHECKING_CYCLE); - - // string strLBADJudge = Status.GetProcessingWeldingData().LBAD_Judge; - // Int16 judgeFlag = 0; - // string judgeResult = ""; - - // while (!context.Stopped) - // { - // // 다음 시퀀스 대기.. - // Thread.Sleep(10); - // if (_PLC.ReadBit((int)eBitInput.PLC_WELD_REQEUST).data) - // { - // return SEQ_CHECK_PAGENO; - // } - // else - // { - // if (_PLC.ReadBit((int)eBitInput.PLC_RESULT_REQUEST).data) - // { - - // _InterfaceStartTime = DateTime.Now; - // while (!context.Stopped) - // { - // if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LBADJudgementComplete))) - // { - // Log.I(string.Format($"[IOInterface]SET LBADJudgementComplete true")); - // _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false); - // Log.I(string.Format($"[IOInterface]SET PCWeldingStop false")); - - // int result = _LBAD.GetResult(out judgeFlag); - // if (result == E1.OK) - // { - // switch (judgeFlag) - // { - // case 0: - // judgeResult = "OK"; - // break; - // case 1: - // judgeResult = "WARNING"; - // break; - // case 2: - // judgeResult = "NA"; - // break; - // case 3: - // judgeResult = "NG"; - // break; - // case 4: - // judgeResult = "ERROR"; - // break; - // default: - // judgeResult = "NG"; - // break; - // } - // } - // else - // { - // // TODO: LBAD 가 not Activated 인 상황이다. error 로 보내야 할꺼 같음. - // judgeFlag = 3; - // judgeResult = "NG"; - // } - - // // 경신 페이지 추가하여 검사 내용 추가 - // //LBADResultPage[_PageNo - 1] = judgeFlag; - - // Log.I(string.Format($"LBAD Judge Flag [kS] : {judgeFlag} PageResult : {judgeResult}")); - // _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), true); - // Status.GetProcessingWeldingData().LBAD_Judge = (judgeFlag + 1).ToString(); - // Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck true")); - // break; - // } - - // _InterfaceSpanTime = DateTime.Now.Subtract(_InterfaceStartTime); - // if (_InterfaceSpanTime.TotalMilliseconds > (PLC_TIMEOUT * 1000)) - // { - // Log.E("TIMEOUT_DI_LBADJudgementComplete_TRUE"); - // _InterfaceStartTime = DateTime.Now; - // } - // Thread.Sleep(10); - // } - - // // 용접 보고 - // UpdatePLCMemoryArea(); - - - // // PLC 에 LBAD 값 보고 - // if (strLBADJudge == "4") - // { - // _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_NG, true); - // Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_NG True, LBAD Result : {strLBADJudge}")); - // } - // else if (strLBADJudge != "4") - // { - // _PLC.WriteBit((int)eBitOutput.PC_LBAD_RESULT_OK, true); - // Log.I(string.Format($"[PLCInterface]SET PC_LBAD_RESULT_OK True, LBAD Result : {strLBADJudge}")); - // } - - // // 초기화 - // _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); - // Log.I(string.Format($"[IOInterface]SET PCJudgementCompleteAck false")); - - // SetPagePlc(0); - // Log.I(string.Format($"[IOInterface]SET PC_WELD_PAGE_CHANGE_COMPLETE {0}")); - - // return SEQ_CHECK_PAGENO; - // } - // Thread.Sleep(10); - // } - // } - - // return SEQ_CHECK_PAGENO; - //} - - private void UpdateProductCount(SequenceContext context) - { - string currentDate = DateTime.Now.ToString("yyyy-MM-dd"); - if (_SystemParameter.CurrentDate != currentDate) - { - _TodayProduct = 0; - _SystemParameter.CurrentDate = currentDate; - } - else - { - _TodayProduct = _SystemParameter.TodayProductCount; - } - if (_TodayProduct < uint.MaxValue) - { - _TodayProduct++; - } - if (_TotalProduct < uint.MaxValue) - { - _TotalProduct++; - } - _SystemParameter.TodayProductCount = _TodayProduct; - _SystemParameter.TotalProductCount = _TotalProduct; - - //Systemparameter Save - context.Settings.Save(CommonSettingIds.SystemParameter, _SystemParameter, "SeqAutoRunKS_New"); - } - - private void UpdateProductInfoForView() - { - Status.GetProcessingWeldingData().TotalProduct = _TotalProduct; - Status.GetProcessingWeldingData().TodayProduct = _TodayProduct; - - Status.GetProcessingWeldingData().AutoRunStartTime = _AutoRunStartTime; - - Status.GetProcessingWeldingData().WeldingStartTime = _WeldingStartTime; - Status.GetProcessingWeldingData().WeldingEndTime = _WeldEndTime; - Status.GetProcessingWeldingData().WeldingSpanTimeMilliseconds = _WeldingSpanTime.TotalMilliseconds.ToString(); - - Status.GetProcessingWeldingData().LotId = _LotId; - Status.GetProcessingWeldingData().CellId = _CellId; - } - - // TODO: ImageUtil 에 있는 함수를 사용하도록 수정 필요 - private void SaveScoutImage(MIL_ID imageID) - { - // 테스트를 위해서 저장한다. 테스트 끝나고 삭제할것 - Log.I(string.Format($"Start to store completed field scan image")); - string fieldScanImageFile = ""; - - //4.스캐너 필드 이미지 파일 저장 - fieldScanImageFile = System.IO.Path.Combine(ConfigurationManager.AppSettings.Get("DATA_PATH"), "_vision", "RealTimeScout", - string.Format($"{DateTime.Now.Year}_{DateTime.Now.Month}_{DateTime.Now.Day}/{DateTime.Now.ToString("HHmmss")}.PNG")); - - //5.압축하여 저장 - //CompressSaveImage(imageID, fieldScanImageFile, MIL.M_JPEG_LOSSY, 10); - SaveImage(imageID, fieldScanImageFile, MIL.M_PNG); - } - - private bool SaveImage(MIL_ID image, string filePath, MIL_INT format) - { - string directoryName = Path.GetDirectoryName(filePath); - if (Directory.Exists(directoryName) == false) - { - Directory.CreateDirectory(directoryName); - } - - MIL.MbufExport(filePath, format, image); - - return true; - } - - private SequenceActionResult SaveResultData(SequenceContext context, string id, SequenceActionResult param) - { - context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true); - return SequenceAction.Ok(); - } - - private SequenceActionResult WriteCompletionPLCBit(SequenceContext context, string id, SequenceActionResult param) - { - // 완료 비트 write 하는 Node 추가 필요. format 유지, ReceiveCellInfo 없음 - Log.D("AutoRun Sequence WriteCompletionPLCBit"); - - return SequenceAction.Ok(); - } - - private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param) - { - RestoreDeviceStatus(); - Log.I("AutoRun Complete"); - - context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult); - SeqAutoRunKS_New_OutParam result = new SeqAutoRunKS_New_OutParam() { Success = seqResult }; - - if (seqResult == false) - { - AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_ResultFailed); - } - - Log.D("AutoRun Sequence Complete"); - Status.SetWorkingPosition(eWorkingPosition.DONE); - - return SequenceAction.Ok(result); - } - - private bool RestoreDeviceStatus() - { - //PLC All BIT OFF - _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false); - _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false); - _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false); - _PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, false); - _PLC.WriteBit((int)eBitOutput.PC_RECIPE_PARAM_UPLOAD_COMPLETE, false); - Log.I(string.Format("[PLCInterface]PC All Bit Off")); - - bool[] Page = new bool[4]; - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - Log.I(string.Format("[PLCInterface]Pgae Reset")); - - //LBAD IO All BIT OFF - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); - Log.I(string.Format("[IOInterface]PC All Bit Off")); - - _LBAD.SetReadybyAuto(false); - - #region _StreamLightLBAD - //LBAD Ready Off - ////_LBAD.SetReadybyAuto(false); - //if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false) { - // Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null")); - //} - #endregion - - //Laser Off - _Laser.LaserOff(); - - //List 실행 종료 - _Scanner.StopExecution(); - - //Anlog 출력 0으로 변경, efunctiontype을 command로 변경해주면 list가 아니라 직접 변경됨 - _Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND); - _Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND); - - //Scanner 원점 복귀 - _Scanner.JumpAbs(0, 0, eFunctionType.COMMAND); - - //Vision Correctiong 파일 변경 - _Scanner.SelectCorrectionTable(1); - - //Recipe를 기존에 Manual에서 작업하던 화면으로 rollback - WeldingRecipeManager.RollbackRecipe(); - - return true; - } - - private void OnForceError(SequenceContext arg1, string arg2) - { - OnSeqActionStop(); - - Log.I("SequenceAction Ok : OnForceError"); - } - - private void OnStopped(SequenceContext obj) - { - OnSeqActionStop(); - - Log.I("SequenceAction Ok : OnStopped"); - } - - private void OnSeqActionStop() - { - //PLC All BIT OFF - _PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false); - _PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false); - _PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false); - _PLC.WriteBit((int)eBitOutput.PC_AUTO_STATUS, false); - _PLC.WriteBit((int)eBitOutput.PC_RECIPE_PARAM_UPLOAD_COMPLETE, false); - Log.I(string.Format("[PLCInterface]PC All Bit Off")); - - bool[] Page = new bool[4]; - Page = new bool[4] { false, false, false, false }; - _PLC.WriteBitBlock((int)eBitOutput.PC_WELD_PAGE_CHANGE_COMPLETE_1, 4, Page); - Log.I(string.Format("[PLCInterface]Pgae Reset")); - - //LBAD IO All BIT OFF - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false); - _IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false); - Log.I(string.Format("[IOInterface]PC All Bit Off")); - - _LBAD.SetReadybyAuto(false); - - #region _StreamLightLBAD - //LBAD Ready Off - ////_LBAD.SetReadybyAuto(false); - //if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_Off) == false) - //{ - // Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null")); - //} - #endregion - - //Laser Off - _Laser.LaserOff(); - - //List 실행 종료 - _Scanner.StopExecution(); - - //Anlog 출력 0으로 변경, efunctiontype을 command로 변경해주면 list가 아니라 직접 변경됨 - _Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND); - _Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND); - - //Scanner 원점 복귀 - _Scanner.JumpAbs(0, 0, eFunctionType.COMMAND); - - //Vision Correctiong 파일 변경 - _Scanner.SelectCorrectionTable(1); - - - - //Recipe를 기존에 Manual에서 작업하던 화면으로 rollback - WeldingRecipeManager.RollbackRecipe(); - } - - } - // For CSV 저장용 - public class CenterPositionData : NotifyPropertyChangedBase - { - private double _CenterX; - public double CenterX { get => _CenterX; set => SetProperty(ref _CenterX, value); } - private double _CenterY; - public double CenterY { get => _CenterY; set => SetProperty(ref _CenterY, value); } - } - - public class SeqAutoRunKS_New_InitParam : InitParam - { - public ScoutSeqParams ScoutSeqParams { get; set; } - - } - - public class SeqAutoRunKS_New_OutParam : OutParam - { - - } - - public class ScannerObjectInfo - { - public object Object { get; set; } // Arc, Line, Spline, Dot - public uint LaserPower1 { get; set; } - public uint LaserPower2 { get; set; } - public double JumpSpeed { get; set; } - public double MarkSpeed { get; set; } - } -} \ No newline at end of file diff --git a/WeldingComponents/WeldingCommon/RCCAlgorithm/ObjectGenerator.cs b/WeldingComponents/WeldingCommon/RCCAlgorithm/ObjectGenerator.cs index 38e27b8..bd9762e 100644 --- a/WeldingComponents/WeldingCommon/RCCAlgorithm/ObjectGenerator.cs +++ b/WeldingComponents/WeldingCommon/RCCAlgorithm/ObjectGenerator.cs @@ -23,8 +23,7 @@ using Aurora; using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; -namespace WeldingCommon.Vision.WeldingObjectGenerator -{ +namespace WeldingCommon.Vision.WeldingObjectGenerator { using TPolygon = List; using TPoint = GeometryLibrary.TPoint; using Vector2 = GeometryLibrary.Vector2; @@ -34,11 +33,10 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator using static System.Windows.Forms.VisualStyles.VisualStyleElement.Menu; using Point = OpenCvSharp.Point; using Size = OpenCvSharp.Size; - - + + // Pixel Data 로부터 Welding Object 를 생성하는 Path List 를 만드는 Class - public class ObjectGenerator - { + public class ObjectGenerator { #region Properties private readonly Logger Log = new Logger("WeldingObjectGenerator"); @@ -81,13 +79,12 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator private bool is_manual = true; private bool EnableAutoMissAlign = false; private int end_point_index = 0; - + #region Original Path 의 정보를 가진 properties //private bool bArcHasRamping; // m_OriginArc 가 Ramping 을 하는 경우 true //private stRampingInfo m_RampingStartInfo; //private stRampingInfo m_RampingEndInfo; - struct stRampingInfo - { + struct stRampingInfo { public int m_Count; // Ramping Count public double length; // Ramping 전체 구간 길이 public double Intervallength; // 1-count 의 원호 길이. rampling 의 전체 길이 / Ramping Count 임. parameter 에 인터벌 값을 직접 입력해서 쓰는듯. @@ -181,14 +178,12 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(thres_img, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); - if (contours.Length > 0) - { + if (contours.Length > 0) { contours = contours.OrderByDescending(c => Cv2.ContourArea(c)).ToArray(); RotatedRect rotatedRect = Cv2.MinAreaRect(contours[0]); return rotatedRect; } - else - { + else { return new RotatedRect(); } @@ -196,8 +191,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator public (Point, float, Point2f[]) find_rectangle_center(Mat imageColor, OpenCvSharp.Rect[] ROIs, int threshold) { Point2f[] points = new Point2f[4]; - for (int i = 0; i < 4; i++) - { + for (int i = 0; i < 4; i++) { Mat gray_img = new Mat(imageColor, ROIs[i]); Cv2.CvtColor(gray_img, gray_img, ColorConversionCodes.BGR2GRAY); Mat thres_img = new Mat(); @@ -205,14 +199,12 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(thres_img, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); - if (contours.Length > 0) - { + if (contours.Length > 0) { contours = contours.OrderByDescending(c => Cv2.ContourArea(c)).ToArray(); RotatedRect rotatedRect = Cv2.MinAreaRect(contours[0]); points[i] = new Point(rotatedRect.Center.X + ROIs[i].X, rotatedRect.Center.Y + ROIs[i].Y); } - else - { + else { return (new Point(), 0, new Point2f[0]); } } @@ -232,8 +224,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Mat rotated_Image_ROI = new Mat(rotated_Image, new OpenCvSharp.Rect(Image.Width / 2 - ROIW, Image.Height / 2 - ROIH / 2, ROIW, ROIH)); //Cv2.ImWrite($"D:/r_i_{DateTime.Now.ToString("MMdd-HHmmssff")}.png", rotated_Image_ROI); int[] sum_array = new int[ROIW + 1]; - for (int i = 0; i < ROIW; i++) - { + for (int i = 0; i < ROIW; i++) { var sum_val = 0; for (int j = 0; j < ROIH; j++) sum_val += (int)rotated_Image_ROI.At(j, i); sum_array[i + 1] = sum_val + sum_array[i]; @@ -252,12 +243,10 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator //start point 찾기 double max_diff = -Double.MaxValue; var end_bead = ROI.Width - 10; - for (int i = ROI.Width - 10; i > 50; i--) - { + for (int i = ROI.Width - 10; i > 50; i--) { double my_diff = (double)(sum_array[ROI.Width - 1] - sum_array[i + 1]) / (double)(ROI.Width - i - 2) - (double)(sum_array[i]) / (double)(i); - if (my_diff > max_diff) - { + if (my_diff > max_diff) { max_diff = my_diff; end_bead = i; } @@ -265,11 +254,9 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator //end point 찾기 max_diff = -Double.MaxValue; var start_bead = 5; - for (int i = end_bead - search_gap; i > 5; i--) - { + for (int i = end_bead - search_gap; i > 5; i--) { double my_diff = (double)(sum_array[end_bead] - sum_array[i + 1]) / (double)(end_bead - i - 1) - (double)sum_array[i] / (double)i; - if (-my_diff > max_diff) - { + if (-my_diff > max_diff) { max_diff = -my_diff; start_bead = i; } @@ -299,8 +286,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Mat diff = new Mat(); diff = gray_next_img.Clone(); //type 0 : Arc, type 1: Spiral - if (type == 0) - { + if (type == 0) { string modelPath = "D:\\ILSOSConfig\\_config_model\\Unet_ring.onnx"; //Cv2.ImWrite($"D:/ring_{DateTime.Now.ToString("MMdd-HHmmssff")}.png", diff); @@ -311,10 +297,8 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Cv2.Resize(gray_next_img, resized_image, new Size(256, 256)); var inputTensor = new DenseTensor(new[] { 1, 1, 256, 256 }); - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { inputTensor[0, 0, y, x] = (resized_image.At(y, x) / 255.0f - 0.5f) / 0.5f; //inputTensor[0, 0, y, x] = (resized_image.At(y, x) / 255.0f); } @@ -333,39 +317,44 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator var output = results.First().AsEnumerable().ToArray(); var outputImage = new Mat(256, 256, MatType.CV_8UC1); - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { outputImage.Set(y, x, (byte)(output[y * 256 + x] > 0.2 ? 255 : 0)); } } Cv2.Resize(outputImage, outputImage, new Size(gray_next_img.Width, gray_next_img.Height)); - // 추가 2025/09/04 - Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(9, 9)); - Cv2.MorphologyEx(outputImage, outputImage, MorphTypes.Close, kernel, iterations: 10); + // 추가 2025/09/04 >> 260206 변경 + //Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(9, 9)); + //Cv2.MorphologyEx(outputImage, outputImage, MorphTypes.Close, kernel, iterations: 10); Cv2.FindContours(outputImage, out Point[][] contours, out _, RetrievalModes.External, ContourApproximationModes.ApproxSimple); // Assuming the largest contour is the ring Point[] largestContour = null; double maxArea = 0; - foreach (var contour in contours) - { + foreach (var contour in contours) { double area = Cv2.ContourArea(contour); - if (area > maxArea) - { + if (area > maxArea) { maxArea = area; largestContour = contour; } } + + //260206 변경 + var sorted = contours.OrderByDescending(c => Cv2.ContourArea(c)).ToArray(); + for (int i = 1; i < sorted.Length; i++) + Cv2.DrawContours(outputImage, new[] { sorted[i] }, -1, Scalar.Black, -1); + +                //  추가 2025/09/04 +                Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(9, 9)); + Cv2.MorphologyEx(outputImage, outputImage, MorphTypes.Close, kernel, iterations: 10); + int[] bead_size_info = new int[4]; Point[] start_bead_point_info = new Point[4]; Point[] end_bead_point_info = new Point[4]; double[] check_theata_list = new double[4] { -80, 100, 10, 190 }; - if (largestContour != null) - { + if (largestContour != null) { // Find the center of the ring Moments moments = Cv2.Moments(largestContour); int centerX = (int)(moments.M10 / moments.M00); @@ -374,8 +363,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // Define the angles in radians double[] angles = { 4 * Math.PI / 6, 7 * Math.PI / 6, 10 * Math.PI / 6, 1 * Math.PI / 6 }; - for (int i = 0; i < 4; i++) - { + for (int i = 0; i < 4; i++) { var angle = angles[i]; // Calculate the coordinates of the points at the specified angles int x1 = centerX + (int)(1000 * Math.Cos(angle)); @@ -393,13 +381,10 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int cnt = 0; // 추가 2025/09/04 - foreach (var point in lineIterator) - { + foreach (var point in lineIterator) { cnt += 1; - if (outputImage.At(point.Pos.Y, point.Pos.X) == 255) - { - if (!insideRing) - { + if (outputImage.At(point.Pos.Y, point.Pos.X) == 255) { + if (!insideRing) { insideRing = true; start_bead_point = new Point(ROI.X + point.Pos.X, point.Pos.Y + ROI.Y); } @@ -456,8 +441,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator //} //return (bead_size_info, start_bead_point_info, end_bead_point_info, new Point[0][]); } - else - { + else { string modelPath = "D:\\ILSOSConfig\\_config_model\\Unet_spiral.onnx"; // ONNX 모델 로드 @@ -467,10 +451,8 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Cv2.Resize(gray_next_img, resized_image, new Size(256, 256)); var inputTensor = new DenseTensor(new[] { 1, 1, 256, 256 }); - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { inputTensor[0, 0, y, x] = (resized_image.At(y, x) / 255.0f - 0.5f) / 0.5f; } } @@ -488,10 +470,8 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator var output = results.First().AsEnumerable().ToArray(); var outputImage = new Mat(256, 256, MatType.CV_8UC1); - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { outputImage.Set(y, x, (byte)(output[y * 256 + x] > 0.6 ? 255 : 0)); } } @@ -505,8 +485,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Point[] start_bead_point_info = new Point[2]; Point[] end_bead_point_info = new Point[2]; // 가장 큰 윤곽선 선택 - if (contours.Length > 0) - { + if (contours.Length > 0) { contours = contours.OrderByDescending(c => Cv2.ContourArea(c)).ToArray(); if (contours[0].Length < 5) return (new int[2], new Point[1], new Point[0], new Point[0][]); Mat maxCntImg = new Mat(gray_next_img.Width, gray_next_img.Height, MatType.CV_8UC1, Scalar.Black); @@ -619,8 +598,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator public void SetInterlockProperties(double DistRange, double dArcLength, double dPathLengthSumRange, double dCenterXYDiffRange, int eMaxMinDiffHigh, int eMaxMinDiffLow, int checkCenterDiff, int distortionCenterDiff, float MissAlignHigh, float MissAlignLow) { - if (DistRange < 0 || dArcLength < 0) - { + if (DistRange < 0 || dArcLength < 0) { dInterlockDistRange = 1.0; return; } @@ -735,13 +713,11 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int RampingEndFinalIndex = 0; double dCalStartDist = 0.0; - for (int i = 1; i < rearranged_polygon.Count; i++) - { + for (int i = 1; i < rearranged_polygon.Count; i++) { double distx = rearranged_polygon[i].x - rearranged_polygon[i - 1].x; double disty = rearranged_polygon[i].y - rearranged_polygon[i - 1].y; dCalStartDist += Math.Sqrt(distx * distx + disty * disty); - if (dCalStartDist > dRampingStartPixelLength) - { + if (dCalStartDist > dRampingStartPixelLength) { RampingStartFinalIndex = i; break; } @@ -749,13 +725,11 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator double dCalEndDist = 0.0; - for (int i = rearranged_polygon.Count - 1; i > 1; i--) - { + for (int i = rearranged_polygon.Count - 1; i > 1; i--) { double distx = rearranged_polygon[i].x - rearranged_polygon[i - 1].x; double disty = rearranged_polygon[i].y - rearranged_polygon[i - 1].y; dCalEndDist += Math.Sqrt(distx * distx + disty * disty); - if (dCalEndDist > dRampingEndPixelLength) - { + if (dCalEndDist > dRampingEndPixelLength) { RampingEndFinalIndex = i; break; } @@ -846,8 +820,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator if (dEndAngle < 0.0) arc.EndAngle = (float)(dEndAngle + 360.0); else arc.EndAngle = (float)dEndAngle; arc.SweepAngle = arc.EndAngle - arc.StartAngle; - if (arc.SweepAngle > 0 && arc.Direction == Arc.eDirection.CW) - { + if (arc.SweepAngle > 0 && arc.Direction == Arc.eDirection.CW) { arc.SweepAngle -= 360; } @@ -877,10 +850,8 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator { List ConvertedDrawObjects = new List(); int no = 0; - foreach (var item in lsPaths) - { - if (item.GetType() == PathItem._PathType.Line) - { + foreach (var item in lsPaths) { + if (item.GetType() == PathItem._PathType.Line) { UnitPoint dStartPoint, dEndPoint; Int64 lx, ly; item.GetStart(out lx, out ly); @@ -894,8 +865,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator ConvertedDrawObjects.Add(lineitem); // parameter ID 는 어떻게? } - else if (item.GetType() == PathItem._PathType.Arc) - { + else if (item.GetType() == PathItem._PathType.Arc) { Canvas.Arc arcitem; ConvertPathArcToDrawingArc(item, image, originArc, out arcitem); @@ -908,8 +878,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator ConvertedDrawObjects.Add(arcitem); } - else - { + else { // 이런 경우 없다 } no++; @@ -955,8 +924,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator if ((param.RampingStartDist > 0 || param.RampingEndDist > 0) && (param.RampingStartDist + param.RampingEndDist < radius * Math.Abs(originArc.SweepAngle)) - && !param.WobbelEnable && !param.SnowManEnable) - { + && !param.WobbelEnable && !param.SnowManEnable) { bArcHasRamping = true; // 1.1. 데이터테이블 기준으로 파워 동작 //percentLaser1 = (float)_laserPowerCalParam.CalibrateWattToPercent(param.LaserPower1, (uint)eAnalogPortOut.DA1); @@ -986,13 +954,11 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator } #endregion - if (bArcHasRamping == false) - { + if (bArcHasRamping == false) { destDrawObjects = srcDrawObjects; return; } - else - { + else { destDrawObjects = new List(); int no = 0; @@ -1009,28 +975,24 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // raming start 구간이 끝나는 index 를 먼저 찾는다. - for (int i = 0; i < srcDrawObjects.Count; i++) - { + for (int i = 0; i < srcDrawObjects.Count; i++) { double objlength = 0; if (srcDrawObjects[i] is Line) objlength = ((Line)srcDrawObjects[i]).Distance; else objlength = ((Arc)srcDrawObjects[i]).Length; dStartRampingLengthSum += objlength; - if (dStartRampingLengthSum > m_RampingStartInfo.length) - { + if (dStartRampingLengthSum > m_RampingStartInfo.length) { rampingstartfinishedindex = i; break; } } // raming end 구간이 시작되는 index 를 먼저 찾는다. double dEndrampingPreDistance = 0; - for (int i = srcDrawObjects.Count - 1; i >= 0; i--) - { + for (int i = srcDrawObjects.Count - 1; i >= 0; i--) { double objlength = 0; if (srcDrawObjects[i] is Line) objlength = ((Line)srcDrawObjects[i]).Distance; else objlength = ((Arc)srcDrawObjects[i]).Length; dEndRampingLengthSum += objlength; - if (dEndRampingLengthSum > m_RampingEndInfo.length) - { + if (dEndRampingLengthSum > m_RampingEndInfo.length) { rampingendbeginindex = i; dEndrampingPreDistance = dEndRampingLengthSum - m_RampingEndInfo.length; break; @@ -1042,30 +1004,24 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // ramping start 구간 // 앞쪽부터 채운다. - if (m_RampingStartInfo.length > 0) - { - for (int i = 0; i <= rampingstartfinishedindex; i++) - { - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { + if (m_RampingStartInfo.length > 0) { + for (int i = 0; i <= rampingstartfinishedindex; i++) { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { dRampingResidueLength = 0; break; } var obj = srcDrawObjects[i]; - if (obj is Line) - { + if (obj is Line) { UnitPoint dStartPoint = new UnitPoint(obj.PF1); UnitPoint dEndPoint = new UnitPoint(obj.PF2); Canvas.Line lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); - if (dRampingResidueLength > 0) - { + if (dRampingResidueLength > 0) { // 전회차에 남은 거리를 object 로 만들어줬다면 모자란 만큼을 처음 object 로 만들어준다. - if (lineitem.Distance < dRampingResidueLength) - { + if (lineitem.Distance < dRampingResidueLength) { // 다음 object 가 모자란 양을 다 못채우는 경우. 즉, 길이가 더 짧은 경우임. (사실상 ramping interval 이 더 짧아서 이런경우는 없을듯) dRampingResidueLength -= lineitem.Distance; lineitem.No = no++; @@ -1074,8 +1030,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dStartRampingLengthSum += lineitem.Distance; continue; } - else - { + else { lineitem.Distance = dRampingResidueLength; dRampingResidueLength = 0; lineitem.No = no++; @@ -1084,8 +1039,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dStartRampingLengthSum += lineitem.Distance; dStartPoint = new UnitPoint(lineitem.PF2); - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { // 구간길이를 모두 채우면 다음 object 이어 붙이고 종료 lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // Ramping Object 아님 @@ -1100,8 +1054,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // while 돌리기 전에 비교를 위해서 라인을 먼저 만든다. // 중간지점 interval 길이만큼 반복으로 채워준다. - while (lineitem.Distance > m_RampingStartInfo.Intervallength) - { + while (lineitem.Distance > m_RampingStartInfo.Intervallength) { lineitem.Distance = m_RampingStartInfo.Intervallength; dRampingResidueLength = 0; lineitem.No = no++; @@ -1111,8 +1064,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dStartPoint = new UnitPoint(lineitem.PF2); lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // while 돌리기 전에 비교를 위해서 라인을 먼저 만든다. - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; @@ -1125,32 +1077,27 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator destDrawObjects.Add(lineitem); dStartRampingLengthSum += lineitem.Distance; - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; } - else - { + else { // 여기까지오면 interval 보다 짧은 구간만 남는다. 채워넣어주고 모자란 길이를 residue 로 기록하자. dRampingResidueLength = m_RampingStartInfo.Intervallength - lineitem.Distance; } } - else if (obj is Arc) - { + else if (obj is Arc) { UnitPoint dStartPoint = new UnitPoint(obj.PF1); UnitPoint dEndPoint = new UnitPoint(obj.PF2); Canvas.Arc arcitem = (Canvas.Arc)obj.Clone(); - if (dRampingResidueLength > 0) - { + if (dRampingResidueLength > 0) { // 전회차에 남은 거리를 object 로 만들어줬다면 모자란 만큼을 처음 object 로 만들어준다. - if (arcitem.Length < dRampingResidueLength) - { + if (arcitem.Length < dRampingResidueLength) { // 다음 object 가 모자란 양을 다 못채우는 경우. 즉, 길이가 더 짧은 경우임. (사실상 ramping interval 이 더 짧아서 이런경우는 없을듯) dRampingResidueLength -= arcitem.Length; arcitem.No = no++; @@ -1159,8 +1106,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dStartRampingLengthSum += arcitem.Length; continue; } - else - { + else { dEndPoint = new UnitPoint(arcitem.PF2.X, arcitem.PF2.Y); arcitem.Length = (float)dRampingResidueLength; dRampingResidueLength = 0; @@ -1170,8 +1116,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dStartRampingLengthSum += (double)(arcitem.Length); dStartPoint = new UnitPoint(arcitem.PF2); - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { // 구간길이를 모두 채우면 다음 object 이어 붙이고 종료 arcitem = (Canvas.Arc)obj.Clone(); arcitem.PF1 = new PointF((float)dStartPoint.X, (float)dStartPoint.Y); @@ -1189,8 +1134,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator arcitem = (Canvas.Arc)obj.Clone(); arcitem.PF1 = new PointF((float)dStartPoint.X, (float)dStartPoint.Y); // while 돌리기 전에 비교를 위해서 라인을 먼저 만든다. // 중간지점 interval 길이만큼 반복으로 채워준다. - while (arcitem.Length > m_RampingStartInfo.Intervallength) - { + while (arcitem.Length > m_RampingStartInfo.Intervallength) { dEndPoint = new UnitPoint(arcitem.PF2.X, arcitem.PF2.Y); arcitem.Length = (float)m_RampingStartInfo.Intervallength; dRampingResidueLength = 0; @@ -1203,8 +1147,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator arcitem.PF1 = new PointF((float)dStartPoint.X, (float)dStartPoint.Y); arcitem.PF2 = new PointF((float)dEndPoint.X, (float)dEndPoint.Y); - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; @@ -1217,27 +1160,23 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator destDrawObjects.Add(arcitem); dStartRampingLengthSum += arcitem.Length; - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; rampingstartfinishedindex = i; break; } - else - { + else { // 여기까지오면 interval 보다 짧은 구간만 남는다. 채워넣어주고 모자란 길이를 residue 로 기록하자. dRampingResidueLength = m_RampingStartInfo.Intervallength - arcitem.Length; } } - else - { + else { // 없음 } } } - else - { + else { //StartRamping을 안쓸경우 rampingstartfinishedindex를 0번부터 만들어줘야하는데.. 쓸 경우는 아래 for문에서 +1을 줘야하니깐 여기서 빼주자 rampingstartfinishedindex -= 1; } @@ -1251,30 +1190,25 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator if (m_RampingStartInfo.length > 0 && m_RampingEndInfo.length == 0) rampingendbeginindex += 1; - for (int i = rampingstartfinishedindex + 1; i < rampingendbeginindex; i++) - { + for (int i = rampingstartfinishedindex + 1; i < rampingendbeginindex; i++) { var obj = srcDrawObjects[i]; obj.No = no++; - if (obj is Line) - { + if (obj is Line) { ((Line)obj).MadebyRCC = true; } - else if (obj is Arc) - { + else if (obj is Arc) { ((Arc)obj).MadebyRCC = true; } - else - { + else { // 이런 경우가 없음 여기로 오면 예외처리 할 것. } destDrawObjects.Add(obj); } - if (m_RampingEndInfo.length > 0) - { + if (m_RampingEndInfo.length > 0) { // ramping end 구간 List RampingEndtDrawObjects = new List(); @@ -1283,8 +1217,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dEndRampingLengthSum = 0; var obj = srcDrawObjects[rampingendbeginindex]; // ramping 아닌 구간을 먼저 채운다. - if (obj is Line) - { + if (obj is Line) { UnitPoint dStartPoint = new UnitPoint(obj.PF1); UnitPoint dEndPoint = new UnitPoint(obj.PF2); @@ -1299,8 +1232,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // while 돌리기 전에 비교를 위해서 라인을 먼저 만든다. // 중간지점 interval 길이만큼 반복으로 채워준다. - while (lineitem.Distance > m_RampingEndInfo.Intervallength) - { + while (lineitem.Distance > m_RampingEndInfo.Intervallength) { lineitem.Distance = m_RampingEndInfo.Intervallength; dRampingResidueLength = 0; lineitem.No = no++; @@ -1310,8 +1242,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dStartPoint = new UnitPoint(lineitem.PF2); lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // while 돌리기 전에 비교를 위해서 라인을 먼저 만든다. - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; @@ -1324,19 +1255,16 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator destDrawObjects.Add(lineitem); dEndRampingLengthSum += lineitem.Distance; - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; } - else - { + else { // 여기까지오면 interval 보다 짧은 구간만 남는다. 채워넣어주고 모자란 길이를 residue 로 기록하자. dRampingResidueLength = m_RampingEndInfo.Intervallength - lineitem.Distance; } } - else if (obj is Arc) - { + else if (obj is Arc) { UnitPoint dStartPoint = new UnitPoint(obj.PF1); UnitPoint dEndPoint = new UnitPoint(obj.PF2); @@ -1355,8 +1283,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator arcitem.PF2 = new PointF((float)dEndPoint.X, (float)dEndPoint.Y); // 여기부터 ramping 구간 - while (arcitem.Length > m_RampingEndInfo.Intervallength) - { + while (arcitem.Length > m_RampingEndInfo.Intervallength) { arcitem.Length = (float)m_RampingEndInfo.Intervallength; dRampingResidueLength = 0; arcitem.No = no++; @@ -1368,16 +1295,14 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator arcitem.PF1 = new PointF((float)dStartPoint.X, (float)dStartPoint.Y); arcitem.PF2 = new PointF((float)dEndPoint.X, (float)dEndPoint.Y); - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; } } // 마지막 남은 잔여 길이 넣음. 위에 while 문에서 경로 생성이 끝났다면 남은 구간 전체를 넣고 종료. 생성이 안끝났어도 남은 구간을 다 넣고 다음 경로로 이동. 남은양을 전달한다. - if (arcitem.Length > 0 && dEndRampingLengthSum < m_RampingEndInfo.length) - { + if (arcitem.Length > 0 && dEndRampingLengthSum < m_RampingEndInfo.length) { arcitem.No = no++; arcitem.MadebyRCC = true; destDrawObjects.Add(arcitem); @@ -1389,28 +1314,23 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // 첫번째 item 입력 완료 // 2번째 이후가 있다면 아래 실행. - for (int i = rampingendbeginindex + 1; i < srcDrawObjects.Count; i++) - { - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + for (int i = rampingendbeginindex + 1; i < srcDrawObjects.Count; i++) { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { dRampingResidueLength = 0; break; } obj = srcDrawObjects[i]; - if (obj is Line) - { + if (obj is Line) { UnitPoint dStartPoint = new UnitPoint(obj.PF1); UnitPoint dEndPoint = new UnitPoint(obj.PF2); Canvas.Line lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); - if (dRampingResidueLength > 0) - { + if (dRampingResidueLength > 0) { // 전회차에 남은 거리를 object 로 만들어줬다면 모자란 만큼을 처음 object 로 만들어준다. - if (lineitem.Distance < dRampingResidueLength) - { + if (lineitem.Distance < dRampingResidueLength) { // 다음 object 가 모자란 양을 다 못채우는 경우. 즉, 길이가 더 짧은 경우임. (사실상 ramping interval 이 더 짧아서 이런경우는 없을듯) dRampingResidueLength -= lineitem.Distance; lineitem.No = no++; @@ -1419,8 +1339,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dEndRampingLengthSum += lineitem.Distance; continue; } - else - { + else { lineitem.Distance = dRampingResidueLength; dRampingResidueLength = 0; lineitem.No = no++; @@ -1429,8 +1348,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dEndRampingLengthSum += lineitem.Distance; dStartPoint = new UnitPoint(lineitem.PF2); - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 object 이어 붙이고 종료 lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // Ramping Object 아님 @@ -1445,8 +1363,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // while 돌리기 전에 비교를 위해서 라인을 먼저 만든다. // 중간지점 interval 길이만큼 반복으로 채워준다. - while (lineitem.Distance > m_RampingEndInfo.Intervallength) - { + while (lineitem.Distance > m_RampingEndInfo.Intervallength) { lineitem.Distance = m_RampingEndInfo.Intervallength; dRampingResidueLength = 0; lineitem.No = no++; @@ -1456,8 +1373,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dStartPoint = new UnitPoint(lineitem.PF2); lineitem = new Canvas.Line(dStartPoint, dEndPoint, fLineDefualtWidth, Color.Blue); // while 돌리기 전에 비교를 위해서 라인을 먼저 만든다. - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; @@ -1470,32 +1386,27 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator destDrawObjects.Add(lineitem); dEndRampingLengthSum += lineitem.Distance; - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; } - else - { + else { // 여기까지오면 interval 보다 짧은 구간만 남는다. 채워넣어주고 모자란 길이를 residue 로 기록하자. dRampingResidueLength = m_RampingEndInfo.Intervallength - lineitem.Distance; } } - else if (obj is Arc) - { + else if (obj is Arc) { UnitPoint dStartPoint = new UnitPoint(obj.PF1); UnitPoint dEndPoint = new UnitPoint(obj.PF2); Canvas.Arc arcitem = (Canvas.Arc)obj.Clone(); - if (dRampingResidueLength > 0) - { + if (dRampingResidueLength > 0) { // 전회차에 남은 거리를 object 로 만들어줬다면 모자란 만큼을 처음 object 로 만들어준다. - if (arcitem.Length < dRampingResidueLength) - { + if (arcitem.Length < dRampingResidueLength) { // 다음 object 가 모자란 양을 다 못채우는 경우. 즉, 길이가 더 짧은 경우임. (사실상 ramping interval 이 더 짧아서 이런경우는 없을듯) dRampingResidueLength -= arcitem.Length; arcitem.No = no++; @@ -1504,8 +1415,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dEndRampingLengthSum += arcitem.Length; continue; } - else - { + else { arcitem.Length = (float)dRampingResidueLength; dRampingResidueLength = 0; arcitem.No = no++; @@ -1514,8 +1424,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dEndRampingLengthSum += (double)(arcitem.Length); dStartPoint = new UnitPoint(arcitem.PF2); - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 object 이어 붙이고 종료 arcitem = (Canvas.Arc)obj.Clone(); arcitem.PF1 = new PointF((float)dStartPoint.X, (float)dStartPoint.Y); @@ -1534,8 +1443,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator arcitem.PF2 = new PointF((float)dEndPoint.X, (float)dEndPoint.Y); // 중간지점 interval 길이만큼 반복으로 채워준다. - while (arcitem.Length > m_RampingEndInfo.Intervallength) - { + while (arcitem.Length > m_RampingEndInfo.Intervallength) { arcitem.Length = (float)m_RampingEndInfo.Intervallength; dRampingResidueLength = 0; arcitem.No = no++; @@ -1547,16 +1455,14 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator arcitem.PF1 = new PointF((float)dStartPoint.X, (float)dStartPoint.Y); arcitem.PF2 = new PointF((float)dEndPoint.X, (float)dEndPoint.Y); - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; } } - if (dEndRampingLengthSum < m_RampingEndInfo.length) - { + if (dEndRampingLengthSum < m_RampingEndInfo.length) { // 마지막 남은 잔여 길이 넣음. 위에 while 문에서 경로 생성이 끝났다면 남은 구간 전체를 넣고 종료. 생성이 안끝났어도 남은 구간을 다 넣고 다음 경로로 이동. 남은양을 전달한다. arcitem.No = no++; arcitem.MadebyRCC = true; @@ -1564,20 +1470,17 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dEndRampingLengthSum += arcitem.Length; } - if (dEndRampingLengthSum >= m_RampingEndInfo.length) - { + if (dEndRampingLengthSum >= m_RampingEndInfo.length) { // 구간길이를 모두 채우면 다음 index 기록하고 ramping 생성 종료 dRampingResidueLength = 0; break; } - else - { + else { // 여기까지오면 interval 보다 짧은 구간만 남는다. 채워넣어주고 모자란 길이를 residue 로 기록하자. dRampingResidueLength = m_RampingEndInfo.Intervallength - arcitem.Length; } } - else - { + else { // 없음 } } @@ -1589,35 +1492,28 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // ramping start 구간 power 설정 // - for (int i = 0; i < destDrawObjects.Count; i++) - { + for (int i = 0; i < destDrawObjects.Count; i++) { var obj = destDrawObjects[i]; - if (dStartRampingLengthSum >= m_RampingStartInfo.length) - { - if (obj is Line) - { + if (dStartRampingLengthSum >= m_RampingStartInfo.length) { + if (obj is Line) { Line line = (Line)obj; line.RCC_PowerRatio = 1; } - if (obj is Arc) - { + if (obj is Arc) { Arc arc = (Arc)obj; arc.RCC_PowerRatio = 1; } } - else - { + else { float powerratio = (float)((1 - m_RampingStartInfo.PowerRatioCh1) * dStartRampingLengthSum / m_RampingStartInfo.length + m_RampingStartInfo.PowerRatioCh1); // 상한, 하한 설정 (ratio 는 0보다 크거나 같고 1보다 작거나 같다) if (powerratio < 0) { powerratio = 0; } else if (powerratio > 1) { powerratio = 1; } - if (obj is Line) - { + if (obj is Line) { Line line = (Line)obj; dStartRampingLengthSum += line.Distance; line.RCC_PowerRatio = powerratio; } - if (obj is Arc) - { + if (obj is Arc) { Arc arc = (Arc)obj; dStartRampingLengthSum += arc.Length; arc.RCC_PowerRatio = powerratio; @@ -1627,10 +1523,8 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // ramping end 구간 power 설정 // - for (int i = destDrawObjects.Count - 1; i > 0; i--) - { - if (dEndRampingLengthSum > m_RampingEndInfo.length) - { + for (int i = destDrawObjects.Count - 1; i > 0; i--) { + if (dEndRampingLengthSum > m_RampingEndInfo.length) { break; } var obj = destDrawObjects[i]; @@ -1639,14 +1533,12 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // 상한, 하한 설정 (ratio 는 0보다 크거나 같고 1보다 작거나 같다) if (powerratio < 0) { powerratio = 0; } else if (powerratio > 1) { powerratio = 1; } - if (obj is Line) - { + if (obj is Line) { Line line = (Line)obj; dEndRampingLengthSum += line.Distance; line.RCC_PowerRatio = powerratio; } - if (obj is Arc) - { + if (obj is Arc) { Arc arc = (Arc)obj; dEndRampingLengthSum += arc.Length; arc.RCC_PowerRatio = powerratio; @@ -1669,60 +1561,48 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator }; bool bRet = true; dPathLengthSum = 0; - foreach (var item in lsDrawObjects) - { - if (item is Line) - { + foreach (var item in lsDrawObjects) { + if (item is Line) { var line = (Line)item; dPathLengthSum += line.Distance; - if (!CheckInRange(GetDistance(line.P1.X - detectedContourCenter.X, line.P1.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) - { + if (!CheckInRange(GetDistance(line.P1.X - detectedContourCenter.X, line.P1.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, Distance(LinePF1, Center) - Distance(ArcRadius) : {GetDistance(line.P1.X - detectedContourCenter.X, line.P1.Y - detectedContourCenter.Y) - originArc.Radius} mm"); bRet = false; } - if (!CheckInRange(GetDistance(line.P2.X - detectedContourCenter.X, line.P2.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) - { + if (!CheckInRange(GetDistance(line.P2.X - detectedContourCenter.X, line.P2.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, Distance(LinePF2, Center) - Distance(ArcRadius) : {GetDistance(line.P2.X - detectedContourCenter.X, line.P2.Y - detectedContourCenter.Y) - originArc.Radius} mm"); bRet = false; } } - else if (item is Arc) - { + else if (item is Arc) { var arc = (Arc)item; dPathLengthSum += arc.Length; - if (!CheckInRange(GetDistance(arc.PF1.X - detectedContourCenter.X, arc.PF1.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) - { + if (!CheckInRange(GetDistance(arc.PF1.X - detectedContourCenter.X, arc.PF1.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, Distance(ArcPF1, Center) - Distance(ArcRadius) : {GetDistance(arc.PF1.X - detectedContourCenter.X, arc.PF1.Y - detectedContourCenter.Y) - originArc.Radius} mm"); bRet = false; } - if (!CheckInRange(GetDistance(arc.PF2.X - detectedContourCenter.X, arc.PF2.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) - { + if (!CheckInRange(GetDistance(arc.PF2.X - detectedContourCenter.X, arc.PF2.Y - detectedContourCenter.Y) - originArc.Radius, dInterlockDistRange)) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, Distance(ArcPF2, Center) - Distance(ArcRadius) : {GetDistance(arc.PF2.X - detectedContourCenter.X, arc.PF2.Y - detectedContourCenter.Y) - originArc.Radius} mm"); bRet = false; } - if (arc.Length > dInterlockArcLength) - { + if (arc.Length > dInterlockArcLength) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, ArcLength : {arc.Length} mm"); bRet = false; } } - else - { + else { } } - if (!CheckInRange(dPathLengthSum - originArc.Length, dInterlockLengthDiffRange)) - { + if (!CheckInRange(dPathLengthSum - originArc.Length, dInterlockLengthDiffRange)) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, TotalPathLength - OriginArcLength : {dPathLengthSum - originArc.Length} mm"); bRet = false; } - if (!CheckInRange(originArc.Center.X - detectedContourCenter.X, dInterlockCenterXYDiffRange)) - { + if (!CheckInRange(originArc.Center.X - detectedContourCenter.X, dInterlockCenterXYDiffRange)) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, OriginArcCenterX - DetectEdgeCenterX : {(originArc.Center.X - detectedContourCenter.X).ToString("F2")} mm"); bRet = false; } - if (!CheckInRange(originArc.Center.Y - detectedContourCenter.Y, dInterlockCenterXYDiffRange)) - { + if (!CheckInRange(originArc.Center.Y - detectedContourCenter.Y, dInterlockCenterXYDiffRange)) { Log.E($"[RCCCheckInterlock] Distance interlock Range Over, OriginArcCenterY - DetectEdgeCenterY : {(originArc.Center.Y - detectedContourCenter.Y).ToString("F2")} mm"); bRet = false; } @@ -1738,8 +1618,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator dataTable.Columns.Add(new System.Data.DataColumn("Index", typeof(int))); - foreach (var item in StrColumnTitles) - { + foreach (var item in StrColumnTitles) { if (item == "No") dataTable.Columns.Add(new System.Data.DataColumn(item, typeof(int))); else @@ -1761,8 +1640,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator //dataTable.Columns.Add(new System.Data.DataColumn("Arc_EndAngle", typeof(int))); //dataTable.Columns.Add(new System.Data.DataColumn("Arc_SweepAngle", typeof(int))); - for (int i = 0; i < lsDrawObjects.Count; i++) - { + for (int i = 0; i < lsDrawObjects.Count; i++) { System.Data.DataRow row = dataTable.NewRow(); int iRowCount = dataTable.Rows.Count; object[] rowArray = new object[StrColumnTitles.Length + 1]; @@ -1772,8 +1650,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator rowArray[0] = iRowCount + 1; //rowArray[1] = lsDrawObjects[i].No; - if (lsDrawObjects[i] is Line) - { + if (lsDrawObjects[i] is Line) { Line line = lsDrawObjects[i] as Line; rowArray[1] = line.No + 1; rowArray[2] = Math.Round(line.P1.X, 4); @@ -1783,8 +1660,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator rowArray[15] = Math.Round(line.Distance, 4); rowArray[16] = Math.Round(line.RCC_PowerRatio, 4); } - else if (lsDrawObjects[i] is Arc) - { + else if (lsDrawObjects[i] is Arc) { Arc arc = lsDrawObjects[i] as Arc; rowArray[1] = arc.No + 1; rowArray[6] = Math.Round(arc.PF1.X, 4); @@ -1817,8 +1693,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator { //Pixel의 시작위치를 Merge전에 첫 Pixel은 가지고있어야 시작점 위치가 변경되지 않을듯 하다 // Arc 정보가없으면 그냥 default 생성된 rearranged_polygon list 를 사용 - if (originArc == null) - { + if (originArc == null) { merged_polygon = null; return; } @@ -1834,8 +1709,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator CalAnglePoint(detectedContourCenter.X, detectedContourCenter.Y, originArc.Radius, originArc.StartAngle, out startX, out startY); ConvertPixelAxisFromDrawingObjectAxis(new UnitPoint(startX, startY), image.Width, image.Height, out startX, out startY); List DistancelistFromStartPoint = new List(); - for (int i = 0; i < polygon.Count; i++) - { + for (int i = 0; i < polygon.Count; i++) { DistancelistFromStartPoint.Add(Math.Sqrt(Math.Pow(Convert.ToDouble(polygon[i].x) - startX, 2) + Math.Pow(Convert.ToDouble(polygon[i].y) - startY, 2))); } // 리스트에서 가장 작은 값 찾기 @@ -1851,15 +1725,13 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // 잘라낸 minIndex개의 아이템을 뒤에 붙임 polygon.AddRange(firstpolygons); - if (originArc.AbsSweepAngle > 360) - { + if (originArc.AbsSweepAngle > 360) { // 종료위치를 찾아서 순서 보정. 좌표계 pixel 좌표계 주의. double endX, endY; CalAnglePoint(detectedContourCenter.X, detectedContourCenter.Y, originArc.Radius, originArc.EndAngle, out endX, out endY); ConvertPixelAxisFromDrawingObjectAxis(new UnitPoint(endX, endY), image.Width, image.Height, out endX, out endY); List DistancelistFromEndPoint = new List(); - for (int i = 0; i < polygon.Count; i++) - { + for (int i = 0; i < polygon.Count; i++) { DistancelistFromEndPoint.Add(Math.Sqrt(Math.Pow(Convert.ToDouble(polygon[i].x) - endX, 2) + Math.Pow(Convert.ToDouble(polygon[i].y) - endY, 2))); } // 리스트에서 가장 작은 값 찾기 @@ -1871,8 +1743,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // 복사한 minIndex개의 아이템을 뒤에 붙임 polygon.AddRange(addpolygons); } - else if (originArc.AbsSweepAngle < 360) - { + else if (originArc.AbsSweepAngle < 360) { // sweep angle 이 360보다 작은 경우 end 까지만 사용하고 나머지는 버린다. // 종료위치를 찾아서 순서 보정. 좌표계 pixel 좌표계 주의. @@ -1881,8 +1752,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator ConvertPixelAxisFromDrawingObjectAxis(new UnitPoint(endX, endY), image.Width, image.Height, out endX, out endY); List DistancelistFromEndPoint = new List(); - for (int i = 0; i < polygon.Count; i++) - { + for (int i = 0; i < polygon.Count; i++) { DistancelistFromEndPoint.Add(Math.Sqrt(Math.Pow(Convert.ToDouble(polygon[i].x) - endX, 2) + Math.Pow(Convert.ToDouble(polygon[i].y) - endY, 2))); } // 리스트에서 가장 작은 값 찾기 @@ -1893,8 +1763,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // 원래 리스트에서 마지막 minIndex개의 아이템 제거 polygon.RemoveRange(minIndexFromEndPoint, polygon.Count - minIndexFromEndPoint); } - else - { + else { // 360도 일때는 시작 point 를 end point 에 하나 더 붙여줘야 원이 완성된다 polygon.Add(polygon[0]); } @@ -1953,7 +1822,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // MIL 해제 MIL.MbufFree(MILImage); } - public MIL_ID ConvertMatToMilID(Mat inputMat) + public MIL_ID ConvertMatToMilID(Mat inputMat) { if (inputMat.Empty()) throw new ArgumentException("입력된 Mat 이미지가 비어 있습니다."); @@ -2001,11 +1870,11 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator } else throw new NotSupportedException($"지원되지 않는 Mat 타입: {inputMat.Type()}"); - + return milImage; } - + public Point[][] FindMaxContour_old(Mat oriImg, double threshold, int morpIterations, int morpMarkSize) { // Convert to grayscale @@ -2024,11 +1893,9 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // Find the largest contour double maxArea = 0; int maxCntNo = 0; - for (int i = 0; i < contours.Length; i++) - { + for (int i = 0; i < contours.Length; i++) { double area = Cv2.ContourArea(contours[i]); - if (maxArea < area) - { + if (maxArea < area) { maxArea = area; maxCntNo = i; } @@ -2082,11 +1949,9 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // Find the largest contour double maxArea = 0; int maxCntNo = 0; - for (int i = 0; i < contours.Length; i++) - { + for (int i = 0; i < contours.Length; i++) { double area = Cv2.ContourArea(contours[i]); - if (maxArea < area) - { + if (maxArea < area) { maxArea = area; maxCntNo = i; } @@ -2121,8 +1986,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator { List shrunkContour = new List(); Point2f centroid = CalculateCentroid(contour); - foreach (var point in contour) - { + foreach (var point in contour) { Point2f point2f = new Point2f(point.X, point.Y); // Convert Point to Point2f Point2f direction = point2f - centroid; Mat directionMat = new Mat(1, 2, MatType.CV_32F); @@ -2140,8 +2004,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator { List shrunkContour = new List(); Point2f centroid = CalculateCentroid(contour); - foreach (var point in contour) - { + foreach (var point in contour) { Point2f point2f = new Point2f(point.X, point.Y); // Convert Point to Point2f Point2f direction = point2f - centroid; Mat directionMat = new Mat(1, 2, MatType.CV_32F); @@ -2162,8 +2025,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator //int cnt = 0; int cnt = 0; - while (cnt < contour.Length - 1) - { + while (cnt < contour.Length - 1) { if (Math.Abs(theta_list[cnt] - angleInDegrees) < Math.Abs(theta_list[cnt + 1] - angleInDegrees)) break; cnt += 1; @@ -2184,8 +2046,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Point2f centroid = CalculateCentroid(contour); //Contour를 특정각도로 나누어서 shrinkRatio를 바꿔보자 우선 하드코딩으로 - foreach (var point in contour) - { + foreach (var point in contour) { Point2f point2f = new Point2f(point.X, point.Y); // Convert Point to Point2f Point2f direction = point2f - centroid; Mat directionMat = new Mat(1, 2, MatType.CV_32F); @@ -2234,8 +2095,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator } public int ReplaceRCCObject(eArcCount arcCount, List sourcelist, List targetlist, UnitPoint detectedContourCenter) { - try - { + try { // sourcelist 의 item 중 RCC mode 가 true 인 것을 targetlist 로 대체. // targetlist 는 group 으로 묶어서 1개 object 로 인식하게 한다. if (sourcelist == null || targetlist == null) @@ -2247,8 +2107,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // RCC Generated Object 를 생성한 Group 의 sublist 로 넣어준다. 참조가 아닌 깊은 복사로 하자. List tempobject = new List(); int startIndex = 0; int nCount = targetlist.Count; - for (int i = startIndex; i < targetlist.Count; i++) - { + for (int i = startIndex; i < targetlist.Count; i++) { if (i >= startIndex + nCount) break; tempobject.Add(targetlist[i]); @@ -2259,10 +2118,8 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // RCCArc 를 Group 으로 Replace 한다. List arcs = new List(); Arc selectedArc = null; - foreach (var item in sourcelist) - { - if (item is Arc arc && arc.RCCArc == true) - { + foreach (var item in sourcelist) { + if (item is Arc arc && arc.RCCArc == true) { arcs.Add(arc); } } @@ -2281,18 +2138,15 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator //} // iteration 은 읽기 전용이므로 foreach 말고 for 문을 써야한다. - for (int i = startIndex; i < endIndex; i++) - { + for (int i = startIndex; i < endIndex; i++) { IDrawObject obj = sourcelist[i]; //Arc가 RCC Mode True이면 해당 Arc를 Group으로 변경한다. - if (CheckReplaceRCCObject(group, obj) == true) - { + if (CheckReplaceRCCObject(group, obj) == true) { // 부모를 넘겨줘야 item 이 replace 된다 ReplaceArcToRCCObjectGroup(group, sourcelist, i); } - else - { + else { // Arc가 아닌 다른 객체는 기존 Arc의 Center와 RCC로 찾은 Center의 차이 Offset만큼 이동시켜줘야함 // Arc외 객체에 Offset을 주기위해 m_OriginArc.center를 사용하지 않고 현재 sourcelist에서 받아온 Arc에서 arcCount에 따라서 Center를 받아온다 // TODO : EdgeDetect PixelShrink를 고려하지않고 Center값 차이만큼 offset을 고려하니깐 Shrink가 커지고 Offset양이 작으면 가접포인트가 RCC로 생성된 객체에 근사하지않음 @@ -2306,8 +2160,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator } return 0; } - catch (Exception e) - { + catch (Exception e) { Log.W($"{e.Message}"); return -1; } @@ -2326,8 +2179,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator return -1; offset_t = offset_t * (180 / Math.PI); // iteration 은 읽기 전용이므로 foreach 말고 for 문을 써야한다. - for (int i = 0; i < sourcelist.Count; i++) - { + for (int i = 0; i < sourcelist.Count; i++) { IDrawObject obj = sourcelist[i] as IDrawObject; UnitPoint offset = new UnitPoint(offset_X, -offset_Y); @@ -2350,15 +2202,12 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // CheckReplaceRCCObject 는 Group 에 대하여 Recursive call 한다. // group 안에 arc 가 있으면 check 만하는게 아니고 replace 까지 한다. - if (obj.Enabled == true) - { - if (obj is Arc) - { + if (obj.Enabled == true) { + if (obj is Arc) { if (((Arc)obj).RCCArc == true) return true; } - else if (obj is Group) - { + else if (obj is Group) { CheckRCCGroupObject(SrcGroup, (Group)obj); return false; } @@ -2371,17 +2220,14 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator private static void CheckRCCGroupObject(Group SrcGroup, Group Targetobj) { // iteration 은 읽기 전용이므로 foreach 말고 for 문을 써야한다. - for (int i = 0; i < Targetobj.SubObjects.Count; i++) - { + for (int i = 0; i < Targetobj.SubObjects.Count; i++) { IDrawObject subObj = Targetobj.SubObjects[i] as IDrawObject; - if (CheckReplaceRCCObject(SrcGroup, subObj) == true) - { + if (CheckReplaceRCCObject(SrcGroup, subObj) == true) { // 부모와 index를 넘겨줘야 item 이 replace 된다 ReplaceArcToRCCObjectGroup(SrcGroup, Targetobj.SubObjects, i); return; } - else - { + else { //UnitPoint offset = DetectedContourCenter - m_OriginArc.Center; //subObj.Move(offset); } @@ -2399,8 +2245,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator parentlist[index] = SrcGroup.Clone(); parentlist[index].No = itemNo; - foreach (IDrawObject objitem in ((Group)parentlist[index]).SubObjects) - { + foreach (IDrawObject objitem in ((Group)parentlist[index]).SubObjects) { if (objitem is Line) ((Line)objitem).ScannerParamNo = paramNo; else if (objitem is Arc) @@ -2413,15 +2258,12 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator //해당 함수는 한번만 실행하고 가져다 쓰는곳에서 arcCount에 따라서 selectedArcs[0], selectedArcs[1]을 사용하자 selectedArcs = new List(); - foreach (var item in recipeDrawObject) - { - if (item is Arc arc && arc.RCCArc == true) - { + foreach (var item in recipeDrawObject) { + if (item is Arc arc && arc.RCCArc == true) { selectedArcs.Add(arc); } } - if (selectedArcs.Count > 0) - { + if (selectedArcs.Count > 0) { return true; } // SetBaseArc를 따로 호출해서 selectedArc를 넣어주자.. @@ -2452,55 +2294,45 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int p_x3 = width / 2; int p_y3 = jig_size; Point P3 = new Point(0, 0); - for (int i = 0; i <= 20; i++) - { + for (int i = 0; i <= 20; i++) { - while (p_x1 > (width / 2)) - { + while (p_x1 > (width / 2)) { p_x1--; double outer = 0; double inner = 0; - for (int j = 1; j < point_num + 1; j++) - { + for (int j = 1; j < point_num + 1; j++) { outer += Convert.ToDouble(grayImg.At(p_y1, p_x1 + j) + grayImg.At(p_y1 - 1, p_x1 + j) + grayImg.At(p_y1 + 1, p_x1 + j)); inner += Convert.ToDouble(grayImg.At(p_y1, p_x1 - j) + grayImg.At(p_y1 - 1, p_x1 - j) + grayImg.At(p_y1 + 1, p_x1 - j)); } - if ((inner - outer) / (3 * point_num) > diff_Threshold) - { + if ((inner - outer) / (3 * point_num) > diff_Threshold) { P1 = new Point(p_x1, p_y1); break; } } - while (p_x2 < (width / 2)) - { + while (p_x2 < (width / 2)) { p_x2++; double outer = 0; double inner = 0; - for (int j = 1; j < point_num + 1; j++) - { + for (int j = 1; j < point_num + 1; j++) { outer += Convert.ToDouble(grayImg.At(p_y2, p_x2 - j) + grayImg.At(p_y2 + 1, p_x2 - j) + grayImg.At(p_y2 - 1, p_x2 - j)); inner += Convert.ToDouble(grayImg.At(p_y2, p_x2 + j) + grayImg.At(p_y2 + 1, p_x2 + j) + grayImg.At(p_y2 - 1, p_x2 + j)); } - if ((inner - outer) / (3 * point_num) > diff_Threshold) - { + if ((inner - outer) / (3 * point_num) > diff_Threshold) { P2 = new Point(p_x2, p_y2); break; } } - while (p_y3 < (height / 2)) - { + while (p_y3 < (height / 2)) { p_y3++; double outer = 0; double inner = 0; - for (int j = 1; j < point_num + 1; j++) - { + for (int j = 1; j < point_num + 1; j++) { outer += Convert.ToDouble(grayImg.At(p_y3 - j, p_x3) + grayImg.At(p_y3 - j, p_x3 + 1) + grayImg.At(p_y3 - j, p_x3 - 1)); inner += Convert.ToDouble(grayImg.At(p_y3 + j, p_x3) + grayImg.At(p_y3 + j, p_x3 + 1) + grayImg.At(p_y3 + j, p_x3 - 1)); } - if ((inner - outer) / (3 * point_num) > diff_Threshold) - { + if ((inner - outer) / (3 * point_num) > diff_Threshold) { P3 = new Point(p_x3, p_y3); break; } @@ -2510,12 +2342,10 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // 점 3개로 원의 중심을 찾고, 원 중심에서부터 각도방향으로 threshod 차이나는 엣지를 찾는다. center = find_circle_center_3Point(P1, P2, P3); Log.I(string.Format($" [{i}] (Distortion Center Diff : ({center.X - centerX},{center.Y - centerY})")); - if (Math.Abs(center.X - centerX) < eDistortionCenterDiff && Math.Abs(center.Y - centerY) < eDistortionCenterDiff) - { + if (Math.Abs(center.X - centerX) < eDistortionCenterDiff && Math.Abs(center.Y - centerY) < eDistortionCenterDiff) { break; } - if (i < 20) - { + if (i < 20) { p_x1 = width - jig_size; p_y1 = ((10 + i) * height / 40); p_x2 = jig_size; @@ -2523,8 +2353,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator p_x3 = ((10 + i) * width / 40); p_y3 = jig_size; } - else - { + else { Log.E(string.Format($"Failed to find a center.")); } @@ -2542,8 +2371,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int cnt = 0; theta_list = new double[3600]; offset_list = new double[3600]; - while (!reader.EndOfStream) - { + while (!reader.EndOfStream) { string[] rows = reader.ReadLine().Split(','); theta_list[cnt] = Double.Parse(rows[0]); offset_list[cnt] = Double.Parse(rows[1]) * LensMagnification / CameraPixelSize * 1000; @@ -2561,8 +2389,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator points_list[0] = new Point[0]; int height = srcImg.Height; int width = srcImg.Width; - if (radius == 0 || margin == 0 || divide == 0 || diff_Threshold == 0) - { + if (radius == 0 || margin == 0 || divide == 0 || diff_Threshold == 0) { Log.E(string.Format("Check the Input Parameters")); return false; @@ -2571,12 +2398,10 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int point_num_theta = 2; Mat grayImg = new Mat(); - if (srcImg.Channels() == 3) - { + if (srcImg.Channels() == 3) { Cv2.CvtColor(srcImg, grayImg, ColorConversionCodes.BGR2GRAY); } - else - { + else { grayImg = srcImg; } Point center = new Point(0, 0); @@ -2590,55 +2415,45 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int p_x3 = width / 2; int p_y3 = jig_size; Point P3 = new Point(0, 0); - for (int i = 0; i <= 20; i++) - { + for (int i = 0; i <= 20; i++) { - while (p_x1 > (width / 2)) - { + while (p_x1 > (width / 2)) { p_x1--; double outer = 0; double inner = 0; - for (int j = 1; j < point_num + 1; j++) - { + for (int j = 1; j < point_num + 1; j++) { outer += Convert.ToDouble(grayImg.At(p_y1, p_x1 + j) + grayImg.At(p_y1 - 1, p_x1 + j) + grayImg.At(p_y1 + 1, p_x1 + j)); inner += Convert.ToDouble(grayImg.At(p_y1, p_x1 - j) + grayImg.At(p_y1 - 1, p_x1 - j) + grayImg.At(p_y1 + 1, p_x1 - j)); } - if ((inner - outer) / (3 * point_num) > diff_Threshold) - { + if ((inner - outer) / (3 * point_num) > diff_Threshold) { P1 = new Point(p_x1, p_y1); break; } } - while (p_x2 < (width / 2)) - { + while (p_x2 < (width / 2)) { p_x2++; double outer = 0; double inner = 0; - for (int j = 1; j < point_num + 1; j++) - { + for (int j = 1; j < point_num + 1; j++) { outer += Convert.ToDouble(grayImg.At(p_y2, p_x2 - j) + grayImg.At(p_y2 + 1, p_x2 - j) + grayImg.At(p_y2 - 1, p_x2 - j)); inner += Convert.ToDouble(grayImg.At(p_y2, p_x2 + j) + grayImg.At(p_y2 + 1, p_x2 + j) + grayImg.At(p_y2 - 1, p_x2 + j)); } - if ((inner - outer) / (3 * point_num) > diff_Threshold) - { + if ((inner - outer) / (3 * point_num) > diff_Threshold) { P2 = new Point(p_x2, p_y2); break; } } - while (p_y3 < (height / 2)) - { + while (p_y3 < (height / 2)) { p_y3++; double outer = 0; double inner = 0; - for (int j = 1; j < point_num + 1; j++) - { + for (int j = 1; j < point_num + 1; j++) { outer += Convert.ToDouble(grayImg.At(p_y3 - j, p_x3) + grayImg.At(p_y3 - j, p_x3 + 1) + grayImg.At(p_y3 - j, p_x3 - 1)); inner += Convert.ToDouble(grayImg.At(p_y3 + j, p_x3) + grayImg.At(p_y3 + j, p_x3 + 1) + grayImg.At(p_y3 + j, p_x3 - 1)); } - if ((inner - outer) / (3 * point_num) > diff_Threshold) - { + if ((inner - outer) / (3 * point_num) > diff_Threshold) { P3 = new Point(p_x3, p_y3); break; } @@ -2648,12 +2463,10 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // 점 3개로 원의 중심을 찾고, 원 중심에서부터 각도방향으로 threshod 차이나는 엣지를 찾는다. center = find_circle_center_3Point(P1, P2, P3); Log.I(string.Format($" [{i}] (Distortion Center Diff : ({center.X - centerX},{center.Y - centerY}))")); - if (Math.Abs(center.X - centerX) < eDistortionCenterDiff && Math.Abs(center.Y - centerY) < eDistortionCenterDiff) - { + if (Math.Abs(center.X - centerX) < eDistortionCenterDiff && Math.Abs(center.Y - centerY) < eDistortionCenterDiff) { break; } - if (i < 20) - { + if (i < 20) { p_x1 = width - jig_size; p_y1 = ((10 + i) * height / 40); p_x2 = jig_size; @@ -2661,8 +2474,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator p_x3 = ((10 + i) * width / 40); p_y3 = jig_size; } - else - { + else { Log.E(string.Format($"Failed to find a center.")); return false; } @@ -2671,8 +2483,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator if (radius + margin > center.X || radius + margin > center.Y || grayImg.Width - (radius + margin) < center.X || - grayImg.Height - (radius + margin) < center.Y) - { + grayImg.Height - (radius + margin) < center.Y) { points_list = new Point[1][]; points_list[0] = new Point[0]; @@ -2684,16 +2495,14 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator List edge_list = new List(); List l_list = new List(); - for (int i = 0; i < divide; i++) - { + for (int i = 0; i < divide; i++) { double degree = Convert.ToDouble(i) * 360.0 / Convert.ToDouble(divide); double l = radius + margin; double[] theta_l = new double[1 + 2 * point_num_theta]; theta_l[0] = degree * Math.PI / 180; - for (int t = 0; t < point_num_theta; t++) - { + for (int t = 0; t < point_num_theta; t++) { theta_l[t * 2 + 1] = (degree - t * (360 / (Convert.ToDouble(divide * (1 + 2 * point_num_theta))))) * Math.PI / 180; theta_l[t * 2 + 2] = (degree + t * (360 / (Convert.ToDouble(divide * (1 + 2 * point_num_theta))))) * Math.PI / 180; } @@ -2701,17 +2510,14 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Point max_p = new Point(0, 0); double outer = 0.0; double inner = 0.0; - while (l > 0) - { + while (l > 0) { outer = 0.0; inner = 0.0; double point_x = center.X + l * Math.Cos(theta_l[0]); double point_y = center.Y + l * Math.Sin(theta_l[0]); - foreach (var theta in theta_l) - { - for (int j = 1; j < point_num + 1; j++) - { + foreach (var theta in theta_l) { + for (int j = 1; j < point_num + 1; j++) { int indexX = Convert.ToInt32(center.Y + (l + j) * Math.Sin(theta)); int indexY = Convert.ToInt32(center.X + (l + j) * Math.Cos(theta)); outer += Convert.ToDouble(grayImg.At(indexX, indexY)); @@ -2721,8 +2527,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator } } - if ((inner - outer) / ((1 + 2 * point_num_theta) * point_num) >= diff_Threshold) - { + if ((inner - outer) / ((1 + 2 * point_num_theta) * point_num) >= diff_Threshold) { Point point = new Point(point_x, point_y); edge_list.Add(point); @@ -2731,13 +2536,11 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator } l = l - 1; - if (l == radius - margin) - { + if (l == radius - margin) { l = radius + margin; degree += (360.0 / Convert.ToDouble(divide * 10)); theta_l[0] = degree * Math.PI / 180; - for (int t = 0; t < point_num_theta; t++) - { + for (int t = 0; t < point_num_theta; t++) { theta_l[t * 2 + 1] = (degree - t * (360 / (Convert.ToDouble(divide * (1 + 2 * point_num_theta))))) * Math.PI / 180; theta_l[t * 2 + 2] = (degree + t * (360 / (Convert.ToDouble(divide * (1 + 2 * point_num_theta))))) * Math.PI / 180; } @@ -2747,8 +2550,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator } } double DetectPercent = (double)edge_list.Count / (double)divide * 100; - if (DetectPercent <= DetectPointPercent) - { + if (DetectPercent <= DetectPointPercent) { Log.E(string.Format("Detected Points Percentage is {0}", DetectPercent)); return false; @@ -2776,8 +2578,7 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator // return 2 : eInterlockMaxMinDiffHigh 이하, eInterlockMaxMinDiffLow 초과 // return 1 : eInterlockMaxMinDiffLow 이하, eCheckCenterDiff 초과 // return 0 : eInterlockMaxMinDiffLow 이하, eCheckCenterDiff 이하 - if (input_points_list[0].Length == 0) - { + if (input_points_list[0].Length == 0) { points_list = new Point[1][]; points_list[0] = new Point[0]; return 3; @@ -2788,71 +2589,59 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator List grid_index = new List { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };//10개 영역의 시작과 끝에 해당하는 index 저장 Point center = new Point((int)input_points_list[0].Average(p => p.X), (int)input_points_list[0].Average(p => p.Y)); #region grid 경계 index 계산 - for (int i = 0; i < input_points_list[0].Length; i++) - { + for (int i = 0; i < input_points_list[0].Length; i++) { int point_x = input_points_list[0][i].X; int point_y = input_points_list[0][i].Y; l_list.Add(Math.Sqrt((center.X - input_points_list[0][i].X) * (center.X - input_points_list[0][i].X) + (center.Y - input_points_list[0][i].Y) * (center.Y - input_points_list[0][i].Y))); - if (i == 0) - { + if (i == 0) { } - else if (point_y < height / 4 && input_points_list[0][i - 1].Y >= height / 4) - { + else if (point_y < height / 4 && input_points_list[0][i - 1].Y >= height / 4) { //1번영역 start grid_index[19] = i - 1; grid_index[0] = i; } - else if (point_x > width / 3 && input_points_list[0][i - 1].X <= width / 3) - { + else if (point_x > width / 3 && input_points_list[0][i - 1].X <= width / 3) { //2번영역 start grid_index[1] = i - 1; grid_index[2] = i; } - else if (point_x > 2 * width / 3 && input_points_list[0][i - 1].X <= 2 * width / 3) - { + else if (point_x > 2 * width / 3 && input_points_list[0][i - 1].X <= 2 * width / 3) { //3번영역 start grid_index[3] = i - 1; grid_index[4] = i; } - else if (point_y > height / 4 && input_points_list[0][i - 1].Y <= height / 4) - { + else if (point_y > height / 4 && input_points_list[0][i - 1].Y <= height / 4) { //4번영역 start grid_index[5] = i - 1; grid_index[6] = i; } - else if (point_y > 2 * height / 4 && input_points_list[0][i - 1].Y <= 2 * height / 4) - { + else if (point_y > 2 * height / 4 && input_points_list[0][i - 1].Y <= 2 * height / 4) { //5번영역 start grid_index[7] = i - 1; grid_index[8] = i; } - else if (point_y > 3 * height / 4 && input_points_list[0][i - 1].Y <= 3 * height / 4) - { + else if (point_y > 3 * height / 4 && input_points_list[0][i - 1].Y <= 3 * height / 4) { //6번영역 start grid_index[9] = i - 1; grid_index[10] = i; } - else if (point_x < 2 * width / 3 && input_points_list[0][i - 1].X >= 2 * width / 3) - { + else if (point_x < 2 * width / 3 && input_points_list[0][i - 1].X >= 2 * width / 3) { //7번영역 start grid_index[11] = i - 1; grid_index[12] = i; } - else if (point_x < width / 3 && input_points_list[0][i - 1].X >= width / 3) - { + else if (point_x < width / 3 && input_points_list[0][i - 1].X >= width / 3) { //8번영역 start grid_index[13] = i - 1; grid_index[14] = i; } - else if (point_y < 3 * height / 4 && input_points_list[0][i - 1].Y >= 3 * height / 4) - { + else if (point_y < 3 * height / 4 && input_points_list[0][i - 1].Y >= 3 * height / 4) { //9번영역 start grid_index[15] = i - 1; grid_index[16] = i; } - else if (point_y < 2 * height / 4 && input_points_list[0][i - 1].Y >= 2 * height / 4) - { + else if (point_y < 2 * height / 4 && input_points_list[0][i - 1].Y >= 2 * height / 4) { //10번영역 start grid_index[17] = i - 1; grid_index[18] = i; @@ -2865,11 +2654,9 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator List grid_length = new List() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //10개 영역의 거리(중심과의) 평균 double max_missalign = 0; List grid_miss_align = new List(); //모서리 8포인트에 대해 miss-align값 확인 - for (int i = 0; i < 10; i++) - { + for (int i = 0; i < 10; i++) { double miss_align = 0; - for (int j = 0; j < 10; j++) - { + for (int j = 0; j < 10; j++) { miss_align += l_list[(grid_index[(i * 2 + 1 + 20) % 20] + j + l_list.Count) % l_list.Count]; miss_align -= l_list[(grid_index[(i * 2 + 2 + 20) % 20] - j + l_list.Count) % l_list.Count]; } @@ -2879,70 +2666,56 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Log.I($"Maximum Miss-Align: {max_missalign}"); Point[] align_offset = new Point[4]; //0:LeftTop, 1:RightTop, 2:RightBottom, 3:LeftBottom - if (EnableAutoMissAlign) - { - if (Math.Abs(grid_miss_align[0]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[1]) <= eInterlockMissAlignLow) - { + if (EnableAutoMissAlign) { + if (Math.Abs(grid_miss_align[0]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[1]) <= eInterlockMissAlignLow) { align_offset[0].Y = (int)grid_miss_align[0]; Log.I("Miss-Align Correction applied"); } - if (Math.Abs(grid_miss_align[9]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[8]) <= eInterlockMissAlignLow) - { + if (Math.Abs(grid_miss_align[9]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[8]) <= eInterlockMissAlignLow) { align_offset[0].X = (int)grid_miss_align[9]; Log.I("Miss-Align Correction applied"); } - if (Math.Abs(grid_miss_align[1]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[0]) <= eInterlockMissAlignLow) - { + if (Math.Abs(grid_miss_align[1]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[0]) <= eInterlockMissAlignLow) { align_offset[1].Y = (int)grid_miss_align[1]; Log.I("Miss-Align Correction applied"); } - if (Math.Abs(grid_miss_align[2]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[3]) <= eInterlockMissAlignLow) - { + if (Math.Abs(grid_miss_align[2]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[3]) <= eInterlockMissAlignLow) { align_offset[1].X = (int)grid_miss_align[2]; Log.I("Miss-Align Correction applied"); } - if (Math.Abs(grid_miss_align[5]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[6]) <= eInterlockMissAlignLow) - { + if (Math.Abs(grid_miss_align[5]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[6]) <= eInterlockMissAlignLow) { align_offset[2].Y = (int)grid_miss_align[5]; Log.I("Miss-Align Correction applied"); } - if (Math.Abs(grid_miss_align[4]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[3]) <= eInterlockMissAlignLow) - { + if (Math.Abs(grid_miss_align[4]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[3]) <= eInterlockMissAlignLow) { align_offset[2].X = (int)grid_miss_align[4]; Log.I("Miss-Align Correction applied"); } - if (Math.Abs(grid_miss_align[6]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[5]) <= eInterlockMissAlignLow) - { + if (Math.Abs(grid_miss_align[6]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[5]) <= eInterlockMissAlignLow) { align_offset[3].Y = (int)grid_miss_align[6]; Log.I("Miss-Align Correction applied"); } - if (Math.Abs(grid_miss_align[7]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[8]) <= eInterlockMissAlignLow) - { + if (Math.Abs(grid_miss_align[7]) >= eInterlockMissAlignHigh && Math.Abs(grid_miss_align[8]) <= eInterlockMissAlignLow) { align_offset[3].X = (int)grid_miss_align[7]; Log.I("Miss-Align Correction applied"); } - for (int i = grid_index[0]; i <= grid_index[1]; i++) - { + for (int i = grid_index[0]; i <= grid_index[1]; i++) { input_points_list[0][i] = new Point(input_points_list[0][i].X + align_offset[0].X, input_points_list[0][i].Y - align_offset[0].Y); } - for (int i = grid_index[4]; i <= grid_index[5]; i++) - { + for (int i = grid_index[4]; i <= grid_index[5]; i++) { input_points_list[0][i] = new Point(input_points_list[0][i].X + align_offset[1].X, input_points_list[0][i].Y + align_offset[1].Y); } - for (int i = grid_index[10]; i <= grid_index[11]; i++) - { + for (int i = grid_index[10]; i <= grid_index[11]; i++) { input_points_list[0][i] = new Point(input_points_list[0][i].X - align_offset[2].X, input_points_list[0][i].Y + align_offset[2].Y); } - for (int i = grid_index[14]; i <= grid_index[15]; i++) - { + for (int i = grid_index[14]; i <= grid_index[15]; i++) { input_points_list[0][i] = new Point(input_points_list[0][i].X - align_offset[3].X, input_points_list[0][i].Y - align_offset[3].Y); } } center = new Point((int)input_points_list[0].Average(p => p.X), (int)input_points_list[0].Average(p => p.Y)); l_list = new List(); - for (int i = 0; i < input_points_list[0].Length; i++) - { + for (int i = 0; i < input_points_list[0].Length; i++) { l_list.Add(Math.Sqrt((center.X - input_points_list[0][i].X) * (center.X - input_points_list[0][i].X) + (center.Y - input_points_list[0][i].Y) * (center.Y - input_points_list[0][i].Y))); } #endregion @@ -2950,25 +2723,21 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator #region 찌그러짐 Test float window_size = (float)l_list.Count / 72; //5도 간격 List diff_W_list = new List(); - for (int w = 0; w < 72; w++) - { + for (int w = 0; w < 72; w++) { double max_val = 0; double min_val = double.MaxValue; - for (int i = (int)(w * window_size); i < (int)((w + 1) * window_size); i++) - { + for (int i = (int)(w * window_size); i < (int)((w + 1) * window_size); i++) { if (l_list[i] > max_val) max_val = l_list[i]; if (l_list[i] < min_val) min_val = l_list[i]; } double diff_W = max_val - min_val; diff_W_list.Add(diff_W); - if (max_val - min_val > eInterlockMaxMinDiffHigh) - { + if (max_val - min_val > eInterlockMaxMinDiffHigh) { Log.E($"Invalid Shape in {(w / 6 + 3) % 12} O'Clock position.(local difference : {max_val - min_val})"); is_OK = false; } - if (max_val - min_val > eInterlockMaxMinDiffLow && is_OK) - { + if (max_val - min_val > eInterlockMaxMinDiffLow && is_OK) { is_Circle = false; } } @@ -2990,18 +2759,15 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator points_list = ShrinkPixelContourQuad(mxCnt, shrinkPixel[0], shrinkPixel[1], shrinkPixel[2], shrinkPixel[3], ShrinkByFunction); else points_list = ShrinkPixelContourCSV(mxCnt, theta_list, offset_list); - if (!is_OK) - { + if (!is_OK) { Log.I("RCC Check Result : Interlock"); return 3; } - if (!is_Circle) - { + if (!is_Circle) { Log.I("RCC Check Result : Generate Object"); return 2; } - if (centerDiff > eCheckCenterDiff) - { + if (centerDiff > eCheckCenterDiff) { Log.I("RCC Check Result : Apply Offset Object"); return 1; } @@ -3038,15 +2804,13 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator public (int, int, double, double, int, int, int, int, double) FindOffset(Mat imageColor, double threshold, double X, double Y, double T, out Point[][] out_contours, string SelectedOption) { Stopwatch stopwatch = Stopwatch.StartNew(); - if (X == 0 && Y == 0) - { + if (X == 0 && Y == 0) { Log.E("No Reference Information"); out_contours = new Point[1][]; out_contours[0] = new Point[0]; return (-1, -1, -1, -1, -1, -1, -1, -1, -1); } - if (SelectedOption == "Inzi") - { + if (SelectedOption == "Inzi") { Mat grayImage = new Mat(); Cv2.CvtColor(imageColor, grayImage, ColorConversionCodes.BGR2GRAY); @@ -3069,20 +2833,17 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator Point topleft = ImgRect.TopLeft; Point bottomright = ImgRect.BottomRight; List<(double area, int index)> contourList = new List<(double, int)>(); - for (int i = 0; i < contours.Length; i++) - { + for (int i = 0; i < contours.Length; i++) { double area = Cv2.ContourArea(contours[i]); if (area < 100) continue; OpenCvSharp.Rect boundingRect = Cv2.BoundingRect(contours[i]); - if (boundingRect.TopLeft.X - topleft.X < 10 || boundingRect.TopLeft.Y - topleft.Y < 10 || bottomright.X - boundingRect.BottomRight.X < 10 || bottomright.Y - boundingRect.BottomRight.Y < 10) - { + if (boundingRect.TopLeft.X - topleft.X < 10 || boundingRect.TopLeft.Y - topleft.Y < 10 || bottomright.X - boundingRect.BottomRight.X < 10 || bottomright.Y - boundingRect.BottomRight.Y < 10) { //가장자리 Case continue; } contourList.Add((area, i)); } - if (contourList.Count < 2) - { + if (contourList.Count < 2) { out_contours = new Point[2][]; out_contours[0] = new Point[0]; out_contours[1] = new Point[0]; @@ -3101,32 +2862,26 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator double ScY = (squareMoments.M01 / squareMoments.M00) * 4; double Otheta = ScX == cX ? 0 : Math.Atan((ScY - cY) / (ScX - cX)); - if (Otheta < 0 && (ScX - cX) >= 0) - { + if (Otheta < 0 && (ScX - cX) >= 0) { Otheta = -Otheta; } - else if (Otheta >= 0 && (ScX - cX) >= 0) - { + else if (Otheta >= 0 && (ScX - cX) >= 0) { Otheta = -Otheta; } - else if (Otheta >= 0 && (ScX - cX) < 0) - { + else if (Otheta >= 0 && (ScX - cX) < 0) { Otheta = Math.PI - Otheta; } - else - { + else { Otheta = Math.PI - Otheta; } - for (int i = 0; i < square.Length; i++) - { + for (int i = 0; i < square.Length; i++) { square[i].X *= 4; square[i].Y *= 4; } double dist = 0; - for (int i = 0; i < circle.Length; i++) - { + for (int i = 0; i < circle.Length; i++) { circle[i].X *= 4; circle[i].Y *= 4; dist += Math.Sqrt((circle[i].X - cX) * (circle[i].X - cX) + (circle[i].Y - cY) * (circle[i].Y - cY)); @@ -3137,15 +2892,13 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator out_contours[1] = square; return ((int)cX - (int)X, (int)cY - (int)Y, Otheta, Otheta - T, (int)cX, (int)cY, (int)ScX, (int)ScY, dist); } - else - { + else { int point_num = 1000; Point[] points = new Point[point_num]; int[] l_l = new int[point_num]; int[] diff_l = new int[point_num]; //TODO : Start, End(610) 파라미터화 - for (int t_i = 0; t_i < point_num; t_i++) - { + for (int t_i = 0; t_i < point_num; t_i++) { double t = (double)t_i / (double)point_num * 360.0; int sum = 0; int max_diff = -int.MaxValue; @@ -3156,36 +2909,31 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int start = 410; int end = 610; int line_width = 30; - if (X + end >= imageColor.Width || Y + end >= imageColor.Width || X - end <= 0 || Y - end <= 0) - { + if (X + end >= imageColor.Width || Y + end >= imageColor.Width || X - end <= 0 || Y - end <= 0) { Log.E("Wrong Reference Point."); out_contours = new Point[1][]; out_contours[0] = new Point[0]; return (-1, -1, -1, -1, -1, -1, -1, -1, -1); } - for (int l = start; l < end; l = l + 3) - { + for (int l = start; l < end; l = l + 3) { Point p = new Point(X + (int)(l * Math.Cos(t * Math.PI / 180)), Y + (int)(l * Math.Sin(t * Math.PI / 180))); sum += imageColor.At(p.Y, p.X); if (l < start + line_width) inner += imageColor.At(p.Y, p.X); else if (l == start + line_width) outer += imageColor.At(p.Y, p.X); - else if (l < start + line_width * 2) - { + else if (l < start + line_width * 2) { outer += imageColor.At(p.Y, p.X); inner += imageColor.At((int)Y + (int)((l - (l - start - line_width)) * Math.Sin(t * Math.PI / 180)), (int)X + (int)((l - (l - start - line_width)) * Math.Cos(t * Math.PI / 180))); inner -= imageColor.At((int)Y + (int)((l - (l - start - line_width * 2)) * Math.Sin(t * Math.PI / 180)), (int)X + (int)((l - (l - start - line_width * 2)) * Math.Cos(t * Math.PI / 180))); } - else - { + else { outer += imageColor.At(p.Y, p.X); outer -= imageColor.At((int)Y + (int)((l - line_width) * Math.Sin(t * Math.PI / 180)), (int)X + (int)((l - line_width) * Math.Cos(t * Math.PI / 180))); inner += imageColor.At((int)Y + (int)((l - line_width) * Math.Sin(t * Math.PI / 180)), (int)X + (int)((l - line_width) * Math.Cos(t * Math.PI / 180))); inner -= imageColor.At((int)Y + (int)((l - line_width * 2) * Math.Sin(t * Math.PI / 180)), (int)X + (int)((l - line_width * 2) * Math.Cos(t * Math.PI / 180))); } int diff = outer - inner; - if (diff > max_diff) - { + if (diff > max_diff) { max_diff = diff; max_l = l - line_width; points[t_i] = new Point(X + (int)((l - line_width) * Math.Cos(t * Math.PI / 180)), Y + (int)((l - line_width) * Math.Sin(t * Math.PI / 180))); @@ -3206,31 +2954,27 @@ namespace WeldingCommon.Vision.WeldingObjectGenerator int search_size = 30; int x_cor_sum = 0; int x_cor_n = 0; int y_cor_sum = 0; int y_cor_n = 0; - for (int t = 0; t < point_num / 3; t++) - { + for (int t = 0; t < point_num / 3; t++) { sum_distance += (l_l[t] + l_l[t + point_num / 3] + l_l[t + point_num * 2 / 3]); sum_diff += (diff_l[t] + diff_l[t + point_num / 3] + diff_l[t + point_num * 2 / 3]); if (t < search_size) continue; sum_distance -= (l_l[t - search_size] + l_l[t + point_num / 3 - search_size] + l_l[t + point_num * 2 / 3 - search_size]); sum_diff -= (diff_l[t - search_size] + diff_l[t + point_num / 3 - search_size] + diff_l[t + point_num * 2 / 3 - search_size]); if ((float)sum_diff < diff_l_avg * (float)search_size * 3) continue; - if ((float)sum_diff > diff_l_avg * (float)search_size * 3) - { + if ((float)sum_diff > diff_l_avg * (float)search_size * 3) { x_cor_sum += (points[t].X + points[t + point_num / 3].X + points[t + point_num * 2 / 3].X); y_cor_sum += (points[t].Y + points[t + point_num / 3].Y + points[t + point_num * 2 / 3].Y); x_cor_n += 3; y_cor_n += 3; } - if (sum_distance < min_sum_) - { + if (sum_distance < min_sum_) { min_sum_ = sum_distance; min_t = t - search_size / 2; } } - if (x_cor_n == 0) - { + if (x_cor_n == 0) { out_contours = new Point[1][]; out_contours[0] = new Point[0]; return (-1, -1, -1, -1, -1, -1, -1, -1, -1);