Files
XplorePlane/XP.Hardware.MotionControl/Documents/Calibration_README.md
T

16 KiB
Raw Blame History

像素-载物台映射子模块 | 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

实验方法:

  1. 在图像中观察某物体,记下其在图像中的位置(如偏左)
  2. 手动向 X+ 方向移动载物台
  3. 观察物体在图像中的运动方向:
    • 如果物体向图像 X+ 方向移动 → PixelDirectionX = 1
    • 如果物体向图像 X- 方向移动 → PixelDirectionX = -1
  4. 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(服务实现)

  • 通过构造函数注入 ILoggerServiceMotionControlConfig
  • 启动时自动判断使用几何计算模式还是手动标定模式,并输出日志
  • 标定文件路径:{AppBaseDirectory}/Calibration/MagnificationCalibration.json(仅作为 fallback
  • 作为单例注册到 MotionControlModule 的 DI 容器

异常约定 | Exception Contract

条件 异常类型 说明
IsReady == false 时调用转换 InvalidOperationException 几何配置无效且未完成手动标定
currentMagnification <= 0 ArgumentException 放大倍率必须为正数

5. 关键算法 | Key Algorithms

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.12026-07-28

新增坐标系补偿功能

  • 新增 IMotionControlService 坐标系补偿接口:ApplyPixelOffsetCompensationRecordPixelOffsetCompensationGetStageCompensationSetStageCompensationResetStageCompensation
  • 新增 CompensationMode 枚举(Replace 默认 / Accumulate
  • 新增 StageCompensationChangedEvent 事件
  • 变更 MoveToTarget / MoveAllToTarget 增加 applyCompensation 参数(默认 false),仅对 StageX/StageY 叠加补偿
  • 重构MoveStageByPixelOffset 的像素→mm 换算抽为私有方法 TryConvertPixelToStageMm,供补偿接口复用(对外行为不变)
  • 补偿功能复用现有几何配置,无需新增 App.config 参数

v2.02026-07-01

重大变更:从手动标定改为基于几何配置的直接计算

  • 新增 GeometryConfig.DetectorPixelSizeX / DetectorPixelSizeY:探测器像素物理尺寸配置
  • 新增 GeometryConfig.PixelDirectionX / PixelDirectionY:像素方向系数配置
  • 新增 IMagnificationCalibrationService.IsReady 属性:替代 IsCalibrated
  • 废弃 手动标定向导流程:标记为 [Obsolete],代码保留但不再推荐使用
  • 废弃 IsCalibratedCurrentDataLoadCalibration()SaveCalibration() 接口成员
  • 变更 MagnificationCalibrationService 构造函数:新增 MotionControlConfig 依赖注入
  • 变更 PixelsToStageMovement 转换逻辑:优先使用几何计算,回退到手动标定数据

迁移指南

  1. 在 App.config 中配置 DetectorPixelSizeXDetectorPixelSizeY(从探测器规格书获取)
  2. 配置 PixelDirectionXPixelDirectionY(通过实验确定方向对应关系)
  3. 将代码中的 IsCalibrated 替换为 IsReady
  4. 无需再运行标定向导,系统启动后即可使用像素映射功能

v1.02026-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 > 0FovDistance1 > 0
Step 3 标定点 2 输入 M2、X 视野实际距离;实时显示 K2、一致性检查结果 M2 > 0FovDistance2 > 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>() 获取模块化日志实例

文档 说明
README.md MotionControl 模块总体说明
GeometryWithDetectorSwing.md FOD/FDD/放大倍率(M)几何计算模型
MotionControl_Design.md 运动控制模块设计文档

最后更新 | Last Updated: 2026-07-01