256 lines
7.4 KiB
C#
256 lines
7.4 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using MainShell.Common;
|
|||
|
|
using SemiconductorVisionAlgorithm.SemiParams;
|
|||
|
|
|
|||
|
|
namespace MainShell.Motion
|
|||
|
|
{
|
|||
|
|
#region 数据结构
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 逼近对位的单轴配置
|
|||
|
|
/// </summary>
|
|||
|
|
public class ApproachAlignmentAxis
|
|||
|
|
{
|
|||
|
|
public ApproachAlignmentAxis(string axisName, double toleranceValue)
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrWhiteSpace(axisName))
|
|||
|
|
{
|
|||
|
|
throw new ArgumentNullException(nameof(axisName));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (toleranceValue <= 0)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentException("Tolerance value must be positive.", nameof(toleranceValue));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AxisName = axisName;
|
|||
|
|
ToleranceValue = toleranceValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 轴名称(如 "X", "Y")
|
|||
|
|
/// </summary>
|
|||
|
|
public string AxisName { get; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 该轴的允许误差(单位与轴位置一致,通常为 mm)
|
|||
|
|
/// </summary>
|
|||
|
|
public double ToleranceValue { get; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 轴的描述信息(用于日志)
|
|||
|
|
/// </summary>
|
|||
|
|
public string Description { get; set; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public enum CenterRecognitionType
|
|||
|
|
{
|
|||
|
|
Template,
|
|||
|
|
EdgeCircle
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class CenterRecognitionParameters
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
|
|||
|
|
public CenterRecognitionParameters()
|
|||
|
|
{
|
|||
|
|
MinScore = 0.8d;
|
|||
|
|
TemplatePath = "Template/Default";
|
|||
|
|
Type = CenterRecognitionType.Template;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public string TemplatePath { get; set; }
|
|||
|
|
|
|||
|
|
public double MinScore { get; set; }
|
|||
|
|
|
|||
|
|
public bool UseRoi { get; set; }
|
|||
|
|
|
|||
|
|
public string RoiName { get; set; }
|
|||
|
|
|
|||
|
|
public CenterRecognitionType Type { get; set; }
|
|||
|
|
|
|||
|
|
public Rectangle1 rectangle { get; set; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 逼近对位请求参数
|
|||
|
|
/// </summary>
|
|||
|
|
public class ApproachAlignmentRequest
|
|||
|
|
{
|
|||
|
|
private IReadOnlyList<ApproachAlignmentAxis> _axes;
|
|||
|
|
|
|||
|
|
public ApproachAlignmentRequest(IEnumerable<ApproachAlignmentAxis> axes, CameraType camera = CameraType.TopPositionCamera)
|
|||
|
|
{
|
|||
|
|
if (axes == null)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentNullException(nameof(axes));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var axesList = axes.ToList();
|
|||
|
|
if (axesList.Count == 0)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentException("At least one axis is required.", nameof(axes));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Axes = axesList.AsReadOnly();
|
|||
|
|
Camera = camera;
|
|||
|
|
MaxIterations = 5;
|
|||
|
|
MoveTimeoutMilliseconds = 30000;
|
|||
|
|
RecognitionTimeoutMilliseconds = 100000;
|
|||
|
|
RecognitionParameters = new CenterRecognitionParameters();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 逼近轴配置列表
|
|||
|
|
/// </summary>
|
|||
|
|
public IReadOnlyList<ApproachAlignmentAxis> Axes
|
|||
|
|
{
|
|||
|
|
get { return _axes; }
|
|||
|
|
private set { _axes = value; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 相机标识(用于采图和识别)
|
|||
|
|
/// </summary>
|
|||
|
|
public CameraType Camera { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 最大循环次数(默认 5)
|
|||
|
|
/// </summary>
|
|||
|
|
public int MaxIterations { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 轴运动的超时时间(毫秒,默认 30000)
|
|||
|
|
/// </summary>
|
|||
|
|
public int MoveTimeoutMilliseconds { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 识别中心的超时时间(毫秒,默认 10000)
|
|||
|
|
/// </summary>
|
|||
|
|
public int RecognitionTimeoutMilliseconds { get; set; }
|
|||
|
|
|
|||
|
|
public CenterRecognitionParameters RecognitionParameters { get; set; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 逼近对位的结果
|
|||
|
|
/// </summary>
|
|||
|
|
public class ApproachAlignmentResult
|
|||
|
|
{
|
|||
|
|
public ApproachAlignmentResult()
|
|||
|
|
{
|
|||
|
|
FinalErrors = new Dictionary<string, double>();
|
|||
|
|
FinalAxisPositions = new Dictionary<string, double>();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 是否成功(所有轴都在允许误差内)
|
|||
|
|
/// </summary>
|
|||
|
|
public bool Succeeded { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 实际完成的迭代次数
|
|||
|
|
/// </summary>
|
|||
|
|
public int CompletedIterations { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 最终的每轴误差(轴名 -> 误差值)
|
|||
|
|
/// </summary>
|
|||
|
|
public Dictionary<string, double> FinalErrors { get; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 最终的轴位置(轴名 -> 位置值,用于调试)
|
|||
|
|
/// </summary>
|
|||
|
|
public Dictionary<string, double> FinalAxisPositions { get; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 异常信息(如果失败)
|
|||
|
|
/// </summary>
|
|||
|
|
public Exception Exception { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取出错消息
|
|||
|
|
/// </summary>
|
|||
|
|
public string Message => Exception?.Message ?? (Succeeded ? "Approach alignment succeeded." : "Approach alignment failed.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 坐标转换结果
|
|||
|
|
/// </summary>
|
|||
|
|
public class CoordinateTransformResult
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 转换后的目标点坐标
|
|||
|
|
/// </summary>
|
|||
|
|
public System.Windows.Point TargetPoint { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 转换是否成功
|
|||
|
|
/// </summary>
|
|||
|
|
public bool Succeeded { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 错误或警告信息
|
|||
|
|
/// </summary>
|
|||
|
|
public string Message { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 转换过程中的异常
|
|||
|
|
/// </summary>
|
|||
|
|
public Exception Exception { get; set; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 接口定义
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 中心识别器接口:通过图像算法识别目标中心
|
|||
|
|
/// </summary>
|
|||
|
|
public interface ICenterRecognizer
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 识别图像中心点
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="camera">相机标识(用于指定采图源)</param>
|
|||
|
|
/// <param name="timeoutMilliseconds">识别超时时间(毫秒)</param>
|
|||
|
|
/// <param name="cancellationToken">取消令牌</param>
|
|||
|
|
/// <returns>中心点 (CenterX, CenterY) 或 null 表示识别失败</returns>
|
|||
|
|
Task<(double CenterX, double CenterY)?> RecognizeCenterAsync(
|
|||
|
|
CameraType camera,
|
|||
|
|
int timeoutMilliseconds,
|
|||
|
|
CancellationToken cancellationToken = default(CancellationToken));
|
|||
|
|
|
|||
|
|
Task<(double CenterX, double CenterY)?> RecognizeCenterAsync(
|
|||
|
|
CameraType camera,
|
|||
|
|
int timeoutMilliseconds,
|
|||
|
|
CenterRecognitionParameters parameters,
|
|||
|
|
CancellationToken cancellationToken = default(CancellationToken));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 坐标转换器接口:将图像中心点转换为各轴的目标位置
|
|||
|
|
/// </summary>
|
|||
|
|
public interface ICoordinateTransformer
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 将图像中心点坐标转换为轴位置
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="centerX">图像中心 X 坐标</param>
|
|||
|
|
/// <param name="centerY">图像中心 Y 坐标</param>
|
|||
|
|
/// <param name="axes">目标轴列表</param>
|
|||
|
|
/// <returns>转换结果,包含各轴的目标位置</returns>
|
|||
|
|
Task<CoordinateTransformResult> TransformAsync(
|
|||
|
|
System.Windows. Point ruler, System.Windows.Point pixel, string cameraName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|