From 9ce42d24d76514d88d57030fd109b2166d26a4d2 Mon Sep 17 00:00:00 2001 From: choiminyeong Date: Mon, 2 Feb 2026 09:31:50 +0900 Subject: [PATCH] =?UTF-8?q?Cell=20Receive=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20Complete=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuroraLBAD/Services/StreamLightLBAD.cs | 10 - .../AuroraLaserScanner/ScannerObj.cs | 2 +- .../Sequences/SeqAutoRunACWH52A.cs | 352 +++++++++--------- .../Sequences/SeqAutoRunCCWH52A.cs | 258 +++++++------ .../WeldingCommon/Data/ActualProcessData.cs | 7 +- .../Sequences/Main/SeqUploadWeldingList.cs | 26 ++ 6 files changed, 358 insertions(+), 297 deletions(-) diff --git a/AuroraDevices/AuroraLBAD/Services/StreamLightLBAD.cs b/AuroraDevices/AuroraLBAD/Services/StreamLightLBAD.cs index 9025ff8..69cedb9 100644 --- a/AuroraDevices/AuroraLBAD/Services/StreamLightLBAD.cs +++ b/AuroraDevices/AuroraLBAD/Services/StreamLightLBAD.cs @@ -11,7 +11,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; -using System.Windows; namespace AuroraLBAD.Service { @@ -130,9 +129,6 @@ namespace AuroraLBAD.Service public bool SendReadyStatus(eRequestData data) { - if (ApplicationExt.IsSimulation) - return true; - Stopwatch sw = Stopwatch.StartNew(); //int requestData = 1001; Log.I($"StreamLight {MESSAGE_PC_LBAD_READY_STATUS} Request"); @@ -153,9 +149,6 @@ namespace AuroraLBAD.Service public bool SendCellInfo(string lotID, string cellID, int recipeNo, int modelID, int jigNo) { - if (ApplicationExt.IsSimulation) - return true; - Stopwatch sw = Stopwatch.StartNew(); byte[] arrCellinfo = null; int sendresult = MakeInfoData(lotID, cellID, recipeNo, modelID, jigNo, out arrCellinfo); @@ -197,9 +190,6 @@ namespace AuroraLBAD.Service } public bool SendWeldingStop() { - if (ApplicationExt.IsSimulation) - return true; - //Welding Stop On Stopwatch sw = Stopwatch.StartNew(); //int requestData = 5000; diff --git a/AuroraDevices/AuroraLaserScanner/ScannerObj.cs b/AuroraDevices/AuroraLaserScanner/ScannerObj.cs index 412c149..dda2a40 100644 --- a/AuroraDevices/AuroraLaserScanner/ScannerObj.cs +++ b/AuroraDevices/AuroraLaserScanner/ScannerObj.cs @@ -91,7 +91,7 @@ namespace AuroraLaserScanner RealImage = 0, VirtualImage = 1 } - public enum eListNo { LIST1 = 1, LIST2 = 2 }; + public enum eListNo { LIST1 = 1, LIST2 = 2, }; public enum eAutoControlParameter { diff --git a/Machines/ILSOS_ACW_H52A/Sequences/SeqAutoRunACWH52A.cs b/Machines/ILSOS_ACW_H52A/Sequences/SeqAutoRunACWH52A.cs index ff40d09..55fdaaf 100644 --- a/Machines/ILSOS_ACW_H52A/Sequences/SeqAutoRunACWH52A.cs +++ b/Machines/ILSOS_ACW_H52A/Sequences/SeqAutoRunACWH52A.cs @@ -51,6 +51,7 @@ namespace ILSOS_ACW_H52A.Sequences public const string SEQ_CHECK_SCANNER_LIST_COMPLETE = "[SeqAutoRunACWH52A] Check Scanner List Complete"; + const string SEQ_CHECK_CAN_EXIST = "[SeqAutoRunACWH52A] Check Can Exist"; const string SEQ_READY_SCANNER_LIST = "[SeqAutoRunACWH52A] Ready ScannerList"; const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunACWH52A] Set Sequence Param (UploadWeldingList Seq)"; @@ -68,6 +69,8 @@ namespace ILSOS_ACW_H52A.Sequences const string SEQ_SET_PARAMS_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunACWH52A] Set Sequence Param (ReportCellResult Seq)"; const string SEQ_DO_ID_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunACWH52A] Process (ReportCellResult Seq)"; const string SEQ_GET_RESULT_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunACWH52A] Get Sequence Result (ReportCellResult Seq)"; + + const string SEQ_APD_DATA_SAVE = "[SeqAutoRunACWH52A] APD Data Save"; //const string SEQ_REPORT_CELLINFO_TO_PLC = "[SeqAutoRunACWH52A] ReportCellInfoToPLC"; const string SEQ_CHECK_CYCLE_STOP = "[SeqAutoRunACWH52A] Check Cycle Stop"; @@ -105,7 +108,7 @@ namespace ILSOS_ACW_H52A.Sequences private IRecipeManager _RecipeManager; - private eListNo _WeldingScannerListNo; + private eListNo _WeldingScannerListNo = eListNo.LIST1; private List _SelectedDrawObjectList; @@ -143,8 +146,9 @@ namespace ILSOS_ACW_H52A.Sequences private double _WeldingStartAngle; - private bool isTheFirstListWrite; - private bool isTheSecondListWrite; + private bool isTheFirstListWrite = true; + private bool isTheSecondListWrite = true; + private bool isTheFirstListExecute; private int _RecipeNo; @@ -174,7 +178,8 @@ namespace ILSOS_ACW_H52A.Sequences sb.AddAction(SEQ_CHECK_LOAD_COMPLETE, CheckLoadComplete); sb.AddAction(SEQ_CHECK_SCANNER_LIST_COMPLETE, CheckScannerListComplete); - sb.AddDecision(SEQ_READY_SCANNER_LIST, ReadyScannerList); + sb.AddDecision(SEQ_CHECK_CAN_EXIST, CheckCanExist); + 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()); @@ -195,20 +200,23 @@ namespace ILSOS_ACW_H52A.Sequences sb.AddDecision(SEQ_CHECK_CAN_WELDED, CheckCanWelded); sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함. + + sb.AddAction(SEQ_APD_DATA_SAVE, SaveCellAPDData); // 용접 완료 시 Cell의 정보를 저장함 sb.AddAction(SEQ_WRITE_COMPLETION_PLC_BIT, WriteCompletionPLCBit); // 정상적으로 종료 되면, complete bit write sb.AddAction(SEQ_INIT_CONDITION_ERROR, InitConditionError); sb.AddAction(SEQ_COMPLETE, Complete); sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_FORK_ENCODER_MONITOR] > sb[SEQ_CHECK_LOAD_COMPLETE] + > sb[SEQ_CHECK_CAN_EXIST] > 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_CHECK_SCANNER_LIST_COMPLETE] > sb[SEQ_READY_SCANNER_LIST] + > 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_EXECUTE_WELDING] > sb[SEQ_REQUEST_UNLOAD_CELL] > sb[SEQ_CHECK_CAN_WELDED] + > sb[SEQ_EXECUTE_WELDING] > sb[SEQ_REQUEST_UNLOAD_CELL] > sb[SEQ_CHECK_SCANNER_LIST_COMPLETE]> sb[SEQ_CHECK_CAN_WELDED] > 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_CHECK_CYCLE_STOP] + > sb[SEQ_APD_DATA_SAVE] > sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_WRITE_COMPLETION_PLC_BIT] > sb[SEQ_JOIN_ENCODER_MONITOR] > sb[SEQ_COMPLETE]); - sb.Flows(sb[SEQ_READY_SCANNER_LIST] > sb[SEQ_EXECUTE_WELDING]); + sb.Flows(sb[SEQ_CHECK_CAN_EXIST] > sb[SEQ_EXECUTE_WELDING]); sb.Flows(sb[SEQ_CHECK_CAN_WELDED] > sb[SEQ_CHECK_CYCLE_STOP]); // 용접을 하지 않은 Cell은 상위보고 하지 않는다. sb.Flows(sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_CHECK_LOAD_COMPLETE]); @@ -302,7 +310,7 @@ namespace ILSOS_ACW_H52A.Sequences var mainPage = WeldingRecipeManager.GetWeldingPage(); _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlAutoPage; - _WeldingScannerListNo = eListNo.LIST1; + //_WeldingScannerListNo = eListNo.LIST1; _CellMeasureCenterOffsetX = 0.0; _CellMeasureCenterOffsetY = 0.0; @@ -386,118 +394,118 @@ namespace ILSOS_ACW_H52A.Sequences //InitAutoRunBit(); // LBAD Initialize // LBAD 는 server 이기 때문에, 만약 끊어졌으면 다시 접속이 필요함 - if (_SystemParameter.BypassModeLBAD == false) - { - if (!_StreamLightLBAD._Client.IsActivated) + if (_SystemParameter.BypassModeLBAD == false) { - int ret = _StreamLightLBAD._Client.Activate(); - Thread.Sleep(500); - if (ret != E1.OK) + if (!_StreamLightLBAD._Client.IsActivated) { - Log.E($"StreamLightClient activate failed"); - return (int)InitErrorList.LBAD_CLIENT_ACTIVATE_FAILED; + int ret = _StreamLightLBAD._Client.Activate(); + Thread.Sleep(500); + if (ret != E1.OK) + { + Log.E($"StreamLightClient activate failed"); + return (int)InitErrorList.LBAD_CLIENT_ACTIVATE_FAILED; + } + } + + if (_StreamLightLBAD._Sub.IsActivated == false) + { + int ret = _StreamLightLBAD._Sub.Activate(); + Thread.Sleep(500); + if (ret != E1.OK) + { + Log.E($"StreamLightSub activate failed"); + return (int)InitErrorList.LBAD_SUB_ACTIVATE_FAILED; + } + } + _StreamLightLBAD.Initialize(); + if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_On) == false) + { + Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null")); + //return false; } } - if (_StreamLightLBAD._Sub.IsActivated == false) + // Laser Initialize + _Laser.PilotLaserOff(); + _Laser.LaserOn(); + Thread.Sleep(500); + if (!_Laser.GetLaserReady()) { - int ret = _StreamLightLBAD._Sub.Activate(); - Thread.Sleep(500); - if (ret != E1.OK) - { - Log.E($"StreamLightSub activate failed"); - return (int)InitErrorList.LBAD_SUB_ACTIVATE_FAILED; - } + Log.E("ERROR Initialize Laser"); + return (int)InitErrorList.LASER_INIT_ERROR; } - _StreamLightLBAD.Initialize(); - if (_StreamLightLBAD.SendReadyStatus(eRequestData.Ready_On) == false) + // Scanner Initialize + if (_Scanner.GetModulationMode()) { - Log.I(string.Format($"[LBAD Interface]CheckReadyStatus null")); - //return false; - } - } - - // Laser Initialize - _Laser.PilotLaserOff(); - _Laser.LaserOn(); - Thread.Sleep(500); - if (!_Laser.GetLaserReady()) - { - Log.E("ERROR Initialize Laser"); - return (int)InitErrorList.LASER_INIT_ERROR; - } - // Scanner Initialize - if (_Scanner.GetModulationMode()) - { - _ModulationMode = true; - } - else - { - _ModulationMode = false; - } - - //// PLC Initialize AutoRun Bit 최소화 작업 진행 - if (_PLC.ReadBit((int)eBitInput.PLC_AUTO_STATUS).data == false) // AutoRun Bit가 OFF인 경우 - { - if (_PLC.ReadBit((int)eBitInput.PLC_AUTO_REQ).data == false) // AutoRun Request 상태 체크 - { - Log.E(string.Format("ERROR Initialize PLC, PLC Alarm ON")); // AutoRun Request와 AutoRun Bit 모두 OFF인 경우, PLC 측에서 Alarm 발생함. - return (int)InitErrorList.PLC_ALARM; + _ModulationMode = true; } else { - Log.E(string.Format("ERROR Initialize PLC, Bit Off PLC_AUTO_STATUS")); // AutoRun Request가 ON인데 AutoRun Bit 모두 OFF인 경우, PLC에서 AutoRun Bit를 켜지 않음. - return (int)InitErrorList.PLC_AUTORUN_BIT_OFF; + _ModulationMode = false; } - } - // Marking On The Flying Off - if (_Scanner.Config.UseMarkingOnTheFly == false) - { - Log.E("ERROR Config Setting : Scanner Marking on the fly (OFF)"); - return (int)InitErrorList.MOTF_OFF; - } + //// PLC Initialize AutoRun Bit 최소화 작업 진행 + if (_PLC.ReadBit((int)eBitInput.PLC_AUTO_STATUS).data == false) // AutoRun Bit가 OFF인 경우 + { + if (_PLC.ReadBit((int)eBitInput.PLC_AUTO_REQ).data == false) // AutoRun Request 상태 체크 + { + Log.E(string.Format("ERROR Initialize PLC, PLC Alarm ON")); // AutoRun Request와 AutoRun Bit 모두 OFF인 경우, PLC 측에서 Alarm 발생함. + return (int)InitErrorList.PLC_ALARM; + } + else + { + Log.E(string.Format("ERROR Initialize PLC, Bit Off PLC_AUTO_STATUS")); // AutoRun Request가 ON인데 AutoRun Bit 모두 OFF인 경우, PLC에서 AutoRun Bit를 켜지 않음. + return (int)InitErrorList.PLC_AUTORUN_BIT_OFF; + } + } - // MOTF Set Scanner List - _Scanner.SelectCorrectionTable(2); - Log.I(string.Format("Normal, Select Laser Correction File")); + // Marking On The Flying Off + if (_Scanner.Config.UseMarkingOnTheFly == false) + { + Log.E("ERROR Config Setting : Scanner Marking on the fly (OFF)"); + return (int)InitErrorList.MOTF_OFF; + } - // Aurora 내부에서 찾아야할 듯 함 - //UsePlcShotThemAll = Dao.SystemRecipe.PlcShotThemAll; - //UsePlcPositionCompensation = Dao.SystemRecipe.PlcPositionCompensationUse; - string[] strArr = Dao.SystemRecipe.WorkRecipeFile.Split('\\'); - RecipeFileName = strArr[strArr.Length - 1]; + // MOTF Set Scanner List + _Scanner.SelectCorrectionTable(2); + Log.I(string.Format("Normal, Select Laser Correction File")); - _LastScannerParamNo = -1; + // Aurora 내부에서 찾아야할 듯 함 + //UsePlcShotThemAll = Dao.SystemRecipe.PlcShotThemAll; + //UsePlcPositionCompensation = Dao.SystemRecipe.PlcPositionCompensationUse; + string[] strArr = Dao.SystemRecipe.WorkRecipeFile.Split('\\'); + RecipeFileName = strArr[strArr.Length - 1]; - // 트럼프 TruDisk를 쓰기 위해서는 SetFirstPulseKiller를 사용해야 함. + _LastScannerParamNo = -1; - // Rotary는 시작 트리거 미사용 - _Scanner.SetControlMode(0); - UtilUnit.logUnit.SetLog(LogUnit.eLogType.DEBUG, MethodBase.GetCurrentMethod().Name, "[AutoRun] 외부 시작 트리거 DISABLE"); + // 트럼프 TruDisk를 쓰기 위해서는 SetFirstPulseKiller를 사용해야 함. - #region MOTF Absolute Encoder 기준으로 초기화 - // Set Rotate Center는 Ctrl명령, 처음 한번만 실행 - _Scanner.SetRotateCenter(_Scanner.Config.MarkingOnTheFlyRotateCenterX, _Scanner.Config.MarkingOnTheFlyRotateCenterY); + // Rotary는 시작 트리거 미사용 + _Scanner.SetControlMode(0); + UtilUnit.logUnit.SetLog(LogUnit.eLogType.DEBUG, MethodBase.GetCurrentMethod().Name, "[AutoRun] 외부 시작 트리거 DISABLE"); - _Scanner.InitFly2D(); // X, Y 엔코더 리셋 - _EncoderOverflowCount = 0; + #region MOTF Absolute Encoder 기준으로 초기화 + // Set Rotate Center는 Ctrl명령, 처음 한번만 실행 + _Scanner.SetRotateCenter(_Scanner.Config.MarkingOnTheFlyRotateCenterX, _Scanner.Config.MarkingOnTheFlyRotateCenterY); - // 현재 정지상태의 Rotary 엔코더 값을 읽어와서 저장 - _RotaryEncoderOffset = GetRotaryCurrentPosition(); // m_abwRotaryEncoderOffset의 범위는 0 이상 360 미만 + _Scanner.InitFly2D(); // X, Y 엔코더 리셋 + _EncoderOverflowCount = 0; - InitRotaryOnTheFlyWeldingCount(_RotaryEncoderOffset, _RotaryJigCount, out _WeldingCount, out _WeldingJigNo); + // 현재 정지상태의 Rotary 엔코더 값을 읽어와서 저장 + _RotaryEncoderOffset = GetRotaryCurrentPosition(); // m_abwRotaryEncoderOffset의 범위는 0 이상 360 미만 - Log.I(string.Format($"ScannerUnit.InitRotaryOnTheFlyWeldingCount : m_abwRotaryEncoderOffset({_RotaryEncoderOffset}), weldingCount({_WeldingCount}), weldingJigNo({_WeldingJigNo}), rotaryJigCount({_RotaryJigCount})")); + InitRotaryOnTheFlyWeldingCount(_RotaryEncoderOffset, _RotaryJigCount, out _WeldingCount, out _WeldingJigNo); + + Log.I(string.Format($"ScannerUnit.InitRotaryOnTheFlyWeldingCount : m_abwRotaryEncoderOffset({_RotaryEncoderOffset}), weldingCount({_WeldingCount}), weldingJigNo({_WeldingJigNo}), rotaryJigCount({_RotaryJigCount})")); // 용접 완료 대기 스캐너 List 리셋 - ResetInputScannerList(); - WaitingScannerList.Reset(); - CompleteScannerList.Reset(); + //ResetInputScannerList(); + //WaitingScannerList.Reset(); + //CompleteScannerList.Reset(); - isTheFirstListWrite = true; // 작업 시작 시 처음 2개의 List는 입력하고 시작한다 - isTheSecondListWrite = true; - isTheFirstListExecute = true; // 제일 첫 List는 ExecuteList 필요. 이후는 AutoChange + //isTheFirstListWrite = true; // 작업 시작 시 처음 2개의 List는 입력하고 시작한다 + //isTheSecondListWrite = true; + //isTheFirstListExecute = true; // 제일 첫 List는 ExecuteList 필요. 이후는 AutoChange InitAutoRunBit(); // GetRotaryCurrentPosition() 호출 이후 AutoStatus True 변경 #endregion @@ -569,6 +577,7 @@ namespace ILSOS_ACW_H52A.Sequences context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false); return SEQ_INIT_CONDITION_ERROR; } + Status.EquipmentMode = eEquipmentMode.AUTO; var startTime = DateTime.Now; context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime); @@ -590,6 +599,7 @@ namespace ILSOS_ACW_H52A.Sequences // List가 실행 중이라면(ex : 엔코더 대기 상태 등), 반환값은 0, LoadList 할 수 없는 상태(List 실행 중이거나, 엔코더 대기 상태) // LoadList가 0보다 크면 다음 시퀀스 진행해야 함 _InterfaceStartTime = DateTime.Now; + while (!context.Stopped) { if (_Scanner.LoadList(_WeldingScannerListNo) > 0) @@ -618,7 +628,6 @@ namespace ILSOS_ACW_H52A.Sequences { isTheFirstListWrite = false; Log.I("Write the 1st scanner list"); - } else { @@ -626,7 +635,6 @@ namespace ILSOS_ACW_H52A.Sequences { isTheSecondListWrite = false; Log.I("Write the 2nd scanner list"); - } else { @@ -656,13 +664,8 @@ namespace ILSOS_ACW_H52A.Sequences if (CompleteScannerList.CanExist) { isWeled = true; - #region 용접 시간, 엔코더 측정/기록 - //_WeldInterval = DateTime.Now - _WeldEndTime; - //_WeldEndTime = DateTime.Now; - //double elapsedTime = _Scanner.GetTime(); - //_WeldingSpanTime = TimeSpan.FromSeconds(elapsedTime); // Encoder 대기 넘어간 후의, 실제 스캐너 리스트 실행 시간 - //_WeldingStartTime = _WeldEndTime.Subtract(_WeldingSpanTime); + #region 용접 시간, 엔코더 측정/기록 double elaspedTime = _Scanner.GetTime(); if (CompleteScannerList.WeldComplete) @@ -686,13 +689,6 @@ namespace ILSOS_ACW_H52A.Sequences UpdateProductInfoForView(); } - //if (_SystemParameter.BypassModeLBAD == false) { - // if (_StreamLightLBAD.SendWeldingStop() == false) { - // Log.I(string.Format($"[LBAD Interface]SendWeldingStop null")); - // //return null; - // } - //} - UtilUnit.logUnit.SetLog(LogUnit.eLogType.PRODUCT, MethodBase.GetCurrentMethod().Name, "UPDATE_WELDING_TIME;" + _WeldingSpanTime.TotalMilliseconds); UtilUnit.logUnit.SetLog(LogUnit.eLogType.PRODUCT, MethodBase.GetCurrentMethod().Name, "UPDATE_PRODUCT_COUNT;" + _WeldEndTime.ToString("yyyy-MM-dd HH:mm:ss")); @@ -713,6 +709,7 @@ namespace ILSOS_ACW_H52A.Sequences _Scanner.SaveRecord(DataFilePath); } #endregion + } } } @@ -744,7 +741,7 @@ namespace ILSOS_ACW_H52A.Sequences return false; } - private string ReadyScannerList(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + private string CheckCanExist(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { Status.SetWorkingPosition(eWorkingPosition.UPLOADING_WELD_LIST); @@ -792,6 +789,17 @@ namespace ILSOS_ACW_H52A.Sequences Log.I("Can Exist : " + canExist.ToString() + ", JigNo " + _WeldingJigNo + " ,CountNo " + _WeldingCount + ", StartAngle(Y) : " + _WeldingStartAngle); + if (canExist) + return SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ; + else + return SEQ_EXECUTE_WELDING; + + #endregion + } + + private SequenceActionResult ReadyScannerList(SequenceContext context, string id, SequenceActionResult param) + { + #region 이력 // 입력한 Scanner List를 완료대기열에 추가 //SetInputScannerList(_WeldingScannerListNo, DateTime.Now, _WeldingCount, _WeldingStartAngle, _WeldingJigNo, _RotaryJigCount, canExist); @@ -815,58 +823,61 @@ namespace ILSOS_ACW_H52A.Sequences //// SEQ_WAIT_WELDING_START 의 기능이 어떻게 되는 지 확인 후 //// 건너뛰어도 되면 SEQ_EXECUTE_WELDING 으로 변경 해도 됨 //return SEQ_WAIT_WELDING_START; + #endregion - if (canExist) + #region 용접할 Objects 선택 + if (_WeldingJigNo - 1 < _ScannerCanvasUserCtrl.Model.Layers.Length) { - #region 용접할 Objects 선택 - if (_WeldingJigNo - 1 < _ScannerCanvasUserCtrl.Model.Layers.Length) - { - _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[_WeldingJigNo - 1].Objects; - Log.I(string.Format("Page 불러오기 : [{0}])", _WeldingJigNo - 1)); - } - else - { - _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; - Log.I(string.Format("Page 불러오기 : [0])")); - } - #endregion - // 입력한 Scanner List를 완료대기열에 추가 - // Won : GetProcessingWeldingData().WorkLotId 는 CellTrakcer로 부터 받은 상태의 LotId - // GetProcessingWeldingData().LotId 는 AutorunView에 표기할 용접이 완료 된 LotID - string LotId = Status.GetProcessingWeldingData().WorkLotId; // CellTracker로 부터 WorkLotID, WorkCellID 받는 구문 추가 후 해당 데이터로 입력 필요 - string CellId = Status.GetProcessingWeldingData().WorkCellId; - SetInputScannerList(_WeldingScannerListNo, DateTime.Now, _WeldingCount, _WeldingStartAngle, _WeldingJigNo, _RotaryJigCount, canExist, LotId, CellId); - _RecipeNo = _RecipeManager.ActivatedRecipe().Id; - - var item = _SelectedDrawObjectList[0]; - - if (item is Line) - { - Line lineItem = (Line)item; - ScannerParam laserParam = WeldingRecipeManager.GetScannerParam(lineItem.ScannerParamNo); - - // EDC 보내는 용도 - Status.GetProcessingWeldingData().LaserPowerCore = laserParam.LaserPower1.ToString(); - Status.GetProcessingWeldingData().MarkSpeed = laserParam.MarkSpeed.ToString(); - Status.GetProcessingWeldingData().FocalLength = (_PLC.ReadDWord((int)eWordInput.PLC_WELDING_FOCAL_LENGTH).data / 1000f).ToString(); - Status.GetProcessingWeldingData().WeldingJigNo = _WeldingJigNo.ToString(); - } - + _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[_WeldingJigNo - 1].Objects; + Log.I(string.Format("Page 불러오기 : [{0}])", _WeldingJigNo - 1)); } else { - return SEQ_EXECUTE_WELDING; + _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; + Log.I(string.Format("Page 불러오기 : [0])")); } - - //var item = _SelectedDrawObjectList[0]; - - - // 여기서 어디로 가는지 설정 필요함 - return SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ; #endregion + // 입력한 Scanner List를 완료대기열에 추가 + // Won : GetProcessingWeldingData().WorkLotId 는 CellTrakcer로 부터 받은 상태의 LotId + // GetProcessingWeldingData().LotId 는 AutorunView에 표기할 용접이 완료 된 LotID + string LotId = Status.GetProcessingWeldingData().WorkLotId; // CellTracker로 부터 WorkLotID, WorkCellID 받는 구문 추가 후 해당 데이터로 입력 필요 + string CellId = Status.GetProcessingWeldingData().WorkCellId; + SetInputScannerList(_WeldingScannerListNo, DateTime.Now, _WeldingCount, _WeldingStartAngle, _WeldingJigNo, _RotaryJigCount, true, LotId, CellId); + _RecipeNo = _RecipeManager.ActivatedRecipe().Id; + SetWeldingData(); + + return SequenceAction.Ok(); + #endregion } + private ScannerParam GetSelectedDrawObjectData(IDrawObject DrawObj) + { + if (DrawObj is Line lineItem) + return WeldingRecipeManager.GetScannerParam(lineItem.ScannerParamNo); + else if (DrawObj is Arc arcItem) + return WeldingRecipeManager.GetScannerParam(arcItem.ScannerParamNo); + else if (DrawObj is Group groupItem) + return WeldingRecipeManager.GetScannerParam(groupItem.ScannerParamNo); + + return null; + } + private void SetWeldingData() + { + ScannerParam laserParam = null; + laserParam = GetSelectedDrawObjectData(_SelectedDrawObjectList[0]); + + if (laserParam != null) + { + // EDC 보내는 용도 + Status.GetProcessingWeldingData().LaserPowerCore = laserParam.LaserPower1.ToString(); + Status.GetProcessingWeldingData().MarkSpeed = laserParam.MarkSpeed.ToString(); + Status.GetProcessingWeldingData().FocalLength = (_PLC.ReadDWord((int)eWordInput.PLC_WELDING_FOCAL_LENGTH).data / 1000f).ToString(); + Status.GetProcessingWeldingData().WeldingJigNo = _WeldingJigNo.ToString(); + } + } + + public void WaitForEncoderNextRotarySection(int weldingCount, int rotaryJigCount, double rotaryAngleOffset, double encoderResetOffset, out double sectionStartAngle) { // 한 바퀴당 지그 숫자에 따른 변경 @@ -897,7 +908,7 @@ namespace ILSOS_ACW_H52A.Sequences _Scanner.WaitForEncoderRotateRange(encoderAllowedMinDegree, encoderAllowedMaxDegree, sectionStartAngle, sectionEndAngle); } - + public bool GetRotaryCanExist(int jigNo) { #region 지그 16개 요청기록 로그 남기기, 빠져나간 캔에 대한 Complete Bit 초기화 @@ -1148,29 +1159,24 @@ namespace ILSOS_ACW_H52A.Sequences return SequenceAction.Ok(); } - - private static string CheckCycleStop(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + public static bool CycleStopTest = false; + private string CheckCycleStop(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { Status.SetWorkingPosition(eWorkingPosition.CHECKING_CYCLE); - // TODO: 확인 필요, CybleStop 에 대한 내용, cycle stop 여부 가져오기 //bCycleStop = GetCycleStopRequest(); // TODO: 한번만 돌도록 설정함, PLC 로 받으면 좋음. //Jin : cycleStop 명령을 용접 프로그램에서 할 경우가 현재는 없음.. // CheckCycleStop 노드와 Complete 노드 사이 다른 노드가 필요하다면 해당 노드를 CheckCycleStop 노드 위로 올리자 - bool cycleStop = false; - if (cycleStop) - { + bool cycleStop = _PLC.ReadBit((int)eBitInput.PLC_MANUAL_REQ).data; + if (cycleStop || CycleStopTest) return SEQ_SAVE_RESULT_DATA; - } else - { return SEQ_CHECK_LOAD_COMPLETE; - } } + // END ALL - #endregion private static string CheckCanWelded(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { if (isWeled) @@ -1179,13 +1185,19 @@ namespace ILSOS_ACW_H52A.Sequences return SEQ_CHECK_CYCLE_STOP; } + private SequenceActionResult SaveCellAPDData(SequenceContext context, string id, SequenceActionResult param) + { + if (Status.GetProcessingWeldingData().APD.Count > 0) + { + string directoryPath = "D:\\ILSOSConfig\\APD_History"; + string fileName = Status.GetProcessingWeldingData().APD.First().Date.ToString("HHmmss") + "_" + Status.GetProcessingWeldingData().APD.First().CellID; + string fullPath = Path.Combine(directoryPath, Status.GetProcessingWeldingData().APD.First().Date.ToString("yyyy-MM-dd"), fileName); + Status.GetProcessingWeldingData().APD.CreateFiles(fullPath); + } + return SequenceAction.Ok(); + } private SequenceActionResult SaveResultData(SequenceContext context, string id, SequenceActionResult param) { - string directoryPath = "D:\\ILSOSConfig\\APD_History"; - string fileName = Status.GetProcessingWeldingData().APD.First().Date.ToString("HHmmss") + "_" + Status.GetProcessingWeldingData().APD.First().CellID; - string fullPath = Path.Combine(directoryPath, Status.GetProcessingWeldingData().APD.First().Date.ToString("yyyy-MM-dd"), fileName); - Status.GetProcessingWeldingData().APD.CreateFiles(fullPath); - context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true); return SequenceAction.Ok(); } @@ -1309,6 +1321,8 @@ namespace ILSOS_ACW_H52A.Sequences private void OnSeqActionStop() { + Status.EquipmentMode = eEquipmentMode.MANUAL; + //PLC All BIT OFF for (int i = 0; i < _RotaryJigCount; i++) { diff --git a/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs b/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs index deb5483..6855d3c 100644 --- a/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs +++ b/Machines/ILSOS_CCW_H52A/Sequences/SeqAutoRunCCWH52A.cs @@ -3,7 +3,6 @@ using Aurora.Api; using Aurora.Api.Manager; using Aurora.View; using AuroraCellTracker; -//using AuroraOCT; using AuroraIO; using AuroraLaser; using AuroraLaserScanner; @@ -13,7 +12,6 @@ using CoreUnit.Control.UserControl.Canvas; using CoreUnit.Scanner.UserControl.ScannerCanvas; using DB; using Hermes; -using ILSOS_CCW_H52A.Device; using ILSOS_CCW_H52A.Models; using ILSOS_CCW_H52A.RMS; using System; @@ -22,18 +20,18 @@ using System.IO; using System.Linq; using System.Reflection; using System.Threading; +using System.Windows; using WeldingCommon; using WeldingCommon.Alarm; using WeldingCommon.Devices; using WeldingCommon.Recipes; using WeldingCommon.Sequences; +using WeldingCommon.Settings; using WeldingCommon.Utils; using static AuroraLBAD.Service.StreamLightLBAD; using static ILSOS_CCW_H52A.Device.IOController_CCW_H52A; using static ILSOS_CCW_H52A.Device.PLCControllerCCWH52A; using static ILSOS_CCW_H52A.Device.ScannerListCCWH52A; -using Application = System.Windows.Application; -using SystemParameter = WeldingCommon.Settings.SystemParameter; namespace ILSOS_CCW_H52A.Sequences { @@ -43,6 +41,7 @@ namespace ILSOS_CCW_H52A.Sequences const string SEQ_ENTER = "[SeqAutoRunCCWH52A] SEQ_ENTER"; // inputParam 으로 받자. const string SEQ_CHECK_INIT_CONDITION = "[SeqAutoRunCCWH52A] Check Init Condition"; // Check Init Condition + const string SEQ_FORK_ENCODER_MONITOR = "[SeqAutoRunCCWH52A] Fork Encoder Monitor"; const string SEQ_ENCODER_MONITOR = "[SeqAutoRunCCWH52A] Check Encoder Monitor"; const string SEQ_JOIN_ENCODER_MONITOR = "[SeqAutoRunCCWH52A] Join Encoder Monitor"; @@ -52,6 +51,7 @@ namespace ILSOS_CCW_H52A.Sequences public const string SEQ_CHECK_SCANNER_LIST_COMPLETE = "[SeqAutoRunCCWH52A] Check Scanner List Complete"; + const string SEQ_CHECK_CAN_EXIST = "[SeqAutoRunCCWH52A] Check Can Exist"; const string SEQ_READY_SCANNER_LIST = "[SeqAutoRunCCWH52A] Ready ScannerList"; const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqAutoRunCCWH52A] Set Sequence Param (UploadWeldingList Seq)"; @@ -70,6 +70,8 @@ namespace ILSOS_CCW_H52A.Sequences const string SEQ_DO_ID_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunCCWH52A] Process (ReportCellResult Seq)"; const string SEQ_GET_RESULT_REPORT_CELL_RESULT_SEQ = "[SeqAutoRunCCWH52A] Get Sequence Result (ReportCellResult Seq)"; + const string SEQ_APD_DATA_SAVE = "[SeqAutoRunCCWH52A] APD Data Save"; + //const string SEQ_REPORT_CELLINFO_TO_PLC = "[SeqAutoRunCCWH52A] ReportCellInfoToPLC"; const string SEQ_CHECK_CYCLE_STOP = "[SeqAutoRunCCWH52A] Check Cycle Stop"; const string SEQ_CHECK_CAN_WELDED = "[SeqAutoRunCCWH52A] Check Can Welded"; @@ -106,7 +108,7 @@ namespace ILSOS_CCW_H52A.Sequences private IRecipeManager _RecipeManager; - private eListNo _WeldingScannerListNo; + private eListNo _WeldingScannerListNo = eListNo.LIST1; private List _SelectedDrawObjectList; @@ -115,6 +117,10 @@ namespace ILSOS_CCW_H52A.Sequences private uint _TodayProduct; private uint _TotalProduct; + private double _LaserPowerByLBAD; + private int _CompletedJigNo; + private static bool isWeled; + private bool _ModulationMode; private DateTime _AutoRunStartTime; @@ -127,9 +133,6 @@ namespace ILSOS_CCW_H52A.Sequences private double _CellMeasureCenterOffsetX; private double _CellMeasureCenterOffsetY; - private double _LaserPowerByLBAD; - private int _CompletedJigNo; - // MOTF private TimeSpan _WeldInterval; @@ -143,16 +146,15 @@ namespace ILSOS_CCW_H52A.Sequences private double _WeldingStartAngle; - private bool isTheFirstListWrite; - private bool isTheSecondListWrite; + private bool isTheFirstListWrite = true; + private bool isTheSecondListWrite = true; + private bool isTheFirstListExecute; private int _RecipeNo; - private static bool isWeled; - private bool _WeldingDone; + private bool UsePlcShotThemAll { get; set; } = false; private bool UsePlcPositionCompensation { get; set; } = false; private string RecipeFileName { get; set; } = ""; - private enum InitErrorList { SUCCESS = 0, @@ -163,7 +165,6 @@ namespace ILSOS_CCW_H52A.Sequences MOTF_OFF, PLC_ALARM, } - public SequenceBuilder Builder() { var sb = new SequenceBuilder(1000, true); @@ -174,18 +175,20 @@ namespace ILSOS_CCW_H52A.Sequences sb.AddFork(SEQ_FORK_ENCODER_MONITOR); sb.AddAction(SEQ_ENCODER_MONITOR, EncoderMonitor); sb.AddJoin(SEQ_JOIN_ENCODER_MONITOR); + sb.AddAction(SEQ_CHECK_LOAD_COMPLETE, CheckLoadComplete); sb.AddAction(SEQ_CHECK_SCANNER_LIST_COMPLETE, CheckScannerListComplete); - sb.AddDecision(SEQ_READY_SCANNER_LIST, ReadyScannerList); - - 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.AddDecision(SEQ_CHECK_CAN_EXIST, CheckCanExist); + 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_SET_PARAMS_RECEIVE_CELL_INFO_SEQ, SetReceiveCellInfo_SeqParams); // Cell 정보를 받아와 입력한다. + sb.AddSubsequence(SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ, SequenceManager.GetSeqBuilder_SeqReceiveCellInfo()); // cell 정보를 받아오는 Sub Seq 실행 + sb.AddAction(SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ, GetReceiveCellInfo_SeqResult); // Cell 정보를 가져온다 + sb.AddAction(SEQ_EXECUTE_WELDING, ExecuteWelding); sb.AddAction(SEQ_REQUEST_UNLOAD_CELL, RequestUnloadCell); @@ -197,20 +200,23 @@ namespace ILSOS_CCW_H52A.Sequences sb.AddDecision(SEQ_CHECK_CAN_WELDED, CheckCanWelded); sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함. + + sb.AddAction(SEQ_APD_DATA_SAVE, SaveCellAPDData); // 용접 완료 시 Cell의 정보를 저장함 sb.AddAction(SEQ_WRITE_COMPLETION_PLC_BIT, WriteCompletionPLCBit); // 정상적으로 종료 되면, complete bit write sb.AddAction(SEQ_INIT_CONDITION_ERROR, InitConditionError); sb.AddAction(SEQ_COMPLETE, Complete); sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_FORK_ENCODER_MONITOR] > sb[SEQ_CHECK_LOAD_COMPLETE] + > sb[SEQ_CHECK_CAN_EXIST] > 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_CHECK_SCANNER_LIST_COMPLETE] > sb[SEQ_READY_SCANNER_LIST] + > 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_EXECUTE_WELDING] > sb[SEQ_REQUEST_UNLOAD_CELL] > sb[SEQ_CHECK_CAN_WELDED] + > sb[SEQ_EXECUTE_WELDING] > sb[SEQ_REQUEST_UNLOAD_CELL] > sb[SEQ_CHECK_SCANNER_LIST_COMPLETE] > sb[SEQ_CHECK_CAN_WELDED] > 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_CHECK_CYCLE_STOP] + > sb[SEQ_APD_DATA_SAVE] > sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_WRITE_COMPLETION_PLC_BIT] > sb[SEQ_JOIN_ENCODER_MONITOR] > sb[SEQ_COMPLETE]); - sb.Flows(sb[SEQ_READY_SCANNER_LIST] > sb[SEQ_EXECUTE_WELDING]); + sb.Flows(sb[SEQ_CHECK_CAN_EXIST] > sb[SEQ_EXECUTE_WELDING]); sb.Flows(sb[SEQ_CHECK_CAN_WELDED] > sb[SEQ_CHECK_CYCLE_STOP]); // 용접을 하지 않은 Cell은 상위보고 하지 않는다. sb.Flows(sb[SEQ_CHECK_CYCLE_STOP] > sb[SEQ_CHECK_LOAD_COMPLETE]); @@ -218,7 +224,11 @@ namespace ILSOS_CCW_H52A.Sequences sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_INIT_CONDITION_ERROR] > sb.Final); sb.Flows(sb[SEQ_FORK_ENCODER_MONITOR] > sb[SEQ_ENCODER_MONITOR] > sb[SEQ_JOIN_ENCODER_MONITOR] > sb[SEQ_COMPLETE]); - #region + #region + //sb.Flows(sb[SEQ_FORK_ENCODER_MONITOR] > sb[SEQ_ENCODER_MONITOR]); + ////sb.Flows(sb[SEQ_FORK_ENCODER_MONITOR] > sb[SEQ_CHECK_LOAD_COMPLETE]); + //sb.Flows(sb[SEQ_JOIN_ENCODER_MONITOR] > sb[SEQ_COMPLETE]); + /// //// 1. 시퀀스 시작 ~ 포크 //sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_FORK_ENCODER_MONITOR]); @@ -267,6 +277,8 @@ namespace ILSOS_CCW_H52A.Sequences _RecipeManager = Application.Current.AuroraEnv().RecipeManager; _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); + + InitDev(context); if (!CheckDeviceReady(context)) { //Check Device @@ -276,7 +288,6 @@ namespace ILSOS_CCW_H52A.Sequences //return null; } - if (InitSequenceVariable(context) == false) { //AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError); @@ -299,7 +310,7 @@ namespace ILSOS_CCW_H52A.Sequences var mainPage = WeldingRecipeManager.GetWeldingPage(); _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlAutoPage; - _WeldingScannerListNo = eListNo.LIST1; + //_WeldingScannerListNo = eListNo.LIST1; _CellMeasureCenterOffsetX = 0.0; _CellMeasureCenterOffsetY = 0.0; @@ -365,7 +376,12 @@ namespace ILSOS_CCW_H52A.Sequences private bool CheckCondition_Interlock() { // PLC, Data, IO 등 Interlock checking - + // Config checking + //if (_Scanner.Config.UseMarkingOnTheFly == false) + //{ + // Log.E("ERROR Config Setting : Scanner Marking on the fly (OFF)"); + // return false; + //} return true; } @@ -483,13 +499,13 @@ namespace ILSOS_CCW_H52A.Sequences Log.I(string.Format($"ScannerUnit.InitRotaryOnTheFlyWeldingCount : m_abwRotaryEncoderOffset({_RotaryEncoderOffset}), weldingCount({_WeldingCount}), weldingJigNo({_WeldingJigNo}), rotaryJigCount({_RotaryJigCount})")); // 용접 완료 대기 스캐너 List 리셋 - ResetInputScannerList(); - WaitingScannerList.Reset(); - CompleteScannerList.Reset(); + //ResetInputScannerList(); + //WaitingScannerList.Reset(); + //CompleteScannerList.Reset(); - isTheFirstListWrite = true; // 작업 시작 시 처음 2개의 List는 입력하고 시작한다 - isTheSecondListWrite = true; - isTheFirstListExecute = true; // 제일 첫 List는 ExecuteList 필요. 이후는 AutoChange + //isTheFirstListWrite = true; // 작업 시작 시 처음 2개의 List는 입력하고 시작한다 + //isTheSecondListWrite = true; + //isTheFirstListExecute = true; // 제일 첫 List는 ExecuteList 필요. 이후는 AutoChange InitAutoRunBit(); // GetRotaryCurrentPosition() 호출 이후 AutoStatus True 변경 #endregion @@ -561,7 +577,6 @@ namespace ILSOS_CCW_H52A.Sequences context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false); return SEQ_INIT_CONDITION_ERROR; } - // AutoMode 전환 시점 Status.EquipmentMode = eEquipmentMode.AUTO; var startTime = DateTime.Now; @@ -584,6 +599,7 @@ namespace ILSOS_CCW_H52A.Sequences // List가 실행 중이라면(ex : 엔코더 대기 상태 등), 반환값은 0, LoadList 할 수 없는 상태(List 실행 중이거나, 엔코더 대기 상태) // LoadList가 0보다 크면 다음 시퀀스 진행해야 함 _InterfaceStartTime = DateTime.Now; + while (!context.Stopped) { if (_Scanner.LoadList(_WeldingScannerListNo) > 0) @@ -632,6 +648,7 @@ namespace ILSOS_CCW_H52A.Sequences Log.I("ERR_SCANNER_LIST_PROCESSING_TIMEOVER"); return SequenceAction.Error(); + // WON : 2칸 전에 용접을 진행하지 않아 현재 Angle이 CompleteScannerList.StartAngle + 45 범위를 벗어난 경우라면 에러 상황이 아니므로 에러로 처리 할 필요가 없다 // 위에 CheckCurrentEncoderAngle if문 조건 대신 아래 내용으로 테스트 해본 뒤에 적용 필요 //if (!CheckCurrentEncoderAngle(CompleteScannerList.StartAngle)) { @@ -647,13 +664,8 @@ namespace ILSOS_CCW_H52A.Sequences if (CompleteScannerList.CanExist) { isWeled = true; - #region 용접 시간, 엔코더 측정/기록 - //_WeldInterval = DateTime.Now - _WeldEndTime; - //_WeldEndTime = DateTime.Now; - //double elapsedTime = _Scanner.GetTime(); - //_WeldingSpanTime = TimeSpan.FromSeconds(elapsedTime); // Encoder 대기 넘어간 후의, 실제 스캐너 리스트 실행 시간 - //_WeldingStartTime = _WeldEndTime.Subtract(_WeldingSpanTime); + #region 용접 시간, 엔코더 측정/기록 double elaspedTime = _Scanner.GetTime(); if (CompleteScannerList.WeldComplete) @@ -665,9 +677,6 @@ namespace ILSOS_CCW_H52A.Sequences _LotId = CompleteScannerList.LotId; _CellId = CompleteScannerList.CellId; - _LaserPowerByLBAD = StreamLightLBAD.LaserPowerByLBAD[CompleteScannerList.JigNo]; - - _CompletedJigNo = CompleteScannerList.JigNo; Log.I(string.Format("JigNo : {0}, Weld start : {1}, Weld End : {2}, WeldTime : {3}, interval : {4:F3}", CompleteScannerList.JigNo, _WeldingStartTime.ToString("HH:mm:ss.fff"), _WeldEndTime.ToString("HH:mm:ss.fff"), _WeldingSpanTime.TotalMilliseconds, _WeldInterval.TotalSeconds)); @@ -680,13 +689,6 @@ namespace ILSOS_CCW_H52A.Sequences UpdateProductInfoForView(); } - //if (_SystemParameter.BypassModeLBAD == false) { - // if (_StreamLightLBAD.SendWeldingStop() == false) { - // Log.I(string.Format($"[LBAD Interface]SendWeldingStop null")); - // //return null; - // } - //} - UtilUnit.logUnit.SetLog(LogUnit.eLogType.PRODUCT, MethodBase.GetCurrentMethod().Name, "UPDATE_WELDING_TIME;" + _WeldingSpanTime.TotalMilliseconds); UtilUnit.logUnit.SetLog(LogUnit.eLogType.PRODUCT, MethodBase.GetCurrentMethod().Name, "UPDATE_PRODUCT_COUNT;" + _WeldEndTime.ToString("yyyy-MM-dd HH:mm:ss")); @@ -707,6 +709,7 @@ namespace ILSOS_CCW_H52A.Sequences _Scanner.SaveRecord(DataFilePath); } #endregion + } } } @@ -729,22 +732,16 @@ namespace ILSOS_CCW_H52A.Sequences if (currentAngle < startAngle + 45)// 다음 리스트 구간이 끝나기 전까지는 완료가 되어야 한다 { Log.I(string.Format("Current encoder check OK, startAngle : {0}, currentAngle : {1})", startAngle, currentAngle)); - _WeldingDone = true; return true; } else Log.I(string.Format("Current encoder check NG(Too late), startAngle : {0}, currentAngle : {1})", startAngle, currentAngle)); } - else - { - Log.I(string.Format("Current encoder check NG(Too early), startAngle : {0}, currentAngle : {1})", startAngle, currentAngle)); - _WeldingDone = false; - - } + else Log.I(string.Format("Current encoder check NG(Too early), startAngle : {0}, currentAngle : {1})", startAngle, currentAngle)); return false; } - private string ReadyScannerList(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + private string CheckCanExist(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { Status.SetWorkingPosition(eWorkingPosition.UPLOADING_WELD_LIST); @@ -792,6 +789,17 @@ namespace ILSOS_CCW_H52A.Sequences Log.I("Can Exist : " + canExist.ToString() + ", JigNo " + _WeldingJigNo + " ,CountNo " + _WeldingCount + ", StartAngle(Y) : " + _WeldingStartAngle); + if (canExist) + return SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ; + else + return SEQ_EXECUTE_WELDING; + + #endregion + } + + private SequenceActionResult ReadyScannerList(SequenceContext context, string id, SequenceActionResult param) + { + #region 이력 // 입력한 Scanner List를 완료대기열에 추가 //SetInputScannerList(_WeldingScannerListNo, DateTime.Now, _WeldingCount, _WeldingStartAngle, _WeldingJigNo, _RotaryJigCount, canExist); @@ -815,58 +823,61 @@ namespace ILSOS_CCW_H52A.Sequences //// SEQ_WAIT_WELDING_START 의 기능이 어떻게 되는 지 확인 후 //// 건너뛰어도 되면 SEQ_EXECUTE_WELDING 으로 변경 해도 됨 //return SEQ_WAIT_WELDING_START; + #endregion - if (canExist) + #region 용접할 Objects 선택 + if (_WeldingJigNo - 1 < _ScannerCanvasUserCtrl.Model.Layers.Length) { - #region 용접할 Objects 선택 - if (_WeldingJigNo - 1 < _ScannerCanvasUserCtrl.Model.Layers.Length) - { - _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[_WeldingJigNo - 1].Objects; - Log.I(string.Format("Page 불러오기 : [{0}])", _WeldingJigNo - 1)); - } - else - { - _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; - Log.I(string.Format("Page 불러오기 : [0])")); - } - #endregion - // 입력한 Scanner List를 완료대기열에 추가 - // Won : GetProcessingWeldingData().WorkLotId 는 CellTrakcer로 부터 받은 상태의 LotId - // GetProcessingWeldingData().LotId 는 AutorunView에 표기할 용접이 완료 된 LotID - string LotId = Status.GetProcessingWeldingData().WorkLotId; // CellTracker로 부터 WorkLotID, WorkCellID 받는 구문 추가 후 해당 데이터로 입력 필요 - string CellId = Status.GetProcessingWeldingData().WorkCellId; - SetInputScannerList(_WeldingScannerListNo, DateTime.Now, _WeldingCount, _WeldingStartAngle, _WeldingJigNo, _RotaryJigCount, canExist, LotId, CellId); - _RecipeNo = _RecipeManager.ActivatedRecipe().Id; - - var item = _SelectedDrawObjectList[0]; - - if (item is Line) - { - Line lineItem = (Line)item; - ScannerParam laserParam = WeldingRecipeManager.GetScannerParam(lineItem.ScannerParamNo); - - // EDC 보내는 용도 - Status.GetProcessingWeldingData().LaserPowerCore = laserParam.LaserPower1.ToString(); - Status.GetProcessingWeldingData().MarkSpeed = laserParam.MarkSpeed.ToString(); - Status.GetProcessingWeldingData().FocalLength = (_PLC.ReadDWord((int)eWordInput.PLC_WELDING_FOCAL_LENGTH).data / 1000f).ToString(); - Status.GetProcessingWeldingData().WeldingJigNo = _WeldingJigNo.ToString(); - } - + _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[_WeldingJigNo - 1].Objects; + Log.I(string.Format("Page 불러오기 : [{0}])", _WeldingJigNo - 1)); } else { - return SEQ_EXECUTE_WELDING; + _SelectedDrawObjectList = _ScannerCanvasUserCtrl.Model.Layers[0].Objects; + Log.I(string.Format("Page 불러오기 : [0])")); } - - //var item = _SelectedDrawObjectList[0]; - - - // 여기서 어디로 가는지 설정 필요함 - return SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ; #endregion + // 입력한 Scanner List를 완료대기열에 추가 + // Won : GetProcessingWeldingData().WorkLotId 는 CellTrakcer로 부터 받은 상태의 LotId + // GetProcessingWeldingData().LotId 는 AutorunView에 표기할 용접이 완료 된 LotID + string LotId = Status.GetProcessingWeldingData().WorkLotId; // CellTracker로 부터 WorkLotID, WorkCellID 받는 구문 추가 후 해당 데이터로 입력 필요 + string CellId = Status.GetProcessingWeldingData().WorkCellId; + SetInputScannerList(_WeldingScannerListNo, DateTime.Now, _WeldingCount, _WeldingStartAngle, _WeldingJigNo, _RotaryJigCount, true, LotId, CellId); + _RecipeNo = _RecipeManager.ActivatedRecipe().Id; + SetWeldingData(); + + return SequenceAction.Ok(); + #endregion } + private ScannerParam GetSelectedDrawObjectData(IDrawObject DrawObj) + { + if (DrawObj is Line lineItem) + return WeldingRecipeManager.GetScannerParam(lineItem.ScannerParamNo); + else if (DrawObj is Arc arcItem) + return WeldingRecipeManager.GetScannerParam(arcItem.ScannerParamNo); + else if (DrawObj is Group groupItem) + return WeldingRecipeManager.GetScannerParam(groupItem.ScannerParamNo); + + return null; + } + private void SetWeldingData() + { + ScannerParam laserParam = null; + laserParam = GetSelectedDrawObjectData(_SelectedDrawObjectList[0]); + + if (laserParam != null) + { + // EDC 보내는 용도 + Status.GetProcessingWeldingData().LaserPowerCore = laserParam.LaserPower1.ToString(); + Status.GetProcessingWeldingData().MarkSpeed = laserParam.MarkSpeed.ToString(); + Status.GetProcessingWeldingData().FocalLength = (_PLC.ReadDWord((int)eWordInput.PLC_WELDING_FOCAL_LENGTH).data / 1000f).ToString(); + Status.GetProcessingWeldingData().WeldingJigNo = _WeldingJigNo.ToString(); + } + } + + public void WaitForEncoderNextRotarySection(int weldingCount, int rotaryJigCount, double rotaryAngleOffset, double encoderResetOffset, out double sectionStartAngle) { // 한 바퀴당 지그 숫자에 따른 변경 @@ -976,7 +987,6 @@ namespace ILSOS_CCW_H52A.Sequences { return null; } - return SequenceAction.Ok(); } @@ -1014,7 +1024,6 @@ namespace ILSOS_CCW_H52A.Sequences return SequenceAction.Ok(); } - private SequenceActionResult EncoderMonitor(SequenceContext context, string id, SequenceActionResult param) { int EncoderLogCount = 0; @@ -1033,7 +1042,6 @@ namespace ILSOS_CCW_H52A.Sequences if (InputScannerList[(int)_WeldingScannerListNo - 1].CanExist) { Log.I($"Fork Before Min Rotate Encoder X : ({encoderX}), Encoder Y : ({currentAngle}), PLC Rotary : ({CurrentPosPLC}), List {_WeldingScannerListNo}, JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})"); - EncoderLogCount = 0; if (!_SystemParameter.BypassModeLBAD) { if (InputScannerList[(int)_WeldingScannerListNo - 1].CheckSendCellinfo == false) @@ -1060,13 +1068,15 @@ namespace ILSOS_CCW_H52A.Sequences { InputScannerList[(int)_WeldingScannerListNo - 1].WeldStartTime = DateTime.Now; InputScannerList[(int)_WeldingScannerListNo - 1].WeldComplete = true; + EncoderLogCount = 0; + Log.I($"Laser On, Welding Complete. JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})"); } if (EncoderLogCount == 0) { - Log.I($"Fork Laser On Encoder X : ({encoderX}), Encoder Y : ({currentAngle}), PLC Rotary : ({CurrentPosPLC}), List {_WeldingScannerListNo} JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})"); + Log.I($"Fork Laser On Encoder X : ({encoderX}), Encoder Y : ({currentAngle}), PLC Rotary : ({CurrentPosPLC}), List {_WeldingScannerListNo}, JigNo : ({InputScannerList[(int)_WeldingScannerListNo - 1].JigNo})"); } - EncoderLogCount = (EncoderLogCount + 1) % 10; + EncoderLogCount = (EncoderLogCount + 1) % 7; } for (int i = 0; i < _RotaryJigCount; i++) @@ -1149,29 +1159,24 @@ namespace ILSOS_CCW_H52A.Sequences return SequenceAction.Ok(); } - private static string CheckCycleStop(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + public static bool CycleStopTest = false; + private string CheckCycleStop(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { Status.SetWorkingPosition(eWorkingPosition.CHECKING_CYCLE); - // TODO: 확인 필요, CybleStop 에 대한 내용, cycle stop 여부 가져오기 //bCycleStop = GetCycleStopRequest(); // TODO: 한번만 돌도록 설정함, PLC 로 받으면 좋음. //Jin : cycleStop 명령을 용접 프로그램에서 할 경우가 현재는 없음.. // CheckCycleStop 노드와 Complete 노드 사이 다른 노드가 필요하다면 해당 노드를 CheckCycleStop 노드 위로 올리자 - bool cycleStop = false; - if (cycleStop) - { + bool cycleStop = _PLC.ReadBit((int)eBitInput.PLC_MANUAL_REQ).data; + if (cycleStop || CycleStopTest) return SEQ_SAVE_RESULT_DATA; - } else - { return SEQ_CHECK_LOAD_COMPLETE; - } } - // END ALL - #endregion + // END ALL private static string CheckCanWelded(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { if (isWeled) @@ -1179,6 +1184,18 @@ namespace ILSOS_CCW_H52A.Sequences else return SEQ_CHECK_CYCLE_STOP; } + + private SequenceActionResult SaveCellAPDData(SequenceContext context, string id, SequenceActionResult param) + { + if (Status.GetProcessingWeldingData().APD.Count > 0) + { + string directoryPath = "D:\\ILSOSConfig\\APD_History"; + string fileName = Status.GetProcessingWeldingData().APD.First().Date.ToString("HHmmss") + "_" + Status.GetProcessingWeldingData().APD.First().CellID; + string fullPath = Path.Combine(directoryPath, Status.GetProcessingWeldingData().APD.First().Date.ToString("yyyy-MM-dd"), fileName); + Status.GetProcessingWeldingData().APD.CreateFiles(fullPath); + } + return SequenceAction.Ok(); + } private SequenceActionResult SaveResultData(SequenceContext context, string id, SequenceActionResult param) { context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true); @@ -1304,7 +1321,6 @@ namespace ILSOS_CCW_H52A.Sequences private void OnSeqActionStop() { - // ManualMode 전환 시점 Status.EquipmentMode = eEquipmentMode.MANUAL; //PLC All BIT OFF @@ -1347,10 +1363,20 @@ namespace ILSOS_CCW_H52A.Sequences } } + // 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 SeqAutoRunCCWH52A_InitParam : InitParam { public ScoutSeqParams ScoutSeqParams { get; set; } public bool UseStream { get; set; } + } public class SeqAutoRunCCWH52A_OutParam : OutParam diff --git a/WeldingComponents/WeldingCommon/Data/ActualProcessData.cs b/WeldingComponents/WeldingCommon/Data/ActualProcessData.cs index 2b3c89f..f286ff0 100644 --- a/WeldingComponents/WeldingCommon/Data/ActualProcessData.cs +++ b/WeldingComponents/WeldingCommon/Data/ActualProcessData.cs @@ -26,6 +26,7 @@ namespace WeldingCommon.Data { table.Columns.Add("Date", typeof(string)); table.Columns.Add("Time", typeof(string)); + table.Columns.Add(nameof(ActualProcessUnit.WeldType), typeof(string)); table.Columns.Add(nameof(ActualProcessUnit.LotID), typeof(string)); table.Columns.Add(nameof(ActualProcessUnit.CellID), typeof(string)); table.Columns.Add(nameof(ActualProcessUnit.EncoderCheck), typeof(bool)); @@ -60,7 +61,7 @@ namespace WeldingCommon.Data protected override void InsertItem(int index, ActualProcessUnit item) { base.InsertItem(index, item); - table.Rows.Add(item.Date.ToString("yyyy-MM-dd"), item.Date.ToString("HH:mm:ss.fff"), item.LotID, item.CellID, item.EncoderCheck, + table.Rows.Add(item.Date.ToString("yyyy-MM-dd"), item.Date.ToString("HH:mm:ss.fff"),item.WeldType, item.LotID, item.CellID, item.EncoderCheck, item.StartPointX, item.StartPointY, item.EndPointX, item.EndPointY, item.WeldCondition, item.LaserOnDelay, item.LaserOffDelay, item.JumpDelay, item.MarkDelay, item.PolygonDelay, item.Power, item.JumpSpeed, item.MarkSpeed, item.JumpX, @@ -80,6 +81,10 @@ namespace WeldingCommon.Data private DateTime _Date; public string LotID { get => Status.GetProcessingWeldingData().LotId; } public string CellID { get => Status.GetProcessingWeldingData().CellId; } + + public string WeldType { get => _WeldType; set => SetProperty(ref _WeldType, value); } + private string _WeldType; + public bool EncoderCheck { get => _EncoderCheck; set => SetProperty(ref _EncoderCheck, value); } private bool _EncoderCheck; public double StartPointX { get => _StartPointX; set => SetProperty(ref _StartPointX, value); } diff --git a/WeldingComponents/WeldingCommon/Sequences/Main/SeqUploadWeldingList.cs b/WeldingComponents/WeldingCommon/Sequences/Main/SeqUploadWeldingList.cs index 71909c2..29e9336 100644 --- a/WeldingComponents/WeldingCommon/Sequences/Main/SeqUploadWeldingList.cs +++ b/WeldingComponents/WeldingCommon/Sequences/Main/SeqUploadWeldingList.cs @@ -418,6 +418,7 @@ namespace WeldingCommon.Sequences { laserLog.Power = param.LaserPower1; laserLog.JumpSpeed = param.JumpSpeed; laserLog.MarkSpeed = param.MarkSpeed; + laserLog.WeldType = "Line"; // 2. 스캐너 가공 작업 // 2.1. Wobbel 관련 설정 @@ -1412,6 +1413,20 @@ namespace WeldingCommon.Sequences { float percentLaser2 = 0; SetScannerProcessCondition(param, out percentLaser1, out percentLaser2); + //CSV Laser Log 추가 + var laserLog = new ActualProcessUnit(); + laserLog.Date = DateTime.Now; + laserLog.WeldCondition = param.No + 1; + laserLog.LaserOnDelay = param.LaserOnDelay; + laserLog.LaserOffDelay = param.LaserOffDelay; + laserLog.JumpDelay = param.JumpDelay; + laserLog.MarkDelay = param.MarkDelay; + laserLog.PolygonDelay = param.PolygonDelay; + laserLog.Power = param.LaserPower1; + laserLog.JumpSpeed = param.JumpSpeed; + laserLog.MarkSpeed = param.MarkSpeed; + laserLog.WeldType = "Arc"; + Log.I(string.Format($"[Arc Weld] Weld Condition(No:{param.No + 1}) Setting(LaserOnDelay:{param.LaserOnDelay},LaserOffDelay:{param.LaserOffDelay},JumpDelay:{param.JumpDelay},MarkDelay:{param.MarkDelay},PolygonDelay:{param.PolygonDelay},Power:{param.LaserPower1},JumpSpeed:{param.JumpSpeed},MarkSpeed:{param.MarkSpeed})")); // 2. 스캐너 가공 작업 @@ -1443,6 +1458,10 @@ namespace WeldingCommon.Sequences { _Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.LIST); _Scanner.JumpAbs(obj.PF1.X + xOffset, obj.PF1.Y + yOffset, eFunctionType.LIST); Log.I(string.Format($"[Arc Weld] Jump ({obj.PF1.X + xOffset},{obj.PF1.Y + yOffset})")); + + //CSV Laser Log 추가 + laserLog.JumpX = obj.PF1.X + xOffset; + laserLog.JumpY = obj.PF1.Y + yOffset; } } else { @@ -1643,6 +1662,13 @@ namespace WeldingCommon.Sequences { Log.I(string.Format($"[Arc Weld] Arc center ({obj.CenterPointF.X + xOffset},{obj.CenterPointF.Y + yOffset}), Sweep angle : ({obj.SweepAngle})")); } + //CSV Laser Log 추가 + laserLog.StartPointX = obj.PF1.X; + laserLog.StartPointY = obj.PF1.Y; + laserLog.EndPointX = obj.PF2.X; + laserLog.EndPointY = obj.PF2.Y; + Status.GetProcessingWeldingData().APD.Add(laserLog); + } private void LoadArc3PScannerParam(Arc3Point obj)