Merge branch '260413_현장Release' of //192.168.3.30/e/Work/GIT/LGPRI_RD_PROJECT_RectangleWelder/ into 260413_현장Release
This commit is contained in:
commit
fe085cd0c1
@ -50,7 +50,7 @@ using WeldingCommon.Views.Recipes.History;
|
||||
using WeldingCommon.Vision.Factory;
|
||||
using static WeldingCommon.Vision.Factory.VisionFactory;
|
||||
|
||||
// 26.04.06
|
||||
// 26.04.06
|
||||
using AuroraACS;
|
||||
using AuroraACS.Views;
|
||||
using AuroraMotor;
|
||||
@ -207,7 +207,7 @@ namespace ILSOS_PrismaticScanner
|
||||
// ──────────────────────────────────────────────────────────────────
|
||||
|
||||
// ── 26.04.06 NDY 추가: 인터락 ─────────────────────────────────────
|
||||
// TODO: PLCControllerPrismaticScanner에 IsDoorOpen, IsEMO 있는지 확인 필요 - 없는 것 확인 완료
|
||||
// TODO: PLCControllerPrismaticScanner에 IsDoorOpen, IsEMO 있는지 확인 필요 - 없는 것 확인 완료
|
||||
//PLC_DOOR_INTERLOCK = 6, // ← 도어 인터락
|
||||
//PLC_EMO_STATUS = 7, // ← EMO
|
||||
AddMotionInterlockCheck(_plc);
|
||||
@ -215,7 +215,7 @@ namespace ILSOS_PrismaticScanner
|
||||
#endregion
|
||||
|
||||
}
|
||||
// 인터락
|
||||
// 인터락
|
||||
private void AddMotionInterlockCheck(PLCControllerPrismaticScanner plc)
|
||||
{
|
||||
var motorIds = new[] {
|
||||
@ -251,7 +251,7 @@ namespace ILSOS_PrismaticScanner
|
||||
{
|
||||
register(CommonRecipeIds.ScannerObjectTeaching, new ScannerObjectTeachingRecipe(),
|
||||
(id, item) => new UCScannerObjectTeaching(AuroraEnv));
|
||||
|
||||
|
||||
|
||||
base.RegisterRecipes(register);
|
||||
}
|
||||
@ -363,13 +363,13 @@ namespace ILSOS_PrismaticScanner
|
||||
//var manual = new MainMenu(CommonViewIds.Manual, MenuIcon.GetMenuIcon(eMenuIcon.DEVICE), PermissionLevel.LEVEL4, true); // Level4 가 맞으나, 개발때는 None 으로 뒀다가 완료되면 풀자.
|
||||
var manual = new MainMenu(CommonViewIds.Manual, MenuIcon.GetMenuIcon(eMenuIcon.CAMERA), PermissionLevel.NONE, true);
|
||||
// 26.04.06 NDY 추가: AutoRun을 Manual 서브메뉴로 추가
|
||||
manual.AddSubMenu(CommonViewIds.AutoRun, new UCMainAutoRun(new UCMainAutoRunViewModel(AuroraEnv, SequenceIds.SeqAutoRun))); // 추가
|
||||
//manual.AddSubMenu(CommonViewIds.AutoRun, new UCMainAutoRun(new UCMainAutoRunViewModel(AuroraEnv, SequenceIds.SeqAutoRun))); // 추가
|
||||
manual.AddSubMenu(CommonViewIds.ScannerOperation, new UCManualScannerOperation(new UCManualScannerOperationViewModel(AuroraEnv, CommonDeviceIds.Scanner, false)));
|
||||
//manual.AddSubMenu(CommonViewIds.OCT, new UCOCTManualMotion(AuroraEnv, CommonDeviceIds.OCT));
|
||||
//manual.AddSubMenu(CommonViewIds.LBAD, new UCLBADDevice(AuroraEnv, CommonDeviceIds.LBAD, CommonDeviceIds.IODevice));
|
||||
//manual.AddSubMenu(CommonViewIds.ConvEdgeObject, new UCConvEdgeObject(AuroraEnv));
|
||||
manual.AddSubMenu(CommonViewIds.ModelFinder, new UCManualModelFinder(new UCManualModelFinderViewModel(AuroraEnv)));
|
||||
#region 26.04.06 ACS 모션 스테이지 메뉴얼 추가 - 진행 예정이였으나, Gun 에 속해서 사용 애매함. View 자체를 전부 가져오지는 못함. - Gun의 view도 common에 복사
|
||||
#region 26.04.06 ACS 모션 스테이지 메뉴얼 추가 - 진행 예정이였으나, Gun 에 속해서 사용 애매함. View 자체를 전부 가져오지는 못함. - Gun의 view도 common에 복사
|
||||
// Manual 메뉴에 추가
|
||||
manual.AddSubMenu(CommonViewIds.StageManual,
|
||||
new UCStageManual(AuroraEnv, AuroraEnv.DeviceManager));
|
||||
@ -390,7 +390,7 @@ namespace ILSOS_PrismaticScanner
|
||||
manager.RegisterMainMenu(calibration);
|
||||
|
||||
// Monitoring
|
||||
#region 26 04 06 주석처리 PLCBitMonitoring PLCWordMonitoring IOInterfaceView (o) PLCInterfaceView (원래부터 주석처리) - 04.10 잠시 추가 - 04.13다시 해제
|
||||
#region 26 04 06 주석처리 PLCBitMonitoring PLCWordMonitoring IOInterfaceView (o) PLCInterfaceView (원래부터 주석처리) - 04.10 잠시 추가 - 04.13다시 해제
|
||||
//var monitoring = new MainMenu(CommonViewIds.Monitoring, MenuIcon.GetMenuIcon(eMenuIcon.MONITORING), PermissionLevel.NONE, true);
|
||||
////manual.AddSubMenu(CommonViewIds.PLCInterfaceView, new UCPLCInterfaceView(AuroraEnv, CommonDeviceIds.PLCDevice));
|
||||
//monitoring.AddSubMenu(CommonViewIds.PLCBitMonitoring, new UCPLCBit() { DataContext = PLCStatic.GetInstanceBitVM(AuroraEnv, CommonDeviceIds.PLCDevice, ePLCNetType.MXComponent, PLCBase.ePLCDevice.M) });
|
||||
|
||||
@ -35,7 +35,7 @@ using VisionCommon;
|
||||
using WeldingCommon;
|
||||
using WeldingCommon.Alarm;
|
||||
using WeldingCommon.Data;
|
||||
using WeldingCommon.Devices.ACS; // 26.04.06
|
||||
using WeldingCommon.Devices.ACS; // 26.04.06
|
||||
using WeldingCommon.Sequences;
|
||||
using WeldingCommon.Settings;
|
||||
using WeldingCommon.Utils;
|
||||
@ -51,29 +51,25 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
{
|
||||
static readonly Logger Log = new Logger("SeqComponentTeachingRun");
|
||||
|
||||
const string SEQ_ENTER = "[SeqComponentTeachingRun] SEQ_ENTER"; // inputParam 으로 받자.
|
||||
const string SEQ_CHECK_INIT_CONDITION = "[SeqComponentTeachingRun] Check Init Condition"; // Check Init Condition
|
||||
const string SEQ_ENTER = "SEQ_ENTER"; // inputParam 으로 받자.
|
||||
const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; // Check Init Condition
|
||||
|
||||
const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "[SeqComponentTeachingRun] Set Sequence Param (UploadWeldingList Seq)";
|
||||
const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "[SeqComponentTeachingRun] Process (UploadWeldingList Seq)";
|
||||
const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "[SeqComponentTeachingRun] Get Sequence Result (UploadWeldingList Seq)";
|
||||
const string SEQ_SET_BLOW_ON = "[SeqComponentTeachingRun] Set Blow On";
|
||||
const string SEQ_SET_BLOW_OFF = "[SeqComponentTeachingRun] Set Blow Off";
|
||||
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_SAVE_RESULT_DATA = "[SeqComponentTeachingRun] Save Result Data";
|
||||
const string SEQ_COMPLETE = "SEQ_COMPLETE"; // 완료
|
||||
|
||||
const string SEQ_COMPLETE = "[SeqComponentTeachingRun] SEQ_COMPLETE"; // 완료
|
||||
|
||||
const string SEQ_UPDATE_COMPONENT_WELDING_PARAMETERS = "[SeqComponentTeachingRun] Update Component Welding Parameters";
|
||||
const string SEQ_START_WELDING = "[SeqComponentTeachingRun] Start All Welding";
|
||||
const string SEQ_DO_COMPONENT_WELDING = "[SeqComponentTeachingRun] Do Component Welding";
|
||||
const string SEQ_CHECK_END_LIST = "[SeqComponentTeachingRun] Check End List";
|
||||
const string SEQ_END_WELDING = "[SeqComponentTeachingRun] End All Welding";
|
||||
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()에 노드 추가
|
||||
const string SEQ_MOVE_STAGE_ORIGIN = "[SeqComponentTeachingRun] Move Stage To Origin";
|
||||
const string SEQ_ENCODER_RESET = "[SeqComponentTeachingRun] Encoder Reset";
|
||||
const string SEQ_STANDBY_MOTION = "Move Stage To Origin";
|
||||
const string SEQ_STANDBY_SCANNER = "Encoder Reset";
|
||||
#endregion
|
||||
|
||||
const int timeoutSeconds = 10;
|
||||
@ -86,22 +82,15 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
private SeqTeachingRun_InitParam _InitParam;
|
||||
|
||||
private static Scanner _Scanner;
|
||||
private static PAIX_PrismaticScanner _IO;
|
||||
|
||||
// 필드 선언 추가 (다른 필드들 옆에)
|
||||
// 변경 전
|
||||
//private ScannerACS _ACS;
|
||||
|
||||
|
||||
|
||||
// 변경 후
|
||||
private IScannerACS _ACS; // 26.04.06 NDY - MOTF용 ACS Stage X 제어
|
||||
private static ACSMotor _AxisX; // 26.04.08 NDY - MOTF용 Stage X 축
|
||||
|
||||
private Laser _Laser;
|
||||
private ILaser _LaserDevice;
|
||||
private LaserTruFiber _LaserTruFiber;
|
||||
private LaserPowerCalParam _LaserPowerCalParam;
|
||||
private PLCControllerPrismaticScanner _plc;
|
||||
private static ACSMotor _AxisX, _AxisZ; // 26.04.08 NDY - MOTF용 Stage X 축
|
||||
|
||||
private SystemParameter _SystemParameter;
|
||||
private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; //스캐너 동작관련 객체 선언
|
||||
@ -112,69 +101,48 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
|
||||
|
||||
private List<IDrawObject> _SelectedObjectList;
|
||||
private Queue<List<IDrawObject>> _DivideObjectsQueue;
|
||||
private List<IDrawObject> _TargetObjects;
|
||||
private static DateTime _SequenceCompleteTime; // 시퀸스 시간
|
||||
private static TimeSpan _MeasurementSpanTime; //측정 시간
|
||||
private static TimeSpan _ScannerSaveLogTime;
|
||||
private static DateTime _partialWeldingStartTime;
|
||||
private static List<IDrawObject> _FlattenRecipes;
|
||||
private static int _CountWeldingObject; // 트럼프 레시피에서 부분 용접 할 Ojbect의 개수
|
||||
private static int _CurrentobjectIndex;
|
||||
private static int _BeforeObjectIndex;
|
||||
private static int _BeforeProgramNo; // 이전 트럼프 레이저 용접 번호
|
||||
private static int _BeforeParameterNo; //
|
||||
|
||||
private static int _CenterBeamPower;
|
||||
private static int _RingBeamPower;
|
||||
private static bool _LaserPowerControlByRatio = false;
|
||||
private static int _CenterRingRatio; // Center Ring의 파워 비율
|
||||
private static double _LaserPowerRatio; // Laser에서 출력 파워 비율
|
||||
public SequenceBuilder Builder()
|
||||
{
|
||||
var sb = new SequenceBuilder(1000, true);
|
||||
////var sb = new SequenceBuilder(1000, false); // With log
|
||||
|
||||
sb.AddAction(SEQ_ENTER, Sequence_Enter);
|
||||
sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); //분기
|
||||
sb.AddAction(SEQ_SET_BLOW_ON, SetBlowOn);
|
||||
#region 26.04.08 추가된 노드 NDY
|
||||
// 26.04.08 필드 좌표 0,0으로 스테이지 이동 시퀸스 + EncoderReset 호출
|
||||
sb.AddAction(SEQ_MOVE_STAGE_ORIGIN, MoveStageToOrigin);
|
||||
sb.AddAction(SEQ_ENCODER_RESET, EncoderReset);
|
||||
#region 26.04.08 추가된 노드 NDY
|
||||
// 26.04.08 필드 좌표 0,0으로 스테이지 이동 시퀸스 + EncoderReset 호출
|
||||
sb.AddAction(SEQ_STANDBY_MOTION, SetStandbyMotion);
|
||||
sb.AddAction(SEQ_STANDBY_SCANNER, SetStandbyScanner);
|
||||
#endregion
|
||||
|
||||
sb.AddAction(SEQ_START_WELDING, StartWelding);
|
||||
sb.AddDecision(SEQ_CHECK_END_LIST, CheckEndList);
|
||||
sb.AddAction(SEQ_UPDATE_COMPONENT_WELDING_PARAMETERS, UpdateComponentWeldingParameters);
|
||||
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.AddAction(SEQ_DO_COMPONENT_WELDING, DoComponentWelding);
|
||||
sb.AddAction(SEQ_END_WELDING, EndWelding);
|
||||
sb.AddAction(SEQ_SET_BLOW_OFF, SetBlowOff);
|
||||
sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함.
|
||||
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);
|
||||
|
||||
|
||||
// 기존 흐름에서 SET_BLOW_ON → START_WELDING 사이에 끼워넣기
|
||||
#region 기존 흐름 26.04.08
|
||||
//sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_SET_BLOW_ON]
|
||||
// > sb[SEQ_START_WELDING] > sb[SEQ_CHECK_END_LIST]);
|
||||
#endregion
|
||||
#region 2개 노드 추가한 흐름 26.04.08
|
||||
sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_SET_BLOW_ON]
|
||||
> sb[SEQ_MOVE_STAGE_ORIGIN] // ← 추가
|
||||
> sb[SEQ_ENCODER_RESET] // ← 추가
|
||||
> sb[SEQ_START_WELDING] > sb[SEQ_CHECK_END_LIST]);
|
||||
#endregion
|
||||
|
||||
// 아래 두 흐름은 기존 그대로 유지
|
||||
sb.Flows(sb[SEQ_CHECK_END_LIST] > sb[SEQ_UPDATE_COMPONENT_WELDING_PARAMETERS]
|
||||
> 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_DO_COMPONENT_WELDING] > sb[SEQ_CHECK_END_LIST]);
|
||||
sb.Flows(sb[SEQ_CHECK_END_LIST] > sb[SEQ_END_WELDING] > sb[SEQ_SET_BLOW_OFF]
|
||||
> sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_COMPLETE] > sb.Final);
|
||||
sb.Flows(sb.Init
|
||||
> sb[SEQ_ENTER]
|
||||
> sb[SEQ_CHECK_INIT_CONDITION]
|
||||
> sb[SEQ_STANDBY_MOTION]
|
||||
> sb[SEQ_STANDBY_SCANNER]
|
||||
> 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_DO_COMPONENT_WELDING]
|
||||
> sb[SEQ_ACS_MOTION_SET]
|
||||
> sb[SEQ_ACS_MOTION_START]
|
||||
> sb[SEQ_CHECK_MOTION_END]
|
||||
> sb[SEQ_COMPLETE]
|
||||
> sb.Final);
|
||||
|
||||
sb.OnStopped(OnStopped);
|
||||
sb.OnForceError(OnForceError);
|
||||
@ -184,23 +152,123 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
|
||||
return sb;
|
||||
}
|
||||
#region 26.04.08 NDY
|
||||
private SequenceActionResult EncoderReset(SequenceContext context, string id, SequenceActionResult param)
|
||||
|
||||
|
||||
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
if (_ACS == null)
|
||||
{
|
||||
Log.W("[EncoderReset] ACS null - 스킵");
|
||||
Log.I("===== SeqTeachingRun Sequence_Enter 진입 ====="); // 임시 추가
|
||||
Log.I("SeqTeachingRun Start");
|
||||
|
||||
_InitParam = param.Param as SeqTeachingRun_InitParam;
|
||||
_SystemParameter = context.Settings[CommonSettingIds.SystemParameter] as SystemParameter;
|
||||
_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; }
|
||||
|
||||
_ACS = context.Devices[DeviceIds.ACS] as ScannerACS;
|
||||
if (_ACS == 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; }
|
||||
|
||||
_AxisZ = context.Devices[CommonDeviceIds.AxisZ] as ACSMotor;
|
||||
if (_AxisZ == 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.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
private bool CheckDeviceReady(SequenceContext context)
|
||||
{
|
||||
List<string> deviceListToCheck = new List<string>() { DeviceIds.ACS, CommonDeviceIds.Scanner, CommonDeviceIds.AxisX2, CommonDeviceIds.AxisZ };
|
||||
//List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.Scanner, CommonDeviceIds.IODevice,DeviceIds.ACS }; 변수 맵 수신 후 ACS 주석 해제 위에 주석 처리
|
||||
bool isAllDeviceActivated = true;
|
||||
foreach (string item in deviceListToCheck) {
|
||||
if (!context.Devices[item].IsActivated) {
|
||||
isAllDeviceActivated = isAllDeviceActivated && false;
|
||||
}
|
||||
}
|
||||
|
||||
return isAllDeviceActivated;
|
||||
}
|
||||
|
||||
private SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
bool boolian = AlarmManager.HasAlarmLevelHigh();
|
||||
if (boolian) {
|
||||
Log.E($"Clear Heavy Alarms For Welding!");
|
||||
MessageUtil.ShowWarningToast(string.Format("Clear Heavy Alarms For Welding!"));
|
||||
return null;
|
||||
}
|
||||
|
||||
_ScannerSaveLogTime = TimeSpan.Zero;
|
||||
|
||||
var startTime = DateTime.Now;
|
||||
context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime);
|
||||
|
||||
Log.D("ComponentTeachingRun Sequence CheckInitCondition");
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
#region 26.04.08 NDY
|
||||
private SequenceActionResult SetStandbyMotion(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
if (_AxisX == null) {
|
||||
Log.W("[MoveStageToOrigin] AxisX2 null - 스킵");
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
if (!_Scanner.Config.UseMarkingOnTheFly)
|
||||
{
|
||||
Log.I("[MoveStageToOrigin] Stage X → 0 이동 시작");
|
||||
|
||||
// (스캐너의 0,0 && 용접 대상의 시작 위치) >> X축을 이동
|
||||
_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();
|
||||
|
||||
// Laser FocusPosition Move
|
||||
_AxisZ.SetTargetPos(0, TargetPosType.ABS);
|
||||
_AxisZ.SetMoveVelocityImm(AuroraACS.Speed.M);
|
||||
_AxisZ.AccelerationImm(AuroraACS.Speed.M);
|
||||
_AxisZ.DecelerationImm(AuroraACS.Speed.M);
|
||||
_AxisZ.JerkImm(AuroraACS.Speed.M);
|
||||
_AxisZ.Move();
|
||||
|
||||
var res = context.RetryUntilSuccess(
|
||||
() => _AxisX.IsReachedTargetPosition(0) && _AxisZ.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 = 0 도달 완료");
|
||||
return SequenceAction.Ok();
|
||||
|
||||
}
|
||||
private SequenceActionResult SetStandbyScanner(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
// Scanner Default Setting
|
||||
var mainPage = CommonHelper.GetMainPage();
|
||||
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
||||
_WeldingScannerListNo = eListNo.LIST1;
|
||||
_SelectedObjectList = FindObjects();
|
||||
//Vision Correction File 선택
|
||||
_Scanner.SelectCorrectionTable(2);
|
||||
|
||||
if (!_Scanner.Config.UseMarkingOnTheFly) {
|
||||
Log.W("[EncoderReset] MOTF 비활성화 - 스킵");
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
Log.I("[EncoderReset] 시작");
|
||||
|
||||
// SeqUploadWeldingList.MarkingOnTheFlyOn 패턴
|
||||
_Scanner.SetFlyX(_Scanner.Config.MarkingOnTheFlyEncoderResolutionX);
|
||||
Log.I($"[EncoderReset] SetFlyX: {_Scanner.Config.MarkingOnTheFlyEncoderResolutionX}");
|
||||
@ -214,117 +282,7 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
Log.I("[EncoderReset] 완료 - Stage(0) = Scanner(0) 동기화");
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
//SeqTeachingPosMoveStageA패턴 참고 - 기존 GUN 프로젝트 시퀸스
|
||||
private SequenceActionResult MoveStageToOrigin(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
if (_AxisX == null)
|
||||
{
|
||||
Log.W("[MoveStageToOrigin] AxisX2 null - 스킵");
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
Log.I("[MoveStageToOrigin] Stage X → 0 이동 시작");
|
||||
|
||||
// SeqTeachingPosMoveStageA.MoveXYStage 패턴
|
||||
_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();
|
||||
|
||||
var res = context.RetryUntilSuccess(
|
||||
() => _AxisX.IsReachedTargetPosition(0),
|
||||
30 * 1000, 20, true);
|
||||
|
||||
if (res == E2.TIMEOUT) { Log.E("[MoveStageToOrigin] TIMEOUT"); return null; }
|
||||
if (res == E2.CANCELLED) { Log.E("[MoveStageToOrigin] CANCELLED"); return null; }
|
||||
|
||||
Log.I("[MoveStageToOrigin] Stage X = 0 도달 완료");
|
||||
return SequenceAction.Ok();
|
||||
|
||||
}
|
||||
#endregion
|
||||
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
Log.I("===== SeqTeachingRun Sequence_Enter 진입 ====="); // 임시 추가
|
||||
Log.I("SeqTeachingRun Start");
|
||||
|
||||
_InitParam = param.Param as SeqTeachingRun_InitParam;
|
||||
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
|
||||
|
||||
_Laser = context.GetLaser();
|
||||
_Laser.GetLaserDevice(ref _LaserDevice);
|
||||
_LaserTruFiber = _LaserDevice as LaserTruFiber;
|
||||
|
||||
if (_plc == null)
|
||||
_plc = context.Devices[DeviceIds.PLCDevice] as PLCControllerPrismaticScanner;
|
||||
|
||||
// Laser 시퀀스 Running. 안 넣어줘도 됨.
|
||||
//_LaserTruFiber.SetIsSeqRunning(true);
|
||||
|
||||
_LaserPowerCalParam = context.GetSetting<LaserPowerCalParam>(CommonSettingIds.LaserPowerCalParam);//우선 AuroraRecipe로 상속받아서 함수 사용하도록 함
|
||||
//laserPowerCalParam 초기화(CSV 파일 불러오기)
|
||||
_LaserPowerCalParam.Initialize(_LaserPowerCalParam.PowerCalibrationCenterBeamCSVFile, _LaserPowerCalParam.PowerCalibrationRingBeamCSVFile);
|
||||
|
||||
_SequenceSetting = context.Settings[CommonSettingIds.Sequence] as SequenceSetting;
|
||||
InitDev(context);
|
||||
if (!CheckDeviceReady(context)) { //Check Device
|
||||
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_TeachingRun_DeviceNotReady);
|
||||
Log.E("The devices are not active.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (InitSequenceVariable(context) == false) {
|
||||
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_TeachingRun_InitVariableError);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
private void InitDev(SequenceContext context)
|
||||
{
|
||||
//Device Init
|
||||
_Scanner = context.GetLaserScanner();
|
||||
_IO = context.Devices[CommonDeviceIds.IODevice] as PAIX_PrismaticScanner;
|
||||
|
||||
// 26.04.06 NDY 추가: ACS 디바이스 취득 (null-safe)
|
||||
// 변수 맵 수신 후 MOTFStart() 호출에 사용
|
||||
// 변경 전
|
||||
//try { _ACS = context.Devices[DeviceIds.ACS] as ScannerACS; }
|
||||
// 변경 후
|
||||
try { _ACS = context.Devices[DeviceIds.ACS] as IScannerACS; }
|
||||
catch { _ACS = null; Log.W("ACS 디바이스 취득 실패 (null 처리)"); }
|
||||
|
||||
//26.04.08 NDY 추가 _AxisX 가져오기
|
||||
try { _AxisX = context.Devices[CommonDeviceIds.AxisX2] as ACSMotor; }
|
||||
catch { _AxisX = null; Log.W("AxisX2 취득 실패"); }
|
||||
}
|
||||
private bool CheckDeviceReady(SequenceContext context)
|
||||
{
|
||||
List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.Scanner, CommonDeviceIds.IODevice };
|
||||
//List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.Scanner, CommonDeviceIds.IODevice,DeviceIds.ACS }; 변수 맵 수신 후 ACS 주석 해제 위에 주석 처리
|
||||
bool isAllDeviceActivated = true;
|
||||
foreach (string item in deviceListToCheck) {
|
||||
if (!context.Devices[item].IsActivated) {
|
||||
isAllDeviceActivated = isAllDeviceActivated && false;
|
||||
}
|
||||
}
|
||||
|
||||
return isAllDeviceActivated;
|
||||
}
|
||||
private bool InitSequenceVariable(SequenceContext context)
|
||||
{
|
||||
var mainPage = CommonHelper.GetMainPage();
|
||||
_ScannerCanvasUserCtrl = mainPage.ScannerCanvasCtrlTeaching;
|
||||
|
||||
_WeldingScannerListNo = eListNo.LIST1;
|
||||
|
||||
_SelectedObjectList = FindObjects();
|
||||
|
||||
return true;
|
||||
}
|
||||
//SeqTeachingPosMoveStageA패턴 참고 - 기존 GUN 프로젝트 시퀸스
|
||||
|
||||
private List<IDrawObject> FindObjects()
|
||||
{
|
||||
@ -335,232 +293,10 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
} else {
|
||||
return _ScannerCanvasUserCtrl.Canvas.Model.SelectedObjects;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
if (!CheckCondition()) {
|
||||
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_TeachingRun_CheckInitCondition);
|
||||
Log.E("Condition is not in state to start sequence.");
|
||||
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false);
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
_CurrentobjectIndex = 0;
|
||||
_BeforeObjectIndex = 0;
|
||||
_CountWeldingObject = 0;
|
||||
_BeforeParameterNo = -1;
|
||||
_BeforeProgramNo = -1;
|
||||
_ScannerSaveLogTime = TimeSpan.Zero;
|
||||
|
||||
_FlattenRecipes = new List<IDrawObject>(); // 레시피 초기화
|
||||
UnpackRecipes(_SelectedObjectList);
|
||||
var startTime = DateTime.Now;
|
||||
context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime);
|
||||
|
||||
Log.D("ComponentTeachingRun Sequence CheckInitCondition");
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
private bool CheckCondition()
|
||||
{
|
||||
if (CheckCondition_Interlock()) {
|
||||
if (InitializeDeviceStatus()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckCondition_Interlock()
|
||||
{
|
||||
//// PLC, Data, IO 등 Interlock checking
|
||||
bool boolian = AlarmManager.HasAlarmLevelHigh();
|
||||
if (boolian) {
|
||||
Log.E($"Clear Heavy Alarms For Welding!");
|
||||
MessageUtil.ShowWarningToast(string.Format("Clear Heavy Alarms For Welding!"));
|
||||
return false;
|
||||
}
|
||||
boolian = AlarmManager.IsPlcDoorOpen();
|
||||
if (boolian) {
|
||||
Log.E($"PLC Door Opened!! Can't Weld Now.");
|
||||
MessageUtil.ShowWarningToast(string.Format("Close Door ! Clear PLC DoorInterlock!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
boolian = AlarmManager.IsPlcEmoAlarm();
|
||||
if (boolian) {
|
||||
Log.E($"PLC EMO Pushed!! Can't Weld Now.");
|
||||
MessageUtil.ShowWarningToast(string.Format("Clear PLC EMO Status!"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool InitializeDeviceStatus()
|
||||
{
|
||||
//Vision Correction File 선택
|
||||
_Scanner.SelectCorrectionTable(2);
|
||||
return true;
|
||||
}
|
||||
|
||||
private SequenceActionResult SetBlowOn(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
if (_InitParam.UseBlow == false) {
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
int intervalTime = _InitParam.IntervalTimeBlowOn;
|
||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.SeamWeldingN2BlowSol), true);
|
||||
Thread.Sleep(intervalTime);
|
||||
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Blow ON Complete"));
|
||||
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
private void SaveScannerRecordFileForamt()
|
||||
{
|
||||
if (_Scanner.Config.UseRecordSignal) {
|
||||
DateTime startTime = DateTime.Now;
|
||||
_Scanner.SaveStackRecord("Normal");
|
||||
_ScannerSaveLogTime += DateTime.Now.Subtract(startTime);
|
||||
}
|
||||
}
|
||||
|
||||
private SequenceActionResult StartWelding(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Start Component Welding"));
|
||||
_SequenceCompleteTime = DateTime.Now;
|
||||
// Laser 판넬 On
|
||||
_IO.WriteDoBit(PAIX_PrismaticScanner.ePrismaticDOAddress.CCCAPLaserOnLampOn, true);
|
||||
|
||||
_DivideObjectsQueue = SplitBySerialize(_FlattenRecipes);
|
||||
Log.I($"Divided DrawObjects List Count[{_DivideObjectsQueue.Count}]");
|
||||
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
// 펼쳐진 객체(_FlattenRecipes)를 여러개의 스캔 파라미터에 따라 여러개로 나눈다
|
||||
public static Queue<List<IDrawObject>> SplitBySerialize(List<IDrawObject> source)
|
||||
{
|
||||
var result = new Queue<List<IDrawObject>>();
|
||||
if (source == null || source.Count == 0)
|
||||
return result;
|
||||
|
||||
List<IDrawObject> current = null;
|
||||
int? currentId = null;
|
||||
|
||||
foreach (var item in source) {
|
||||
if (current == null || currentId.Value != item.ScannerParamID) {
|
||||
current = new List<IDrawObject>();
|
||||
result.Enqueue(current);
|
||||
currentId = item.ScannerParamID;
|
||||
}
|
||||
|
||||
current.Add(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string CheckEndList(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
||||
{
|
||||
if (_DivideObjectsQueue.Count == 0)
|
||||
return SEQ_END_WELDING;
|
||||
|
||||
// 파일 저장 변수 초기화
|
||||
if (_Scanner.Config.UseRecordSignal) {
|
||||
DateTime startTime = DateTime.Now;
|
||||
_Scanner.InitializeRecord();
|
||||
_ScannerSaveLogTime += DateTime.Now.Subtract(startTime);
|
||||
}
|
||||
|
||||
return SEQ_UPDATE_COMPONENT_WELDING_PARAMETERS;
|
||||
|
||||
}
|
||||
|
||||
private SequenceActionResult UpdateComponentWeldingParameters(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
_partialWeldingStartTime = DateTime.Now;
|
||||
var currentDivideObject = _DivideObjectsQueue.Peek();
|
||||
int paramIndex = currentDivideObject[0].ScannerParamID - 1;
|
||||
Log.I($"Remain Divided DrawObjects Count[{currentDivideObject.Count}] / ParameterNo[{paramIndex + 1}]");
|
||||
|
||||
int SlotNo = _plc.ReadWord(eWordInput.PLC_CURRENT_SLOT_NO).data;
|
||||
if (SlotNo <= 0)
|
||||
SlotNo = 1;
|
||||
// 결과 Data 를 업데이트 함.
|
||||
var power = Status.GetProcessingWeldingData().UploadProcessDatas.Where(data => data.DataName == $"Power_{SlotNo}_{_SequenceSetting.LastPageNo}").FirstOrDefault();
|
||||
|
||||
#region 26.04.08 NDY 캘리브레이션 노드 추가 테스트를 위해서 잠시 예외처리 코드 추가
|
||||
if (power != null)
|
||||
power.Value = ScannerCanvasUserCtrl.ScannerParams[paramIndex].LaserPower1
|
||||
+ ScannerCanvasUserCtrl.ScannerParams[paramIndex].LaserPower2;
|
||||
#endregion
|
||||
// 26.04.08 NDY 주석처리 - power null 예외 방지 (위 null 체크로 대체)
|
||||
//power.Value = ScannerCanvasUserCtrl.ScannerParams[paramIndex].LaserPower1 + ScannerCanvasUserCtrl.ScannerParams[paramIndex].LaserPower2;
|
||||
|
||||
|
||||
var velocity = Status.GetProcessingWeldingData().UploadProcessDatas.Where(data => data.DataName == $"Velocity_{SlotNo}_{_SequenceSetting.LastPageNo}").FirstOrDefault();
|
||||
#region 26.04.08 NDY velocity null에 대한 예외 처리
|
||||
if (velocity != null)
|
||||
velocity.Value = ScannerCanvasUserCtrl.ScannerParams[paramIndex].MarkSpeed;
|
||||
#endregion
|
||||
// 26.04.08 NDY 주석처리 - velocity null 예외 방지 (위 null 체크로 대체)
|
||||
//velocity.Value = ScannerCanvasUserCtrl.ScannerParams[paramIndex].MarkSpeed;
|
||||
|
||||
|
||||
// 26.04.08 NDY - FDC 데이터 상신 -기존 코드 주석처리
|
||||
//_plc.UploadReportDatas(Status.GetProcessingWeldingData().UploadProcessDatas);
|
||||
// 26.04.08 NDY - FDC 상신도 데이터 있을 때만 - 테스트 목적 예외 처리 추가
|
||||
if (Status.GetProcessingWeldingData().UploadProcessDatas.Count > 0)
|
||||
_plc.UploadReportDatas(Status.GetProcessingWeldingData().UploadProcessDatas);
|
||||
|
||||
_CenterBeamPower = (int)ScannerCanvasUserCtrl.ScannerParams[paramIndex].LaserPower1;
|
||||
_RingBeamPower = (int)ScannerCanvasUserCtrl.ScannerParams[paramIndex].LaserPower2;
|
||||
_CenterRingRatio = 0;
|
||||
|
||||
if (_CenterBeamPower == 0 && _RingBeamPower == 0)
|
||||
_CenterRingRatio = 100;
|
||||
else
|
||||
_CenterRingRatio = (int)Math.Round((double)(100 * _CenterBeamPower) / (double)(_CenterBeamPower + _RingBeamPower), 0); // Discrete 한 값이라서 Ring은 오차 발생
|
||||
|
||||
if (_Laser.Config.TruFiberType == eTruFiberType.TruFiberP) {
|
||||
_CenterBeamPower = _LaserPowerCalParam.CalibrateWattToWatt(_CenterBeamPower, (uint)LaserPowerCalParam.beamMode.Center);
|
||||
_RingBeamPower = _LaserPowerCalParam.CalibrateWattToWatt(_RingBeamPower, (uint)LaserPowerCalParam.beamMode.Ring);
|
||||
}
|
||||
// Ready 상태 변경 확인(Complete 상태에서 Laser Ready로 변환되기까지 시간이 걸림)
|
||||
// 여기서는 왜 IW03과 Center를 비교하는 것인지.... 아직 값을 써주지 않았으므로 레이저 출사 가능 여부만 확인하면 되지 않을까.
|
||||
var res = context.RetryUntilSuccess(_Laser.GetLaserReady, timeoutSeconds * 1000, 1);
|
||||
|
||||
if (res == E2.TIMEOUT) {
|
||||
Log.E(string.Format($"[Page Change Req] Laser Program Ready Timeout When LaserReady"));
|
||||
return null;
|
||||
}
|
||||
Log.D(string.Format($"[Page Change Req] Laser Program Ready OK"));
|
||||
|
||||
// Laser Program Parameters 설정(Laser Ready 상태는 용접 직전에 확인)
|
||||
List<(int, int, bool)> datas = new List<(int, int, bool)>();
|
||||
datas.Add((csWriteNodeNo.IW03, _CenterBeamPower, true));
|
||||
datas.Add((csWriteNodeNo.IW04, _RingBeamPower, true));
|
||||
datas.Add((csWriteNodeNo.IW05, _CenterRingRatio, true));
|
||||
|
||||
// 업데이트 될 경우, 프로그램 전환을 위한 프로그램 종료 시퀸스 진행됨.
|
||||
if (_LaserTruFiber.UpdatesDatasIfChanged(datas)) {
|
||||
|
||||
// 프로그램이 종료 될 때까지 대기.
|
||||
res = context.RetryUntilSuccess(_LaserTruFiber.GetProgramCompleted, timeoutSeconds * 1000, 10);
|
||||
|
||||
if (res == E2.TIMEOUT) {
|
||||
Log.E(string.Format($"[Page Change Req] Laser Program Completed Timeout When Parameter Changes"));
|
||||
return null;
|
||||
}
|
||||
Log.D(string.Format($"[Page Change Req] Laser Program Completed OK When Data Updated"));
|
||||
}
|
||||
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
Status.SetWorkingPosition(eWorkingPosition.UPLOADING_WELD_LIST);
|
||||
@ -571,16 +307,11 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
IncludeListStartEnd = true,
|
||||
CellMeasureCenterOffsetX = _SystemParameter.CellPosMeasureCenterOffsetX + _InitParam.CellCenterOffsetX,
|
||||
CellMeasureCenterOffsetY = _SystemParameter.CellPosMeasureCenterOffsetY + _InitParam.CellCenterOffsetY,
|
||||
SelectedDrawObjectList = _DivideObjectsQueue.Peek(),
|
||||
SelectedDrawObjectList = _SelectedObjectList,
|
||||
WeldingScannerListNo = _WeldingScannerListNo,
|
||||
};
|
||||
|
||||
var _PageNo = _SequenceSetting.LastPageNo;
|
||||
|
||||
Log.W($"page {_PageNo}({Status.GetProcessingWeldingData().CellId}) : Cell Offset Value Check ; X : {_SystemParameter.CellPosMeasureCenterOffsetX} + {_InitParam.CellCenterOffsetX} ; Y : {_SystemParameter.CellPosMeasureCenterOffsetY} + {_InitParam.CellCenterOffsetY}");
|
||||
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Set UploadWelindList Seq Param"));
|
||||
|
||||
return SequenceAction.Ok(seqParams);
|
||||
}
|
||||
|
||||
@ -600,32 +331,7 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
|
||||
private SequenceActionResult DoComponentWelding(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
_DivideObjectsQueue.Dequeue();
|
||||
Log.I("UploadWeldingList Complete");
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Component Welding Start idx :({_BeforeObjectIndex} ~ {_BeforeObjectIndex + _CountWeldingObject - 1})"));
|
||||
|
||||
#region PSTART_DYN 사용시 참고
|
||||
//// PSTART_DYN에서는 레이저가 활성화되었는지 확인하여야 함. 하지만, PSTART_STATICALLY에서는 굳이 확인할 필요 없음. (이전에 확인해줄 것이므로)
|
||||
// var res = context.RetryUntilSuccess(_LaserTruFiber.GetProgramActive, timeoutSeconds * 1000, 1);
|
||||
//if (res == E2.TIMEOUT)
|
||||
//{
|
||||
// Log.E(string.Format($"[ComponentTeachingRun] Laser Program Active Timeout"));
|
||||
// return null;
|
||||
//}
|
||||
#endregion
|
||||
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Check LaserReadyResponse"));
|
||||
// 만일 프로그램이 정상적으로 종료 및 변경 원할 경우, 레이저 스레드에서 Ready 상태로 만들어주고 있을 것임.
|
||||
// Ready 상태 변경 확인
|
||||
var res = context.RetryUntilSuccess(LaserReadyResponse, timeoutSeconds * 1000, 10);
|
||||
if (res == E2.TIMEOUT) {
|
||||
Log.E(string.Format($"[ComponentTeachingRun] Laser Program Ready Timeout When LaserReadyResponse"));
|
||||
return null;
|
||||
}
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Laser Program Ready OK When ReadyResponse"));
|
||||
|
||||
Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD);
|
||||
|
||||
Log.I("ExecuteList Start");
|
||||
Log.I($"Welding List Space : {_Scanner.GetListSpace()}");
|
||||
DateTime weldingTime = DateTime.Now;
|
||||
_Scanner.ExecuteList(_WeldingScannerListNo);
|
||||
@ -640,29 +346,12 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
|
||||
|
||||
|
||||
_Scanner.WaitForListTaskCompleted(_SystemParameter.WeldLinesTaskTimeOut);
|
||||
|
||||
// ── 26.04.06 NDY 추가: ACS 완료 대기 ─────────────────
|
||||
// TODO: 변수 맵 수신 후 활성화
|
||||
// while (!_ACS.CheckMOTFComp()) { Thread.Sleep(10); }
|
||||
// ────────────────────────────────────────────────────
|
||||
|
||||
_MeasurementSpanTime = DateTime.Now.Subtract(weldingTime);
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Component Welding Complete Time : {_MeasurementSpanTime.TotalMilliseconds}"));
|
||||
|
||||
#region PSTART_DYN 사용시 참고
|
||||
//// 굳이 확인할 필요가 없을 듯 함.PSTAT_STATICALLY 활용시.
|
||||
//res = context.RetryUntilSuccess(_LaserTruFiber.GetProgramCompleted, timeoutSeconds * 1000, 1);
|
||||
|
||||
//if (res == E2.TIMEOUT)
|
||||
//{
|
||||
// Log.E(string.Format($"[ComponentTeachingRun] Laser Program Complete Timeout"));
|
||||
// return null;
|
||||
//}
|
||||
#endregion
|
||||
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Laser Program Complete OK"));
|
||||
|
||||
|
||||
if (_Scanner.Config.UseRecordSignal) {
|
||||
DateTime startTime = DateTime.Now;
|
||||
@ -679,29 +368,35 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
|
||||
_ScannerCanvasUserCtrl.TimeLabelUpdate(_MeasurementSpanTime.TotalMilliseconds, PartialTactTime.TotalMilliseconds);
|
||||
|
||||
// 용접 끝난 후, 초기화 시킴
|
||||
var UploadDatas = Status.GetProcessingWeldingData().UploadProcessDatas;
|
||||
foreach (var data in UploadDatas)
|
||||
data.Clear();
|
||||
_plc.UploadReportDatas(UploadDatas);
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
private SequenceActionResult SetMotion(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
// 메뉴얼 화면에서 셋팅이 필요해보임
|
||||
_ACS.SetMOTFParams(0, 0, 0, 0, 0);
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
private SequenceActionResult StartMotion(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
_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();
|
||||
}
|
||||
private bool LaserReadyResponse()
|
||||
{
|
||||
if (ApplicationExt.IsSimulation)
|
||||
return true;
|
||||
|
||||
// Ready 상태를 확인하기 위해서는 프로그램 파라메터가 최신 상태인지, Ready 상태인지 둘 다 확인해야 한다.
|
||||
return Convert.ToInt32(_LaserTruFiber.GetWriteInputWord(csWriteNodeNo.IW03)) == _CenterBeamPower
|
||||
&& Convert.ToInt32(_LaserTruFiber.GetWriteInputWord(csWriteNodeNo.IW04)) == _RingBeamPower
|
||||
&& Convert.ToInt32(_LaserTruFiber.GetWriteInputWord(csWriteNodeNo.IW05)) == _CenterRingRatio
|
||||
//&& _LaserTruFiber.GetProgramNo() == _BeforeProgramNo
|
||||
&& _LaserTruFiber.GetLaserReady();
|
||||
}
|
||||
|
||||
private SequenceActionResult EndWelding(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
_Scanner.WaitForListTaskCompleted(_SystemParameter.WeldLinesTaskTimeOut);
|
||||
Log.I("ExecuteList Complete");
|
||||
|
||||
_MeasurementSpanTime = DateTime.Now.Subtract(_SequenceCompleteTime);
|
||||
Log.D(string.Format($"[TactTime] Complete All Component Weld : {_MeasurementSpanTime.TotalMilliseconds}"));
|
||||
|
||||
@ -711,9 +406,6 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND);
|
||||
_Scanner.JumpAbs(0, 0, eFunctionType.COMMAND);
|
||||
|
||||
// Laser 판넬 Off
|
||||
_IO.WriteDoBit(PAIX_PrismaticScanner.ePrismaticDOAddress.CCCAPLaserOnLampOn, false);
|
||||
|
||||
var mesurementTime = DateTime.Now;
|
||||
|
||||
//용접 완료 후 CorrectionFile Vision으로 원복
|
||||
@ -725,28 +417,6 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
private SequenceActionResult SetBlowOff(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
if (_InitParam.UseBlow == false) {
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
int intervalTime = _InitParam.IntervalTimeBlowOff;
|
||||
Thread.Sleep(intervalTime);
|
||||
|
||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.SeamWeldingN2BlowSol), false);
|
||||
|
||||
Log.D(string.Format($"[ComponentTeachingRun] Blow OFF Complete"));
|
||||
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
private SequenceActionResult SaveResultData(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true);
|
||||
return SequenceAction.Ok();
|
||||
}
|
||||
|
||||
private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param)
|
||||
{
|
||||
context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult);
|
||||
@ -760,24 +430,15 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
return SequenceAction.Ok(result);
|
||||
}
|
||||
|
||||
private static void UnpackRecipes(List<IDrawObject> recipes)
|
||||
private void SaveScannerRecordFileForamt()
|
||||
{
|
||||
// Recipe를 재귀적으로 탐색해서 List로 재구성하는 함수
|
||||
if (recipes == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < recipes.Count; i++) {
|
||||
if (recipes[i] is Group) {
|
||||
Group subGroup = recipes[i] as Group;
|
||||
List<IDrawObject> subrecipes = subGroup.SubObjects as List<IDrawObject>;
|
||||
UnpackRecipes(subrecipes);
|
||||
} else {
|
||||
_FlattenRecipes.Add(recipes[i]);
|
||||
}
|
||||
if (_Scanner.Config.UseRecordSignal) {
|
||||
DateTime startTime = DateTime.Now;
|
||||
_Scanner.SaveStackRecord("Normal");
|
||||
_ScannerSaveLogTime += DateTime.Now.Subtract(startTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnForceError(SequenceContext context, string arg2)
|
||||
{
|
||||
// Scanner Log 저장
|
||||
@ -790,9 +451,6 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND);
|
||||
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND);
|
||||
|
||||
// TruFiber레이저 Ready로 변경
|
||||
ForceLaserReady();
|
||||
|
||||
//Scanner 원점 복귀
|
||||
// 복귀 시 Scanner Busy 상태일 수 있으므로 진행중인 작업이 끝날 때까지 대기
|
||||
Thread.Sleep(10);
|
||||
@ -814,40 +472,15 @@ namespace ILSOS_PrismaticScanner.Sequences
|
||||
_Scanner.WriteDA((uint)eAnalogPortOut.DA1, 0, eFunctionType.COMMAND);
|
||||
_Scanner.WriteDA((uint)eAnalogPortOut.DA2, 0, eFunctionType.COMMAND);
|
||||
|
||||
// TruFiber레이저 Ready로 변경
|
||||
ForceLaserReady();
|
||||
|
||||
//Scanner 원점 복귀
|
||||
// 복귀 시 Scanner Busy 상태일 수 있으므로 진행중인 작업이 끝날 때까지 대기
|
||||
Thread.Sleep(10);
|
||||
_Scanner.JumpAbs(0, 0, eFunctionType.COMMAND);
|
||||
Thread.Sleep(10);
|
||||
|
||||
// Laser 판넬 Off
|
||||
_IO.WriteDoBit(PAIX_PrismaticScanner.ePrismaticDOAddress.CCCAPLaserOnLampOn, false);
|
||||
|
||||
Log.I("SequenceAction Ok : OnStopped");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void ForceLaserReady()
|
||||
{
|
||||
// 트럼프 레이저에서 PStartDyn, Prog_Stop을 감시하여 강제로 Ready 상태로 만드는 함수
|
||||
if (_Laser.IsSimul) {
|
||||
return;
|
||||
}
|
||||
|
||||
//// PSTART_STATICAL 에서는 필요 없어보임.
|
||||
//_LaserTruFiber.SetProgEnd();
|
||||
|
||||
// Laser 판넬 Off
|
||||
_IO.WriteDoBit(PAIX_PrismaticScanner.ePrismaticDOAddress.CCCAPLaserOnLampOn, false);
|
||||
|
||||
Log.I("SequenceAction Ok : Set Laser Ready");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: UseStream 으로 TeachingRun 을 할 필요가 있을까?? 확인 필요
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user