Files

521 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 探测器摆动几何计算模型 | Geometry Calculation with Detector Swing
> 文档版本:v1.0
> 创建日期:2026-04-13
> 适用模块:XP.Hardware.MotionControl
---
## 1. 问题背景 | Background
原始几何计算假设射线源(Source)、载物台旋转中心(Stage)、探测器(Detector)三者共线于 Z 轴,使用简单的绝对坐标差值计算 FOD 和 FDD。
但实际系统中,探测器具有摆动轴(DetectorSwing),可在 XZ 平面内绕固定旋转中心(Pivot)旋转。当摆动角度 θ ≠ 0 时,探测器感光面中心偏离 Z 轴,射线束从射线源到探测器的路径不再沿 Z 轴方向,FOD 和 FDD 的定义需要重新考虑。
---
## 2. 物理模型 | Physical Model
### 2.1 坐标系定义 | Coordinate System
- Z 轴:垂直方向(射线源和探测器的主运动方向)
- X 轴:水平方向(探测器摆动平面内的横向)
- 原点:系统参考零点
### 2.2 关键几何元素 | Key Geometry Elements
```
探测器中心 D ● (Dx, Dz)
\
\ R ← 摆动半径(Pivot 到探测器感光面中心的距离)
\
\ θ ← 摆动角度
/
摆动旋转中心 P ● (Px=0, Pz=SwingPivotZ)
|
|
载物台旋转中心 O ● (Ox=0, Oz=StageRotationCenterZ)
|
| ← 射线束中心线(从 S 到 D)
|
射线源 S (Sx=0, Sz=SourceZ_abs)
```
### 2.3 各点坐标 | Point Coordinates
| 点 | X 坐标 | Z 坐标 | 说明 |
|----|--------|--------|------|
| S(射线源)| 0 | `SourceZ_pos + SourceZOrigin` | 射线源始终在 Z 轴上 |
| O(载物台旋转中心)| 0 | `StageRotationCenterZ`(配置固定值)| 载物台平面与 Z 轴的交点 |
| P(摆动旋转中心)| 0 | `SwingPivotZ`(配置固定值)| 探测器摆动的旋转中心,在 Z 轴上 |
| D(探测器感光面中心)| `Dx` | `Dz` | 由摆动角度和半径计算得出 |
### 2.4 探测器中心坐标计算 | Detector Center Coordinate Calculation
摆动角度 θ 定义:θ = 0 时探测器正对射线源(D 在 Z 轴上,P 正上方),正角度为顺时针(向 X 正方向偏转)。
```
Dx = Px + R × sin(θ) = R × sin(θ) (因为 Px = 0
Dz = Pz - R × cos(θ) (探测器感光面在 Pivot 下方,朝向射线源)
```
注意:这里假设 θ=0 时探测器在 Pivot 正下方(朝向射线源方向),Z 轴向上为正。射线源在底部(Z 值小),探测器在顶部(Z 值大),探测器感光面朝下。公式为:
```
Dx = R × sin(θ)
Dz = Pz - R × cos(θ)
```
---
## 3. FOD 和 FDD 的正确定义 | Correct FOD and FDD Definitions
### 3.1 FOD(焦点到物体距离)| Focus-to-Object Distance
FOD 的定义是:射线源焦点到载物台旋转中心的距离,沿射线束中心线方向测量。
但在平面 CT 系统中,更常用的定义是:射线源到载物台旋转中心沿 Z 轴的投影距离(因为载物台是一个平面,射线束穿过载物台平面的位置才是关键)。
**方案 A:沿射线束中心线的 FOD(几何真实距离)**
射线束中心线从 S 到 D,载物台平面在 Z = StageRotationCenterZ 处。FOD 是射线源 S 到射线束与载物台平面交点的距离。
射线束参数方程(从 S 到 D):
```
x(t) = Sx + t × (Dx - Sx) = t × Dx
z(t) = Sz + t × (Dz - Sz)
```
载物台平面在 Z = Oz,求交点时 t:
```
t_stage = (Oz - Sz) / (Dz - Sz)
```
交点坐标:
```
x_intersect = t_stage × Dx
z_intersect = Oz
```
FOD = S 到交点的欧几里得距离:
```
FOD = sqrt((x_intersect - Sx)² + (z_intersect - Sz)²)
= sqrt((t_stage × Dx)² + (Oz - Sz)²)
```
**方案 B:沿 Z 轴的 FOD(简化定义,与原始实现一致)**
```
FOD_z = |Sz - Oz|
```
这是原始实现的方式,不受探测器摆动影响。
### 3.2 FDD(焦点到探测器距离)| Focus-to-Detector Distance
FDD 是射线源焦点到探测器感光面中心的欧几里得距离:
```
FDD = sqrt((Dx - Sx)² + (Dz - Sz)²)
= sqrt((R × sin(θ))² + (Pz - R × cos(θ) - Sz)²)
```
当 θ = 0 时:
```
FDD = |Pz - R - Sz|
```
此时 `Pz - R` 就是探测器感光面中心在 Z 轴上的绝对坐标(Pivot 下方 R 处),与原始公式 `|DetectorZ_abs - SourceZ_abs|` 一致。
### 3.3 放大倍率 | Magnification
```
M = FDD / FOD
```
---
## 4. 推荐方案 | Recommended Approach
### 4.1 采用方案 A(射线束中心线投影)
对于平面 CT 系统,FOD 应该是沿射线束中心线测量的,因为放大倍率 M = FDD / FOD 直接决定了成像的几何放大关系。
### 4.2 正算公式汇总 | Forward Calculation Summary
已知输入:
- `Sz`:射线源 Z 绝对坐标 = SourceZ_pos + SourceZOrigin
- `Pz`:摆动旋转中心 Z 绝对坐标 = SwingPivotZ(配置)
- `R`:摆动半径 = SwingRadius(配置)
- `θ`:探测器摆动角度 = DetectorSwing 实际角度(度)
- `Oz`:载物台旋转中心 Z 绝对坐标 = StageRotationCenterZ(配置)
计算步骤:
```
1. 探测器中心坐标:
Dx = R × sin(θ)
Dz = Pz - R × cos(θ)
2. FDD = sqrt(Dx² + (Dz - Sz)²)
3. 射线束与载物台平面交点参数:
t_stage = (Oz - Sz) / (Dz - Sz)
4. 交点 X 坐标:
x_intersect = t_stage × Dx
5. FOD = sqrt(x_intersect² + (Oz - Sz)²)
6. M = FDD / FOD
```
### 4.3 反算公式汇总 | Inverse Calculation Summary
反算场景:给定目标 FOD 和 FDD(以及当前探测器摆动角度 θ),计算 SourceZ 和 DetectorZ 的目标位置。
**重要约束**:反算时,探测器摆动角度 θ 是已知的当前值(或目标值),不由 FOD/FDD 反算决定。
已知输入:
- `targetFOD`:目标 FOD
- `targetFDD`:目标 FDD
- `θ`:探测器摆动角度(当前值或目标值)
- `Pz``R``Oz`:配置参数
当 θ = 0 时(简化情况,退化为原始公式):
```
Dx = 0, Dz = Pz - R
FOD = |Sz - Oz| → Sz = Oz - targetFOD(射线源在载物台下方)
FDD = |Dz - Sz| → Dz = Sz + targetFDD
DetectorZ_pos = Dz - DetectorZOrigin
```
当 θ ≠ 0 时:
由 FOD 求 SourceZ
```
FOD 的定义涉及射线束方向,而射线束方向取决于 S 和 D 的位置。
D 的位置取决于 DetectorZ(通过 Pz 和 R 和 θ 计算)。
但在本系统中,探测器的 Z 位置由 DetectorZ 轴控制,
而摆动角度 θ 只改变探测器在 XZ 平面内的朝向。
实际上,Pz(摆动旋转中心)的 Z 坐标 = DetectorZ_pos + DetectorZOrigin + PivotOffset
其中 PivotOffset 是从 DetectorZ 轴位置到 Pivot 点的固定偏移。
简化模型:Pivot 的 Z 坐标随 DetectorZ 轴移动。
```
**关键认识**:摆动旋转中心 P 是固定在探测器机械臂上的,它随 DetectorZ 轴一起上下移动。因此:
```
Pz = DetectorZ_pos + DetectorZOrigin + PivotOffsetFromDetectorOrigin
```
其中 `PivotOffsetFromDetectorOrigin` 是一个固定的机械偏移量(配置参数)。
但为了简化,我们可以将 Pivot 的 Z 坐标直接表示为:
```
Pz = DetectorZ_abs + SwingPivotOffset
```
其中 `SwingPivotOffset` 是 Pivot 相对于 DetectorZ 绝对坐标的固定偏移。
探测器感光面中心:
```
Dx = R × sin(θ)
Dz = Pz - R × cos(θ) = DetectorZ_abs + SwingPivotOffset - R × cos(θ)
```
反算步骤:
1. 由 targetFOD 确定 SourceZ
- 当 θ 较小时,FOD ≈ |Sz - Oz|,所以 Sz ≈ Oz - targetFOD
- 精确求解需要迭代(因为 FOD 的定义涉及射线束方向,而射线束方向又取决于 D 的位置)
2. 由 targetFDD 和已知 Sz 确定 DetectorZ
```
FDD² = Dx² + (Dz - Sz)²
= (R × sin(θ))² + (DetectorZ_abs + SwingPivotOffset - R × cos(θ) - Sz)²
```
设 `A = SwingPivotOffset - R × cos(θ)``B = R × sin(θ)`,则:
```
FDD² = B² + (DetectorZ_abs + A - Sz)²
DetectorZ_abs + A - Sz = ±sqrt(FDD² - B²)
DetectorZ_abs = Sz - A + sqrt(FDD² - B²) (取正值,探测器在射线源上方)
```
3. 转换为轴相对坐标:
```
SourceZ_pos = Sz - SourceZOrigin
DetectorZ_pos = DetectorZ_abs - DetectorZOrigin
```
---
## 5. 配置参数完整说明 | Complete Configuration Parameters
所有参数在 `App.config` 的 `<appSettings>` 中配置,键名前缀为 `MotionControl:`。
### 5.1 几何计算相关参数 | Geometry Calculation Parameters
以下参数直接参与 FOD/FDD/放大倍率的计算:
| 参数 | 键名 | 默认值 | 单位 | 说明 |
|------|------|--------|------|------|
| 射线源Z原点偏移 | `Geometry:SourceZOrigin` | 0 | mm | 射线源Z轴的原点偏移。绝对坐标 = 轴位置 + Origin。用于将轴的相对坐标转换为系统绝对坐标 |
| 探测器Z原点偏移 | `Geometry:DetectorZOrigin` | 600 | mm | 探测器Z轴的原点偏移。含义同上。通常设为探测器回零时感光面中心的绝对Z坐标 |
| 载物台旋转中心Z | `Geometry:StageRotationCenterZ` | 300 | mm | 载物台旋转中心的绝对Z坐标(固定值)。载物台平面与Z轴的交点,FOD 的参考基准 |
| 摆动旋转中心偏移 | `Geometry:SwingPivotOffset` | 0 | mm | 探测器摆动旋转中心(Pivot)相对于 DetectorZ 绝对坐标的Z方向偏移。Pivot 在探测器上方(Z 值更大),正值。Pivot 的绝对Z坐标 = DetectorZ_abs + SwingPivotOffset |
| 摆动半径 | `Geometry:SwingRadius` | 0 | mm | Pivot 到探测器感光面中心的距离。当值为 0 时,系统退化为无摆动的简化模型(完全向后兼容) |
参数间的关系:
```
射线源绝对Z坐标 Sz = SourceZ_pos + SourceZOrigin
探测器绝对Z坐标 DetZ_abs = DetectorZ_pos + DetectorZOrigin
摆动旋转中心Z坐标 Pz = DetZ_abs + SwingPivotOffset
探测器感光面中心 Dx = SwingRadius × sin(θ)
Dz = Pz - SwingRadius × cos(θ)
载物台旋转中心 Oz = StageRotationCenterZ(固定值)
```
### 5.2 直线轴配置 | Linear Axis Configuration
每个直线轴包含 3 个参数,键名格式为 `MotionControl:<AxisName>:<Param>`
| 轴名 | Min | Max | Origin | 说明 |
|------|-----|-----|--------|------|
| SourceZ | 0 | 500 | 0 | 射线源Z轴,控制射线源上下运动(mm) |
| DetectorZ | 0 | 600 | 0 | 探测器Z轴,控制探测器上下运动(mm) |
| StageX | -150 | 150 | 0 | 载物台X轴,控制载物台前后运动(mm) |
| StageY | -150 | 150 | 0 | 载物台Y轴,控制载物台左右运动(mm) |
- `Min` / `Max`:轴的软限位范围(相对坐标),超出范围的移动命令会被拒绝
- `Origin`:轴的原点偏移,用于将相对坐标转换为绝对坐标
### 5.3 旋转轴配置 | Rotary Axis Configuration
每个旋转轴包含 4 个参数,键名格式为 `MotionControl:<AxisName>:<Param>`
| 轴名 | Min | Max | Origin | Enabled | 说明 |
|------|-----|-----|--------|---------|------|
| DetectorSwing | -45 | 45 | 0 | true | 探测器摆动轴,在XZ平面内旋转(度) |
| StageRotation | -360 | 360 | 0 | true | 载物台旋转轴,绕Z轴旋转(度) |
| FixtureRotation | -90 | 90 | 0 | true | 夹具旋转轴,可选配置(度) |
- `Enabled`:是否启用该旋转轴,`false` 时 UI 隐藏且拒绝所有命令
### 5.4 运行参数 | Runtime Parameters
| 参数 | 键名 | 默认值 | 单位 | 说明 |
|------|------|--------|------|------|
| 轮询周期 | `MotionControl:PollingInterval` | 100 | ms | PLC 状态轮询周期,每个周期读取所有轴位置并重新计算几何参数 |
| 默认速度 | `MotionControl:DefaultVelocity` | 500 | - | 未指定速度时使用的默认运动速度 |
---
## 5.5 实际设备配置示例 | Real Device Configuration Example
以下是一个典型平面CT设备的配置示例和测量方法。
### 设备物理布局
假设设备的实际机械尺寸如下:
```
Z=1000mm (顶部)
┃ DetectorZ 轴行程 0~800mm
┃ 探测器回零时 DetectorZ 绝对坐标在 Z=500mm 处
┃ |
┃ D | 探测器感光面中心(朝下,面向射线源)
┃ ● |
┃ \θ |
┃ \ | R=200mm
┃ \ |
┃ \|
┃ ● P 摆动旋转中心 (Z=580mm,随 DetectorZ 移动)
┃ |
┃ |
┃ ● O 载物台旋转中心 (Z=350mm,固定)
┃ |
┃ |
┃ |
┃ ● S 射线源焦点 (Z=50mm,即 SourceZ_pos=0 时)
┃ SourceZ 轴行程 0~500mm
┃ 射线源回零时焦点在 Z=50mm 处
Z=0mm (底部)
```
### 测量方法
1. **SourceZOrigin(射线源原点偏移)**
- 将射线源移动到回零位置(SourceZ_pos = 0
- 测量此时射线源焦点的绝对Z坐标 → 即为 SourceZOrigin
- 本例:焦点在 Z=50mm → `SourceZOrigin = 50`
2. **DetectorZOrigin(探测器原点偏移)**
- 将探测器移动到回零位置(DetectorZ_pos = 0
- 测量此时探测器Z轴参考点的绝对Z坐标 → 即为 DetectorZOrigin
- 本例:参考点在 Z=500mm → `DetectorZOrigin = 500`
3. **StageRotationCenterZ(载物台旋转中心Z坐标)**:
- 测量载物台旋转中心的绝对Z坐标(固定值,由机械结构决定)
- 本例:Z=350mm → `StageRotationCenterZ = 350`
4. **SwingPivotOffset(摆动旋转中心偏移)**:
- 将探测器移动到回零位置,此时 DetectorZ_abs = 0 + 500 = 500mm
- 测量摆动旋转中心(Pivot)的绝对Z坐标 → 本例 Z=580mm
- SwingPivotOffset = Pz - DetectorZ_abs = 580 - 500 = 80mm
- `SwingPivotOffset = 80`
- 注意:Pivot 随 DetectorZ 轴一起移动,此偏移是固定的机械常数
5. **SwingRadius(摆动半径)**
- 测量 Pivot 到探测器感光面中心的距离(固定值,由机械臂长度决定)
- 本例:200mm → `SwingRadius = 200`
### 对应的 App.config 配置
```xml
<!-- 直线轴配置 -->
<add key="MotionControl:SourceZ:Min" value="0" />
<add key="MotionControl:SourceZ:Max" value="500" />
<add key="MotionControl:SourceZ:Origin" value="0" />
<add key="MotionControl:DetectorZ:Min" value="0" />
<add key="MotionControl:DetectorZ:Max" value="800" />
<add key="MotionControl:DetectorZ:Origin" value="0" />
<add key="MotionControl:StageX:Min" value="-150" />
<add key="MotionControl:StageX:Max" value="150" />
<add key="MotionControl:StageX:Origin" value="0" />
<add key="MotionControl:StageY:Min" value="-150" />
<add key="MotionControl:StageY:Max" value="150" />
<add key="MotionControl:StageY:Origin" value="0" />
<!-- 旋转轴配置 -->
<add key="MotionControl:DetectorSwing:Min" value="-45" />
<add key="MotionControl:DetectorSwing:Max" value="45" />
<add key="MotionControl:DetectorSwing:Origin" value="0" />
<add key="MotionControl:DetectorSwing:Enabled" value="true" />
<add key="MotionControl:StageRotation:Min" value="-360" />
<add key="MotionControl:StageRotation:Max" value="360" />
<add key="MotionControl:StageRotation:Origin" value="0" />
<add key="MotionControl:StageRotation:Enabled" value="true" />
<add key="MotionControl:FixtureRotation:Min" value="-90" />
<add key="MotionControl:FixtureRotation:Max" value="90" />
<add key="MotionControl:FixtureRotation:Origin" value="0" />
<add key="MotionControl:FixtureRotation:Enabled" value="false" />
<!-- 几何参数 -->
<add key="MotionControl:Geometry:SourceZOrigin" value="50" />
<add key="MotionControl:Geometry:DetectorZOrigin" value="500" />
<add key="MotionControl:Geometry:StageRotationCenterZ" value="350" />
<add key="MotionControl:Geometry:SwingPivotOffset" value="80" />
<add key="MotionControl:Geometry:SwingRadius" value="200" />
<!-- 运行参数 -->
<add key="MotionControl:PollingInterval" value="100" />
<add key="MotionControl:DefaultVelocity" value="500" />
```
### 验证计算
以上述配置为例,当 SourceZ_pos=100, DetectorZ_pos=200, θ=15° 时:
```
Sz = 100 + 50 = 150mm (射线源绝对Z,底部)
DetZ_abs = 200 + 500 = 700mm (探测器绝对Z,顶部)
Pz = 700 + 80 = 780mm (Pivot 绝对Z,探测器上方)
Dx = 200 × sin(15°) = 200 × 0.2588 = 51.76mm (探测器中心X偏移)
Dz = 780 - 200 × cos(15°) = 780 - 193.19 = 586.81mm (探测器感光面中心ZPivot 下方)
FDD = sqrt(51.76² + (586.81 - 150)²)
= sqrt(2679.1 + 190,729.5)
= sqrt(193,408.6)
≈ 439.78mm
射线束与载物台平面交点参数:
t_stage = (350 - 150) / (586.81 - 150) = 200 / 436.81 = 0.4579
x_intersect = 0.4579 × 51.76 = 23.70mm
FOD = sqrt(23.70² + 200²)
= sqrt(561.7 + 40000)
= sqrt(40561.7)
≈ 201.40mm
M = FDD / FOD = 439.78 / 201.40 ≈ 2.183
对比 θ=0 时(同样轴位置):
Dx = 0, Dz = 780 - 200 = 580mm
FDD_0 = |150 - 580| = 430mm
FOD_0 = |150 - 350| = 200mm
M_0 = 430 / 200 = 2.15
可以看到 θ=15° 时 FDD 略大(439.78 vs 430),FOD 略大(201.40 vs 200),
放大倍率从 2.15 升为 2.183。这是因为摆动使探测器感光面中心在 X 方向偏移,
增加了射线源到探测器的欧几里得距离。
```
---
## 6. 几何示意图 | Geometry Diagram
### 6.1 θ = 0(无摆动,退化为原始模型)
```
D ●─────────────────── 探测器感光面中心 (Z = Pz - R)
|
| R(摆动半径)
|
P ●─────────────────── 摆动旋转中心 (Z = Pz = DetZ_abs + Offset)
|
|
O ●─────────────────── 载物台旋转中心 (Z = Oz)
|
| FOD = |Sz - Oz|
|
S ●─────────────────── 射线源 (Z = Sz)
FDD = |Sz - (Pz - R)| = |Sz - Dz|
```
### 6.2 θ ≠ 0(有摆动)
```
D ●────/──────────── 探测器感光面中心 (Dx, Dz)
/ /
/θ /
/ /
P ●────/──────────────── 摆动旋转中心 (0, Pz)
| /
| / 射线束与载物台平面的交点 I (x_i, Oz)
O ●──/────────────────── 载物台旋转中心 (0, Oz)
| /
| / ← 射线束中心线
| /
|/
S ●─────────────────── 射线源 (0, Sz)
Dx = R × sin(θ)
Dz = Pz - R × cos(θ)
FDD = sqrt(Dx² + (Dz - Sz)²)
FOD = sqrt(x_i² + (Oz - Sz)²)
其中 x_i = Dx × (Oz - Sz) / (Dz - Sz)
```
---
## 7. 特殊情况处理 | Edge Cases
| 情况 | 处理方式 |
|------|----------|
| θ = 0 | 退化为原始公式,Dx = 0FDD = \|Dz - Sz\| |
| SwingRadius = 0 | 完全退化为原始模型(无摆动影响) |
| FOD ≈ 0 | 放大倍率返回 NaN(与原始行为一致) |
| Dz = Sz | FDD 方向水平,t_stage 无穷大,FOD 计算需要特殊处理 |
| FDD < \|R × sin(θ)\| | 反算时 sqrt 内为负数,目标不可达,返回错误 |
---
**最后更新 | Last Updated**: 2026-04-14