# 逼近对位功能快速参考 ## 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 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 TransformAsync( double centerX, double centerY, IEnumerable 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().ToSelf().InSingletonScope(); builder.Bind().To().InSingletonScope(); builder.Bind().To().InSingletonScope(); builder.Bind().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 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 TransformAsync( double centerX, double centerY, IEnumerable 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` 做生产动作