1. URDF基础入门

做机器人开发这些年,我越来越觉得——URDF 就像机器人的「身份证」加「骨架图」。你想想看,没有它,你的机器人就只是一堆电机和铝型材,谁都不知道它长什么样、关节怎么动。说白了,URDF 就是让机器人变得可描述、可仿真、可控制的第一步。

什么是URDF?

URDF 的全称是 Unified Robot Description Format,统一机器人描述格式。它是基于 XML 的一种文本文件。嗯,你可以把它理解成机器人的「简历」——写清楚有哪些部件(link),部件之间怎么连接(joint),每个部件长什么形状、有多重、颜色如何。

我记得刚接触 ROS 那会儿,看到 URDF 文件第一反应是:这不就是一堆标签吗?后来才发现,正是这些标签撑起了整个仿真和运动规划的基石。没有 URDF,Gazebo 不知道你的机器人长啥样,MoveIt 也不知道怎么规划路径。

核心要点: URDF 只描述机器人的运动学与动力学属性,不包含控制逻辑。它负责「长什么样、怎么动」,至于「怎么控制」是控制器的事。

URDF在机器人开发中的作用

我习惯把 URDF 比作「乐高说明书」。你想想,如果没有说明书,给你一堆零件你也拼不出一个机械臂。URDF 就是那份说明书——它告诉 ROS 系统:

  • 可视化与调试——在 RViz 里看到机器人模型,检查关节是否合理
  • 运动学计算——正解、逆解都依赖 link 和 joint 的拓扑关系
  • 仿真与物理引擎——Gazebo 通过 URDF 加载碰撞、惯性、摩擦参数
  • 导航与规划——MoveIt 需要 URDF 来生成碰撞检测场景

我曾经在一个项目中,因为 URDF 里一个 joint 的 axis 写反了,导致仿真里机械臂直接「反关节」运动,折腾了两天才排查出来。所以,URDF 看似简单,但细节决定成败。

💡 个人经验: 我建议新手第一次写 URDF 时,先用简单的两连杆练手。把 link 和 joint 的关系彻底搞懂,再去做复杂的机器人。否则后面报错你都不知道从哪查。

第一个URDF文件结构

直接上代码。下面是一个最简的 URDF 文件,描述了一个基座加一个旋转关节的模型:

<?xml version="1.0"?>
<robot name="my_first_robot">
    <link name="base_link">
        <visual>
            <geometry>
                <box size="0.2 0.2 0.1"/>
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0"/>
        </visual>
    </link>

    <joint name="joint1" type="continuous">
        <parent link="base_link"/>
        <child link="arm_link"/>
        <origin xyz="0 0 0.1" rpy="0 0 0"/>
        <axis xyz="0 0 1"/>
    </joint>

    <link name="arm_link">
        <visual>
            <geometry>
                <cylinder length="0.3" radius="0.03"/>
            </geometry>
            <origin xyz="0 0 0.15" rpy="0 0 0"/>
        </visual>
    </link>
</robot>

结构其实很清晰:<robot> 是根标签,里面包含 <link> 和 <joint>。每个 link 定义外观(visual)和碰撞(collision,本例省略),每个 joint 定义父子关系以及运动类型。

你可能会问:为什么 joint 里要写 origin 和 axis?origin 决定了子 link 相对于父 link 的位置,axis 决定了旋转轴方向。我刚开始总把这两个搞混,后来养成了一个习惯——先在纸上画坐标系,再写 URDF。

⚠️ 避坑指南: 我曾经在 joint 的 origin 里忘了设置 rpy,结果子 link 默认旋转了一个奇怪的角度。记住:origin 的 rpy 默认是 0 0 0,但如果你不写,解析器可能按 0 处理,但可读性很差。建议每次都显式写出 xyz 和 rpy。
URDF 核心结构 link 部件 visual 视觉 collision 碰撞 inertial 惯性 joint 关节 parent/child origin/axis type 类型 一个 robot 包含多个 link 和 joint,形成树状结构 每个 link 可定义视觉/碰撞/惯性,每个 joint 定义运动关系

上面这张图概括了 URDF 的骨架。你可以看到,link 和 joint 是平级元素,一个机器人就是一棵树。根节点通常叫 base_link,然后通过 joint 挂载其他 link。

文件结构速览表

标签作用常用子标签
<robot>根元素,name 属性必填link, joint
<link>定义刚体部件visual, collision, inertial
<joint>定义连接与运动parent, child, origin, axis, limit
<visual>可视化外观geometry, origin, material
<collision>碰撞检测形状geometry, origin
<inertial>质量与惯性矩阵mass, inertia

嗯,这张表你可以存着,写 URDF 时对照着看。我个人习惯把 visual 和 collision 分开写,虽然很多时候形状一样,但为了仿真准确,碰撞模型通常用更简化的几何体。

🔧 小技巧: 如果你不确定 joint 的 type 该用哪个,记住:
continuous —— 无限旋转(比如轮子)
revolute —— 有限角度旋转(比如关节臂)
prismatic —— 直线滑动
fixed —— 完全固定(比如把传感器粘在基座上)

最后说一句:URDF 入门不难,难的是把每个细节都做对。我见过很多初学者一上来就写复杂的四足机器人,结果 joint 方向全乱套。我的建议是——从最简单的两连杆开始,在 RViz 里亲眼看到它动起来,那种成就感会推着你往前走。