Robotics

统一机器人描述格式(URDF)

什么是统一机器人描述格式(URDF)

统一机器人描述格式(URDF)是一种基于 XML 的格式,用于描述机器人的物理与运动学属性。它被广泛应用于 ROS(机器人操作系统)中, 用来定义机器人的结构,以便对其进行可视化、仿真和控制。

URDF 的设计规则

唯一的硬规则:右手定则。 关节的正转方向 = 右手拇指指向 <axis> 向量、四指弯曲的方向。所以"定义某个关节的正方向",本质就是 决定这个 axis 箭头往哪边指。箭头一旦定下来,正方向就被右手定则锁死了。剩下要做的,是用一套约定来决定每个箭头的朝向,并把它和零位、硬件对齐。

下面是我建议你按顺序走的规则: -

  • 第 1 步:先把 base 系定死。 用 ROS REP-103 标准:+X 向前、+Y 向左、+Z 向上,右手系。所有关节的符号都从这个系派生,不要孤立地给单个关节定方向。
  • 第 2 步:每个关节的转轴对齐到对应的主轴。 按它在哪个平面转:
    • YAW(绕竖直轴)→ 轴线沿 Z
    • ROLL(绕前后轴)→ 轴线沿 X
    • PITCH(绕左右轴)→ 轴线沿 Y

定义

<robot name="Qmini">
    <mujoco>
        <compiler meshdir="meshes" discardvisual="false"/>
    </mujoco>
    <!-- [注意] 转换为 mujoco 时取消注释 -->
    <!-- <link name="world"></link>
    <joint name="floating_base_joint" type="floating">
      <parent link="world"/>
      <child link="base_link"/>
    </joint> -->
    <link name="base_link">
        <inertial>
            <origin xyz="-0.014456 5.6E-05 -0.041502" rpy="0 0 0"/>
            <mass value="4.7754"/>
            <inertia ixx="0.026652" ixy="-6E-06" ixz="-0.006659" iyy="0.04973" iyz="-9E-06" izz="0.049037"/>
        </inertial>
        <visual>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <mesh filename="meshes/base_link.STL"/>
            </geometry>
            <material name="">
                <color rgba="1 1 1 1"/>
            </material>
        </visual>
        <collision>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <mesh filename="meshes/base_link.STL"/>
            </geometry>
        </collision>
    </link>
    <link name="LL_hip_yaw">
        <inertial>
            <origin xyz="0.001558 0.000796 -0.10656" rpy="0 0 0"/>
            <mass value="0.73407"/>
            <inertia ixx="0.001096" ixy="1E-06" ixz="7E-06" iyy="0.000691" iyz="4E-06" izz="0.000544"/>
        </inertial>
        <visual>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <mesh filename="meshes/LL_hip_yaw.STL"/>
            </geometry>
            <material name="">
                <color rgba="1 1 1 1"/>
            </material>
        </visual>
        <!-- <collision>
          <origin xyz="0 0 0" rpy="0 0 0"/>
          <geometry>
            <mesh filename="meshes/LL_hip_yaw.STL"/>
          </geometry>
        </collision> -->
    </link>
    <joint name="LL-joint1" type="revolute">
        <origin xyz="0 0.055 0" rpy="0 0 0"/>
        <parent link="base_link"/>
        <child link="LL_hip_yaw"/>
        <axis xyz="0 0 1"/>
        <limit lower="-0.349" upper="0.525" effort="20" velocity="1"/>
    </joint>
</robot>

坐标系

坐标系只是参考标签,你怎么摆它,机器人的实际几何、质量、能怎么动都不变。它真正改变的是三样东西:导出到 URDF 里的那些数字(rpy、axis、惯性的非对角项)、各关节的符号约定(哪边算正转),以及那些默认你遵守某种约定的下游工具能不能正确理解你的模型。所以影响分两类——一类是搞错了会真的出问题,一类只是让数字变难看但仍能跑。先说会真出问题的。

  • 根坐标系(base_link)相对世界的朝向,是最要命的一个。ROS 全套(REP-103)默认机器人 x 朝前、y 朝左、z 朝上。如果你的根坐标系 Z 不是朝上,那么在 RViz/Gazebo 里机器人会侧躺或朝着奇怪方向,仿真里的重力会作用在错误方向,导航、定位、足底受力判断全跟着错。这个必须一开始就摆对。
  • 关节的正转方向(axis 符号),是第二个。如果你让某个坐标系的轴去对齐旋转轴,那么这个轴朝哪头,就决定了关节 axis 的"+1"是哪边、正角度往哪个物理方向转。它连带影响限位该放在哪一侧、Home Pose 里这个关节角的正负、PD 目标、以及训练好的策略。这个搞错了关节会反着动——好在它能在导出后补救(翻向量+翻限位)。
  • 传感器和执行器的坐标系对齐也属于会出问题的范畴。IMU、相机、足底力传感器都按各自约定输出数据(比如 IMU 的重力向量、相机的光学系 z 朝前)。如果你装传感器那个连杆的坐标系朝向乱,你就得额外加一层旋转去把读数对齐到控制器期望的方向,很容易在符号上栽跟头。

接下来是"不破坏功能、但会让你后面很难受"的那些

  • 每个关节 origin 里的 rpy,来自父子两个坐标系的相对朝向。如果你把全身坐标系朝向摆得一致(比如零位时都和机体轴对齐),导出的 rpy 就是干净的小数甚至 0;如果各摆各的,rpy 就是一堆乱七八糟的角度。URDF 照样合法、照样能跑,但你以后读它、调它、排查问题时会很痛苦。

  • axis 向量的形态同理:坐标系 Z 对齐旋转轴,导出就是干净的 0 0 1;坐标系歪着,旋转轴就变成 0 0.97 0.26 这种斜向量。两者都对,但前者好调试。

  • 惯性张量的非对角项也在这一类:惯性是在连杆坐标系里表达的,坐标系朝向不同,ixy/ixz/iyz 这些值就不同。只要全程让 SolidWorks 自动算,它内部是自洽的、不会错;但你一旦想手动核对或微调,就必须清楚它表达在哪个朝向里。

  • 正逆运动学和雅可比(KDL、Pinocchio 等)都在这些坐标系里算,末端位姿、目标点也用它们表达。朝向规整、约定一致,你设目标、读结果、调控制都直观;朝向混乱则处处要做心算换算。

  • 左右对称这一点贯穿始终:坐标系有手性,镜像腿会翻手性,导致左右关节的轴符号和 rpy 系统性相反。坐标系朝向约定统一,左右控制代码才能对称复用。

  • 落到实践,就两条:必须保证根坐标系是 z 朝上、x 朝前(合 REP-103),以及每个关节轴的正方向符合你定的统一约定;强烈建议把所有连杆坐标系朝向摆一致(要么零位时都对齐机体轴,要么 DH 式让每个 Z 沿关节轴),这样 rpy、axis 都干净、左右对称、日后好维护。最后还是回 RViz 验一遍:机器人是不是直立、z 是不是朝上、每个关节正角度是不是往对的方向转、左右是不是镜像对称。这四条过了,坐标系朝向这关就稳了。


参考轴

Solidworks 中的参考轴具有方向性,只是它不画箭头,看起来像没方向,这正是让很多人在添加参考轴后,预览 URDF 时旋转轴和预期不一致的根源。

  • 在 SolidWorks 里,参考轴在几何上就是一条直线,屏幕上显示成一根中心线,没有箭头,所以肉眼看上去确实"无所谓方向"。但在内部,每条参考轴都带一个方向向量(有"从哪头指向哪头"),只是 UI 不把它显著地标出来。导出器读的就是这个隐藏的内部方向,把它当成关节 axis 的"+1"那一头。于是你看着一条没箭头的线,完全猜不到导出后正方向会朝哪边——方向一直在,只是看不见。 这个隐藏方向是在你创建参考轴的那一刻、由构造方式决定的:用两个点建轴,方向就是从先选的点指向后选的点;用圆柱面/锥面建轴,方向按 SolidWorks 对那个面的内部规则定;用两平面交线、用边线,各有各的定向规则。你当时关心的只是"轴在这条线上",没人会去管它内部朝哪头,所以结果往往不是你想要的那一头——尤其镜像腿,手性一翻,方向就系统性反过来。 麻烦在于:单独的参考轴,在界面里不容易直接翻方向,它的指向跟着构造几何走。所以想控制符号,通常走这几条路,从最省事到最彻底: 最省事的还是上一轮说的——导出后直接在 URDF 里把向量取反(记得连限位一起翻并互换)。这是大多数人实际在做的。 想在源头看清并控制方向,推荐走坐标系而不是单纯靠参考轴:你新建参考坐标系时,SolidWorks 会给 X/Y/Z 每个轴一个明确的"反向(Flip)"按钮,而且坐标系会显示带箭头的三维坐标三脚架,方向一眼可见、可翻。把关节轴对齐到坐标系的某个轴(比如让 Z 对准旋转轴),你就能在这里把符号调成想要的,且方向是可视的。这也是之前建议"让坐标系 Z 对齐旋转轴"的另一个好处。 如果非要用参考轴,可以重建它、调换拾取顺序(比如两点法换个先后)来得到想要的指向。 还有一招省得反复试错:在导出器的预览界面里,它通常会把每个关节的轴画成带箭头的方向显示出来。你在点导出之前先看一眼那个箭头朝哪,就知道这条关节的正方向对不对,不用等导出完再回头改。 一句话收尾:参考轴的方向是"存在但不可见",所以符号问题几乎注定要到导出后才暴露——要么用坐标系把它变可见可翻,要么干脆在 URDF 里翻、顺手改限位。
Previous
Unitree Qmini
Next
Bundle