674 lines
28 KiB
C#
674 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_PrismaticScanner.Models;
|
|
using Aurora;
|
|
using DB.Recipe;
|
|
using System.Runtime.Remoting.Contexts;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
using WeldingCommon.Utils;
|
|
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_PrismaticScanner.Device.PLCControllerPrismaticScanner;
|
|
using System.Windows.Forms.VisualStyles;
|
|
using static AuroraIO.Vendor.PAIX.PAIXIO;
|
|
using WeldingCommon.Alarm;
|
|
using ILSOS_PrismaticScanner.Device;
|
|
|
|
namespace ILSOS_PrismaticScanner.Sequences
|
|
{
|
|
class SeqAutoRunComponentWeld
|
|
{
|
|
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_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_SeqAutoRunPrismaticScanner";
|
|
public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqAutoRunPrismaticScanner";
|
|
}
|
|
|
|
const int PLC_TIMEOUT = 60; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다
|
|
|
|
#region 변수 정의
|
|
// 디바이스 정의
|
|
private Scanner _Scanner;
|
|
private Laser _Laser;
|
|
private PLCControllerPrismaticScanner _PLC;
|
|
private IODevice _IO;
|
|
|
|
// 비전 정의
|
|
private FovRecipe _FovRecipe;
|
|
private CameraAgentBase _CameraAgent;
|
|
private ICameraDisplay _CameraDisplay;
|
|
private CamConfig _CamConfig;
|
|
private MIL_ID _GrabImage = MIL.M_NULL;
|
|
private int _Raduis_Pixel;
|
|
|
|
// 시스템 및 용접 파라미터 정의
|
|
private SystemParameter _SystemParameter;
|
|
private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; //스캐너 동작관련 객체 선언
|
|
private List<IDrawObject> _SelectedDrawObjectList;
|
|
|
|
private SeqAutoRunPrismaticScanner_InitParam _InitParam;
|
|
|
|
// 생산 데이터 정의
|
|
private uint _TodayProduct;
|
|
private uint _TotalProduct;
|
|
|
|
private DateTime _AutoRunStartTime;
|
|
private DateTime _WeldStartTime;
|
|
private DateTime _WeldEndTime;
|
|
private TimeSpan _WeldSpanTime;
|
|
private TimeSpan _InterfaceSpanTime;
|
|
private DateTime _InterfaceStartTime;
|
|
|
|
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("SeqAutoRunPrismaticScanner Start");
|
|
|
|
_InitParam = param.Param as SeqAutoRunPrismaticScanner_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);
|
|
SeqAutoRunPrismaticScanner_OutParam result = new SeqAutoRunPrismaticScanner_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 PLCControllerPrismaticScanner;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
} |