2026-01-26 14:51:28 +09:00

272 lines
8.9 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 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_SampleWeldEquipment.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_SampleWeldEquipment.Device.PLCControllerSampleWeldEquipment;
using System.Windows.Forms.VisualStyles;
using static AuroraIO.Vendor.PAIX.PAIXIO;
using WeldingCommon.Alarm;
namespace ILSOS_SampleWeldEquipment.Sequences
{
class SeqAutoRunSampleWeldEquipment
{
static readonly Logger Log = new Logger("SeqAutoRunSampleWeldEquipment");
const string SEQ_ENTER = "[SeqAutoRunSampleWeldEquipment] SEQ_ENTER"; // inputParam 으로 받자.
const string SEQ_CHECK_INIT_CONDITION = "[SeqAutoRunSampleWeldEquipment] Check Init Condition"; // Check Init Condition
// TODO: [장비구현필요] 실제 공정 추가
const string SEQ_SAVE_RESULT_DATA = "[SeqAutoRunSampleWeldEquipment] Save Result Data";
const string SEQ_WRITE_COMPLETION_PLC_BIT = "[SeqAutoRunSampleWeldEquipment] Write Completion PLC Bit";
const string SEQ_COMPLETE = "[SeqAutoRunSampleWeldEquipment] SEQ_COMPLETE"; // 완료
static class ContextKey
{
public const string KEY_SEQUENCE_RESULT = "KEY_SEQUENCE_RESULT_SeqAutoRunSampleWeldEquipment";
public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqAutoRunSampleWeldEquipment";
}
const int PLC_TIMEOUT = 60; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다
private Scanner _Scanner;
private LaserDevice _Laser;
private SystemParameter _SystemParameter;
private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; //스캐너 동작관련 객체 선언
private List<IDrawObject> _SelectedDrawObjectList;
private SeqAutoRunSampleWeldEquipment_InitParam _InitParam;
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); //분기
// TODO: [장비구현필요] 실제 공정 추가
sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함.
sb.AddAction(SEQ_WRITE_COMPLETION_PLC_BIT, WriteCompletionPLCBit); // 정상적으로 종료 되면, complete bit write
sb.AddAction(SEQ_COMPLETE, Complete);
sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION]
> sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_WRITE_COMPLETION_PLC_BIT] > sb[SEQ_COMPLETE]);
sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_COMPLETE] > sb.Final);
sb.OnStopped(OnStopped);
sb.OnForceError(OnForceError);
//sb.Draw("SeqAutoRunSampleWeldEquipment.pdf");
return sb;
}
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
{
Log.I("SeqAutoRunSampleWeldEquipment Start");
_InitParam = param.Param as SeqAutoRunSampleWeldEquipment_InitParam;
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
InitDev(context);
if (!CheckDeviceReady(context)) { //Check Device
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 bool InitSequenceVariable(SequenceContext context)
{
// TODO: [장비구현필요] Initialize Variable 추가
return true;
}
private void InitDev(SequenceContext context)
{
//Device Init
_Scanner = context.GetLaserScanner();
_Laser = context.GetLaser();
}
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 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);
// TODO: [장비구현필요] 다음 공정 Node 변경
return SEQ_SAVE_RESULT_DATA;
}
// TODO: [장비구현필요] 공정 Node 구현
private SequenceActionResult SaveResultData(SequenceContext context, string id, SequenceActionResult param)
{
context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true);
return SequenceAction.Ok();
}
private SequenceActionResult WriteCompletionPLCBit(SequenceContext context, string id, SequenceActionResult param)
{
// 완료 비트 write 하는 Node 추가 필요. format 유지
return SequenceAction.Ok();
}
private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param)
{
RestoreDeviceStatus();
context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult);
SeqAutoRunSampleWeldEquipment_OutParam result = new SeqAutoRunSampleWeldEquipment_OutParam() { Success = seqResult };
if (seqResult == false) {
AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_ResultFailed);
}
Status.SetWorkingPosition(eWorkingPosition.DONE);
return SequenceAction.Ok(result);
}
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()
{
}
}
public class SeqAutoRunSampleWeldEquipment_InitParam : InitParam
{
}
public class SeqAutoRunSampleWeldEquipment_OutParam : OutParam
{
}
}