机器人点位补偿中 Base 坐标系 Rx 与 Tool 坐标系 Rx 的区别
2026/7/9 1:48:49 网站建设 项目流程

在机械臂点位补偿调试中,我们经常会遇到一个看似反直觉的问题:

明明只是调整了Rx倾斜角,为什么在 Web 示教器里切换BaseTool后,末端姿态变化效果完全不一样?

根本原因是:
Base.RxTool.Rx虽然都叫Rx,但它们绕的不是同一根轴。

1. 问题背景

在工件模板的二号工位机械臂点位补偿中,我们希望对加工点位做三类补偿:

ΔZ :到位高度补偿 ΔRx :倾斜角补偿 ΔJ6 :第六轴水平补偿

最初的实现方式是直接修改 TCP 姿态中的Rx

cartesianTarget.Rx += compensation.TiltAngleDeg;

这看起来像是在“绕 X 轴旋转”,但现场测试时发现,它的效果更像 Tool 坐标系下的旋转,而不是我们想要的 Base 坐标系下的旋转。

2. Base 坐标系和 Tool 坐标系的区别

机械臂中常见的两个坐标系:

Base 坐标系: 机器人基座坐标系,固定不动。 Tool 坐标系: 工具坐标系,跟随当前 TCP 姿态一起运动。

可以这样理解:

Base 坐标系像地面坐标; Tool 坐标系像工具自己身上的坐标。

图示:

Base 坐标系(固定不动) Z ↑ | | o --------→ X / / Y

而 Tool 坐标系会随着末端姿态变化:

当前 TCP 姿态 Tool-Z ↑ / / Tool-X ← TCP \ → Tool-Y

所以:

Base 下 Rx: 绕固定的 Base-X 轴旋转。 Tool 下 Rx: 绕当前工具自身的 Tool-X 轴旋转。

这两个旋转轴在工具姿态发生变化后通常并不重合,因此最终效果必然不同。

3. 为什么不能简单写 Rx += ΔRx

很多人会直觉地认为:

pose.Rx += delta;

就等价于:

绕 X 轴旋转 delta 度

但这并不严谨。

Rx / Ry / Rz是姿态矩阵的一种欧拉角表达方式。欧拉角不是三个彼此独立的线性分量。直接修改某一个欧拉角字段,可能会受到控制器姿态定义、旋转顺序、当前姿态以及逆解算法的影响。

也就是说:

直接改 Rx 数值 ≠ 严格意义上的 Base 坐标系 X 轴旋转

因此,下面这种写法并不能稳定表达“Base 下 Rx 旋转”:

cartesianTarget.Rx += compensation.TiltAngleDeg;

4. 正确表达 Base 下 Rx:矩阵左乘

如果我们希望明确表示:

绕 Base 坐标系 X 轴旋转 ΔRx

应该使用旋转矩阵计算。

核心公式是:

R_final = R_base_x_delta × R_current

其中:

R_current :当前 TCP 姿态对应的旋转矩阵 R_base_x_delta :Base 坐标系下绕 X 轴旋转 ΔRx 的旋转矩阵 R_final :补偿后的最终姿态矩阵

关键点是:

左乘 = Base 坐标系旋转 右乘 = Tool 坐标系旋转

也就是说:

Base 下旋转: R_final = R_base_x_delta × R_current
Tool 下旋转: R_final = R_current × R_tool_x_delta

两者顺序不同,含义完全不同。


5. 补偿流程对比

旧逻辑

原始关节 ↓ 原始关节 + ΔJ6 ↓ 正解 当前 TCP 姿态 Rx/Ry/Rz ↓ Rx = Rx + ΔRx ↓ 逆解 最终执行关节

旧逻辑的问题是:

直接修改 Rx 欧拉角,不严格等价于 Base-X 旋转。

新逻辑

原始关节 ↓ 原始关节 + ΔJ6 ↓ 正解 当前 TCP 姿态 R_current ↓ 构造 Base-X 旋转矩阵 R_base_x_delta ↓ R_final = R_base_x_delta × R_current ↓ R_final 转回 Rx/Ry/Rz ↓ 逆解 最终执行关节

新逻辑的含义更明确:

ΔRx 一定表示 Base 坐标系下绕 X 轴的倾斜补偿。

6. 代码实现思路

核心调用:

ApplyBaseCoordinateRxTilt(cartesianTarget, compensation.TiltAngleDeg);

而不是:

cartesianTarget.Rx += compensation.TiltAngleDeg;

核心实现逻辑:

private static void ApplyBaseCoordinateRxTilt(RobotArmPosition pose, double angleDeg) { if (pose == null || Math.Abs(angleDeg) < 1e-9) { return; } double[,] currentRotation = BuildRotationMatrixFromRpy( pose.Rx, pose.Ry, pose.Rz); double[,] baseRxRotation = BuildBaseRxRotationMatrix(angleDeg); double[,] finalRotation = MultiplyRotationMatrix( baseRxRotation, currentRotation); (pose.Rx, pose.Ry, pose.Rz) = ConvertRotationMatrixToRpy(finalRotation); }

重点是这行:

double[,] finalRotation = MultiplyRotationMatrix( baseRxRotation, currentRotation);

这里是左乘。

如果写成:

currentRotation × baseRxRotation

含义就变成了 Tool 坐标系下的局部旋转。


7. 为什么最终 J1~J6 仍然会联动变化

即使我们定义的是 Base 下ΔRx,最终执行仍然要经过逆解:

最终 TCP 姿态 ↓ 逆解 最终 J1~J6

因此,最终关节角可能会发生联动变化。

这不是错误,而是机械臂逆解的正常结果。

也就是说:

ΔRx 定义的是 TCP 姿态补偿方向; J1~J6 是控制器为达到该 TCP 姿态解出来的关节结果。

所以我们不能用“J6 有没有变化”来判断ΔRx是否正确。更应该看:

最终 TCP 姿态是否符合 Base-X 倾斜补偿的预期。

8. 最终补偿语义

当前二号工位点位补偿语义可以定义为:

ΔZ: 加工到位高度补偿。 ΔRx: Base 坐标系下绕 X 轴的倾斜角补偿。 ΔJ6: 关节空间下第六轴水平补偿。

对应流程:

1. 原始示教点 2. 原始关节 + ΔJ6 3. 正解得到当前 TCP 4. 在 Base 坐标系下叠加 ΔZ / ΔRx 5. 逆解得到最终执行关节 6. 下发最终点位

图示:

原始示教点 │ ▼ 原始关节 + ΔJ6 │ ▼ 正解得到当前 TCP 姿态 │ ▼ Base 坐标系下叠加 ΔZ / ΔRx │ ▼ 逆解得到最终关节 J1~J6 │ ▼ 执行最终点位

9. 结论

如果业务要求的是:

在 Base 坐标系下调整倾斜角

那么不能简单地写:

pose.Rx += delta;

而应该使用矩阵左乘:

R_final = R_base_x_delta × R_current

这样才能明确表达:

绕固定 Base-X 轴旋转

而不是:

绕当前 Tool-X 轴旋转

这也是机器人点位补偿中区分 Base / Tool 坐标系的关键。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询