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

279 lines
8.8 KiB
C#

/*
* Copyright (c) 2025 LG Electronics Inc.
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
*/
using Aurora.Api;
using Aurora.Api.Devices;
using VisionCommon;
using VisionSequence.Pattern;
using Hermes;
using System.Collections.Generic;
using VisionSequence.Camera;
using VisionLight;
namespace VisionSequence.Aligner {
/// <summary>
/// 리뷰 타입
/// </summary>
public enum eReviewType {
/// <summary>공정 진행 전 수행</summary>
Preview,
/// <summary>공정 진행 후 수행</summary>
Review
}
/// <summary>
/// C1_MV 리뷰 시퀀스 파라미터
/// </summary>
public class ReviewSeqParams_C1_MV {
/// <summary>서브 시스템 키 정보</summary>
public SubSysInfo SubSysInfo { get; set; }
/// <summary>리뷰 타입</summary>
public eReviewType ReviewType { get; set; }
/// <summary>리뷰 포지션 (모터 절대 위치)</summary>
public List<Position> Positions { get; set; }
/// <summary>자재 정보</summary>
public MaterialInfo MaterialInfo { get; set; }
/// <summary>
/// C1_MV 얼라인 시퀀스 파라미터를 얻어온다.
/// </summary>
/// <param name="subSysInfo">서브 시스템 키 정보</param>
/// <param name="reviewType">리뷰 타입</param>
/// <param name="positions">리뷰 포지션 (모터 절대 위치)</param>
/// <param name="materialInfo">자재 정보</param>
public ReviewSeqParams_C1_MV(
SubSysInfo subSysInfo,
eReviewType reviewType,
List<Position> positions = null,
MaterialInfo materialInfo = null) {
this.SubSysInfo = subSysInfo;
this.ReviewType = reviewType;
this.Positions = positions;
this.MaterialInfo = materialInfo;
}
}
/// <summary>
/// CAM 1대 / N개 포지션 이동 / 리뷰 시퀀스
/// </summary>
public class ReviewSeq_C1_MV : SubSeqBase {
private readonly Logger LOG = new Logger(typeof(ReviewSeq_C1_MV).Name);
private ReviewSeqParams_C1_MV _Params;
private FovInfo _FovInfo;
private ImageManager _ImageManager = new ImageManager();
private int _CurPosIdx = 0;
private string _SeqName;
#region Sequence Id
private const string SEQ_ID_INIT = "INIT";
private const string SEQ_ID_CLEAR = "CLEAR";
private const string SEQ_ID_MOVE_FOV_POS = "MOVE_FOV_POS";
private const string SEQ_ID_GRAB = "GRAB";
private const string SEQ_ID_SAVE_IMAGE = "SAVE_IMAGE";
private const string SEQ_ID_CHECK_MOVE_FINISHED = "CHECK_MOVE_FINISHED";
private const string SEQ_ID_SEQ_COMPLETE = "SEQ_COMPLETE";
#endregion
/// <summary>
/// 생성자
/// </summary>
public ReviewSeq_C1_MV() {
}
private void SetActions(SequenceBuilder sb) {
SequenceBuilder grabSeqBuilder = SubSeqManager.CreateSubSeqBuilder(new GrabSeq(), typeof(GrabSeq).Name);
sb.AddAction(SEQ_ID_INIT, Init);
sb.AddAction(SEQ_ID_CLEAR, Clear);
sb.AddAction(SEQ_ID_MOVE_FOV_POS, MoveFovPos);
sb.AddAction(SEQ_ID_GRAB, Grab);
sb.AddAction(SEQ_ID_SAVE_IMAGE, SaveImage);
sb.AddDecision(SEQ_ID_CHECK_MOVE_FINISHED, CheckMoveFinished);
sb.AddAction(SEQ_ID_SEQ_COMPLETE, SeqComplete);
}
public override SequenceBuilder Builder(string seqName) {
_SeqName = seqName;
SequenceBuilder sb = new SequenceBuilder(1000);
SetActions(sb);
sb.OnStopped(OnStopped);
sb.OnForceError(OnForceError);
sb.Flows(
sb.Init
> sb[SEQ_ID_INIT]
> sb[SEQ_ID_CLEAR]
> sb[SEQ_ID_MOVE_FOV_POS]
> sb[SEQ_ID_GRAB]
> sb[SEQ_ID_SAVE_IMAGE]
> sb[SEQ_ID_CHECK_MOVE_FINISHED]
> sb[SEQ_ID_SEQ_COMPLETE]
);
sb.Flows(
sb[SEQ_ID_CHECK_MOVE_FINISHED]
> sb[SEQ_ID_MOVE_FOV_POS]
);
sb.Flows(
sb[SEQ_ID_SEQ_COMPLETE]
> sb.Final
);
#if SEQ_DRAW
sb.Draw($"{GetType().Name}.pdf");
#endif
return sb;
}
private SequenceActionResult Init(
SequenceContext context,
string id,
SequenceActionResult param) {
if (param.Param != null) {
_Params = param.Param as ReviewSeqParams_C1_MV;
}
else {
LOG.E($"Param is null.");
return null;
}
_FovInfo = VisionRecipeManager.GetFovInfo(_Params.SubSysInfo, eFovId.Fov1); // 리뷰 시퀀스는 Fov가 오직 한 개만 존재
return SequenceAction.Ok();
}
private SequenceActionResult Clear(
SequenceContext context,
string id,
SequenceActionResult param) {
ClearCurPosIdx();
return SequenceAction.Ok();
}
private SequenceActionResult MoveFovPos(
SequenceContext context,
string id,
SequenceActionResult param) {
if (EquipAdapter.Instance.EquipMode.IsSimulMode()) {
return SequenceAction.Ok();
}
int res = EquipAdapter.Instance.TeachingMotionManager.AbsMove(_FovInfo, _Params.Positions[_CurPosIdx]);
if (res == E1.OK) {
ApplyGrabDelay(_Params.SubSysInfo);
return SequenceAction.Ok();
}
else {
return SequenceAction.Error(E2.ABORTED);
}
}
private SequenceActionResult Grab(
SequenceContext context,
string id,
SequenceActionResult param) {
var cameraAgent = CameraAgentManager.GetCameraAgent(_FovInfo);
var milCameraDisplay = CameraDisplayManager.GetDisplay(_FovInfo);
var lightParams = LightHub.Instance.GetLightParams(VisionRecipeManager.GetCamRecipe(_FovInfo).CamId);
var grabImage = GrabFindSeqUtil.GetProcGrabImage(_FovInfo, new LightInfo() { LightParams = lightParams });
var image = (object)grabImage;
cameraAgent.GrabSync(milCameraDisplay, ref image);
return SequenceAction.Ok(grabImage);
}
private SequenceActionResult SaveImage(
SequenceContext context,
string id,
SequenceActionResult param) { // Param : GrabImage
object grabImage = param.Param;
string dirPath = GetDirPath();
string fileName = GetFileName();
_ImageManager.SaveImage(dirPath, fileName, grabImage);
return SequenceAction.Ok();
}
private string GetDirPath() {
List<string> subDirNames = ImagePathManager.Instance.GetSubDirNames(_FovInfo, _Params.MaterialInfo);
subDirNames.Add("Review");
return ImagePathManager.Instance.GetDirPath(subDirNames);
}
private string GetFileName() {
var status = _Params.ReviewType.ToString();
var fileNameWithMaterialInfo = ImagePathManager.Instance.
GetFileNameWithMaterialInfo(_Params.SubSysInfo.SubSysName, _FovInfo.FovName, status, _Params.MaterialInfo);
var fileNameWithDateTime = ImagePathManager.Instance.GetFileNameWithDataTime(fileNameWithMaterialInfo);
return $"Pos_{_CurPosIdx}" + "_" + fileNameWithDateTime;
}
private string CheckMoveFinished(
SequenceContext context,
string id,
ICollection<string> branches,
SequenceActionResult param) {
if (_CurPosIdx == _Params.Positions.Count - 1) {
return SEQ_ID_SEQ_COMPLETE;
}
else {
IncreaseCurPosIdx();
return SEQ_ID_MOVE_FOV_POS;
}
}
private SequenceActionResult SeqComplete(
SequenceContext context,
string id,
SequenceActionResult param) {
return SequenceAction.Ok();
}
private void ClearCurPosIdx() {
_CurPosIdx = 0;
}
private void IncreaseCurPosIdx() {
_CurPosIdx++;
}
void OnStopped(
SequenceContext context) {
LOG.I($"{context.SequenceId} - STOP Handler");
HandleAbnormalFinish(context);
}
void OnForceError(
SequenceContext context, string id) {
LOG.E($"{context.SequenceId} - FORCE ERROR Handler");
HandleAbnormalFinish(context);
}
void HandleAbnormalFinish(
SequenceContext context) {
}
}
}