to3796zw 6223627821 CleanVersion_1st
PTOP 각형만 남은 버전
2026-06-18 11:15:10 +09:00

662 lines
28 KiB
C#

using Aurora.Api;
using AuroraCellTracker;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WeldingCommon.Sequences;
using WeldingCommon;
using AuroraLaserScanner;
using WeldingCommon.Settings;
using WeldingCommon.Utils;
using AuroraLaser;
using AuroraOCT;
using AuroraPLC;
using AuroraIO;
using VisionCommon;
using CoreUnit.Scanner.UserControl.ScannerCanvas;
using Aurora.Api.Manager;
using AuroraLBAD;
using CoreUnit.Control.UserControl.Canvas;
using Matrox.MatroxImagingLibrary;
using WeldingCommon.Vision.WeldingObjectGenerator;
using OpenCvSharp;
using System.Diagnostics;
using ILSOS_PrismaticRD_PTOP.Models;
using Aurora;
using DB.Recipe;
using System.Runtime.Remoting.Contexts;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using OpenCvSharp.Dnn;
using static AuroraIO.AJINEXTEK.AjinIO.IOModuleInfo;
using DB;
using System.Configuration;
using System.Runtime.InteropServices.ComTypes;
using System.Windows.Media.Imaging;
using OpenCvSharp.WpfExtensions;
using System.Windows;
using Aurora.View;
using System.Drawing;
using System.Collections.ObjectModel;
using WeldingCommon.Views;
using WeldingCommon.Data;
using Hermes;
using System.CodeDom.Compiler;
using static Aurora.Api.SequenceBuilder;
using WeldingCommon.Devices;
using static ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP;
using System.Windows.Forms.VisualStyles;
using static AuroraIO.Vendor.PAIX.PAIXIO;
using WeldingCommon.Alarm;
using ILSOS_PrismaticRD_PTOP.Device;
namespace ILSOS_PrismaticRD_PTOP.Sequences
{
class SeqAutoRunComponentWeld
{
static readonly Logger Log = new Logger("SeqAutoRunPrismatic");
const string SEQ_ENTER = "SEQ_ENTER"; // inputParam 으로 받자.
const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; // Check Init Condition
const string SEQ_GET_PLC_WELD_READY_REQ_ON = "Get PLC Weld Ready Request On"; // PLC 용접 준비 요청 수신
const string SEQ_CHECK_CELL_INFO_RECEIVE = "Check Cell Info Receive"; // 셀 정보 수신 확인
const string SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ = "Get Sequence Result (ReceiveCellInfo Seq)";
const string SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ = "Process (ReceiveCellInfo Seq)";
const string SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ = "Set Sequence Param (ReceiveCellInfo Seq)";
const string SEQ_SET_PC_WELD_READY_ACK_ON_WITH_CELL = "Set PC Weld Ready Ack On With Cell"; // 셀과 함께 PC 용접 준비 확인
const string SEQ_MEASURE_CELL_POSITION = "Measure Cell Position"; // 셀 위치 측정
const string SEQ_SET_MIL_MODEL_FINDER_SEQ = "Set MIL Model Finder Seq"; // MIL 모델 찾기 시퀀스 설정
const string SEQ_DO_ID_MIL_MODEL_FINDER_SEQ = "Process (MIL Model Finder Seq)"; // MIL 모델 찾기 시퀀스 처리
const string SEQ_GET_MIL_MODEL_FINDER_SEQ = "Get MIL Model Finder Seq"; // MIL 모델 찾기 시퀀스 가져오기
const string SEQ_GENERATE_WELDING_OBJECT = "Generate Welding Object"; // 용접 객체 생성
const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "Set Params Upload Welding List Seq"; // 용접 리스트 업로드 파라미터 설정
const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "Process (Upload Welding List Seq)"; // 용접 리스트 업로드 시퀀스 처리
const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "Get Result Upload Welding List Seq"; // 용접 리스트 업로드 결과 가져오기
const string SEQ_GET_PLC_WELD_READY_REQ_OFF = "Get PLC Weld Ready Request Off"; // PLC 용접 준비 요청 종료
const string SEQ_SET_PC_WELD_READY_ACK_OFF = "Set PC Weld Ready Ack Off"; // PC 용접 준비 확인 종료
const string SEQ_WAIT_WELDING_START = "Wait Welding Start"; // 용접 시작 대기
const string SEQ_EXECUTE_WELDING = "Execute Welding"; // 용접 실행
const string SEQ_CHECK_VISION_COMPENSION_USE = "Check Vision Compensation Use"; // 비전 보상 사용 확인
const string SEQ_CHECK_PLC_WELDING_COMPLETE = "Check Rewelding Request"; // 재용접 요청 확인
const string SEQ_SET_PC_WELD_COMPLETE_ON = "Set PC Weld Complete On"; // PC 용접 완료 설정
const string SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END = "Set PC Weld Complete Off With End"; // 종료와 함께 PC 용접 완료 설정
const string SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF = "Set PLC Weld Complete Ack Off"; // PLC 용접 완료 확인 종료
const string SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY = "Set PC Weld Complete Off With Retry"; // 재시도와 함께 PC 용접 완료 설정
const string SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON = "Set PC Page Change Complete On"; // PC 페이지 변경 완료 설정
const string SEQ_GET_PLC_PAGE_REQ_OFF = "Get PLC Page Request Off"; // PLC 페이지 요청 종료
const string SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF = "Set PC Page Change Complete Off"; // PC 페이지 변경 완료 종료
const string SEQ_SAVE_RESULT_DATA = "Save Result Data"; // 결과 데이터 저장
const string SEQ_COMPLETE = "SEQ_COMPLETE"; // 완료
static class ContextKey
{
public const string KEY_SEQUENCE_RESULT = "KEY_SEQUENCE_RESULT_SeqAutoRunPrismatic";
public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqAutoRunPrismatic";
}
const int PLC_TIMEOUT = 60; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다
#region 변수 정의
// 디바이스 정의
private Scanner _Scanner;
private Laser _Laser;
private PLCControllerPTOP _PLC;
// 비전 정의
private MIL_ID _GrabImage = MIL.M_NULL;
// 시스템 및 용접 파라미터 정의
private SystemParameter _SystemParameter;
private SeqAutoRunPrismatic_InitParam _InitParam;
// 생산 데이터 정의
private uint _TodayProduct;
private uint _TotalProduct;
private DateTime _WeldStartTime;
private DateTime _WeldEndTime;
private TimeSpan _WeldSpanTime;
private string _LotId = "N/A";
private string _CellId = "N/A";
const int timeoutSeconds = 10;
#endregion
public SequenceBuilder Builder()
{
var sb = new SequenceBuilder(1000, true);
////var sb = new SequenceBuilder(1000, false); // With log
sb.AddAction(SEQ_ENTER, Sequence_Enter);
sb.AddDecision(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); //분기
////// PLC_WELD_READY_REQ ON Check & Cell Load
sb.AddAction(SEQ_GET_PLC_WELD_READY_REQ_ON, GetPlcWeldReadyReqOn);
sb.AddDecision(SEQ_CHECK_CELL_INFO_RECEIVE, CheckCellInfoReceive);
sb.AddAction(SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ, SetReceiveCellInfo_SeqParams);
sb.AddSubsequence(SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ, SequenceManager.GetSeqBuilder_SeqReceiveCellInfo());
sb.AddAction(SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ, GetReceiveCellInfo_SeqResult);
////// PC_WELD_READY_ACK ON & PLC_WELD_READY_REQ OFF Check & Use Model Finder
sb.AddAction(SEQ_SET_PC_WELD_READY_ACK_ON_WITH_CELL, SetPcWeldReadyAckOnWithCell);
sb.AddAction(SEQ_GET_PLC_WELD_READY_REQ_OFF, GetPlcWeldReadyReqOff);
sb.AddDecision(SEQ_CHECK_VISION_COMPENSION_USE, CheckVisionCompensationUse);
sb.AddAction(SEQ_MEASURE_CELL_POSITION, MeasureCellPosition);
sb.AddAction(SEQ_SET_MIL_MODEL_FINDER_SEQ, SetMilModelFinder_SeqParams);
///* 반드시 변경 필요함. FlyingVision은 아님. *///
sb.AddSubsequence(SEQ_DO_ID_MIL_MODEL_FINDER_SEQ, SequenceManager.GetSeqBuilder_SeqScoutFlyingVision());
sb.AddAction(SEQ_GET_MIL_MODEL_FINDER_SEQ, GetMilModelFinder_SeqResult);
sb.AddAction(SEQ_GENERATE_WELDING_OBJECT, GenerateWeldingObject);
////// PC_WELD_READY_ACK OFF & Weld Start / Complete
sb.AddAction(SEQ_SET_PC_WELD_READY_ACK_OFF, SetPcWeldReadyAckOff);
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_WAIT_WELDING_START, WaitWeldingStart);
sb.AddAction(SEQ_EXECUTE_WELDING, ExecuteWelding);
/////// Check Welding Retry Request
sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_ON, SetPcWeldCompleteOn);
sb.AddDecision(SEQ_CHECK_PLC_WELDING_COMPLETE, SeqCheckPlcWeldingComplete);
sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END, SetPcWeldCompleteOffWithEnd);
sb.AddAction(SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF, GetPlcWeldCompleteAckOff);
sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY, SetPcWeldCompleteOffWithRetry);
sb.AddAction(SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON, SetPcPageChangeCompleteOn);
sb.AddAction(SEQ_GET_PLC_PAGE_REQ_OFF, GetPlcPageReqOff);
sb.AddAction(SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF, SetPcPageChangeCompleteOff);
sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함.
sb.AddAction(SEQ_COMPLETE, Complete);
sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION]
> sb[SEQ_GET_PLC_WELD_READY_REQ_ON] > sb[SEQ_CHECK_CELL_INFO_RECEIVE]
> sb[SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ]
> sb[SEQ_SET_PC_WELD_READY_ACK_ON_WITH_CELL] > sb[SEQ_GET_PLC_WELD_READY_REQ_OFF]
> sb[SEQ_CHECK_VISION_COMPENSION_USE] > sb[SEQ_MEASURE_CELL_POSITION]
> sb[SEQ_SET_MIL_MODEL_FINDER_SEQ] > sb[SEQ_DO_ID_MIL_MODEL_FINDER_SEQ] > sb[SEQ_GET_MIL_MODEL_FINDER_SEQ] > sb[SEQ_GENERATE_WELDING_OBJECT]
> sb[SEQ_SET_PC_WELD_READY_ACK_OFF] > sb[SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ]
> sb[SEQ_WAIT_WELDING_START] > sb[SEQ_EXECUTE_WELDING]
> sb[SEQ_SET_PC_WELD_COMPLETE_ON] > sb[SEQ_CHECK_PLC_WELDING_COMPLETE]
> sb[SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END] > sb[SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF] > sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_COMPLETE]);
// SEQ_CHECK_INIT_CONDITION
sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_COMPLETE] > sb.Final);
// SEQ_CHECK_CELL_INFO_RECEIVE
sb.Flows(sb[SEQ_CHECK_CELL_INFO_RECEIVE] > sb[SEQ_SET_PC_WELD_READY_ACK_ON_WITH_CELL]);
// SEQ_CHECK_VISION_COMPENSION_USE
sb.Flows(sb[SEQ_CHECK_VISION_COMPENSION_USE] > sb[SEQ_SET_PC_WELD_READY_ACK_OFF]);
// SEQ_CHECK_PLC_WELDING_COMPLETE
sb.Flows(sb[SEQ_CHECK_PLC_WELDING_COMPLETE] > sb[SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY]
> sb[SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON] > sb[SEQ_GET_PLC_PAGE_REQ_OFF] > sb[SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF]
> sb[SEQ_CHECK_VISION_COMPENSION_USE]);
sb.OnStopped(OnStopped);
sb.OnForceError(OnForceError);
//sb.Draw("SeqAutoRunComponentWeld.pdf");
return sb;
}
#region 시퀸스 함수
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
{
Log.I("SeqAutoRunPrismatic Start");
_InitParam = param.Param as SeqAutoRunPrismatic_InitParam;
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
InitDev(context);
if (!CheckDeviceReady(context))
{
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_DeviceNotReady);
Log.E("The devices are not active.");
return null;
}
if (InitSequenceVariable(context) == false)
{
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError);
return null;
}
return SequenceAction.Ok();
}
private string CheckInitCondition(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
if (!CheckCondition(context))
{
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition);
Log.E("Condition is not in state to start sequence.");
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false);
return SEQ_COMPLETE;
}
var startTime = DateTime.Now;
context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime);
return SEQ_SAVE_RESULT_DATA;
}
private SequenceActionResult GetPlcWeldReadyReqOn(SequenceContext context, string id, SequenceActionResult param)
{
// while context가 적절한지 고민이 됨.
while (!context.Stopped)
{
if (_PLC.ReadBit(eBitInput.PLC_WELD_READY_REQ).data){
Log.I(string.Format("PLC Weld Ready Request ON"));
break;
}
}
return SequenceAction.Ok();
}
private string CheckCellInfoReceive(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset)
{
Log.I(string.Format("Check Cell Info Receive"));
return SEQ_CHECK_CELL_INFO_RECEIVE;
}
else
{
Log.I(string.Format("Pass Cell Info Receive"));
return SEQ_SET_PC_WELD_READY_ACK_ON_WITH_CELL;
}
}
private SequenceActionResult SetReceiveCellInfo_SeqParams(SequenceContext context, string id, SequenceActionResult param)
{
SeqReceiveCellInfo_InitParam seqParams = new SeqReceiveCellInfo_InitParam()
{
};
return SequenceAction.Ok(seqParams);
}
private SequenceActionResult GetReceiveCellInfo_SeqResult(SequenceContext context, string id, SequenceActionResult param)
{
var resultOutParam = param.Param as SeqReceiveCellInfo_OutParam;
if (resultOutParam.Success == false)
{
return null;
}
return SequenceAction.Ok();
}
private SequenceActionResult SetPcWeldReadyAckOnWithCell(SequenceContext context, string id, SequenceActionResult param)
{
_PLC.WriteBit(eBitOutput.PC_WELD_READY_ACK, true);
// Cell ID를 PLC에 적어줄지 고민해볼 것.
Log.I(string.Format("Set PC Weld Ready Ack On With Cell"));
return SequenceAction.Ok();
}
private SequenceActionResult GetPlcWeldReadyReqOff(SequenceContext context, string id, SequenceActionResult param)
{
// Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess
Func<bool> plcResponse = () => _PLC.ReadBit(eBitInput.PLC_WELD_READY_REQ).data;
var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000);
if (res == E2.TIMEOUT)
{
Log.FuncE("Get PLC Weld Ready Request OFF Timeout !");
return null;
}
else Log.I(string.Format("Get PLC Weld Ready Request Complete"));
return SequenceAction.Ok();
}
private string CheckVisionCompensationUse(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset)
{
Log.I(string.Format("Use Vision Compensation"));
return SEQ_MEASURE_CELL_POSITION;
}
else
{
Log.I(string.Format("Unuse Vision Compensation"));
return SEQ_SET_PC_WELD_READY_ACK_OFF;
}
}
private SequenceActionResult MeasureCellPosition(SequenceContext context, string id, SequenceActionResult param)
{
double ScannerPosX = 0, ScannerPosY = 0;
// 처음 객체 기반의 중앙 기반
FindFirstObjectCenter(out ScannerPosX, out ScannerPosY);
Log.I(string.Format($"Move Scanner - ScannerPosX : {ScannerPosX},ScannerPosY : {ScannerPosY} "));
_Scanner.JumpAbs(ScannerPosX, ScannerPosY);
return SequenceAction.Ok();
}
private SequenceActionResult SetMilModelFinder_SeqParams(SequenceContext context, string id, SequenceActionResult param)
{
throw new NotImplementedException();
}
private SequenceActionResult GetMilModelFinder_SeqResult(SequenceContext context, string id, SequenceActionResult param)
{
throw new NotImplementedException();
}
private SequenceActionResult GenerateWeldingObject(SequenceContext context, string id, SequenceActionResult param)
{
throw new NotImplementedException();
}
private SequenceActionResult SetPcWeldReadyAckOff(SequenceContext context, string id, SequenceActionResult param)
{
_PLC.WriteBit(eBitOutput.PC_WELD_READY_ACK, false);
Log.I(string.Format("Set PC Weld Ready Ack Off"));
return SequenceAction.Ok();
}
private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param)
{
_WeldStartTime = DateTime.Now;
Status.GetProcessingWeldingData().WeldingStartTime = _WeldStartTime;
throw new NotImplementedException();
}
private SequenceActionResult GetUploadWeldingList_SeqResult(SequenceContext context, string id, SequenceActionResult param)
{
throw new NotImplementedException();
}
private SequenceActionResult WaitWeldingStart(SequenceContext context, string id, SequenceActionResult param)
{
throw new NotImplementedException();
}
private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param)
{
_WeldEndTime = DateTime.Now;
_WeldSpanTime = _WeldEndTime.Subtract(_WeldStartTime);
UpdateProductCount(context);
UpdateProductInfoForView();
throw new NotImplementedException();
}
private SequenceActionResult SetPcWeldCompleteOn(SequenceContext context, string id, SequenceActionResult param)
{
_PLC.WriteBit(eBitOutput.PC_WELD_COMPLETE, true);
Log.I(string.Format("Set PC Weld Complete On"));
return SequenceAction.Ok();
}
private string SeqCheckPlcWeldingComplete(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
// Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess
Func<bool> plcResponse = () => _PLC.ReadBit(eBitInput.PLC_WELD_COMPLETE_ACK).data
|| _PLC.ReadBit(eBitInput.PLC_PAGE_CHANGE_REQ).data;
var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000);
if (res == E2.TIMEOUT)
{
Log.FuncE("Get PLC Welding Complete or Page Change Request Timeout !");
return null;
}
else
{
if (_PLC.ReadBit(eBitInput.PLC_WELD_COMPLETE_ACK).data)
{
Log.I(string.Format("Get PLC Weld Complete Ack On"));
return SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END;
}
else if (_PLC.ReadBit(eBitInput.PLC_PAGE_CHANGE_REQ).data)
{
Log.I(string.Format("Get PLC Page Change Request On"));
return SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY;
}
else
{
Log.I(string.Format("Unexpected Situation."));
return null;
}
}
}
private SequenceActionResult SetPcWeldCompleteOffWithEnd(SequenceContext context, string id, SequenceActionResult param)
{
_PLC.WriteBit(eBitOutput.PC_WELD_COMPLETE, false);
Log.I(string.Format("Set PC Weld Complete Off For End"));
return SequenceAction.Ok();
}
private SequenceActionResult GetPlcWeldCompleteAckOff(SequenceContext context, string id, SequenceActionResult param)
{
// Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess
Func<bool> plcResponse = () => !_PLC.ReadBit(eBitInput.PLC_WELD_COMPLETE_ACK).data;
var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000);
if (res == E2.TIMEOUT)
{
Log.FuncE("Get PLC Welding Complete ACK Off Timeout !");
return null;
}
else
{
Log.I(string.Format("Get PLC Weld Complete Ack Off"));
}
return SequenceAction.Ok();
}
private SequenceActionResult SetPcWeldCompleteOffWithRetry(SequenceContext context, string id, SequenceActionResult param)
{
_PLC.WriteBit(eBitOutput.PC_WELD_COMPLETE, false);
Log.I(string.Format("Set PC Weld Complete On For Retry"));
return SequenceAction.Ok();
}
private SequenceActionResult SetPcPageChangeCompleteOn(SequenceContext context, string id, SequenceActionResult param)
{
short pageNo = _PLC.ReadWord(eWordInput.PLC_PAGE_NO).data;
ChangeRecipes(pageNo);
_PLC.WriteBit(eBitOutput.PC_PAGE_CHANGE_COMPLETE, true);
Log.I(string.Format("Set PC Page Change Complete On"));
return SequenceAction.Ok();
}
private SequenceActionResult GetPlcPageReqOff(SequenceContext context, string id, SequenceActionResult param)
{
// Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess
Func<bool> plcResponse = () => !_PLC.ReadBit(eBitInput.PLC_PAGE_CHANGE_REQ).data;
var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000);
if (res == E2.TIMEOUT)
{
Log.FuncE("Get PLC Page Change Request Off Timeout !");
return null;
}
else
{
Log.I(string.Format("Get PLC Page Change Request Off"));
}
return SequenceAction.Ok();
}
private SequenceActionResult SetPcPageChangeCompleteOff(SequenceContext context, string id, SequenceActionResult param)
{
_PLC.WriteBit(eBitOutput.PC_PAGE_CHANGE_COMPLETE, false);
Log.I(string.Format("Set PC Page Change Complete Off"));
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)
{
RestoreDeviceStatus();
context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult);
SeqAutoRunPrismatic_OutParam result = new SeqAutoRunPrismatic_OutParam() { Success = seqResult };
if (seqResult == false)
{
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_ResultFailed);
}
Status.SetWorkingPosition(eWorkingPosition.DONE);
return SequenceAction.Ok(result);
}
#endregion
#region 구동 함수
private bool InitSequenceVariable(SequenceContext context)
{
// TODO: [장비구현필요] Initialize Variable 추가
return true;
}
private void InitDev(SequenceContext context)
{
//Device Init
_Scanner = context.GetLaserScanner();
_Laser = context.GetLaser();
_PLC = context.GetPLC() as PLCControllerPTOP;
}
private bool CheckDeviceReady(SequenceContext context)
{
List<string> deviceListToCheck = new List<string>() { CommonDeviceIds.Scanner, CommonDeviceIds.Laser };
bool isAllDeviceActivated = true;
foreach (string item in deviceListToCheck)
{
if (!context.Devices[item].IsActivated)
{
isAllDeviceActivated = isAllDeviceActivated && false;
}
}
return isAllDeviceActivated;
}
private bool CheckCondition(SequenceContext context)
{
if (CheckCondition_Interlock())
{
if (InitializeDeviceStatus(context))
{
return true;
}
}
return false;
}
private bool CheckCondition_Interlock()
{
// PLC, Data, IO 등 Interlock checking
return true;
}
private bool InitializeDeviceStatus(SequenceContext context)
{
return true;
}
private void FindFirstObjectCenter(out double x, out double y)
{
// 구현 필요
x = 0; y = 0;
}
private void ChangeRecipes(short pageNo)
{
}
#endregion
private bool RestoreDeviceStatus()
{
return true;
}
private void OnForceError(SequenceContext arg1, string arg2)
{
OnSeqActionStop();
Log.I("SequenceAction Ok : OnForceError");
}
private void OnStopped(SequenceContext obj)
{
OnSeqActionStop();
Log.I("SequenceAction Ok : OnStopped");
}
private void OnSeqActionStop()
{
}
private void UpdateProductCount(SequenceContext context)
{
//SystemParameter의 Today, Total Product Count를 어디선간 Reset을 해줘야 함..추가해주고 주석 제거하자
_TodayProduct = _SystemParameter.TodayProductCount;
_TotalProduct = _SystemParameter.TotalProductCount;
if (_TodayProduct < uint.MaxValue)
{
_TodayProduct++;
}
if (_TotalProduct < uint.MaxValue)
{
_TotalProduct++;
}
_SystemParameter.TodayProductCount = _TodayProduct;
_SystemParameter.TotalProductCount = _TotalProduct;
//Systemparameter Save
context.Settings.Save(CommonSettingIds.SystemParameter, _SystemParameter, "SeqAutoRunLHS_New");
}
private void UpdateProductInfoForView()
{
Status.GetProcessingWeldingData().TotalProduct = _TotalProduct;
Status.GetProcessingWeldingData().TodayProduct = _TodayProduct;
Status.GetProcessingWeldingData().WeldingStartTime = _WeldStartTime;
Status.GetProcessingWeldingData().WeldingEndTime = _WeldEndTime;
Status.GetProcessingWeldingData().WeldingSpanTimeMilliseconds = _WeldSpanTime.TotalMilliseconds.ToString();
Status.GetProcessingWeldingData().LotId = _LotId;
Status.GetProcessingWeldingData().CellId = _CellId;
}
}
}