2026-03-30 17:09:29 +09:00

278 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aurora.Api;
using AuroraLaserScanner;
using Matrox.MatroxImagingLibrary;
using MilCommon;
using VisionCommon;
using WeldingCommon.Alarm;
using WeldingCommon.Data;
using WeldingCommon.Settings;
using WeldingCommon.Sequences;
using WeldingCommon.Utils;
using WeldingCommon;
using System.Threading;
namespace ILSOS_PrismaticScanner.Sequences
{
class SeqEventQTest
{
static readonly Logger Log = new Logger("SeqAutoRunPrismaticScanner");
#region 시퀸스 변수명
const string SEQ_ENTER = "SEQ_ENTER"; // inputParam 으로 받자.
const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; // Check Init Condition
const string SEQ_CHECK_SEQ_FINISH = "Check Seq Finish";
const string SEQ_MOVE_SCANNER = "Move Scanner";
const string SEQ_SEND_EVENT_SENDER = "Event Sender"; // Image Q 저장
const string SEQ_EVENT_Q_SAVE_FILE = "EventQ Save File";
const string SEQ_SAVE_IMAGES = "Save Images";
const string SEQ_COMPLETE = "Complete";
#endregion
#region 변수 정의
// 디바이스 정의
private Scanner _Scanner;
// 비전 정의
private CameraAgentBase _CameraAgent;
private ICameraDisplay _CameraDisplay;
private PatternAgentBase _PatternAgent;
private PatternInfo _PatternInfo;
private PatternResult _PatternResult;
private FieldScanParams _FieldScanParams;
private object _GrabImage;
private MIL_ID _GrabImageMilId;
private MIL_ID _ResultImageMilId;
private bool _SuccessVisionCompension = false;
private int _SeqCount = 0;
private int _RetryCount = 0;
private double _OffsetXfromModelFinder = 0;
private double _OffsetYfromModelFinder = 0;
// 시스템 및 용접 파라미터 정의
private SystemParameter _SystemParameter;
private static SequenceSetting _SequenceSetting;
public string EVENT_TRIGGER_SAVE_FILE = "EventTriggerSaveFile";
#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_USE_PAGE_CHANGE_INTERFACE
sb.AddDecision(SEQ_CHECK_SEQ_FINISH, CheckSeqFinish);
sb.AddAction(SEQ_MOVE_SCANNER, MoveScanner);
///// Event Q
sb.AddEventSender(SEQ_SEND_EVENT_SENDER, SendEvent);
sb.AddEventQ(SEQ_EVENT_Q_SAVE_FILE, 2);
sb.AddAction(SEQ_SAVE_IMAGES, SaveImagesEvent);
sb.AddAction(SEQ_COMPLETE, Complete);
// [Action] 초기 세팅
sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION]
// [Decision] SEQ 끝낼지 고민된다면 !
> sb[SEQ_CHECK_SEQ_FINISH] > sb[SEQ_MOVE_SCANNER]
> sb[SEQ_SEND_EVENT_SENDER].Send(EVENT_TRIGGER_SAVE_FILE)
> sb[SEQ_CHECK_SEQ_FINISH]);
// Scout Image Save Event Seq
sb.Flows(sb[SEQ_EVENT_Q_SAVE_FILE].On(EVENT_TRIGGER_SAVE_FILE) > sb[SEQ_SAVE_IMAGES]>sb.FlowFinal);
// Complete
sb.Flows(sb[SEQ_CHECK_SEQ_FINISH] > sb[SEQ_COMPLETE]>sb.Final);
///// Fork2 & Join
sb.OnForceError(OnForceError);
sb.OnStopped(OnStopped);
//sb.Draw("SeqEventQ.pdf");
return sb;
}
private void OnStopped(SequenceContext context)
{
Log.I("SeqEventQ Stop");
}
private void OnForceError(SequenceContext context, string arg2)
{
Log.I("SeqEventQ Force Error");
}
private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param)
{
Log.I("SeqEventQ Start");
_SystemParameter = context.GetSetting<SystemParameter>(CommonSettingIds.SystemParameter);
_SequenceSetting = context.GetSetting<SequenceSetting>(CommonSettingIds.Sequence);
_Scanner = context.GetLaserScanner();
if (!_Scanner.IsActivated)
{
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 추가
FovInfo _fovInfo = VisionRecipeManager.GetFovInfos().FirstOrDefault();
_PatternAgent = FovPatternAgentManager.GetAgent(_fovInfo.ToSubSysInfo());
List<PatternInfo> patterns = _PatternAgent.GetMainPatterns(_fovInfo);
_PatternInfo = patterns[0];
_CameraDisplay = CameraDisplayManager.GetDisplay(_fovInfo, eDisplayType.Pattern);
_CameraAgent = CameraAgentManager.GetCameraAgent(_fovInfo);
_FieldScanParams = FieldScanParams.GetInstance();
_RetryCount = 3;
_SeqCount = 0;
var mainPage = CommonHelper.GetMainPage();
return true;
}
private string CheckInitCondition(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
return SEQ_CHECK_SEQ_FINISH;
}
private string CheckSeqFinish(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
if (_SeqCount > 20) return SEQ_COMPLETE;
else return SEQ_MOVE_SCANNER;
}
private SequenceActionResult MoveScanner(SequenceContext context, string id, SequenceActionResult param)
{
if (_SeqCount % 2 == 1) _Scanner.JumpAbs(1, 5);
else _Scanner.JumpAbs(-10, 5);
Thread.Sleep(20);
//// 테스트를 위한 변경
/// ClearAllGraphic으로 변경하였음. GC는 종종 생성해보임.
_CameraDisplay.ClearMeasureGraphics();
_CameraDisplay.ClearTrainGraphics();
_CameraDisplay.ClearFindGraphics();
object image = null;
Log.D($"Image Grab Start");
_CameraAgent.StopLive();
_CameraAgent.GrabSync(_CameraDisplay, ref image);
Log.D($"Image Grab Complete");
Log.D($"Pattern Find Start");
_PatternResult = _PatternAgent.Find(_PatternInfo, image, _CameraDisplay);
_PatternAgent.Draw(_PatternInfo, _PatternResult, _CameraDisplay);
if (_PatternResult.Status == eFoundStatus.FoundOK)
{
_PatternAgent.Draw(_PatternInfo, _PatternResult, _CameraDisplay);
_SuccessVisionCompension = true;
Log.D($"Pattern Find Success!!");
}
else
{
_SuccessVisionCompension = false;
}
Log.D($"Pattern Find Complete");
// 성공하든 아니든 이미지를 남겨보자.
MIL_ID temp1 = MilEnvironment.CloneImage((MIL_ID)image);
MIL_ID temp2 = MilEnvironment.GetOverlayImage((IMilCameraDisplay)_CameraDisplay, temp1);
// Event로 넘겨줄 Param은 따로 없음.
SeqVisionData_Param seqParam = new SeqVisionData_Param
{
originalImageID = temp1,
overlayImageID = temp2,
IsSuccess = _SuccessVisionCompension
,
VisionData_Foler = _SequenceSetting.VisionFolderName
};
return SequenceAction.Ok(seqParam);
}
private object SendEvent(SequenceContext context, string id, SequenceActionResult param)
{
var seqInfoParam = param.Param as SeqVisionData_Param;
_SeqCount++;
return seqInfoParam;
}
private SequenceActionResult SaveImagesEvent(SequenceContext context, string id, SequenceActionResult param)
{
SeqVisionData_Param seqParam = param.Param as SeqVisionData_Param;
string SequenceSettingFilePath = seqParam.VisionData_Foler;
string SuccessStatus = seqParam.IsSuccess ? "OK" : "NG";
string CurrentTimeStamp = DateTime.Now.ToString("yyMMdd-HHmmss_fff");
string rawFileName = $"{SequenceSettingFilePath}\\Raw\\{SuccessStatus}\\{CurrentTimeStamp}.png";
string resultFileName = $"{SequenceSettingFilePath}\\Result\\{SuccessStatus}\\{CurrentTimeStamp}.png";
if (seqParam.originalImageID != MIL.M_NULL)
{
ImageUtil.SaveFieldScanImageJPG(seqParam.originalImageID, rawFileName, 10);
Log.D($"Update Q Raw Image Complete;{rawFileName}");
MilEnvironment.FreeImage(seqParam.originalImageID);
seqParam.originalImageID = MIL.M_NULL;
}
else
{
Log.E($"Update Q Raw Image Failed;{rawFileName};rawImage Is Null..");
}
if (seqParam.overlayImageID != MIL.M_NULL)
{
ImageUtil.SaveFieldScanImageJPG(seqParam.overlayImageID, resultFileName, 10);
Log.D($"Update Q Overlay Image Complete;{resultFileName}");
MilEnvironment.FreeImage(seqParam.overlayImageID);
seqParam.overlayImageID = MIL.M_NULL;
} else
{
Log.E($"Update Q Overlay Image Failed;{resultFileName};resultImage Is Null");
}
return SequenceAction.Ok();
}
private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param)
{
return SequenceAction.Ok();
}
public class SeqVisionData_Param
{
public MIL_ID originalImageID;
public MIL_ID overlayImageID;
public bool IsSuccess;
public string VisionData_Foler;
}
}
}