2026-01-26 18:56:53 +09:00

327 lines
13 KiB
C#

/*
* Copyright (c) 2025 LG Electronics Inc.
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
*/
using PropertyTools.DataAnnotations;
using System;
namespace VisionCommon {
public enum eAlignId {
None = -1,
Align1 = 0, Align2, Align3, Align4, Align5,
Max
}
public enum eAlignAlgorithm {
AVG = 0,
ICP
}
public class AlignRecipe : ICloneCopy<AlignRecipe> {
public eAlignId AlignId { get; set; } = eAlignId.Align1;
public string AlignName { get; set; } = eAlignId.Align1.ToString();
public AlignThetaOrigin AlignThetaOrigin { get; set; } = new AlignThetaOrigin();
public AlignTgtDist AlignTgtDist { get; set; } = new AlignTgtDist(); // Src와 Tgt간에 도면 거리 및 각도 (X/Y/T)
public AlignRetry AlignRetry { get; set; } = new AlignRetry();
public AlignOffset AlignOffset { get; set; } = new AlignOffset();
public AlignLimit AlignLimit { get; set; } = new AlignLimit();
public ProcParams ProcParams { get; set; } = new ProcParams();
public InspParams InspParams { get; set; } = new InspParams();
public AlignRecipe Clone() {
return ((ICloneable)this).Clone() as AlignRecipe;
}
object ICloneable.Clone() {
var cloneObj = new AlignRecipe();
CopyTo(cloneObj);
return cloneObj;
}
public void CopyTo(AlignRecipe target) {
target.AlignId = this.AlignId;
target.AlignName = this.AlignName;
target.AlignThetaOrigin = this.AlignThetaOrigin;
target.AlignTgtDist = this.AlignTgtDist.Clone() as AlignTgtDist;
target.AlignRetry = this.AlignRetry.Clone() as AlignRetry;
target.AlignOffset = this.AlignOffset.Clone() as AlignOffset;
target.AlignLimit = this.AlignLimit.Clone() as AlignLimit;
target.ProcParams = this.ProcParams.Clone() as ProcParams;
target.InspParams = this.InspParams.Clone() as InspParams;
}
}
public class AlignThetaOrigin : ICloneable {
public StaticPoint Offset { get; set; } = new StaticPoint(); // [mm]
public object Clone() {
return new AlignThetaOrigin() {
Offset = this.Offset.Clone() as StaticPoint
};
}
}
public class AlignTgtDist : ICloneable {
public bool Enabled { get; set; } = false;
[Converter(typeof(CoordUnitValueConverter))]
public double DistX { get; set; } = 0; // 단위 : mm
[Converter(typeof(CoordUnitValueConverter))]
public double DistY { get; set; } = 0;
public double DistT { get; set; } = 0; // 단위 : deg
public object Clone() {
return new AlignTgtDist() {
Enabled = this.Enabled,
DistX = this.DistX,
DistY = this.DistY,
DistT = this.DistT
};
}
}
public class AlignRetry : ICloneable {
public bool Enabled { get; set; } = false;
[Converter(typeof(CoordUnitValueConverter))]
public double RangeX { get; set; } = 0.5; // 단위 : mm
[Converter(typeof(CoordUnitValueConverter))]
public double RangeY { get; set; } = 0.5;
public double RangeT { get; set; } = 0.2; // 단위 : deg
[SelectorStyle(SelectorStyle.ComboBox)]
public eRetryCnt RetryCnt { get; set; } = eRetryCnt.Cnt_2;
public object Clone() {
return new AlignRetry() {
Enabled = this.Enabled,
RangeX = this.RangeX,
RangeY = this.RangeY,
RangeT = this.RangeT,
RetryCnt = this.RetryCnt
};
}
}
public class AlignOffset : ICloneable {
public bool Enabled { get; set; } = false;
[Converter(typeof(CoordUnitValueConverter))]
public double OffsetX { get; set; } = 0; // 단위 : mm
[Converter(typeof(CoordUnitValueConverter))]
public double OffsetY { get; set; } = 0;
public double OffsetT { get; set; } = 0; // 단위 : deg
public object Clone() {
return new AlignOffset() {
Enabled = this.Enabled,
OffsetX = this.OffsetX,
OffsetY = this.OffsetY,
OffsetT = this.OffsetT
};
}
}
public class AlignLimit : ICloneable {
public bool Enabled { get; set; } = false;
[Converter(typeof(CoordUnitValueConverter))]
public double LimitX { get; set; } = 3; // 단위 : mm
[Converter(typeof(CoordUnitValueConverter))]
public double LimitY { get; set; } = 3;
public double LimitT { get; set; } = 1; // 단위 : deg
public object Clone() {
return new AlignLimit() {
Enabled = this.Enabled,
LimitX = this.LimitX,
LimitY = this.LimitY,
LimitT = this.LimitT
};
}
}
public class ProcParams : ICloneable {
/// <summary>
/// Grab & Find Sequence에서 Light retry 관련된 Parameters
/// </summary>
[Browsable(false)]
public LightRetryParams LightRetryParams { get; set; } = new LightRetryParams();
public bool ForceOkEnabled { get; set; } = false;
public bool FirstTeachingMoveEnabled { get; set; } = false; // 첫 Fov의 Teaching 위치로 이동유무
public bool AlignDeltaMoveEnabled { get; set; } = false; // 얼라인시 RelMove 사용유무
public bool FixedLineIntersections { get; set; } = false; // C2_F4 or C4_F4 라인 교점 얼라인시, 이웃한 FOV들 간에 상관관계를 이용하여 라인 교점을 보상
[SelectorStyle(SelectorStyle.ComboBox)]
public eProcFovType ProcFovType { get; set; } = eProcFovType.C1_F1_M2C;
[SelectorStyle(SelectorStyle.ComboBox)]
public eAlignMode AlignMode { get; set; } = eAlignMode.Stage;
public eAlignAlgorithm AlignAlgorithm { get; set; } = eAlignAlgorithm.AVG;
public eAlignAxis AlignAxis { get; set; } = eAlignAxis.XYT;
public object Clone() {
return new ProcParams() {
LightRetryParams = this.LightRetryParams.Clone() as LightRetryParams,
ForceOkEnabled = this.ForceOkEnabled,
FirstTeachingMoveEnabled = this.FirstTeachingMoveEnabled,
AlignDeltaMoveEnabled = this.AlignDeltaMoveEnabled,
FixedLineIntersections = this.FixedLineIntersections,
ProcFovType = this.ProcFovType,
AlignMode = this.AlignMode,
AlignAlgorithm = this.AlignAlgorithm,
AlignAxis = this.AlignAxis
};
}
public static int GetFovNum(eProcFovType procFovType) {
switch (procFovType) {
case eProcFovType.C1_F1_M2C:
case eProcFovType.C1_F1_M2R:
case eProcFovType.C1_F1_AP2_A2:
case eProcFovType.C1_F1_SPN_AN:
return 1;
case eProcFovType.C2_F2:
case eProcFovType.C1_F2_MV:
return 2;
case eProcFovType.C4_F4:
case eProcFovType.C2_F4_MV:
case eProcFovType.C1_F4_MV:
return 4;
default:
return 0;
}
}
public static int GetProcNum(eProcFovType procFovType) {
switch (procFovType) {
case eProcFovType.C1_F1_M2C:
case eProcFovType.C2_F2:
case eProcFovType.C1_F2_MV:
case eProcFovType.C4_F4:
case eProcFovType.C2_F4_MV:
case eProcFovType.C1_F4_MV:
case eProcFovType.C1_F1_SPN_AN:
return 1;
case eProcFovType.C1_F1_M2R:
case eProcFovType.C1_F1_AP2_A2:
return 2;
default:
return 0;
}
}
}
public enum eLightRetryMode
{
Ratio_OneWay,
Step_OneWay,
Ratio_Swing,
Step_Swing
}
public class LightRetryParams : ICloneable
{
/// <summary>
/// Light Retry 사용 여부
/// </summary>
public bool LightRetryEnabled { get; set; } = false;
/// <summary>
/// Light Retry Mode ( Step Mode & Ratio Mode )
/// </summary>
[SelectorStyle(SelectorStyle.ComboBox)]
public eLightRetryMode LightRetryMode { get; set; } = eLightRetryMode.Ratio_Swing;
/// <summary>
/// Light Retry Value ( 모드 적용 시 움직일 Step 값 )
/// </summary>
public int LightRetryStep { get; set; }
/// <summary>
/// Light Retry Value ( 모드 적용 시 움직일 Step 값 )
/// </summary>
[DisplayName("LightRetryRatio(%)")]
public double LightRetryRatio { get; set; }
/// <summary>
/// Light Retry Step으로 반복 할 횟수
/// </summary>
public int LightRetryCount { get; set; }
public object Clone()
{
return new LightRetryParams()
{
LightRetryEnabled = this.LightRetryEnabled,
LightRetryMode = this.LightRetryMode,
LightRetryStep = this.LightRetryStep,
LightRetryCount = this.LightRetryCount
};
}
}
public class InspParams : ICloneable {
public bool CodeEnabled { get; set; } = false; // Barcode, QRCode, DataMatrix 검사 사용유무
public bool PatternExistEnabled { get; set; } = false; // 패턴 유무 검사 사용유무
public PatternDistanceParam PatternDistanceParam { get; set; } = new PatternDistanceParam(); // 패턴 간에 거리 측정
public object Clone() {
return new InspParams() {
CodeEnabled = this.CodeEnabled,
PatternExistEnabled = this.PatternExistEnabled,
PatternDistanceParam = this.PatternDistanceParam.Clone() as PatternDistanceParam
};
}
}
public class PatternDistanceParam : ICloneable {
public bool Enabled { get; set; } = false;
[Converter(typeof(CoordUnitValueConverter))]
public double ErrRange { get; set; } = 1;
public object Clone() {
return new PatternDistanceParam() {
Enabled = this.Enabled,
ErrRange = this.ErrRange
};
}
}
public enum eRetryCnt {
Cnt_1 = 1, // 얼라인 리트라이 1회
Cnt_2 = 2, // 얼라인 리트라이 2회
Cnt_3 = 3, // 얼라인 리트라이 3회
Cnt_4 = 4, // 얼라인 리트라이 4회
Cnt_5 = 5 // 얼라인 리트라이 5회
}
public enum eProcFovType {
C1_F1_M2C, // CAM 1대 / FOV 1개 / 포지션 이동 (X) / 1 Point Align / 1 MeasurePattern to 1 CenterPos
C1_F1_M2R, // CAM 1대 / FOV 1개 / 포지션 이동 (X) / 1 Point Align / 1 MeasurePattern to 1 ReferencePattern
C1_F2_MV, // CAM 1대 / FOV 2개 / 포지션 이동 (O) / 2 Point Align / 2 MeasurePatterns to 2 ReferencePatterns
C2_F2, // CAM 2대 / FOV 2개 / 포지션 이동 (X) / 2 Point Align / 2 MeasurePatterns to 2 ReferencePatterns
C1_F4_MV, // CAM 1대 / FOV 4개 / 포지션 이동 (O) / 4 Point Align / 4 MeasurePatterns to 4 ReferencePatterns
C2_F4_MV, // CAM 2대 / FOV 4개 / 포지션 이동 (O) / 4 Point Align / 4 MeasurePatterns to 4 ReferencePatterns
C4_F4, // CAM 4대 / FOV 4개 / 포지션 이동 (X) / 4 Point Align / 4 MeasurePatterns to 4 ReferencePatterns
C1_F1_AP2_A2, // CAM 1대 / FOV 1개 / 서로 다른(Another) 패턴 2개 / 얼라인 2개 / 1 Point Align 2개 / MeasurePattern to (Center + Target Offset)
C1_F1_SPN_AN, // CAM 1대 / FOV 1개 / 서로 같은(Same) 패턴 N개 / 얼라인 N개 / 1 Point Align N개 / MeasurePattern to (Center + Target Offset)
}
/// <summary>
/// 얼라인 모드(알고리즘)를 정의
/// </summary>
public enum eAlignMode {
/// <summary>스테이지 얼라인 (스테이지 또는 자재가 이동)</summary>
Stage,
/// <summary>헤드 얼라인 (카메라, 레이저 등이 이동)</summary>
Head,
/// <summary>장비에서 직접 구현하기 위한 모드</summary>
MachineAlign_A,
/// <summary>장비에서 직접 구현하기 위한 모드</summary>
MachineAlign_B,
}
/// <summary>
/// 얼라인 계산 축(DOF)
/// 활성화한 축의 보정량만 계산된다.
/// 비활성화된 축의 보정량은 0이다.
/// </summary>
public enum eAlignAxis {
X = 0x01,
Y = 0x02,
T = 0x04,
XY = X | Y,
XT = X | T,
YT = Y | T,
XYT = X | Y | T
}
}