Robotics- URDF 里面为什么 joint 没有惯量矩阵
URDF 里面为什么 joint 没有惯量矩阵
打开一份 URDF,你会看到 <link> 里写着 <mass> 和 <inertia>,而 <joint> 只有类型、轴、限位和 damping / friction——从来没有惯性矩阵。这不是疏忽:惯量只属于物质,joint 描述的是约束。下面先把「什么东西真正带惯量」说清楚,再谈 CAD 怎么给数、多密度与液体怎么处理,最后落到 joint 本身,并对照《机器人导论》里的系统惯性矩阵 \(M(q)\)。
惯量属于刚体:体坐标固定,世界坐标会变
要解释 joint 为何没有惯量,先得明确:惯性矩阵描述的是某一块质量分布,因此只对刚体(在 URDF 里就是 link)有意义。
对某个特定刚体,在其体坐标系 / 质心坐标系下,惯性矩阵是固定的。形状、尺寸、密度分布不变时,它就是常量;URDF 的 <inertial> 把这份常量交给仿真器(如 Gazebo),通常也就不再改。

体坐标系下 \(I\) 为常量;世界系下 \(I_{\mathrm{world}}=R I_{\mathrm{body}} R^{T}\),随姿态变。
容易混淆的是世界坐标系下的分量:刚体一转,同样那份惯量在世界系里的六个分量会跟着变。动力学里用旋转矩阵 \(R\) 做
变的是表示,不是刚体本身的固有属性——固有属性仍在体坐标里。
例外也指向同一边界:形变、液体晃动会破坏「刚体」假设,惯量随时间变;但在标准 URDF 刚体模型里,你写进文件的那份 <inertia> 仍被当作固定参数。后面谈液体时会看到:即便质量分布在动,工程做法也是加更多带惯量的 link,而不是给 joint 塞一个张量。
数字从哪来:CAD 到 <inertial>
Link 上的惯量从哪来?工程里最常用的来源是 CAD。SolidWorks、Fusion 360、CATIA 等在赋好材料(密度)后,质量属性可直接给出质量、质心和惯性张量;把 \(I_{xx}, I_{yy}, I_{zz}, I_{xy}, I_{xz}, I_{yz}\) 写入 <inertia> 即可。

CAD 读数须先过单位换算与坐标系对齐,再写入 <inertial>。
「CAD 能算」不等于「可以无脑粘贴」。两关不过,仿真会立刻失真:
| 问题 | 说明 | 对策 |
|---|---|---|
| 坐标系 | CAD 常相对装配原点或零件默认原点;URDF 惯量相对 link 坐标系(多在关节轴附近) | 在 CAD 把原点对齐到 link origin,或输出相对质心的惯量,并把质心写入 <inertial>/<origin> |
| 单位 | CAD 常见 mm、g,惯量常为 \(g\cdot mm^2\);ROS/URDF 要 kg、m,惯量为 \(kg\cdot m^2\) | 在 CAD 用 MKS 再读数,或做 \(10^{-9}\) 量级换算(\(g\cdot mm^2 \to kg\cdot m^2\)) |
单位差几个数量级时,机器人要么轻得飞起来,要么重得抬不动——问题不在动力学公式,而在 link 上那组数写错了。
省力一点:SolidWorks 的 sw_urdf_exporter 之类插件会顺带处理对齐与单位;手写 xacro 时把惯量提成参数或宏;复杂件也可近似成圆柱/长方体,或用 CAD「覆盖质量属性」做粗仿真。无论哪种路径,终点都是某一个 link 的一份 <inertial>,而不是 joint。
多密度拼合:仍是一个 link 的一份惯量
真实零件很少均匀密度:铝壳配铅块、碳纤维蒙皮加金属嵌件,都很常见。这对「惯量写在 link 上」并不构成反例——前提是每个零件都赋对材料。
在物理引擎眼里,零件之间若刚性固定、无相对运动,就是一个刚体:一个总质量、一个总惯性矩阵。CAD 按各自密度算各零件的质量与惯量,再用平行轴定理平移到装配体总质心,求和即得总惯量。

多密度装配在 CAD 内叠加;URDF 一个 <link> 只填总质量、总惯量与总质心。
URDF 的 <link> 不支持在一个 link 里枚举多种密度。你不需要描述「怎么拼的」,只给整体结果:总质量,以及相对该 link 局部原点的总惯量。三个常见坑都与此有关:
- 质心偏移: 一侧轻、一侧重时,
<inertial>/<origin>必须是 CAD 算出的总质心,别习惯性写0 0 0。 - 单位: 密度与惯量最终仍要落到 \(kg\cdot m^2\)。
- 坐标系: 总惯量相对 link 局部原点(常在关节轴),不是装配全局原点。
何时「一个固定惯量」不再够用?零件之间开始有相对运动(电机转子相对外壳转)——那就拆成两个 <link>,中间用 <joint> 连起来;弹簧、液压油等变形/流动则超出标准刚体 URDF,需要插件或更专门的工具。可见边界情况处理方式仍是:质量留在 link,运动关系交给 joint。多密度装配体尽量别手算,CAD 赋材质后用导出插件生成最稳。
液体:刚体假设松动时,仍然用 link,而不是给 joint 加惯量
液体最容易让人想「惯量是不是该写在别处」。其实结论更干脆:液体让单个固定 <inertial> 不够用时,仍然是通过更多的 link(和连接它们的 joint)来建模,而不是给某个 joint 挂上惯性矩阵。
液体占满且近似静止时,可把它当固定密度固体,在 CAD 里赋液体密度,与外壳一起算总质量/总惯量,URDF 填一份固定 <inertial>——仍是一个 link。
液体不满、会晃动时,质心动态偏移,惯量随时间变,还有晃动力,单一固定 <inertial> 描述不了。常见策略是:
| 方案 | 思路 | 适用 |
|---|---|---|
| A. 等效质点 / 多刚体 | 几个质量块 + 弹簧/阻尼接到容器;URDF 里独立 link + 带阻尼 joint | 标准 Gazebo,粗模拟晃动 |
| B. 流体友好仿真器 | CoppeliaSim、Isaac Sim(粒子流体)、CFD 联合仿真 | 高精度,成本高 |
| C. 控制用等效模型 | 弹簧–质量–阻尼或等效摆,在动力学/控制里补偿 | 算法设计 |
泵入/泵出则使总质量与质心实时变化。URDF 是静态描述,需运行时插件改质量惯量,或用外力近似反推力——改的仍然是 link 侧的惯性参数。
工程上最常用的是方案 A 的细化:用等效摆 / 弹簧–质量–阻尼把晃动力矩「骗」进标准多体引擎。

自由液面不可用固定 <inertial>;工程上用容器内虚拟质量 + 阻尼 joint 等效晃荡。
具体做法是:容器内加 1~3 个虚拟质量 <link>,用带 damping / stiffness 的 joint 接到容器;参数靠液深与容器形状整定,看不到真实波浪,但兼容 Gazebo、算得快。也可以用 10~50 个小球作微元(万向节/球关节加大阻尼),不规则容器时更自然,但粒子一多易穿透、爆炸。真要波浪细节,则换 CoppeliaSim、Isaac Sim 粒子流体,或 Fluent + ROS;Gazebo 默认的 ODE/Bullet 不适合当真流体。运行时改惯量多用于理论补偿——多数引擎启动后不再重读 URDF 惯量。
一句话:晃荡时容器是多体系统,不是单个刚体。等效模型里,质量仍挂在虚拟 link 上;joint 只提供弹簧、阻尼与自由度,依然没有自己的惯性张量。
正题:joint 为什么没有惯量矩阵
铺垫至此,答案已经呼之欲出。
因为 joint 是约束与运动学关系,不是物质实体。 没有实体就没有质量,也就没有惯性张量。

节点是带质量/惯量的 link;边是无质量的 joint(约束)。
| Link | Joint | |
|---|---|---|
| 角色 | 刚体、有材料与质量 | 两 link 间的连接与自由度限制 |
| URDF | <mass> + <inertia> |
类型、轴、限位、damping / friction、effort/velocity 等 |
| 动力学 | 提供惯性力、重力 | 约束方程、耗散与驱动边界 |
URDF 是一棵树:节点是 link,边是 joint。引擎先算各 link 的惯量与重力,再经 joint 约束把它们耦合起来。若边也带质量,就偏离标准树状多体(拉格朗日 / 牛顿–欧拉)的建模习惯——前面 CAD、多密度、液体等效,全都在反复确认同一分工。
那现实中的电机、轴承质量去哪了?工程上分摊到相邻 link:
- 转子 → 常归入被驱动的子 link;
- 外壳 / 减速器 → 常归入父 link;
- 轴承 → 忽略或并入父 link。
关节质量大到不能简单合并时,就单独建一个 link(例如电机壳体),再串 joint。复杂 URDF 里 link 数多于「看得见的臂杆」,往往就是为了给关节硬件找一个挂质量的节点——仍然不是给 joint 写惯性矩阵。
joint 上确有「动态」字段:<dynamics damping="..." friction="..."/>、<limit effort velocity> 等。它们描述的是运动约束与驱动能力(耗散项或边界条件),不参与惯性张量定义。阻尼像摩擦,不是质量。
教材里怎么说:系统矩阵 \(M(q)\),不是「关节惯性张量」
若你学过 Craig、Siciliano 一类《机器人导论》,会看到关节坐标下的标准形式,容易误以为「关节上也有惯量」。数学上与 URDF 一致,侧重点不同:教材面向控制推导,URDF 面向仿真落地。

各 link 的 \(m_i,I_i\) 经雅可比进入动能二次型,系数矩阵即随 \(q\) 变化的 \(M(q)\)。
这里的 \(M(q)\) 是关节空间系统惯性矩阵:它随位形 \(q\) 变化,由各连杆质量、惯量经运动学(雅可比)拼出。它既不是某一个连杆的 \(I\),也不是写在 joint 上的空间张量。
连杆 \(i\) 的动能
用雅可比把 \(v_{c_i}\)、\(\omega_i\) 写成 \(\dot{q}\) 的函数,对所有连杆求和,二次型的系数矩阵就是 \(M(q)\)。教材同样不单独给 joint 一个空间惯性张量:
- 电机转子: 经减速比 \(r\) 折算到关节轴,约 \(r^2 I_m\),常加在 \(M(q)\) 对角线——对应 URDF 把转子归入被驱 link。
- 外壳 / 减速器: 并入父连杆的 \(m_i\)、\(I_i\)——对应 URDF 并入父 link。
| 维度 | 《机器人导论》 | URDF / Gazebo |
|---|---|---|
| 参考系 | 多在质心系给 \(I_i\) | 在 link 坐标系;相对质心时用平行轴定理 |
| 关节质量 | 转子折算到轴;外壳并入父连杆 | 转子→子 link,外壳→父 link |
| 输出 | 解析 \(M(q)\),给控制器 | 数值多体,给碰撞与受力 |
| 摩擦 | \(\tau_{\text{friction}}\) 等项 | joint 的 damping / friction |
| 液体晃荡 | 进阶:附加广义坐标、更大耦合 \(M\) | 等效多体或换流体引擎 |
所以教材从不写「关节惯性矩阵」,而是用雅可比把连杆与折算后的电机惯量打进 \(M(q)\)。URDF 是同一套理论的工程化:关节硬件的质量拆给相邻 link,好让引擎用标准树状多体求解——这与「<joint> 里没有 <inertia>」是同一句话的两种说法。
收束
惯量描述质量分布,因此只写在 link 上:体坐标下对刚体固定,世界系分量随姿态变;CAD(含多密度叠加)负责给出那份数,但必须过坐标系与 \(kg\cdot m^2\) 两关。液体晃荡打破单个刚体假设时,仍用等效多体或流体引擎,质量继续挂在 link 上。Joint 是树上的边——约束、限位与阻尼——没有物质,也就没有惯性矩阵;电机等实物质分摊到相邻 link,或单独建 link。教材里的 \(M(q)\) 吸收全部连杆与折算电机惯量,看起来「在关节坐标里」,本质仍不是 joint 自己的张量。

浙公网安备 33010602011771号