using Aurora; using Aurora.Api; using Aurora.Api.Devices; using Aurora.Api.Manager; using Aurora.View; using AuroraACS; using AuroraCellTracker; using AuroraIO; using AuroraLaser; using AuroraLaser.Trumpf; using AuroraLaserScanner; using AuroraLBAD; using AuroraLight; using AuroraOCT; using AuroraPLC; using CoreUnit.Control.UserControl.Canvas; using CoreUnit.Scanner.UserControl.ScannerCanvas; using DB; using DB.Recipe; using Hermes; using Hermes.Functional; using Hermes.Functional.Option; using ILSOS_PrismaticScanner.Device; using ILSOS_PrismaticScanner.Models; using Matrox.MatroxImagingLibrary; using MilCommon; using MilUI; using OpenCvSharp; using OpenCvSharp.Dnn; using OpenCvSharp.WpfExtensions; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Data; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.IO.Pipes; using System.Linq; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Runtime.Remoting.Contexts; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows; 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.Devices.ACS; using WeldingCommon.Models; using WeldingCommon.Sequences; using WeldingCommon.Sequences.Main; using WeldingCommon.Settings; using WeldingCommon.Utils; using WeldingCommon.Views; using WeldingCommon.Vision.WeldingObjectGenerator; using static Aurora.Api.SequenceBuilder; using static AuroraIO.AJINEXTEK.AjinIO.IOModuleInfo; using static AuroraIO.Vendor.PAIX.PAIXIO; using static ILSOS_PrismaticScanner.Device.PLCControllerPrismaticScanner; using static WeldingCommon.Devices.PLCController; using static WeldingCommon.Sequences.Main.SeqExecutePlcBitInterface_InitParam; namespace ILSOS_PrismaticScanner.Sequences { /// /// Auto run sequence for prismatic scanner type /// public class SeqAutoRunPrismaticScanner { static readonly Logger Log = new Logger("SeqAutoRunPrismaticScanner"); const string SEQ_ENTER = "SEQ_ENTER"; const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; const string SEQ_SET_BEFORE_UPLOAD = "Set Before Upload"; const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "Set Sequence Param (UploadWeldingList Seq)"; const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "Process (UploadWeldingList Seq)"; const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "Get Sequence Result (UploadWeldingList Seq)"; const string SEQ_CHECK_AFTER_UPLOAD = "Check After Upload"; const string SEQ_COMPLETE = "SEQ_COMPLETE"; const string SEQ_START_WELDING = "Start All Welding"; const string SEQ_DO_COMPONENT_WELDING = "Do Component Welding"; const string SEQ_ACS_MOTION_SET = "Set ACS Motion Parameter"; const string SEQ_ACS_MOTION_START = "ACS Motion Start"; const string SEQ_CHECK_MOTION_END = "Check ACS Motion Complete"; #region 260408 NDY nodes added const string SEQ_STANDBY_MOTION = "Move Stage To Origin"; const string SEQ_STANDBY_SCANNER = "Encoder Reset"; #endregion const int timeoutSeconds = 10; static class ContextKey { public const string KEY_SEQUENCE_RESULT = "KEY_SEQUENCE_RESULT_SeqAutoRunPrismaticScanner"; public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqAutoRunPrismaticScanner"; } // 기존 private SeqTeachingRun_InitParam _InitParam; // 변경 //private SeqAutoRunPrismaticScanner_InitParam _InitParam; private static Scanner _Scanner; private IScannerACS _ACS; private static ACSMotor _AxisX, _AxisZ; private SystemParameter _SystemParameter; private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; private static SequenceSetting _SequenceSetting; private eListNo _WeldingScannerListNo; private List _SelectedObjectList; private List _TargetObjects; private static DateTime _SequenceCompleteTime; private static TimeSpan _MeasurementSpanTime; private static TimeSpan _ScannerSaveLogTime; private static DateTime _partialWeldingStartTime; private int _PageNum; private double lastX, lastY; private double _LastX, _LastY; public SequenceBuilder Builder() { var sb = new SequenceBuilder(1000, true); sb.AddAction(SEQ_ENTER, Sequence_Enter); sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); #region 26.04.08 NDY nodes added sb.AddAction(SEQ_STANDBY_MOTION, SetStandbyMotion); sb.AddAction(SEQ_STANDBY_SCANNER, SetStandbyScanner); #endregion sb.AddAction(SEQ_SET_BEFORE_UPLOAD, SetBeforeUpload); sb.AddAction(SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ, SetUploadWeldingList_SeqParams); sb.AddSubsequence(SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ, CommonSequenceManager.GetSeqBuilder_SeqUploadWeldingList()); sb.AddAction(SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ, GetUploadWeldingList_SeqResult); sb.AddDecision(SEQ_CHECK_AFTER_UPLOAD, CheckAfterUpload); sb.AddAction(SEQ_DO_COMPONENT_WELDING, DoComponentWelding); sb.AddAction(SEQ_ACS_MOTION_SET, SetMotion); sb.AddAction(SEQ_ACS_MOTION_START, StartMotion); sb.AddAction(SEQ_CHECK_MOTION_END, EndWelding); sb.AddAction(SEQ_COMPLETE, Complete); sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_STANDBY_MOTION] > sb[SEQ_STANDBY_SCANNER] > sb[SEQ_SET_BEFORE_UPLOAD] > 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_CHECK_AFTER_UPLOAD] > sb[SEQ_DO_COMPONENT_WELDING] > sb[SEQ_ACS_MOTION_SET] > sb[SEQ_ACS_MOTION_START] > sb[SEQ_CHECK_MOTION_END] > sb[SEQ_COMPLETE] > sb.Final); sb.Flows(sb[SEQ_CHECK_AFTER_UPLOAD] > sb[SEQ_SET_BEFORE_UPLOAD]); sb.OnStopped(OnStopped); sb.OnForceError(OnForceError); //sb.Draw("SeqAutoRunPrismaticScanner.pdf"); return sb; } // ==================== SEQ_ENTER ==================== private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) { Log.I("===== [SEQ_ENTER] Sequence entry ====="); Log.I("SeqTeachingRun Start"); _InitParam = param.Param as SeqTeachingRun_InitParam; // 이곳에서 못 가져오는 이유 if(_InitParam == null) { Log.D($"(확인용)InitParam이 ({_InitParam}) null 입니다."); } _SystemParameter = context.Settings[CommonSettingIds.SystemParameter] as SystemParameter; _SequenceSetting = context.Settings[CommonSettingIds.Sequence] as SequenceSetting; _Scanner = context.Devices[DeviceIds.Scanner] as Scanner; if (_Scanner == null) { Log.E("[SEQ_ENTER] Scanner is NULL"); MessageUtil.ShowErrorToast("Scanner not Ready", Log); return null; } _ACS = context.Devices[DeviceIds.ACS] as ScannerACS; if (_ACS == null) { Log.E("[SEQ_ENTER] ACS is NULL"); MessageUtil.ShowErrorToast("ACS not Ready", Log); return null; } _AxisX = context.Devices[CommonDeviceIds.AxisX2] as ACSMotor; if (_AxisX == null) { Log.E("[SEQ_ENTER] AxisX2 is NULL"); MessageUtil.ShowErrorToast("AxisX not Ready", Log); return null; } _AxisZ = context.Devices[CommonDeviceIds.AxisZ] as ACSMotor; if (_AxisZ == null) { Log.E("[SEQ_ENTER] AxisZ is NULL"); MessageUtil.ShowErrorToast("AxisZ not Ready", Log); return null; } if (!CheckDeviceReady(context)) { AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_TeachingRun_DeviceNotReady); Log.E("[SEQ_ENTER] Device not ready -> exit"); return null; } Log.I("[SEQ_ENTER] Complete -> CheckInitCondition"); return SequenceAction.Ok(); } private bool CheckDeviceReady(SequenceContext context) { List deviceListToCheck = new List() { DeviceIds.ACS, CommonDeviceIds.Scanner, CommonDeviceIds.AxisX2, CommonDeviceIds.AxisZ }; bool isAllDeviceActivated = true; foreach (string item in deviceListToCheck) { bool activated = context.Devices[item].IsActivated; Log.D($"[CheckDeviceReady] {item} -> IsActivated={activated}"); if (!activated) isAllDeviceActivated = false; } return isAllDeviceActivated; } // ==================== SEQ_CHECK_INIT_CONDITION ==================== private SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param) { bool hasAlarm = AlarmManager.HasAlarmLevelHigh(); Log.D($"[CheckInitCondition] HasAlarmLevelHigh={hasAlarm}"); if (hasAlarm) { Log.E("[CheckInitCondition] High alarm exists -> exit"); MessageUtil.ShowWarningToast("Clear Heavy Alarms For Welding!"); return null; } _ScannerSaveLogTime = TimeSpan.Zero; _PageNum = 2; var startTime = DateTime.Now; context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime); Log.I($"[CheckInitCondition] Initial _PageNum={_PageNum}, StartTime={startTime:HH:mm:ss.fff}"); Log.D("ComponentTeachingRun Sequence CheckInitCondition"); return SequenceAction.Ok(); } // ==================== SEQ_STANDBY_MOTION ==================== #region 26.04.08 NDY private SequenceActionResult SetStandbyMotion(SequenceContext context, string id, SequenceActionResult param) { if (_AxisX == null) { Log.W("[MoveStageToOrigin] AxisX2 null - skip"); return SequenceAction.Ok(); } Log.I("[MoveStageToOrigin] Stage X -> 310 move start"); // 26.04.17 NDY - start from 310 _AxisX.SetTargetPos(0, TargetPosType.ABS); _AxisX.SetMoveVelocityImm(AuroraACS.Speed.M); _AxisX.AccelerationImm(AuroraACS.Speed.M); _AxisX.DecelerationImm(AuroraACS.Speed.M); _AxisX.JerkImm(AuroraACS.Speed.M); _AxisX.Move(); Log.D("[MoveStageToOrigin] AxisX.Move() called (target=310)"); // Laser FocusPosition Move 22.8 <- Z axis material position- 자재 위치 기준 하드 코딩 값 _AxisZ.SetTargetPos(22.8, TargetPosType.ABS); _AxisZ.SetMoveVelocityImm(AuroraACS.Speed.M); _AxisZ.AccelerationImm(AuroraACS.Speed.M); _AxisZ.DecelerationImm(AuroraACS.Speed.M); _AxisZ.JerkImm(AuroraACS.Speed.M); _AxisZ.Move(); Log.D("[MoveStageToOrigin] AxisZ.Move() called (target=22.8mm)"); //var res = context.RetryUntilSuccess( // () => _AxisX.IsReachedTargetPosition(0) && _AxisZ.IsReachedTargetPosition(0), // 30 * 1000, 20, true); //var res = context.RetryUntilSuccess( // () => _AxisX.IsReachedTargetPosition(0), // 30 * 1000, 20, true); var res = context.RetryUntilSuccess( () => _AxisX.IsReachedTargetPosition(0), 30 * 1000, 20, true); if (res == E2.TIMEOUT) { Log.E("[MoveStageToOrigin] TIMEOUT"); return null; } else if (res == E2.CANCELLED) { Log.E("[MoveStageToOrigin] CANCELLED"); return null; } Log.I("[MoveStageToOrigin] Stage X = 310 reached"); return SequenceAction.Ok(); } // ==================== SEQ_STANDBY_SCANNER ==================== private SequenceActionResult SetStandbyScanner(SequenceContext context, string id, SequenceActionResult param) { var mainPage = CommonHelper.GetMainPage(); _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; _WeldingScannerListNo = eListNo.LIST1; // _SelectedObjectList = FindObjects(); // removed duplicate 260417 _Scanner.SelectCorrectionTable(2); Log.D("[EncoderReset] SelectCorrectionTable(2) done"); if (!_Scanner.Config.UseMarkingOnTheFly) { Log.W("[EncoderReset] MOTF disabled - skip"); return SequenceAction.Ok(); } Log.I("[EncoderReset] Start"); _Scanner.SetStartList(_WeldingScannerListNo); Log.D($"[EncoderReset] SetStartList({_WeldingScannerListNo}) done"); _Scanner.SetFlyY(_Scanner.Config.MarkingOnTheFlyEncoderResolutionX); // _Scanner.SetFlyX(_Scanner.Config.MarkingOnTheFlyEncoderResolutionX); Log.I($"[EncoderReset] SetFlyY: {_Scanner.Config.MarkingOnTheFlyEncoderResolutionX}"); //_Scanner.WaitForEncoderX(_Scanner.Config.MarkingStartEncoderPositionX); //Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.MarkingStartEncoderPositionX}"); // 26.04.17 NDY - encoder reset at Stage X = 310 //_Scanner.StoreEncoder(0); //_Scanner.SaveAndRestartTimer(); //Log.I("[EncoderReset] Complete - Stage(310) = Scanner Encoder(0) synchronized"); return SequenceAction.Ok(); } private List FindObjects() { if (_InitParam.IsUseExternalObjects) return _InitParam.ExternalObjects; else if (_InitParam.IsObjectSelectAll) return _ScannerCanvasUserCtrl.Model.ActiveLayer.Objects; else return _ScannerCanvasUserCtrl.Canvas.Model.SelectedObjects; } #endregion // ==================== SEQ_SET_BEFORE_UPLOAD ==================== private SequenceActionResult SetBeforeUpload(SequenceContext context, string id, SequenceActionResult param) { Log.I($"===== [SetBeforeUpload] Entry PageNum={_PageNum} ====="); var mainPage = CommonHelper.GetMainPage(); _ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching; int layerIdx = _PageNum - 1; Log.D($"[SetBeforeUpload] LayerIndex={layerIdx}, TotalLayers={_ScannerCanvasUserCtrl.Model.Layers.Count()}"); _SelectedObjectList = _ScannerCanvasUserCtrl.Model.Layers[_PageNum - 1].Objects; Log.D($"[SetBeforeUpload] PageNum={_PageNum} ObjectCount={_SelectedObjectList?.Count ?? 0}"); _LastX = lastX; _LastY = lastY; Log.D($"[SetBeforeUpload] Prev LastX={_LastX:F4}, LastY={_LastY:F4}"); // ScannerConfig dump Log.I("---- [SetBeforeUpload] ScannerConfig values ----"); Log.I($" MarkingStartX_1 = {_Scanner.Config.MarkingStartX_1} (forward start)"); Log.I($" MarkingStartX_2 = {_Scanner.Config.MarkingStartX_2} (reverse start)"); Log.I($" XDiff_Page1and2 = {_Scanner.Config.XDiff_Page1and2} (360, Page1/2 boundary)"); Log.I($" XDiff_Page3and4 = {_Scanner.Config.XDiff_Page3and4} (590, Page3/4 boundary)"); Log.I($" EncoderResolutionX = {_Scanner.Config.MarkingOnTheFlyEncoderResolutionX}"); Log.I("------------------------------------------------"); if (_PageNum == 2 || _PageNum == 4) { if (_PageNum == 2) { // 기존 코드 유지 (if _PageNum==0 -> if _PageNum==2 수정) Log.I($"[SetBeforeUpload] PageNum=2 -> WaitForEncoderX({_Scanner.Config.MarkingStartX_1:F4})"); Log.D($" MarkingStartX_1={_Scanner.Config.MarkingStartX_1} / XDiff_Page1and2={_Scanner.Config.XDiff_Page1and2}"); _Scanner.WaitForEncoderY(-_Scanner.Config.MarkingStartX_1); Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.MarkingStartX_1}"); // 26.04.17 NDY - if need 360 boundary, replace with below //_Scanner.WaitForEncoderX(_Scanner.Config.XDiff_Page1and2); //Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.XDiff_Page1and2}"); } else // PageNum == 4 { // 기존 코드 유지 Log.I($"[SetBeforeUpload] PageNum=4 -> WaitForEncoderX({_Scanner.Config.MarkingStartX_2:F4})"); Log.D($" MarkingStartX_2={_Scanner.Config.MarkingStartX_2} / XDiff_Page3and4={_Scanner.Config.XDiff_Page3and4}"); _Scanner.WaitForEncoderY(-_Scanner.Config.MarkingStartX_2); Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.MarkingStartX_2}"); // 26.04.17 NDY - if need 590 boundary, replace with below //_Scanner.WaitForEncoderX(_Scanner.Config.XDiff_Page3and4); //Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.XDiff_Page3and4}"); } int lineCount = 0; foreach (IDrawObject obj in _SelectedObjectList) { if (obj is Line) { lastX = obj.PF2.X; lastY = obj.PF2.Y; lineCount++; } } Log.D($"[SetBeforeUpload] Line objects={lineCount}, lastX={lastX:F4}, lastY={lastY:F4}"); } else { Log.D($"[SetBeforeUpload] PageNum={_PageNum} -> WaitForEncoderX skip"); } Log.I($"[SetBeforeUpload] Complete -> SetUploadWeldingList_SeqParams (PageNum={_PageNum})"); Log.D($"[SetBeforeUpload] Set Before UploadWeldingList"); return SequenceAction.Ok(); } // ==================== SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ ==================== private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param) { Status.SetWorkingPosition(eWorkingPosition.UPLOADING_WELD_LIST); bool _isUseInitParam = _InitParam == null ? false : true; SeqUploadWeldingList_InitParam seqParams = new SeqUploadWeldingList_InitParam() { NeedSetLaserTiming = _isUseInitParam ? _InitParam.NeedSetLaserTiming : true, IncludeListStartEnd = false, CellMeasureCenterOffsetX = _SystemParameter.CellPosMeasureCenterOffsetX + (_isUseInitParam ? _InitParam.CellCenterOffsetX : 0), CellMeasureCenterOffsetY = _SystemParameter.CellPosMeasureCenterOffsetY + (_isUseInitParam ? _InitParam.CellCenterOffsetY : 0), SelectedDrawObjectList = _SelectedObjectList, WeldingScannerListNo = _WeldingScannerListNo, PageNum = _PageNum, LastX = _LastX, LastY = _LastY }; Log.D($"[ComponentTeachingRun] Set UploadWeldingList Seq Param"); return SequenceAction.Ok(seqParams); } // ==================== SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ ==================== private SequenceActionResult GetUploadWeldingList_SeqResult(SequenceContext context, string id, SequenceActionResult param) { Log.D($"[ComponentTeachingRun] Get UploadWeldingList Seq Param"); var resultOutParam = param.Param as SeqUploadWeldingList_OutParam; if (resultOutParam.Success == false) { Log.E($"[ComponentTeachingRun] Failed UploadWeldingList Sequence"); return null; } return SequenceAction.Ok(); } // ==================== SEQ_CHECK_AFTER_UPLOAD ==================== private string CheckAfterUpload(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { _PageNum += 1; if (_PageNum == 5) _PageNum = 1; Log.I($"[CheckAfterUpload] PageNum after increment={_PageNum}"); if (_PageNum == 2) { Log.I("[CheckAfterUpload] PageNum==2 -> branch to DoComponentWelding"); return SEQ_DO_COMPONENT_WELDING; } else { Log.I($"[CheckAfterUpload] PageNum={_PageNum} -> branch to SetBeforeUpload (loop)"); return SEQ_SET_BEFORE_UPLOAD; } } // ==================== SEQ_DO_COMPONENT_WELDING ==================== private SequenceActionResult DoComponentWelding(SequenceContext context, string id, SequenceActionResult param) { // Close list buffer before execute - subsequence has no SetStartList/SetEndList //Log.I($"[DoComponentWelding] ListSpace (before SetEndList)={_Scanner.GetListSpace()}"); _Scanner.SetEndList(); Log.I($"[DoComponentWelding] ListSpace (after SetEndList)={_Scanner.GetListSpace()}"); double x = 0.0, y = 0.0; _Scanner.GetEncoder(out x, out y); Log.I($"ExecuteList Start(Encoder x[{x}], y[{y}])"); Log.I($"Welding List Space : {_Scanner.GetListSpace()}"); DateTime weldingTime = DateTime.Now; _Scanner.ExecuteList(_WeldingScannerListNo); Log.I($"[DoComponentWelding] ExecuteList called at {weldingTime:HH:mm:ss.fff}"); // 26.04.06 NDY - ACS Stage X move (simultaneous with scanner list) // MOTF: Stage X encoder triggers WaitForEncoderX -> galvano marking // _ACS?.MOTFStart(); // 26.04.06 NDY - ACS completion wait // while (!_ACS.CheckMOTFComp()) { Thread.Sleep(10); } if (_Scanner.Config.UseRecordSignal) { DateTime startTime = DateTime.Now; _Scanner.StackRecord(); _ScannerSaveLogTime += DateTime.Now.Subtract(startTime); } SaveScannerRecordFileForamt(); Log.D($"[ComponentTeachingRun] SaveScannerRecordFileForamt Time : {_ScannerSaveLogTime.TotalMilliseconds}"); var PartialTactTime = DateTime.Now.Subtract(_partialWeldingStartTime); Log.D($"[TactTime] Complete Partial Component Weld : {PartialTactTime.TotalMilliseconds}"); _ScannerCanvasUserCtrl.TimeLabelUpdate(_MeasurementSpanTime.TotalMilliseconds, PartialTactTime.TotalMilliseconds); return SequenceAction.Ok(); } // ==================== SEQ_ACS_MOTION_SET ==================== private SequenceActionResult SetMotion(SequenceContext context, string id, SequenceActionResult param) { var _scannerConfig = _Scanner.Config; Log.I("[SetMotion] Forward param setting start"); Log.I($"[SetMotion] PosX={_scannerConfig.MarkingStartX_1}, NegX={_scannerConfig.MarkingStartX_2}, Vel={_scannerConfig.MOTFStageSpeed}"); // iMOTFComplete reset _ACS.ResetMOTFComp(); Log.I("[SetMotion] ResetMOTFComp done"); double x = 0.0, y = 0.0; _Scanner.GetEncoder(out x, out y); Log.I($"Motion Move End (Encoder x[{x}], y[{y}])"); // Forward direction param setting (310 -> 640) bool result = _ACS.SetMOTFParams( posX: _scannerConfig.MarkingStartX_1, negX: _scannerConfig.MarkingStartX_2, velocity: _scannerConfig.MOTFStageSpeed, acc: 5000, interval: 100 ); if (!result) { Log.E("[SetMotion] SetMOTFParams failed"); return null; } Log.I("[SetMotion] SetMOTFParams done"); // 26.04.17 NDY - below line overwrites with MarkSpeed/0/0, commented out // _ACS.SetMOTFParams(_scannerConfig.MarkingStartX_1, _scannerConfig.MarkingStartX_2, _scannerConfig.MarkSpeed, 0, 0); return SequenceAction.Ok(); } // ==================== SEQ_ACS_MOTION_START ==================== private SequenceActionResult StartMotion(SequenceContext context, string id, SequenceActionResult param) { #region old code (commented out) //_ACS.MOTFStart(); //var res = context.Wait(1000, 100); //if (res == E2.TIMEOUT) {;} //else if (res == E2.CANCELLED) { Log.E("[MOTF] Motion CANCELLED"); return null; } //res = context.RetryUntilSuccess(() => _ACS.CheckMOTFComp(), 1000 * 20, 100, true); //if (res == E2.TIMEOUT) { Log.E("[MOTF] Motion TIMEOUT"); return null; } //else if (res == E2.CANCELLED) { Log.E("[MOTF] Motion CANCELLED"); return null; } //return SequenceAction.Ok(); #endregion var config = _Scanner.Config; // ── Forward execution (310 -> 640, params already set in SetMotion) ── Log.I("[StartMotion] Forward MOTFStart called"); _ACS.MOTFStart(); int waitMs = (int)((50.0 / config.MOTFStageSpeed) * 1000) + 200; Log.I($"[StartMotion] Forward 50mm wait {waitMs}ms"); var res = context.Wait(waitMs, 10); if (res == E2.CANCELLED) { Log.E("[StartMotion] Forward 50mm wait CANCELLED"); return null; } Log.I("[StartMotion] Forward CheckMOTFComp wait start"); res = context.RetryUntilSuccess(() => _ACS.CheckMOTFComp(), 1000 * 30, 100, true); if (res == E2.TIMEOUT) { Log.E("[StartMotion] Forward TIMEOUT"); return null; } else if (res == E2.CANCELLED) { Log.E("[StartMotion] Forward CANCELLED"); return null; } Log.I("[StartMotion] Forward complete"); // ── Reverse setting (640 -> 310) after forward complete ── Log.I("[StartMotion] Reverse param setting start"); _ACS.ResetMOTFComp(); Log.I("[StartMotion] Reverse ResetMOTFComp done"); bool result = _ACS.SetMOTFParams( posX: config.MarkingStartX_2, // 640 start negX: config.MarkingStartX_1, // 310 end velocity: config.MOTFStageSpeed, acc: 5000, interval: 100 ); if (!result) { Log.E("[StartMotion] Reverse SetMOTFParams failed"); return null; } Log.I($"[StartMotion] Reverse SetMOTFParams done | PosX={config.MarkingStartX_2}, NegX={config.MarkingStartX_1}"); // ── Reverse execution ── Log.I("[StartMotion] Reverse MOTFStart called"); _ACS.MOTFStart(); Log.I($"[StartMotion] Reverse 50mm wait {waitMs}ms"); res = context.Wait(waitMs, 10); if (res == E2.CANCELLED) { Log.E("[StartMotion] Reverse 50mm wait CANCELLED"); return null; } Log.I("[StartMotion] Reverse CheckMOTFComp wait start"); res = context.RetryUntilSuccess(() => _ACS.CheckMOTFComp(), 1000 * 30, 100, true); if (res == E2.TIMEOUT) { Log.E("[StartMotion] Reverse TIMEOUT"); return null; } else if (res == E2.CANCELLED) { Log.E("[StartMotion] Reverse CANCELLED"); return null; } Log.I("[StartMotion] Reverse complete -> EndWelding"); #region Stage X return to 0 after welding complete // 26.04.16 NDY - Stage X return to origin(0) after welding _AxisX.SetTargetPos(25, TargetPosType.ABS); _AxisX.SetMoveVelocityImm(AuroraACS.Speed.M); _AxisX.AccelerationImm(AuroraACS.Speed.M); _AxisX.DecelerationImm(AuroraACS.Speed.M); _AxisX.JerkImm(AuroraACS.Speed.M); _AxisX.Move(); Log.D("[StartMotion] AxisX.Move() to 0 called"); Func plcResponse = () => { Debug.WriteLine($"Scanner Busy : {_Scanner.GetBusyStatus()}"); eListNo list; uint point = 0; _Scanner.GetListPointer(out list, out point); Debug.WriteLine($"Scanner list Pointer : {point}"); return _AxisX.IsReachedTargetPosition(25); }; res = context.RetryUntilSuccess( plcResponse, 30 * 1000, 20, true); if (res == E2.TIMEOUT) { Log.E("[EndWelding] Stage X return TIMEOUT"); } else if (res == E2.CANCELLED) { Log.E("[EndWelding] Stage X return CANCELLED"); } else { Log.I("[EndWelding] Stage X = 0 return complete"); } #endregion // 26.04.16 NDY - sequence result set context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true); Log.I("[StartMotion] KEY_SEQUENCE_RESULT = true set"); return SequenceAction.Ok(); } // ==================== SEQ_CHECK_MOTION_END ==================== private SequenceActionResult EndWelding(SequenceContext context, string id, SequenceActionResult param) { Log.I("[EndWelding] Entry"); _Scanner.WaitForListTaskCompleted(_SystemParameter.WeldLinesTaskTimeOut); Log.I("ExecuteList Complete"); _MeasurementSpanTime = DateTime.Now.Subtract(_SequenceCompleteTime); Log.D($"[TactTime] Complete All Component Weld : {_MeasurementSpanTime.TotalMilliseconds}"); // Analog output - COMMAND mode = direct (not list) _Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND); _Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND); Log.D("[EndWelding] WriteDA(DA1=0, DA2=0) done"); _Scanner.JumpAbs(0, 0, eFunctionType.COMMAND); Log.D("[EndWelding] JumpAbs(0,0) done"); _Scanner.Fly_Return(_Scanner.Config.MarkingOntheFlyParkingPositionX, _Scanner.Config.MarkingOntheFlyParkingPositionY); Log.D($"[EndWelding] Fly_Return({_Scanner.Config.MarkingOntheFlyParkingPositionX}, {_Scanner.Config.MarkingOntheFlyParkingPositionY}) done"); // _Scanner.SetEndList(); // moved to DoComponentWelding var mesurementTime = DateTime.Now; // Restore CorrectionFile to Vision after welding _Scanner.SelectCorrectionTable(1); Log.D("[EndWelding] SelectCorrectionTable(1) restored"); _MeasurementSpanTime = DateTime.Now.Subtract(mesurementTime); Log.D($"[ComponentTeachingRun] Change SelectCorrectionTable Time : {_MeasurementSpanTime.TotalMilliseconds}"); return SequenceAction.Ok(); } // ==================== SEQ_COMPLETE ==================== private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param) { Log.D("[Complete] Start"); context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult); SeqTeachingRun_OutParam result = new SeqTeachingRun_OutParam() { Success = seqResult }; Log.I($"[Complete] seqResult = {seqResult}"); if (seqResult == false) AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_TeachingRun_ResultFailed); Log.D("ComponentTeachingRun Sequence Complete"); return SequenceAction.Ok(result); } // ==================== Helper methods ==================== private void SaveScannerRecordFileForamt() { if (_Scanner.Config.UseRecordSignal) { DateTime startTime = DateTime.Now; _Scanner.SaveStackRecord("Normal"); _ScannerSaveLogTime += DateTime.Now.Subtract(startTime); } } private void OnForceError(SequenceContext context, string arg2) { Log.E("===== [OnForceError] Force error occurred ====="); SaveScannerRecordFileForamt(); _Scanner.StopExecution(); Log.D("[OnForceError] StopExecution done"); _Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND); _Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND); Thread.Sleep(10); _Scanner.JumpAbs(0, 0, eFunctionType.COMMAND); Thread.Sleep(10); Log.I("SequenceAction Ok : OnForceError"); } private void OnStopped(SequenceContext context) { Log.W("===== [OnStopped] Sequence stopped ====="); SaveScannerRecordFileForamt(); _Scanner.StopExecution(); Log.D("[OnStopped] StopExecution done"); _Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND); _Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND); Thread.Sleep(10); _Scanner.JumpAbs(0, 0, eFunctionType.COMMAND); Thread.Sleep(10); Log.I("SequenceAction Ok : OnStopped"); } } public class SeqAutoRunPrismaticScanner_InitParam : InitParam { public bool IsObjectSelectAll { get; set; } public bool UseStream { get; set; } public bool UseBlow { get; set; } public int IntervalTimeBlowOn { get; set; } public int IntervalTimeBlowOff { get; set; } public bool NeedSetLaserTiming { get; set; } } public class SeqAutoRunPrismaticScanner_OutParam : OutParam { } }