[XP.Hardware.MotionControl] README 文档目录树补齐全部文档条目并加入 CoordinateCompensation.md
16 KiB
像素-载物台映射子模块 | Pixel-to-Stage Mapping Submodule
文档版本:v2.0 创建日期:2026-06-30 更新日期:2026-07-01 适用模块:XP.Hardware.MotionControl / Calibration
1. 概述 | Overview
本子模块建立图像像素坐标与载物台物理运动距离之间的映射关系,使系统能够根据当前放大倍率,将图像上的像素偏移量转换为载物台的实际运动距离(mm)。
1.1 推荐方式:基于几何配置直接计算(v2.0 新增)
核心公式:
mmPerPixelX = DetectorPixelSizeX / M
mmPerPixelY = DetectorPixelSizeY / M
其中:
DetectorPixelSizeX:探测器单像素 X 方向物理尺寸(mm),由探测器硬件规格决定,配置在 App.config 中DetectorPixelSizeY:探测器单像素 Y 方向物理尺寸(mm),通常与 X 相同(正方形像素)M:当前放大倍率(Magnification),由 FDD / FOD 实时计算得出(参见 GeometryWithDetectorSwing.md)
原理说明:探测器感光面上每个像素对应固定的物理尺寸(如 0.139mm),经过锥束放大后,载物台平面上每个像素对应的实际物理尺寸 = 像素物理尺寸 / 放大比。这是纯几何关系,无需标定即可直接计算。
优势:
- 无需手动标定流程,配置一次即可使用
- 放大比变化时自动适配(因为 M 是实时计算的)
- 精度取决于机构精度(FOD/FDD 的准确性),对于大多数定位应用已足够
1.2 已废弃方式:手动标定向导
旧方式通过两点标定求取标定常数 K,公式为 mmPerPixel = K / M。该方式已标记为 [Obsolete],代码保留用于向后兼容,但不再推荐使用。
当 DetectorPixelSizeX 配置为 0 或未配置时,系统会自动回退到手动标定数据(如果存在)。
典型应用场景:用户在图像上点击某一点,系统计算该点相对图像中心的像素偏移,自动将载物台移动到使该点居中的物理位置。
2. 目录结构 | Directory Structure
XP.Hardware.MotionControl/Calibration/
├── Interfaces/ # 服务接口定义 | Service interfaces
│ └── IMagnificationCalibrationService.cs
├── Models/ # 数据模型(已废弃的标定数据)| Data models (deprecated)
│ └── MagnificationCalibrationData.cs
├── Implementations/ # 服务实现 | Service implementations
│ └── MagnificationCalibrationService.cs
├── ViewModels/ # 向导 ViewModel(已废弃)| Wizard ViewModel (deprecated)
│ └── CalibrationWizardViewModel.cs
└── Views/ # 向导窗口(已废弃)| Wizard window (deprecated)
├── CalibrationWizardWindow.xaml
└── CalibrationWizardWindow.xaml.cs
3. 配置参数 | Configuration
在 App.config 的 <appSettings> 中配置,键名前缀为 MotionControl:Geometry::
| 参数 | 键名 | 默认值 | 单位 | 说明 |
|---|---|---|---|---|
| 探测器像素物理尺寸X | Geometry:DetectorPixelSizeX |
0.139 | mm | 探测器单像素 X 方向物理尺寸,由探测器规格书获取 |
| 探测器像素物理尺寸Y | Geometry:DetectorPixelSizeY |
0.139 | mm | 探测器单像素 Y 方向物理尺寸,通常与 X 相同 |
| 像素方向系数X | Geometry:PixelDirectionX |
1 | — | 对齐图像 X 轴方向与载物台 X 运动方向(+1 或 -1) |
| 像素方向系数Y | Geometry:PixelDirectionY |
-1 | — | 对齐图像 Y 轴方向与载物台 Y 运动方向(+1 或 -1) |
App.config 配置示例
<!-- 探测器像素物理尺寸(mm)| Detector pixel physical size (mm) -->
<!-- 用于直接计算像素到载物台距离的映射:mmPerPixel = PixelSize / Magnification -->
<add key="MotionControl:Geometry:DetectorPixelSizeX" value="0.139" />
<add key="MotionControl:Geometry:DetectorPixelSizeY" value="0.139" />
<!-- 像素方向系数:对齐图像像素坐标方向与载物台运动方向(+1 或 -1)| Pixel direction coefficients -->
<add key="MotionControl:Geometry:PixelDirectionX" value="1" />
<add key="MotionControl:Geometry:PixelDirectionY" value="-1" />
如何确定 DetectorPixelSizeX / Y
从探测器规格书中获取。例如:
- Varex 3072×3060 探测器:像素尺寸 0.139mm × 0.139mm
- 当使用 2×2 Binning 时:等效像素尺寸 0.278mm × 0.278mm
注意:如果使用了 Binning 模式,需要将像素尺寸乘以 Binning 倍数。
如何确定 PixelDirectionX / Y
实验方法:
- 在图像中观察某物体,记下其在图像中的位置(如偏左)
- 手动向 X+ 方向移动载物台
- 观察物体在图像中的运动方向:
- 如果物体向图像 X+ 方向移动 →
PixelDirectionX = 1 - 如果物体向图像 X- 方向移动 →
PixelDirectionX = -1
- 如果物体向图像 X+ 方向移动 →
- Y 方向同理
4. 核心组件 | Core Components
4.1 IMagnificationCalibrationService(服务接口)
| 成员 | 类型 | 说明 |
|---|---|---|
IsReady |
bool (get) |
是否可以进行像素到载物台转换(几何配置有效 或 手动标定已完成) |
IsCalibrated |
bool (get) |
⚠️ 已废弃。是否已完成手动标定 |
CurrentData |
MagnificationCalibrationData (get) |
⚠️ 已废弃。当前手动标定数据 |
LoadCalibration() |
bool |
⚠️ 已废弃。从 JSON 加载手动标定数据 |
SaveCalibration(data) |
bool |
⚠️ 已废弃。保存手动标定数据到 JSON |
PixelsToStageMovement(dx, dy, M) |
(double, double) |
像素偏移 → 载物台移动距离转换 |
4.2 转换逻辑优先级 | Conversion Logic Priority
PixelsToStageMovement(dxPixels, dyPixels, currentMagnification):
1. 优先:几何直接计算(当 DetectorPixelSizeX > 0 时)
mmPerPixelX = DetectorPixelSizeX / M
mmPerPixelY = DetectorPixelSizeY / M
stageDx = dxPixels × mmPerPixelX × PixelDirectionX
stageDy = dyPixels × mmPerPixelY × PixelDirectionY
2. 回退:手动标定数据(当几何配置无效且标定文件存在时)
mmPerPixel = K / M
stageDx = dxPixels × mmPerPixel × DirectionX
stageDy = dyPixels × mmPerPixel × DirectionY
3. 异常:两者均不可用时抛出 InvalidOperationException
4.3 MagnificationCalibrationService(服务实现)
- 通过构造函数注入
ILoggerService和MotionControlConfig - 启动时自动判断使用几何计算模式还是手动标定模式,并输出日志
- 标定文件路径:
{AppBaseDirectory}/Calibration/MagnificationCalibration.json(仅作为 fallback) - 作为单例注册到
MotionControlModule的 DI 容器
异常约定 | Exception Contract
| 条件 | 异常类型 | 说明 |
|---|---|---|
IsReady == false 时调用转换 |
InvalidOperationException |
几何配置无效且未完成手动标定 |
currentMagnification <= 0 |
ArgumentException |
放大倍率必须为正数 |
5. 关键算法 | Key Algorithms
5.1 几何直接计算(推荐)| Geometry Direct Calculation (Recommended)
stageDx_mm = dxPixels × (DetectorPixelSizeX / M) × PixelDirectionX
stageDy_mm = dyPixels × (DetectorPixelSizeY / M) × PixelDirectionY
物理意义:
- 探测器感光面上每个像素的物理尺寸是固定的(由硬件决定)
- 锥束投影下,载物台平面上的等效像素尺寸 = 探测器像素尺寸 / 放大比
- 放大比 M = FDD / FOD,由几何计算器根据当前轴位置实时计算
精度分析:
- 假设 DetectorPixelSizeX = 0.139mm(精确值,来自规格书)
- 放大比 M 的精度取决于 FOD/FDD 的精度(即轴位置 + 几何原点偏移的精度)
- 若 FOD 有 1mm 误差(500mm 中),放大比相对误差约 0.2%
- 对于 100mm 视场范围,位置误差约 0.2mm,满足绝大多数定位需求
5.2 手动标定(已废弃)| Manual Calibration (Deprecated)
K = M × FovDistance / DetectorPixelCountX (标定常数计算)
mmPerPixel = K / currentMagnification (使用时转换)
K 本质上就是探测器单像素的物理尺寸(理想情况下 K ≈ DetectorPixelSizeX),手动标定的意义在于:
- 修正 FOD/FDD 的系统性偏差
- 补偿探测器实际像素尺寸与标称值的差异
- 对精度要求极高的场景仍可使用
6. 模块集成 | Module Integration
在 MotionControlModule.RegisterTypes 中注册:
// 注册放大比标定服务(单例)| Register magnification calibration service (singleton)
containerRegistry.RegisterSingleton<IMagnificationCalibrationService, MagnificationCalibrationService>();
外部调用示例 | External Usage Example
public class SomeViewModel
{
private readonly IMotionControlService _motion;
public SomeViewModel(IMotionControlService motion)
{
_motion = motion;
}
// 用户点击图像某点,计算相对图像中心的像素偏移后,一键驱动载物台移动
// User clicks a point on image, calculates pixel offset from center, and drives stage movement
public void CenterOnPixel(double dxPixels, double dyPixels)
{
// 直接驱动载物台移动(内部自动获取放大比、计算距离、执行运动)
// Directly drives stage move (internally gets magnification, calculates distance, executes motion)
var result = _motion.MoveStageByPixelOffset(dxPixels, dyPixels);
if (!result.Success)
{
// 处理错误 | Handle error
MessageBox.Show(result.ErrorMessage);
}
}
// 仅预览计算结果,不实际移动 | Preview calculation only, no actual move
public string PreviewMove(double dxPixels, double dyPixels)
{
var result = _motion.MoveStageByPixelOffset(dxPixels, dyPixels, executeMove: false);
return result.ErrorMessage; // 成功时包含计算的位移信息 | Contains displacement info on success
}
}
也可以使用底层接口单独计算(不驱动运动):
public class AnotherViewModel
{
private readonly IMagnificationCalibrationService _calibration;
private readonly IMotionControlService _motion;
public AnotherViewModel(
IMagnificationCalibrationService calibration,
IMotionControlService motion)
{
_calibration = calibration;
_motion = motion;
}
// 仅计算像素偏移对应的载物台距离(不移动)
// Calculate only, no move
public (double dx, double dy) CalculateOffset(double dxPixels, double dyPixels)
{
if (!_calibration.IsReady) return (0, 0);
var geometry = _motion.GetCurrentGeometry();
return _calibration.PixelsToStageMovement(dxPixels, dyPixels, geometry.Magnification);
}
}
6.1 两种用途辨析:点击居中 vs 坐标系补偿 | Click-to-Center vs Coordinate Compensation
MoveStageByPixelOffset 与坐标系补偿接口都基于相同的像素→mm 换算(内部统一由私有方法 TryConvertPixelToStageMm 计算),但用途不同:
| 用途 | 接口 | 是否记录补偿 | 说明 |
|---|---|---|---|
| 点击居中 | MoveStageByPixelOffset(dx, dy) |
否 | 用户点击图像某点,一次性把该点移到中心,不影响后续运动 |
| 坐标系补偿 | ApplyPixelOffsetCompensation(dx, dy) |
是 | 主框架坐标匹配后记录补偿并修正到位,后续定点运动可叠加补偿 |
坐标系补偿的完整说明见 MotionControl_Design.md 第 14 节与 GUIDENCE.md 第 11 节。
7. 版本变更说明 | Change Log
v2.1(2026-07-28)
新增坐标系补偿功能
- 新增
IMotionControlService坐标系补偿接口:ApplyPixelOffsetCompensation、RecordPixelOffsetCompensation、GetStageCompensation、SetStageCompensation、ResetStageCompensation - 新增
CompensationMode枚举(Replace默认 /Accumulate) - 新增
StageCompensationChangedEvent事件 - 变更
MoveToTarget/MoveAllToTarget增加applyCompensation参数(默认false),仅对 StageX/StageY 叠加补偿 - 重构 将
MoveStageByPixelOffset的像素→mm 换算抽为私有方法TryConvertPixelToStageMm,供补偿接口复用(对外行为不变) - 补偿功能复用现有几何配置,无需新增 App.config 参数
v2.0(2026-07-01)
重大变更:从手动标定改为基于几何配置的直接计算
- 新增
GeometryConfig.DetectorPixelSizeX/DetectorPixelSizeY:探测器像素物理尺寸配置 - 新增
GeometryConfig.PixelDirectionX/PixelDirectionY:像素方向系数配置 - 新增
IMagnificationCalibrationService.IsReady属性:替代IsCalibrated - 废弃 手动标定向导流程:标记为
[Obsolete],代码保留但不再推荐使用 - 废弃
IsCalibrated、CurrentData、LoadCalibration()、SaveCalibration()接口成员 - 变更
MagnificationCalibrationService构造函数:新增MotionControlConfig依赖注入 - 变更
PixelsToStageMovement转换逻辑:优先使用几何计算,回退到手动标定数据
迁移指南:
- 在 App.config 中配置
DetectorPixelSizeX和DetectorPixelSizeY(从探测器规格书获取) - 配置
PixelDirectionX和PixelDirectionY(通过实验确定方向对应关系) - 将代码中的
IsCalibrated替换为IsReady - 无需再运行标定向导,系统启动后即可使用像素映射功能
v1.0(2026-06-30)
- 初始版本,基于两点手动标定的像素-载物台映射
8. 已废弃:标定向导流程 | Deprecated: Calibration Wizard Flow
⚠️ 以下内容为 v1.0 的手动标定向导,已废弃。仅在
DetectorPixelSizeX未配置时作为 fallback 使用。
向导窗口 CalibrationWizardWindow 基于 Telerik RadWizard + Crystal 主题,分为五步:
| 步骤 | 名称 | 主要内容 | 下一步条件 |
|---|---|---|---|
| Step 1 | 标定介绍 | 显示标定原理和核心公式;输入探测器 X 方向像素数 | DetectorPixelCountX > 0 |
| Step 2 | 标定点 1 | 输入 M1、X 视野实际距离;实时显示 K1 | M1 > 0 且 FovDistance1 > 0 |
| Step 3 | 标定点 2 | 输入 M2、X 视野实际距离;实时显示 K2、一致性检查结果 | M2 > 0 且 FovDistance2 > 0 |
| Step 4 | 方向标定 | 选择 X/Y 方向系数(+1/-1) | — |
| Step 5 | 验证与保存 | 标定结果汇总;输入测试放大比显示 mm/pixel;保存 | 保存成功后关闭窗口 |
标定文件路径:{AppBaseDirectory}/Calibration/MagnificationCalibration.json
9. 多语言支持 | Localization
所有向导界面文本通过模块级 Resources 资源文件管理,支持简体中文(zh-CN)、繁体中文(zh-TW)和英文(en-US)。
- 资源文件位置:
XP.Hardware.MotionControl/Resources/Resources*.resx - 资源键前缀:
Calibration_ - XAML 绑定方式:
{loc:Localization Calibration_WizardTitle} - 服务日志输出采用双语格式(中文 | English)
10. 错误处理与日志 | Error Handling & Logging
- 启动时输出当前模式信息(几何直接计算 / 手动标定 fallback)
- 几何配置无效时输出 Warn 级别日志
- 标定文件加载失败时输出 Error/Warn 级别日志(不影响几何计算模式)
PixelsToStageMovement在非法输入时抛出明确异常- 统一使用
ILoggerService.ForModule<MagnificationCalibrationService>()获取模块化日志实例
11. 关联文档 | Related Documents
| 文档 | 说明 |
|---|---|
README.md |
MotionControl 模块总体说明 |
GeometryWithDetectorSwing.md |
FOD/FDD/放大倍率(M)几何计算模型 |
MotionControl_Design.md |
运动控制模块设计文档 |
最后更新 | Last Updated: 2026-07-01