添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,300 @@
|
||||
using MainShell.AlgorithmCalib.Common;
|
||||
using MainShell.AlgorithmCalib.Model;
|
||||
using MainShell.Common;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Log;
|
||||
using MainShell.Motion;
|
||||
using SemiconductorVisionAlgorithm.SemiParams;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SemiPoint = SemiconductorVisionAlgorithm.SemiParams.Point;
|
||||
|
||||
namespace MainShell.AlgorithmCalib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 融合对位处理器
|
||||
/// 3步对位流程:
|
||||
/// 1. 抓Pad点(框选ROI识别Pad坐标)
|
||||
/// 2. Die网格飞拍(首点+参数 → 蛇形扫描获取x*y个Die点)
|
||||
/// 3. 对位验证(选择一个Die点 → 与Pad点对位 → 输出结果)
|
||||
/// </summary>
|
||||
public class FusionAlignProcessor
|
||||
{
|
||||
private readonly FusionCalibMotionService _motionService;
|
||||
private readonly HardwareManager _hardware;
|
||||
private readonly FusionCalibModuleItem _moduleItem;
|
||||
private readonly ApproachAlignmentService _approachAlignmentService;
|
||||
|
||||
// 飞拍参数
|
||||
private double _flyScanStartX;
|
||||
private double _flyScanStartY;
|
||||
private int _flyScanXCount;
|
||||
private int _flyScanYCount;
|
||||
private double _flyScanStep;
|
||||
|
||||
public event EventHandler<CalibrationProgressEventArgs> ProgressChanged;
|
||||
private readonly Func<Rectangle1> _roiRectProvider; // ROI 提供者委托
|
||||
|
||||
|
||||
public FusionAlignProcessor(
|
||||
FusionCalibMotionService motionService,
|
||||
HardwareManager hardware,
|
||||
FusionCalibModuleItem moduleItem,
|
||||
Func<Rectangle1> roiRectProvider)
|
||||
{
|
||||
_motionService = motionService;
|
||||
_hardware = hardware;
|
||||
_moduleItem = moduleItem;
|
||||
_approachAlignmentService = IoC.Get<ApproachAlignmentService>();
|
||||
_roiRectProvider = roiRectProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置飞拍参数
|
||||
/// </summary>
|
||||
public void SetFlyScanParams(double startX, double startY, int xCount, int yCount, double step)
|
||||
{
|
||||
_flyScanStartX = startX;
|
||||
_flyScanStartY = startY;
|
||||
_flyScanXCount = xCount;
|
||||
_flyScanYCount = yCount;
|
||||
_flyScanStep = step;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 步骤1:抓Pad点
|
||||
/// 框选ROI区域,识别Pad目标点坐标(pad运动系:X1,Y2)
|
||||
/// </summary>
|
||||
public async Task CapturePadPointAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
ReportProgress("抓Pad点...", 1, 3);
|
||||
|
||||
bool success = await ApproachAtPointAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (!success)
|
||||
{
|
||||
throw new InvalidOperationException($"逼近对齐失败");
|
||||
}
|
||||
|
||||
_moduleItem.PadRealX = _hardware.Axis_X1.State.ActualPos;
|
||||
_moduleItem.PadRealY = _hardware.Axis_Y2.State.ActualPos;
|
||||
|
||||
"抓Pad点完成".LogInfo();
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 步骤2a:抓Die首点
|
||||
/// 框选ROI区域,识别Die首点坐标(die运动系:X2,Y1)
|
||||
/// </summary>
|
||||
public async Task CaptureDieFirstPointAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await Task.Run(async() =>
|
||||
{
|
||||
ReportProgress("抓Die首点...", 1, 3);
|
||||
|
||||
bool success = await ApproachAtPointAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (!success)
|
||||
{
|
||||
throw new InvalidOperationException($"逼近对齐失败");
|
||||
}
|
||||
|
||||
_moduleItem.DieRealX = _hardware.Axis_X2.State.ActualPos;
|
||||
_moduleItem.DieRealY = _hardware.Axis_Y1.State.ActualPos;
|
||||
|
||||
"抓Die首点完成".LogInfo();
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 步骤2b:Die网格飞拍
|
||||
/// 以首点为起点,按step和count执行蛇形网格飞拍,获取x*y个Die点
|
||||
/// </summary>
|
||||
public async Task ExecuteDieGridFlyScanAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await Task.Run(async() =>
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
int totalPoints = _flyScanXCount * _flyScanYCount;
|
||||
int captured = 0;
|
||||
|
||||
ReportProgress($"开始飞拍,网格{_flyScanXCount}×{_flyScanYCount},共{totalPoints}点...", 0, totalPoints);
|
||||
|
||||
// 清空之前的数据
|
||||
_moduleItem.DieGridPoints = new List<Tuple<int, int, SemiPoint>>();
|
||||
|
||||
for (int row = 0; row < _flyScanYCount; row++)
|
||||
{
|
||||
// 蛇形扫描:偶数行从左到右,奇数行从右到左
|
||||
for (int col = 0; col < _flyScanXCount; col++)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
int actualCol = row % 2 == 0 ? col : (_flyScanXCount - 1 - col);
|
||||
|
||||
// 计算目标位置
|
||||
double targetX2 = _flyScanStartX + actualCol * _flyScanStep;
|
||||
double targetY1 = _flyScanStartY + row * _flyScanStep;
|
||||
|
||||
// 移动轴到目标位置
|
||||
_motionService.MoveWsAvoidance(targetX2, targetY1);
|
||||
|
||||
// 等待运动完成
|
||||
Thread.Sleep(200);
|
||||
|
||||
bool success = await ApproachAtPointAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (!success)
|
||||
{
|
||||
throw new InvalidOperationException($"逼近对齐失败");
|
||||
}
|
||||
|
||||
// 读取当前位置
|
||||
double currentX2 = _hardware.Axis_X2.State.ActualPos;
|
||||
double currentY1 = _hardware.Axis_Y1.State.ActualPos;
|
||||
|
||||
|
||||
SemiPoint point = new SemiPoint(currentX2, currentY1);
|
||||
_moduleItem.DieGridPoints.Add(Tuple.Create(row, actualCol, point));
|
||||
|
||||
captured++;
|
||||
ReportProgress($"飞拍中... ({captured}/{totalPoints})", captured, totalPoints);
|
||||
}
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
$"Die网格飞拍完成,共{captured}点,耗时{sw.ElapsedMilliseconds}ms".LogInfo();
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 步骤3:执行对位
|
||||
/// 用户选择网格中的一个Die点(row, col),与Pad点执行对位
|
||||
/// 对位流程:Die X对齐Pad → Pad Y对齐Die → X2补偿
|
||||
/// </summary>
|
||||
public async Task ExecuteAlignAsync(CancellationToken ct, int selectedRow, int selectedCol)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
ReportProgress("执行对位...", 1, 6);
|
||||
|
||||
// 从网格中找到选中的Die点
|
||||
SemiPoint selectedDie = null;
|
||||
foreach (var pt in _moduleItem.DieGridPoints)
|
||||
{
|
||||
if (pt.Item1 == selectedRow && pt.Item2 == selectedCol)
|
||||
{
|
||||
selectedDie = pt.Item3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedDie == null)
|
||||
{
|
||||
throw new Exception($"未找到Die点[{selectedRow},{selectedCol}]");
|
||||
}
|
||||
|
||||
// 使用选中的Die点作为对位基准
|
||||
_moduleItem.DieRealX = selectedDie.X;
|
||||
_moduleItem.DieRealY = selectedDie.Y;
|
||||
_moduleItem.PadRealX = _moduleItem.PadRulerX;
|
||||
_moduleItem.PadRealY = _moduleItem.PadRulerY;
|
||||
|
||||
ReportProgress("Die X方向对齐Pad...", 2, 6);
|
||||
|
||||
// === 步骤3a:Die X方向对齐Pad ===
|
||||
// 查die融合表,将Die的X方向对齐到Pad的X方向
|
||||
// 移动X2,Y1 → Y1会产生少许偏移
|
||||
//
|
||||
// TODO: 接入JM1融合表查询
|
||||
// SemiPoint dieReal = new SemiPoint(_moduleItem.DieRealX, _moduleItem.DieRealY);
|
||||
// SemiPoint padReal = new SemiPoint(_moduleItem.PadRealX, _moduleItem.PadRealY);
|
||||
// SemiJM1Manager.Instance.get_ws_pos_die(dieReal, padReal, out SemiPoint wsTarget);
|
||||
//
|
||||
// 暂时模拟:使用Die坐标作为目标
|
||||
double wsTargetX = _moduleItem.DieRealX;
|
||||
double wsTargetY = _moduleItem.DieRealY;
|
||||
|
||||
_motionService.MoveWsAvoidance(wsTargetX, wsTargetY);
|
||||
|
||||
// 读取此时Y1位置(已产生偏移)
|
||||
double currentY1 = _hardware.Axis_Y1.State.ActualPos;
|
||||
|
||||
ReportProgress("Pad Y方向对齐Die...", 3, 6);
|
||||
|
||||
// === 步骤3b:Pad Y方向对齐Die ===
|
||||
// 根据当前Y1值,查pad融合表,计算X1,Y2目标位置
|
||||
// 移动X1,Y2 → X1会产生少许偏移
|
||||
//
|
||||
// TODO: 接入pad融合表查询
|
||||
// SemiPoint padTarget = FusionTableLookupPad(padReal, currentY1);
|
||||
//
|
||||
// 暂时模拟
|
||||
double padTargetX = _moduleItem.PadRealX;
|
||||
double padTargetY = _moduleItem.PadRealY;
|
||||
|
||||
_motionService.MovePhsAvoidance(padTargetX, padTargetY);
|
||||
|
||||
// 读取此时X1位置(已产生偏移)
|
||||
double currentX1 = _hardware.Axis_X1.State.ActualPos;
|
||||
|
||||
ReportProgress("X2补偿...", 4, 6);
|
||||
|
||||
// === 步骤3c:X2补偿 ===
|
||||
// X2跟上X1的移动量
|
||||
double x1Delta = currentX1 - _moduleItem.PadRulerX;
|
||||
double x2Target = wsTargetX + x1Delta;
|
||||
|
||||
_motionService.SafeMove(_hardware.Axis_X2, x2Target);
|
||||
|
||||
// 记录结果
|
||||
_moduleItem.AlignResultX = currentX1;
|
||||
_moduleItem.AlignResultY = currentY1;
|
||||
_moduleItem.AlignResultX2 = x2Target;
|
||||
|
||||
ReportProgress("对位完成", 5, 6);
|
||||
$"对位完成: Die[{selectedRow},{selectedCol}] → Pad, X1={currentX1:F4}, Y1={currentY1:F4}, X2 ={ x2Target: F4}".LogInfo();
|
||||
}, ct);
|
||||
}
|
||||
|
||||
private void ReportProgress(string message, int current, int total)
|
||||
{
|
||||
ProgressChanged?.Invoke(this, new CalibrationProgressEventArgs
|
||||
{
|
||||
Message = message,
|
||||
Current = current,
|
||||
Total = total
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逼近对齐
|
||||
/// </summary>
|
||||
private async Task<bool> ApproachAtPointAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Rectangle1 roiRect = _roiRectProvider?.Invoke();
|
||||
var request = new ApproachAlignmentRequest(
|
||||
axes: new[]
|
||||
{
|
||||
new ApproachAlignmentAxis(_hardware.Axis_X2.Name, 0.005),
|
||||
new ApproachAlignmentAxis(_hardware.Axis_Y1.Name, 0.005)
|
||||
},
|
||||
camera: CameraType.TopPositionCamera)
|
||||
{
|
||||
MaxIterations = 3,
|
||||
RecognitionTimeoutMilliseconds = 5000,
|
||||
RecognitionParameters = new CenterRecognitionParameters()
|
||||
{
|
||||
Type = CenterRecognitionType.EdgeCircle,
|
||||
rectangle = roiRect
|
||||
}
|
||||
};
|
||||
|
||||
var result = await _approachAlignmentService.ApproachAlignmentAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
return result.Succeeded;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Motion;
|
||||
using MaxwellFramework.Core.Attributes;
|
||||
using MwFramework.Device;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.AlgorithmCalib.Service
|
||||
{
|
||||
[Singleton]
|
||||
public class FusionCalibMotionService
|
||||
{
|
||||
private readonly HardwareManager _hardware;
|
||||
private readonly SafeAxisMotion _safeAxisMotion;
|
||||
|
||||
public FusionCalibMotionService(HardwareManager hardware, SafeAxisMotion safeAxisMotion)
|
||||
{
|
||||
_hardware = hardware ?? throw new ArgumentNullException(nameof(hardware));
|
||||
_safeAxisMotion = safeAxisMotion ?? throw new ArgumentNullException(nameof(safeAxisMotion));
|
||||
}
|
||||
|
||||
public void SafeMove(IAxis axis, double position)
|
||||
{
|
||||
_safeAxisMotion.SafeMove(
|
||||
MotionMoveRequest.ForAxis(GetRequiredAxis(axis, nameof(axis)), position));
|
||||
}
|
||||
|
||||
public void MoveWsAvoidance(double xPosition, double yPosition)
|
||||
{
|
||||
_safeAxisMotion.SafeMove(
|
||||
MotionMoveRequest.ForAxis(GetRequiredAxis(_hardware.Axis_X2, nameof(_hardware.Axis_X2)), xPosition),
|
||||
MotionMoveRequest.ForAxis(GetRequiredAxis(_hardware.Axis_Y1, nameof(_hardware.Axis_Y1)), yPosition));
|
||||
}
|
||||
|
||||
public void MovePhsAvoidance(double xPosition, double yPosition)
|
||||
{
|
||||
_safeAxisMotion.SafeMove(
|
||||
MotionMoveRequest.ForAxis(GetRequiredAxis(_hardware.Axis_X1, nameof(_hardware.Axis_X1)), xPosition),
|
||||
MotionMoveRequest.ForAxis(GetRequiredAxis(_hardware.Axis_Y2, nameof(_hardware.Axis_Y2)), yPosition));
|
||||
}
|
||||
|
||||
public void RotatePos(double rotatePosition)
|
||||
{
|
||||
_safeAxisMotion.SafeMove(
|
||||
MotionMoveRequest.ForAxis(GetRequiredAxis(_hardware.Axis_WS_R, nameof(_hardware.Axis_WS_R)), rotatePosition));
|
||||
}
|
||||
|
||||
private static MwFramework.Device.IAxis GetRequiredAxis(MwFramework.Device.IAxis axis, string axisPropertyName)
|
||||
{
|
||||
if (axis == null)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Axis '{0}' is not available.", axisPropertyName));
|
||||
}
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
using MainShell.AlgorithmCalib.Common;
|
||||
using MainShell.AlgorithmCalib.Model;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Log;
|
||||
using SemiconductorVisionAlgorithm.SemiParams;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.AlgorithmCalib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 融合标定后处理器(Die/Pad共用)
|
||||
/// 通过 IsWaferCalib 内部区分行为
|
||||
/// </summary>
|
||||
public class FusionCalibPostProcessor : IAlgorithmCalibrationPostProcessor
|
||||
{
|
||||
private readonly FusionCalibMotionService _motionService;
|
||||
private readonly HardwareManager _hardware;
|
||||
private readonly FusionCalibModuleItem _moduleItem;
|
||||
private readonly Func<Rectangle1> _roiRectProvider;
|
||||
|
||||
public event EventHandler<CalibrationProgressEventArgs> ProgressChanged;
|
||||
|
||||
private Point[,] _initialwsPos;
|
||||
private Dictionary<int, Point[,]> _calibResultPointData = new Dictionary<int, Point[,]>();
|
||||
private List<double> _calibPosList = new List<double>();
|
||||
|
||||
public string Name => "FusionCalib";
|
||||
|
||||
public FusionCalibPostProcessor(
|
||||
FusionCalibMotionService motionService,
|
||||
HardwareManager hardware,
|
||||
FusionCalibModuleItem moduleItem,
|
||||
Func<Rectangle1> roiRectProvider)
|
||||
{
|
||||
_motionService = motionService ?? throw new ArgumentNullException(nameof(motionService));
|
||||
_hardware = hardware ?? throw new ArgumentNullException(nameof(hardware));
|
||||
_moduleItem = moduleItem ?? throw new ArgumentNullException(nameof(moduleItem));
|
||||
_roiRectProvider = roiRectProvider;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(AlgorithmCalibExecutionResult calibrationResult, CancellationToken cancellationToken)
|
||||
{
|
||||
$"{(_moduleItem.IsWaferCalib ? "Die" : "Pad")}融合标定开始。".LogInfo();
|
||||
|
||||
try
|
||||
{
|
||||
_calibResultPointData.Clear();
|
||||
_calibPosList.Clear();
|
||||
|
||||
double waferStep = _moduleItem.CalibStep;
|
||||
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _moduleItem.ModelPath);
|
||||
|
||||
int totalSteps = _moduleItem.Count + 1;
|
||||
ReportProgress("采集初始网格点...", 0, totalSteps);
|
||||
|
||||
// 1. 初始网格
|
||||
_initialwsPos = await Task.Run(() =>
|
||||
ApprochTable(waferStep,
|
||||
_moduleItem.MoveAxisPos,
|
||||
GetCurrentY1(),
|
||||
_moduleItem.ApproachXPos,
|
||||
_moduleItem.ApproachYPos,
|
||||
0, path, cancellationToken),
|
||||
cancellationToken);
|
||||
|
||||
// 2. 循环采集
|
||||
for (int i = 0; i < _moduleItem.Count; i++)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ReportProgress($"采集第 {i + 1}/{_moduleItem.Count} 组...", i + 1, totalSteps);
|
||||
|
||||
double x1, y1, x2, y2;
|
||||
CalculatePositions(i, out x1, out y1, out x2, out y2);
|
||||
|
||||
Point[,] points = await Task.Run(() =>
|
||||
ApprochTable(waferStep, x1, y1, x2, y2, i + 1, path, cancellationToken),
|
||||
cancellationToken);
|
||||
|
||||
_calibResultPointData[i] = points;
|
||||
_calibPosList.Add(GetCurrentMoveAxisPos());
|
||||
}
|
||||
|
||||
// 3. 调用平台算法
|
||||
ReportProgress("计算融合矩阵...", totalSteps, totalSteps);
|
||||
await Task.Run(() =>
|
||||
{
|
||||
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CalibData");
|
||||
|
||||
if (_moduleItem.IsWaferCalib)
|
||||
{
|
||||
SemiJM1Vision.SemiJM1Manager.Instance.cal_wafer_fusion_die(
|
||||
_calibResultPointData, _calibPosList, _initialwsPos,
|
||||
_moduleItem.CalibStep, waferStep, _moduleItem.CalibCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
SemiJM1Vision.SemiJM1Manager.Instance.cal_wafer_fusion_pad(
|
||||
_moduleItem.Index, _calibResultPointData, _calibPosList, _initialwsPos,
|
||||
_moduleItem.CalibStep, waferStep, _moduleItem.CalibCount);
|
||||
SemiJM1Vision.SemiJM1Manager.Instance.set_center(new Point(0, 0));
|
||||
}
|
||||
|
||||
SemiJM1Vision.SemiJM1Manager.Instance.Save(filePath);
|
||||
}, cancellationToken);
|
||||
|
||||
$"{(_moduleItem.IsWaferCalib ? "Die" : "Pad")}融合标定完成。".LogInfo();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
"融合标定已取消。".LogInfo();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
$"融合标定失败:{ex.Message}".LogSysError();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task VerifyAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: 验证流程
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
#region 位置计算(Die/Pad分支)
|
||||
|
||||
private void CalculatePositions(int stepIndex, out double x1, out double y1, out double x2, out double y2)
|
||||
{
|
||||
if (_moduleItem.IsWaferCalib)
|
||||
{
|
||||
// Die: 移动X1,逼近X2+Y1
|
||||
x1 = _moduleItem.CameraAxisPos + _moduleItem.Step * stepIndex;
|
||||
y1 = _moduleItem.StartY;
|
||||
x2 = _moduleItem.StartX + _moduleItem.Step * stepIndex;
|
||||
y2 = _hardware.Axis_Y2.State.ActualPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pad: 移动Y1,逼近X1+Y2
|
||||
x1 = _moduleItem.StartX;
|
||||
y1 = _moduleItem.CameraAxisPos + _moduleItem.Step * stepIndex;
|
||||
x2 = _hardware.Axis_X2.State.ActualPos;
|
||||
y2 = _moduleItem.StartY + _moduleItem.Step * stepIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private double GetCurrentY1()
|
||||
{
|
||||
return _hardware.Axis_Y1.State.ActualPos;
|
||||
}
|
||||
|
||||
private double GetCurrentMoveAxisPos()
|
||||
{
|
||||
return _moduleItem.IsWaferCalib
|
||||
? _hardware.Axis_X1.State.ActualPos
|
||||
: _hardware.Axis_Y1.State.ActualPos;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 网格采集
|
||||
|
||||
private Point[,] ApprochTable(double calibStep, double x1, double y1, double x2, double y2,
|
||||
int count, string path, CancellationToken ct)
|
||||
{
|
||||
int calibCount = _moduleItem.CalibCount;
|
||||
Point[,] pointArray = new Point[calibCount, calibCount];
|
||||
|
||||
// 先移到起始位置
|
||||
if (_moduleItem.IsWaferCalib)
|
||||
_motionService.MoveWsAvoidance(x2, y1);
|
||||
else
|
||||
_motionService.MovePhsAvoidance(x1, y2);
|
||||
|
||||
for (int y = 0; y < calibCount; y++)
|
||||
{
|
||||
double Y1 = y * calibStep + y1;
|
||||
double Y2 = y * calibStep + y2;
|
||||
|
||||
for (int x = 0; x < calibCount; x++)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
int index = y % 2 == 0 ? x : calibCount - 1 - x;
|
||||
double X2 = index * calibStep + x2;
|
||||
double X1 = index * calibStep + x1;
|
||||
|
||||
if (_moduleItem.IsWaferCalib)
|
||||
{
|
||||
_motionService.MoveWsAvoidance(X2, Y1);
|
||||
// TODO: 调用逼近识别
|
||||
pointArray[index, y] = new Point(
|
||||
_hardware.Axis_X2.State.ActualPos,
|
||||
_hardware.Axis_Y1.State.ActualPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
_motionService.MovePhsAvoidance(X1, Y2);
|
||||
// TODO: 调用逼近识别
|
||||
pointArray[index, y] = new Point(
|
||||
_hardware.Axis_X1.State.ActualPos,
|
||||
_hardware.Axis_Y2.State.ActualPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pointArray;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ReportProgress(string message, int current, int total)
|
||||
{
|
||||
ProgressChanged?.Invoke(this, new CalibrationProgressEventArgs
|
||||
{
|
||||
Message = message,
|
||||
Current = current,
|
||||
Total = total
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user