302 lines
10 KiB
Markdown
302 lines
10 KiB
Markdown
|
|
# 逼近对位功能快速参考
|
|||
|
|
|
|||
|
|
## 1. 文档范围
|
|||
|
|
|
|||
|
|
本文档基于当前仓库 `main` 分支最新已提交代码整理,描述 [`MainShell/Motion/ApproachAlignment`](D:/ww/盘古/PanGu.DieBonderApp/MainShell/Motion/ApproachAlignment) 目录下逼近对位模块的真实实现、调用方式和接入注意事项。
|
|||
|
|
|
|||
|
|
说明:
|
|||
|
|
- 本文档以 `git` 最新已提交代码为准。
|
|||
|
|
- 若旧 README、注释或设计文档与代码不一致,以代码为准。
|
|||
|
|
- 当前模块的流程框架已具备,但坐标变换仍需业务侧补齐真实实现。
|
|||
|
|
|
|||
|
|
## 2. 文件清单
|
|||
|
|
|
|||
|
|
| 文件 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `ApproachAlignment.cs` | 数据结构和接口定义 |
|
|||
|
|
| `ApproachAlignmentService.cs` | 逼近对位主流程 |
|
|||
|
|
| `CenterRecognizer.cs` | 中心识别实现 |
|
|||
|
|
| `CoordinateTransformer.cs` | 坐标转换实现 |
|
|||
|
|
|
|||
|
|
## 3. 核心类型
|
|||
|
|
|
|||
|
|
当前代码中,以下类型定义在 [`ApproachAlignment.cs`](D:/ww/盘古/PanGu.DieBonderApp/MainShell/Motion/ApproachAlignment/ApproachAlignment.cs) 中:
|
|||
|
|
|
|||
|
|
- `ApproachAlignmentAxis`
|
|||
|
|
- `ApproachAlignmentRequest`
|
|||
|
|
- `ApproachAlignmentResult`
|
|||
|
|
- `CoordinateTransformResult`
|
|||
|
|
- `ICenterRecognizer`
|
|||
|
|
- `ICoordinateTransformer`
|
|||
|
|
|
|||
|
|
### 3.1 ApproachAlignmentAxis
|
|||
|
|
|
|||
|
|
用于描述参与逼近对位的单根轴:
|
|||
|
|
|
|||
|
|
- `AxisName`:轴名
|
|||
|
|
- `ToleranceValue`:该轴允许误差
|
|||
|
|
- `Description`:可选描述,用于日志或调试
|
|||
|
|
|
|||
|
|
### 3.2 ApproachAlignmentRequest
|
|||
|
|
|
|||
|
|
用于描述一次逼近对位请求:
|
|||
|
|
|
|||
|
|
- `Axes`:参与对位的轴列表
|
|||
|
|
- `Camera`:相机类型,默认 `CameraType.UpCamera`
|
|||
|
|
- `MaxIterations`:最大迭代次数,默认 5
|
|||
|
|
- `MoveTimeoutMilliseconds`:运动超时,默认 30000
|
|||
|
|
- `RecognitionTimeoutMilliseconds`:识别超时,默认 10000
|
|||
|
|
|
|||
|
|
### 3.3 ApproachAlignmentResult
|
|||
|
|
|
|||
|
|
用于描述逼近对位结果:
|
|||
|
|
|
|||
|
|
- `Succeeded`:是否成功收敛
|
|||
|
|
- `CompletedIterations`:实际完成的迭代次数
|
|||
|
|
- `FinalErrors`:各轴最终误差
|
|||
|
|
- `FinalAxisPositions`:各轴最终位置
|
|||
|
|
- `Exception`:失败或取消时的异常
|
|||
|
|
- `Message`:结果消息
|
|||
|
|
|
|||
|
|
## 4. 当前真实入口
|
|||
|
|
|
|||
|
|
当前 `git` 最新代码中,逼近对位的真实调用入口是:
|
|||
|
|
|
|||
|
|
- [`ApproachAlignmentService.cs`](D:/ww/盘古/PanGu.DieBonderApp/MainShell/Motion/ApproachAlignment/ApproachAlignmentService.cs)
|
|||
|
|
|
|||
|
|
主要方法:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
Task<ApproachAlignmentResult> ApproachAlignmentAsync(
|
|||
|
|
ApproachAlignmentRequest request,
|
|||
|
|
CancellationToken cancellationToken = default(CancellationToken))
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
注意:
|
|||
|
|
- 当前 `SafeAxisMotion` 中并没有 `ApproachAlignmentAsync()` 或 `ApproachAlignment()` 这组方法。
|
|||
|
|
- 旧 README 中写到 `SafeAxisMotion.ApproachAlignmentAsync()` 的内容,和当前代码不一致。
|
|||
|
|
- 实际接入时应直接注入并调用 `ApproachAlignmentService`。
|
|||
|
|
|
|||
|
|
## 5. 工作流程
|
|||
|
|
|
|||
|
|
[`ApproachAlignmentService.cs`](D:/ww/盘古/PanGu.DieBonderApp/MainShell/Motion/ApproachAlignment/ApproachAlignmentService.cs) 当前实现的是一个迭代式流程:
|
|||
|
|
|
|||
|
|
1. 根据请求进入循环,最多执行 `MaxIterations` 次。
|
|||
|
|
2. 首次迭代调用 `ICenterRecognizer.RecognizeCenterAsync()` 识别中心。
|
|||
|
|
3. 调用 `ICoordinateTransformer.TransformAsync()` 将视觉中心转换为各轴目标位置。
|
|||
|
|
4. 把转换结果封装为 `MotionMoveRequest` 数组。
|
|||
|
|
5. 调用 `SafeAxisMotion.SafeMoveAsync()` 执行多轴移动。
|
|||
|
|
6. 再次识别中心。
|
|||
|
|
7. 再次做坐标转换。
|
|||
|
|
8. 用“当前轴位置”和“新转换目标位置”计算误差。
|
|||
|
|
9. 如果所有轴误差都在各自 `ToleranceValue` 内,则成功结束。
|
|||
|
|
10. 否则继续下一轮迭代,直到达到最大迭代次数。
|
|||
|
|
|
|||
|
|
## 6. 必须实现或理解的接口
|
|||
|
|
|
|||
|
|
### 6.1 ICenterRecognizer
|
|||
|
|
|
|||
|
|
接口定义:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
Task<(double CenterX, double CenterY)?> RecognizeCenterAsync(
|
|||
|
|
CameraType camera,
|
|||
|
|
int timeoutMilliseconds,
|
|||
|
|
CancellationToken cancellationToken = default(CancellationToken));
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当前默认实现是 [`CenterRecognizer.cs`](D:/ww/盘古/PanGu.DieBonderApp/MainShell/Motion/ApproachAlignment/CenterRecognizer.cs)。
|
|||
|
|
|
|||
|
|
它的真实行为是:
|
|||
|
|
- 依赖 `IVisionAlgorithmService`
|
|||
|
|
- 构造 `VisionProcessRequest`
|
|||
|
|
- `AlgorithmType = VisionAlgorithmType.FindCenter`
|
|||
|
|
- `CaptureOptions = CameraCaptureOptions.CreateStream(timeoutMilliseconds)`
|
|||
|
|
- 从结果里读取 `OffsetX` / `OffsetY`
|
|||
|
|
- 识别失败时返回 `null`
|
|||
|
|
|
|||
|
|
如果你们已有自己的视觉流程,也可以替换成自定义的 `ICenterRecognizer` 实现。
|
|||
|
|
|
|||
|
|
### 6.2 ICoordinateTransformer
|
|||
|
|
|
|||
|
|
接口定义:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
Task<CoordinateTransformResult> TransformAsync(
|
|||
|
|
double centerX,
|
|||
|
|
double centerY,
|
|||
|
|
IEnumerable<ApproachAlignmentAxis> axes);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当前默认实现是 [`CoordinateTransformer.cs`](D:/ww/盘古/PanGu.DieBonderApp/MainShell/Motion/ApproachAlignment/CoordinateTransformer.cs)。
|
|||
|
|
|
|||
|
|
但需要特别注意:
|
|||
|
|
- 当前实现只是占位版本
|
|||
|
|
- 它会给每根轴写入 `0.0` 作为目标位置
|
|||
|
|
- 然后直接返回 `Succeeded = true`
|
|||
|
|
|
|||
|
|
这表示:
|
|||
|
|
- 逼近对位的流程框架是完整的
|
|||
|
|
- 但真实标定坐标转换还没有完成
|
|||
|
|
- 若直接用于生产逻辑,目标位置会被错误地写成固定值
|
|||
|
|
|
|||
|
|
因此,接入前必须替换为你们设备真实可用的坐标变换实现。
|
|||
|
|
|
|||
|
|
## 7. 依赖关系
|
|||
|
|
|
|||
|
|
当前 `ApproachAlignmentService` 构造函数依赖:
|
|||
|
|
|
|||
|
|
- `SafeAxisMotion`
|
|||
|
|
- `ICenterRecognizer`
|
|||
|
|
- `ICoordinateTransformer`
|
|||
|
|
- `HardwareManager`
|
|||
|
|
|
|||
|
|
依赖注入示例:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
protected override void ConfigureIoC(IStyletIoCBuilder builder)
|
|||
|
|
{
|
|||
|
|
builder.Bind<SafeAxisMotion>().ToSelf().InSingletonScope();
|
|||
|
|
builder.Bind<ICenterRecognizer>().To<CenterRecognizer>().InSingletonScope();
|
|||
|
|
builder.Bind<ICoordinateTransformer>().To<CalibratedCoordinateTransformer>().InSingletonScope();
|
|||
|
|
builder.Bind<ApproachAlignmentService>().ToSelf().InSingletonScope();
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
说明:
|
|||
|
|
- `CenterRecognizer` 可以直接复用当前实现
|
|||
|
|
- `ICoordinateTransformer` 建议替换为你们自己的真实标定实现,不建议直接使用当前占位版 `CoordinateTransformer`
|
|||
|
|
|
|||
|
|
## 8. 推荐接入方式
|
|||
|
|
|
|||
|
|
### 8.1 典型调用流程
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
1. 创建 ApproachAlignmentAxis 列表
|
|||
|
|
2. 创建 ApproachAlignmentRequest
|
|||
|
|
3. 调用 ApproachAlignmentService.ApproachAlignmentAsync()
|
|||
|
|
4. 检查 ApproachAlignmentResult.Succeeded
|
|||
|
|
5. 如失败,查看 Exception 或 Message
|
|||
|
|
6. 如成功,读取 FinalAxisPositions 和 FinalErrors
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 8.2 示例代码
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
public async Task<ApproachAlignmentResult> RunApproachAlignmentAsync(CancellationToken cancellationToken)
|
|||
|
|
{
|
|||
|
|
var request = new ApproachAlignmentRequest(
|
|||
|
|
new[]
|
|||
|
|
{
|
|||
|
|
new ApproachAlignmentAxis("Axis_X", 0.01) { Description = "X axis" },
|
|||
|
|
new ApproachAlignmentAxis("Axis_Y", 0.01) { Description = "Y axis" }
|
|||
|
|
},
|
|||
|
|
camera: CameraType.UpCamera)
|
|||
|
|
{
|
|||
|
|
MaxIterations = 5,
|
|||
|
|
MoveTimeoutMilliseconds = 30000,
|
|||
|
|
RecognitionTimeoutMilliseconds = 10000
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var result = await _approachAlignmentService.ApproachAlignmentAsync(
|
|||
|
|
request,
|
|||
|
|
cancellationToken);
|
|||
|
|
|
|||
|
|
if (!result.Succeeded)
|
|||
|
|
{
|
|||
|
|
throw result.Exception ?? new InvalidOperationException(result.Message);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 9. 自定义坐标转换器示例
|
|||
|
|
|
|||
|
|
以下示例展示如何替换当前占位版 `CoordinateTransformer`:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
public class CalibratedCoordinateTransformer : ICoordinateTransformer
|
|||
|
|
{
|
|||
|
|
public Task<CoordinateTransformResult> TransformAsync(
|
|||
|
|
double centerX,
|
|||
|
|
double centerY,
|
|||
|
|
IEnumerable<ApproachAlignmentAxis> axes)
|
|||
|
|
{
|
|||
|
|
var result = new CoordinateTransformResult();
|
|||
|
|
|
|||
|
|
foreach (var axis in axes)
|
|||
|
|
{
|
|||
|
|
var target = CalculateTarget(axis.AxisName, centerX, centerY);
|
|||
|
|
result.AxisPositions[axis.AxisName] = target;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
result.Succeeded = true;
|
|||
|
|
return Task.FromResult(result);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private double CalculateTarget(string axisName, double centerX, double centerY)
|
|||
|
|
{
|
|||
|
|
// 替换为实际标定变换逻辑
|
|||
|
|
throw new NotImplementedException();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 10. 日志输出示例
|
|||
|
|
|
|||
|
|
当前代码里,`ApproachAlignmentService` 会输出类似这样的日志:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
[INFO] Approach alignment iteration 1/5 started.
|
|||
|
|
[INFO] Center recognized: X=1024.5600, Y=768.3200
|
|||
|
|
[INFO] Coordinate transformation completed: 2 axes.
|
|||
|
|
[INFO] Axes moved successfully: 2 axes completed.
|
|||
|
|
[INFO] Center recognized again: X=1023.9800, Y=768.1500
|
|||
|
|
[INFO] Axis: Axis_X, Current: 100.0250, Expected: 100.0200, Error: 0.005000, Tolerance: 0.0100, WithinTolerance: True
|
|||
|
|
[INFO] Axis: Axis_Y, Current: 200.0150, Expected: 200.0100, Error: 0.005000, Tolerance: 0.0100, WithinTolerance: True
|
|||
|
|
[INFO] Approach alignment succeeded after 1 iteration(s).
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果异常发生,也会记录失败日志,例如:
|
|||
|
|
- `Center recognition failed.`
|
|||
|
|
- `Coordinate transformation failed: ...`
|
|||
|
|
- `Failed to get current position for axis ...`
|
|||
|
|
|
|||
|
|
## 11. 常见问题
|
|||
|
|
|
|||
|
|
### Q: 如何修改最大迭代次数?
|
|||
|
|
A: 设置 `ApproachAlignmentRequest.MaxIterations`。
|
|||
|
|
|
|||
|
|
### Q: 如何设置不同轴的允许误差?
|
|||
|
|
A: 为每个 `ApproachAlignmentAxis` 设置不同的 `ToleranceValue`。
|
|||
|
|
|
|||
|
|
### Q: 能否在执行中途取消?
|
|||
|
|
A: 可以,通过 `CancellationToken` 取消。取消后结果中的 `Exception` 会记录取消异常。
|
|||
|
|
|
|||
|
|
### Q: 如何查看每个轴的最终误差?
|
|||
|
|
A: 查看 `ApproachAlignmentResult.FinalErrors`。
|
|||
|
|
|
|||
|
|
### Q: 逼近失败时如何获取原因?
|
|||
|
|
A: 查看 `ApproachAlignmentResult.Exception` 或 `ApproachAlignmentResult.Message`。
|
|||
|
|
|
|||
|
|
### Q: 当前默认实现能直接用于生产吗?
|
|||
|
|
A: 不建议。`CenterRecognizer` 基本可接真实视觉流程,但 `CoordinateTransformer` 仍是占位实现,必须先替换。
|
|||
|
|
|
|||
|
|
## 12. 当前状态总结
|
|||
|
|
|
|||
|
|
当前 `ApproachAlignment` 模块的真实状态是:
|
|||
|
|
|
|||
|
|
- 数据结构已经完整
|
|||
|
|
- 主流程已经完整
|
|||
|
|
- 视觉识别已有可接真实系统的实现
|
|||
|
|
- 运动执行复用了 `SafeAxisMotion`
|
|||
|
|
- 坐标变换仍需业务侧补齐真实算法
|
|||
|
|
- README 中旧的 `SafeAxisMotion.ApproachAlignmentAsync()` 说法已经不适用
|
|||
|
|
|
|||
|
|
接入建议:
|
|||
|
|
- 直接注入 `ApproachAlignmentService`
|
|||
|
|
- 保留当前 `CenterRecognizer` 或替换成自定义实现
|
|||
|
|
- 优先补齐真实的 `ICoordinateTransformer`
|
|||
|
|
- 在真实设备上联调前,不要使用默认 `CoordinateTransformer` 做生产动作
|