diff --git a/Machines/ILSOS_PrismaticScanner/Sequences/SeqAutoRunPrismaticScanner.cs b/Machines/ILSOS_PrismaticScanner/Sequences/SeqAutoRunPrismaticScanner.cs
index 45b264b..4d9cd36 100644
--- a/Machines/ILSOS_PrismaticScanner/Sequences/SeqAutoRunPrismaticScanner.cs
+++ b/Machines/ILSOS_PrismaticScanner/Sequences/SeqAutoRunPrismaticScanner.cs
@@ -18,6 +18,7 @@ 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;
@@ -39,6 +40,7 @@ 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;
@@ -72,31 +74,27 @@ 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"; // inputParam 으로 받자.
- const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; // Check Init Condition
-
+ 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_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 노드 추가
- // Builder()에 노드 추가
+ #region 260408 NDY nodes added
const string SEQ_STANDBY_MOTION = "Move Stage To Origin";
const string SEQ_STANDBY_SCANNER = "Encoder Reset";
#endregion
@@ -108,51 +106,37 @@ namespace ILSOS_PrismaticScanner.Sequences
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 ScannerACS _ACS;
-
-
- // 변경 후
- private IScannerACS _ACS; // 26.04.06 NDY - MOTF용 ACS Stage X 제어
- private static ACSMotor _AxisX, _AxisZ; // 26.04.08 NDY - MOTF용 Stage X 축
-
+ private IScannerACS _ACS;
+ private static ACSMotor _AxisX, _AxisZ;
private SystemParameter _SystemParameter;
- private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; //스캐너 동작관련 객체 선언
-
+ 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 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; // 진짜로 UploadWeldingList에 들어갈 값
+ 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
- // 26.04.08 필드 좌표 x 0 y 22.8(자재 기준)으로 스테이지 이동 시퀸스
+ sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition);
+ #region 26.04.08 NDY nodes added
sb.AddAction(SEQ_STANDBY_MOTION, SetStandbyMotion);
- // 26 04 17 스테이지 x =0 에서 스캐너 엔코더 0 상태에서 기록된 듯 싶습니다.
- sb.AddAction(SEQ_STANDBY_SCANNER, SetStandbyScanner);
+ 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());
@@ -164,7 +148,6 @@ namespace ILSOS_PrismaticScanner.Sequences
sb.AddAction(SEQ_CHECK_MOTION_END, EndWelding);
sb.AddAction(SEQ_COMPLETE, Complete);
-
sb.Flows(sb.Init
> sb[SEQ_ENTER]
> sb[SEQ_CHECK_INIT_CONDITION]
@@ -188,16 +171,14 @@ namespace ILSOS_PrismaticScanner.Sequences
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("===== SeqTeachingRun Sequence_Enter 진입 ====="); // 임시 추가
+ Log.I("===== [SEQ_ENTER] Sequence entry =====");
Log.I("SeqTeachingRun Start");
_InitParam = param.Param as SeqTeachingRun_InitParam;
@@ -205,50 +186,50 @@ namespace ILSOS_PrismaticScanner.Sequences
_SequenceSetting = context.Settings[CommonSettingIds.Sequence] as SequenceSetting;
_Scanner = context.Devices[DeviceIds.Scanner] as Scanner;
- if (_Scanner == null) { MessageUtil.ShowErrorToast("Scanner not Ready", Log); return null; }
+ 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) { MessageUtil.ShowErrorToast("ACS not Ready", Log); return null; }
+ 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) { MessageUtil.ShowErrorToast("AxisX not Ready", Log); return null; }
+ 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) { MessageUtil.ShowErrorToast("AxisZ not Ready", Log); return null; }
+ if (_AxisZ == null) { Log.E("[SEQ_ENTER] AxisZ is NULL"); MessageUtil.ShowErrorToast("AxisZ not Ready", Log); return null; }
- //Check Device
if (!CheckDeviceReady(context))
{
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_TeachingRun_DeviceNotReady);
- Log.E("The devices are not active.");
+ 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 };
- //List deviceListToCheck = new List() { CommonDeviceIds.Scanner, CommonDeviceIds.IODevice,DeviceIds.ACS }; 변수 맵 수신 후 ACS 주석 해제 위에 주석 처리
bool isAllDeviceActivated = true;
foreach (string item in deviceListToCheck)
{
- if (!context.Devices[item].IsActivated)
- {
- isAllDeviceActivated = isAllDeviceActivated && false;
- }
+ 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 boolian = AlarmManager.HasAlarmLevelHigh();
- if (boolian)
+ bool hasAlarm = AlarmManager.HasAlarmLevelHigh();
+ Log.D($"[CheckInitCondition] HasAlarmLevelHigh={hasAlarm}");
+ if (hasAlarm)
{
- Log.E($"Clear Heavy Alarms For Welding!");
- MessageUtil.ShowWarningToast(string.Format("Clear Heavy Alarms For Welding!"));
+ Log.E("[CheckInitCondition] High alarm exists -> exit");
+ MessageUtil.ShowWarningToast("Clear Heavy Alarms For Welding!");
return null;
}
@@ -257,159 +238,191 @@ namespace ILSOS_PrismaticScanner.Sequences
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 - 스킵");
+ Log.W("[MoveStageToOrigin] AxisX2 null - skip");
return SequenceAction.Ok();
}
- Log.I("[MoveStageToOrigin] Stage X → 0 이동 시작");
+ Log.I("[MoveStageToOrigin] Stage X -> 310 move start");
- // (스캐너의 0,0 && 용접 대상의 시작 위치) >> X축을 이동
- _AxisX.SetTargetPos(0, TargetPosType.ABS);
+ // 26.04.17 NDY - start from 310
+ _AxisX.SetTargetPos(310, 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 축 자재 위치
+ // 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), // Z축 조건 제거
- 30 * 1000, 20, true);
+ () => _AxisX.IsReachedTargetPosition(310),
+ 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 = 0 도달 완료");
+ Log.I("[MoveStageToOrigin] Stage X = 310 reached");
return SequenceAction.Ok();
-
}
+
+ // ==================== SEQ_STANDBY_SCANNER ====================
private SequenceActionResult SetStandbyScanner(SequenceContext context, string id, SequenceActionResult param)
{
- // Scanner Default Setting
var mainPage = CommonHelper.GetMainPage();
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
_WeldingScannerListNo = eListNo.LIST1;
- //_SelectedObjectList = FindObjects(); // 중복 주석 처리 260417
- //Vision Correction File 선택
+ // _SelectedObjectList = FindObjects(); // removed duplicate 260417
_Scanner.SelectCorrectionTable(2);
+ Log.D("[EncoderReset] SelectCorrectionTable(2) done");
if (!_Scanner.Config.UseMarkingOnTheFly)
{
- Log.W("[EncoderReset] MOTF 비활성화 - 스킵");
+ Log.W("[EncoderReset] MOTF disabled - skip");
return SequenceAction.Ok();
}
- Log.I("[EncoderReset] 시작");
- // SeqUploadWeldingList.MarkingOnTheFlyOn 패턴
+ Log.I("[EncoderReset] Start");
_Scanner.SetStartList(_WeldingScannerListNo);
+ Log.D($"[EncoderReset] SetStartList({_WeldingScannerListNo}) done");
+
_Scanner.SetFlyX(_Scanner.Config.MarkingOnTheFlyEncoderResolutionX);
Log.I($"[EncoderReset] SetFlyX: {_Scanner.Config.MarkingOnTheFlyEncoderResolutionX}");
- // _Scanner.WaitForEncoderX(_Scanner.Config.MarkingStartEncoderPositionX);
- // Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.MarkingStartEncoderPositionX}");
+ //_Scanner.WaitForEncoderX(_Scanner.Config.MarkingStartEncoderPositionX);
+ //Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.MarkingStartEncoderPositionX}");
- // 스캐너 기준 엔코더 리셋이 스테이지 x = 0에서 이뤄졌음. 260417
+ // 26.04.17 NDY - encoder reset at Stage X = 310
_Scanner.StoreEncoder(0);
_Scanner.SaveAndRestartTimer();
-
- Log.I("[EncoderReset] 완료 - Stage(0) = Scanner 엔코더(0) 동기화");
+ Log.I("[EncoderReset] Complete - Stage(310) = Scanner Encoder(0) synchronized");
return SequenceAction.Ok();
}
- //SeqTeachingPosMoveStageA패턴 참고 - 기존 GUN 프로젝트 시퀸스
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
- // 260417 NDY 먼저 업로드 되는 것 - 페이지 2번 4번 ?? 1번 4번은 어떻게 되는지 궁금합니다.
+
+ // ==================== 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;
- _SelectedObjectList = _ScannerCanvasUserCtrl.Model.Layers[_PageNum-1].Objects;
+
+ 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;
- if (_PageNum == 2 || _PageNum == 4) {
+ 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)
- { // NDY 26 04 17 0 아니고 2 인 것 같습니다. MarkingStartX_1 = 현재 310 (출발위치)
+ {
+ // 기존 코드 유지 (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.WaitForEncoderX(_Scanner.Config.MarkingStartX_1);
Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.MarkingStartX_1}");
- // NDY 26 04 17아래가 반영해야 할 용접 시작위치라고 생각하는 구간 엔코더 리셋이 사실 용접 시작인 360 에서 이뤄져야하는 것 같은데 위 변수 값 맞는지 확인
- //_Scanner.WaitForEncoderX(_Scanner.Config.XDiff_Page1and2); // XDiff_Page1and2 = 360
+ // 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}");
-
- // 페이지 1,2 가 360에서 가공되어야 할 것
}
- else // pageNum 4
- { // MarkingStartX_2 = 현재 640 (출발 위치) 돌아오는 , 해당 리셋 위치가 원래는 용접 위치인 590 인 Diff에서 가져와야 하는 건 아닌지 의문
+ 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.WaitForEncoderX(_Scanner.Config.MarkingStartX_2);
Log.I($"[EncoderReset] WaitForEncoderX: {_Scanner.Config.MarkingStartX_2}");
- // NDY 26 04 17아래가 반영해야 할 용접 시작위치라고 생각하는 구간
- //_Scanner.WaitForEncoderX(_Scanner.Config.XDiff_Page3and4); // XDiff_Page3and4 = 590
+ // 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}");
-
- // 페이지 3,4 가 590에서 가공되어야 할 것
-
}
- foreach (IDrawObject obj in _SelectedObjectList) {
- if (obj is Line) {
+
+ 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.D(string.Format($"[SetBeforeUpload] Set Before UploadWeldingList"));
+ 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;
- // TeachingRun에는 용접 시퀀스만 정의해서 Auto Run에서도 사용하므로 Offset 넣어줘야 함
SeqUploadWeldingList_InitParam seqParams = new SeqUploadWeldingList_InitParam()
{
NeedSetLaserTiming = _isUseInitParam ? _InitParam.NeedSetLaserTiming : true,
IncludeListStartEnd = false,
- CellMeasureCenterOffsetX = _SystemParameter.CellPosMeasureCenterOffsetX + (_isUseInitParam ? _InitParam.CellCenterOffsetX :0),
+ CellMeasureCenterOffsetX = _SystemParameter.CellPosMeasureCenterOffsetX + (_isUseInitParam ? _InitParam.CellCenterOffsetX : 0),
CellMeasureCenterOffsetY = _SystemParameter.CellPosMeasureCenterOffsetY + (_isUseInitParam ? _InitParam.CellCenterOffsetY : 0),
SelectedDrawObjectList = _SelectedObjectList,
WeldingScannerListNo = _WeldingScannerListNo,
@@ -418,55 +431,64 @@ namespace ILSOS_PrismaticScanner.Sequences
LastY = _LastY
};
- Log.D(string.Format($"[ComponentTeachingRun] Set UploadWelindList Seq Param"));
+ 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(string.Format($"[ComponentTeachingRun] Get UploadWelindList Seq Param"));
+ Log.D($"[ComponentTeachingRun] Get UploadWeldingList Seq Param");
var resultOutParam = param.Param as SeqUploadWeldingList_OutParam;
if (resultOutParam.Success == false)
{
- Log.E(string.Format($"[ComponentTeachingRun] Failed UploadWeldingList Sequence"));
+ 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;
- if (_PageNum == 2) return SEQ_DO_COMPONENT_WELDING;
- else return SEQ_SET_BEFORE_UPLOAD;
+ 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()}");
+
Log.I("ExecuteList Start");
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 이동 ──────────────
- // MOTF: Scanner List 실행과 동시에 Stage X 이동 시작
- // Stage X 엔코더가 트리거 → WaitForEncoderX 조건 도달 시 갈바노 마킹
- // TODO: 변수 맵 수신 후 _ACS.MOTFStart()로 교체
+ // 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 완료 대기 ─────────────────
- // TODO: 변수 맵 수신 후 활성화
+ // 26.04.06 NDY - ACS completion wait
// while (!_ACS.CheckMOTFComp()) { Thread.Sleep(10); }
- // ────────────────────────────────────────────────────
-
if (_Scanner.Config.UseRecordSignal)
{
@@ -475,32 +497,30 @@ namespace ILSOS_PrismaticScanner.Sequences
_ScannerSaveLogTime += DateTime.Now.Subtract(startTime);
}
- // excel 파일 작성
SaveScannerRecordFileForamt();
- Log.D(string.Format($"[ComponentTeachingRun] SaveScannerRecordFileForamt Time : {_ScannerSaveLogTime.TotalMilliseconds}"));
+ Log.D($"[ComponentTeachingRun] SaveScannerRecordFileForamt Time : {_ScannerSaveLogTime.TotalMilliseconds}");
var PartialTactTime = DateTime.Now.Subtract(_partialWeldingStartTime);
- Log.D(string.Format($"[TactTime] Complete Partial Component Weld : {PartialTactTime.TotalMilliseconds}"));
+ 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)
{
- #region 디바이스 세팅 값만 가져오기
var _scannerConfig = _Scanner.Config;
- #endregion
- Log.I("[SetMotion] 정방향 파라미터 세팅 시작");
- Log.I($"[SetMotion] PosX={_scannerConfig.MarkingStartX_1}, NegX={_scannerConfig.MarkingStartX_2}, Vel={_scannerConfig.MOTFStageSpeed}");
- // 메뉴얼 화면에서 셋팅이 필요해보임 - 출발, 도착, 스피드,rPCset_MOF_WEL_ACC,iPCset_MOF_WEL_MOTION_INTERVAL
- // iMOTFComplete 리셋
- _ACS.ResetMOTFComp(); // 0 으로 바꿔주는 거 다시 추가해줘야함.
-
- Log.I("[SetMotion] ResetMOTFComp 완료");
- // 정방향 파라미터 세팅 (310 → 640)
+ 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");
+
+ // Forward direction param setting (310 -> 640)
bool result = _ACS.SetMOTFParams(
posX: _scannerConfig.MarkingStartX_1,
negX: _scannerConfig.MarkingStartX_2,
@@ -508,129 +528,153 @@ namespace ILSOS_PrismaticScanner.Sequences
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);
- if (!result) { Log.E("[SetMotion] SetMOTFParams 실패"); return null; }
- Log.I("[SetMotion] SetMOTFParams 완료");
- _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
+ #region old code (commented out)
//_ACS.MOTFStart();
- //// 모션 동작시키고 바로 확인하면 그냥 빠져나올 것 같음
//var res = context.Wait(1000, 100);
- //if (res == E2.TIMEOUT) {;}
+ //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;
- // ── 정방향 실행 (310 → 640) ──
- Log.I("[StartMotion] 정방향 MOTFStart 호출");
+ // ── Forward execution (310 -> 640, params already set in SetMotion) ──
+ Log.I("[StartMotion] Forward MOTFStart called");
_ACS.MOTFStart();
- // 출발 후 50mm 이동 시간만큼 대기
- // 50mm / velocity(mm/s) * 1000 = ms
- int waitMs = (int)((50.0 / config.MOTFStageSpeed) * 1000) + 200; // 여유 200ms
- Log.I($"[StartMotion] 정방향 50mm 이동 대기 {waitMs}ms");
+ 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] 정방향 50mm 대기 CANCELLED"); return null; }
+ if (res == E2.CANCELLED) { Log.E("[StartMotion] Forward 50mm wait CANCELLED"); return null; }
- // 정방향 완료 대기
- Log.I("[StartMotion] 정방향 CheckMOTFComp 대기 시작");
+ Log.I("[StartMotion] Forward CheckMOTFComp wait start");
res = context.RetryUntilSuccess(() => _ACS.CheckMOTFComp(), 1000 * 30, 100, true);
- if (res == E2.TIMEOUT) { Log.E("[StartMotion] 정방향 TIMEOUT"); return null; }
- else if (res == E2.CANCELLED) { Log.E("[StartMotion] 정방향 CANCELLED"); return null; }
- Log.I("[StartMotion] 정방향 완료");
+ 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");
- // ── 역방향 세팅 (640 → 310) ──
- Log.I("[StartMotion] 역방향 파라미터 세팅 시작");
+ // ── Reverse setting (640 -> 310) after forward complete ──
+ Log.I("[StartMotion] Reverse param setting start");
_ACS.ResetMOTFComp();
- Log.I("[StartMotion] 역방향 ResetMOTFComp 완료");
+ Log.I("[StartMotion] Reverse ResetMOTFComp done");
bool result = _ACS.SetMOTFParams(
- posX: config.MarkingStartX_2, // 640 출발
- negX: config.MarkingStartX_1, // 310 도착
+ posX: config.MarkingStartX_2, // 640 start
+ negX: config.MarkingStartX_1, // 310 end
velocity: config.MOTFStageSpeed,
acc: 5000,
interval: 100
);
- if (!result) { Log.E("[StartMotion] 역방향 SetMOTFParams 실패"); return null; }
- Log.I($"[StartMotion] 역방향 SetMOTFParams 완료 | PosX={config.MarkingStartX_2}, NegX={config.MarkingStartX_1}");
+ if (!result) { Log.E("[StartMotion] Reverse SetMOTFParams failed"); return null; }
+ Log.I($"[StartMotion] Reverse SetMOTFParams done | PosX={config.MarkingStartX_2}, NegX={config.MarkingStartX_1}");
- // ── 역방향 실행 (640 → 310) ──
- Log.I("[StartMotion] 역방향 MOTFStart 호출");
+ // ── Reverse execution ──
+ Log.I("[StartMotion] Reverse MOTFStart called");
_ACS.MOTFStart();
- // 출발 후 50mm 이동 대기
- Log.I($"[StartMotion] 역방향 50mm 이동 대기 {waitMs}ms");
+ Log.I($"[StartMotion] Reverse 50mm wait {waitMs}ms");
res = context.Wait(waitMs, 10);
- if (res == E2.CANCELLED) { Log.E("[StartMotion] 역방향 50mm 대기 CANCELLED"); return null; }
+ if (res == E2.CANCELLED) { Log.E("[StartMotion] Reverse 50mm wait CANCELLED"); return null; }
- // 역방향 완료 대기
- Log.I("[StartMotion] 역방향 CheckMOTFComp 대기 시작");
+ Log.I("[StartMotion] Reverse CheckMOTFComp wait start");
res = context.RetryUntilSuccess(() => _ACS.CheckMOTFComp(), 1000 * 30, 100, true);
- if (res == E2.TIMEOUT) { Log.E("[StartMotion] 역방향 TIMEOUT"); return null; }
- else if (res == E2.CANCELLED) { Log.E("[StartMotion] 역방향 CANCELLED"); return null; }
- Log.I("[StartMotion] 역방향 완료 → EndWelding 진입");
+ 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(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("[StartMotion] AxisX.Move() to 0 called");
+
+ res = context.RetryUntilSuccess(
+ () => _AxisX.IsReachedTargetPosition(0),
+ 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(string.Format($"[TactTime] Complete All Component Weld : {_MeasurementSpanTime.TotalMilliseconds}"));
+ Log.D($"[TactTime] Complete All Component Weld : {_MeasurementSpanTime.TotalMilliseconds}");
-
- //Anlog 출력 0으로 변경, efunctiontype을 command로 변경해주면 list가 아니라 직접 변경됨
+ // Analog output - COMMAND mode = direct (not list)
_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 5, eFunctionType.COMMAND);
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 5, eFunctionType.COMMAND);
+ Log.D("[EndWelding] WriteDA(DA1=5, DA2=5) done");
+
_Scanner.JumpAbs(0, 0, eFunctionType.COMMAND);
+ Log.D("[EndWelding] JumpAbs(0,0) done");
+
_Scanner.Fly_Return(_Scanner.Config.MarkingOntheFlyParkingPositionX, _Scanner.Config.MarkingOntheFlyParkingPositionY);
- _Scanner.SetEndList();
+ Log.D($"[EndWelding] Fly_Return({_Scanner.Config.MarkingOntheFlyParkingPositionX}, {_Scanner.Config.MarkingOntheFlyParkingPositionY}) done");
+
+ // _Scanner.SetEndList(); // moved to DoComponentWelding
var mesurementTime = DateTime.Now;
- //용접 완료 후 CorrectionFile Vision으로 원복
+ // Restore CorrectionFile to Vision after welding
_Scanner.SelectCorrectionTable(1);
+ Log.D("[EndWelding] SelectCorrectionTable(1) restored");
_MeasurementSpanTime = DateTime.Now.Subtract(mesurementTime);
- Log.D(string.Format($"[ComponentTeachingRun] Change SelectCorrectionTable Time : {_MeasurementSpanTime.TotalMilliseconds}"));
+ 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)
@@ -643,18 +687,14 @@ namespace ILSOS_PrismaticScanner.Sequences
private void OnForceError(SequenceContext context, string arg2)
{
- // Scanner Log 저장
+ Log.E("===== [OnForceError] Force error occurred =====");
SaveScannerRecordFileForamt();
-
- //List 실행 종료
_Scanner.StopExecution();
+ Log.D("[OnForceError] StopExecution done");
- //Anlog 출력 0으로 변경, efunctiontype을 command로 변경해주면 list가 아니라 직접 변경됨
_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND);
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND);
- //Scanner 원점 복귀
- // 복귀 시 Scanner Busy 상태일 수 있으므로 진행중인 작업이 끝날 때까지 대기
Thread.Sleep(10);
_Scanner.JumpAbs(0, 0, eFunctionType.COMMAND);
Thread.Sleep(10);
@@ -664,44 +704,33 @@ namespace ILSOS_PrismaticScanner.Sequences
private void OnStopped(SequenceContext context)
{
- // Scanner Log 저장
+ Log.W("===== [OnStopped] Sequence stopped =====");
SaveScannerRecordFileForamt();
-
- //List 실행 종료
_Scanner.StopExecution();
+ Log.D("[OnStopped] StopExecution done");
- //Anlog 출력 0으로 변경, efunctiontype을 command로 변경해주면 list가 아니라 직접 변경됨
_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND);
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND);
- //Scanner 원점 복귀
- // 복귀 시 Scanner Busy 상태일 수 있으므로 진행중인 작업이 끝날 때까지 대기
Thread.Sleep(10);
_Scanner.JumpAbs(0, 0, eFunctionType.COMMAND);
Thread.Sleep(10);
-
Log.I("SequenceAction Ok : OnStopped");
}
}
- // TODO: UseStream 으로 TeachingRun 을 할 필요가 있을까?? 확인 필요
public class SeqAutoRunPrismaticScanner_InitParam : InitParam
{
- public bool IsObjectSelectAll { get; set; } // All == true, Selected Object == false
-
+ 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; } // For SubSequence, SeqUploadWeldingList
-
+ public bool NeedSetLaserTiming { get; set; }
}
public class SeqAutoRunPrismaticScanner_OutParam : OutParam
{
-
}
-}
+}
\ No newline at end of file
diff --git a/Machines/ILSOS_PrismaticScanner/Views/Main/UCMainAutoRunViewModel.cs b/Machines/ILSOS_PrismaticScanner/Views/Main/UCMainAutoRunViewModel.cs
index 7901615..8a851d1 100644
--- a/Machines/ILSOS_PrismaticScanner/Views/Main/UCMainAutoRunViewModel.cs
+++ b/Machines/ILSOS_PrismaticScanner/Views/Main/UCMainAutoRunViewModel.cs
@@ -219,8 +219,23 @@ namespace ILSOS_PrismaticScanner.Views
// 자동으로 Activated Recipe로 변경
OnUpdateCurrentActivatedRecipe(null);
- var param = new SeqAutoRunPrismaticScanner_InitParam() {
- //VisionRecipeNo = 0 // 해당 InitParam에는 없는 선언
+ //var param = new SeqAutoRunPrismaticScanner_InitParam() {
+ // //VisionRecipeNo = 0 // 해당 InitParam에는 없는 선언
+ //};
+
+ // 26 04 17 수정
+ //var param = new SeqAutoRunPrismaticScanner_InitParam()
+ //{
+ // NeedSetLaserTiming = true,
+ // IsObjectSelectAll = true, // 전체 오브젝트 선택
+ //};
+
+ var param = new SeqTeachingRun_InitParam()
+ {
+ IsObjectSelectAll = true,
+ CellCenterOffsetX = 0,
+ CellCenterOffsetY = 0,
+
};
Status.SetStatus(eEqpStatus.Auto);