# Pair 局部诊断与全局灵敏度扫描

本说明补充主 README。所有变换均采用：

```text
X = T_body_lidar
A_ij X = X B_ij
B_ij = T_Li_Lj（把站点 j 点云变到站点 i）
```

模式 4 相对模式 3 的数值差定义为：

```text
Delta_ij = B_ij^-1 * (X^-1 * A_ij * X)
```

打印的平移 xyz 和旋转 RPY 是 `Delta_ij` 在站点 j 雷达局部坐标系中的分量，不是屏幕坐标。3D 相机视角会改变画面中的“横向”，所以不能仅凭屏幕左右判断车体系 Y 或 yaw。

## Pair 0 当前诊断

Open3D 精筛 Pair 0（station 0 <- 1）的当前结果为：

```text
translation xyz = [-1.2535, +1.4157, +7.7441] cm
rotation RPY xyz = [-0.5355, -0.1093, +0.0247] deg
norm = 7.9716 cm / 0.547109 deg
```

因此这对主要表现为 roll/pitch 相关姿态差和相对 Z 差，yaw 仅约 `0.025 deg`，不应优先调 yaw。

## 可视化试验

查看原结果：

```powershell
$Repo = "D:\你的代码目录\calibration"
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$Repo\run\view_open3d_result.ps1" -PairIndex 0
```

试验车体系左乘 pitch `+0.2 deg`：

```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$Repo\run\view_open3d_result.ps1" -PairIndex 0 -LeftPitchDeg 0.2
```

此时按键含义：`3` 为 GICP 的 B，`4` 为当前最终 X 预测，`5` 为试验修正后的 X 预测。试验使用：

```text
X_test = DeltaR_body * X
```

这是真正的车体系左乘，会同时旋转 X 的旋转部分和平移向量；小角度下才近似等价于直接给 JSON 的 pitch 加相同角度。

## 全部运动对扫描

运行：

```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$Repo\run\run_sensitivity_scan.ps1" -PairIndex 0
```

程序扫描：

- pitch：`+0.1/+0.2/+0.3 deg`；
- 在这些 pitch 及零 pitch 附近扫描 roll：`-0.2/-0.1/+0.1 deg`；
- yaw `-0.2/+0.2 deg` 只作为低灵敏度对照；
- Open3D 全部精筛对、small_gicp 全部精筛对、跨后端共识对分别计算；
- 同时报告地面法向与高度残差；
- 使用 `0.05 m / 0.5 deg` 作为透明的归一化尺度，统计全局 RMS、改善对数和恶化对数。

输出位于 `results/diagnostics/`。JSON 保存逐对结果，CSV 便于横向比较。

## 接受规则

局部扫描只用于定位，程序不会覆盖 `final_extrinsic_recommended.json`。候选至少需要满足：

1. 不能只改善 Pair 0；全部精筛对的归一化 RMS 应下降；
2. 改善的运动对数量应多于恶化数量；
3. Open3D、small_gicp 与共识集合应给出相同方向的趋势；
4. 地面法向和高度约束不能明显恶化；
5. 多个代表性运动对的模式 4/5 可视化应同步改善。

如果只有 Pair 0 改善，应把它视为局部配准或场景问题，不修改全局 X。

对于当前仅含 yaw 的 RTK A，车体系 Z 轴平移在 AX=XB 中不可观。扫描程序会用 `X.z + 0.10 m` 做数值检查，但不会扫描或修改 z；z 必须由地面高度约束或外部量测确定。
