3 · 构建你的第一个机器人模型

写差速底盘 URDF,再用 robot_state_publisher 把它可视化出来——这一章我们亲手让机器人“出生”。

差速底盘 URDF link: base_link link: left_wheel link: right_wheel joint: base_to_left joint: base_to_right robot_state_publisher 差速底盘核心结构 · 可视化链路

3.1 差速底盘长什么样?

说白了,差速底盘就是两个主动轮 + 一个或两个万向轮。我习惯把两个驱动轮放在底盘两侧,前后各加一个支撑轮。你想想看,这样机器人转弯时左右轮转速不同,就能原地打转或者画弧线。

在 URDF 里,我们至少需要三个 link:base_link(车身)、left_wheel、right_wheel。再加两个万向轮也行,但这一章我们先做最简版本。

3.2 编写底盘 URDF

直接上代码。我个人习惯把每个 link 的几何和视觉分开写,这样后面改尺寸特别方便。

<?xml version="1.0"?>
<robot name="diff_drive_bot">
  <!-- 车身 -->
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.4 0.3 0.12"/>
      </geometry>
      <material name="blue">
        <color rgba="0.2 0.4 0.9 1.0"/>
      </material>
    </visual>
  </link>

  <!-- 左轮 -->
  <link name="left_wheel">
    <visual>
      <geometry>
        <cylinder radius="0.06" length="0.04"/>
      </geometry>
      <material name="gray">
        <color rgba="0.3 0.3 0.3 1.0"/>
      </material>
    </visual>
  </link>

  <!-- 右轮 -->
  <link name="right_wheel">
    <visual>
      <geometry>
        <cylinder radius="0.06" length="0.04"/>
      </geometry>
      <material name="gray">
        <color rgba="0.3 0.3 0.3 1.0"/>
      </material>
    </visual>
  </link>

  <!-- 关节:左轮 -->
  <joint name="base_to_left_wheel" type="continuous">
    <parent link="base_link"/>
    <child link="left_wheel"/>
    <origin xyz="-0.15 0.2 0" rpy="0 0 0"/>
    <axis xyz="0 1 0"/>
  </joint>

  <!-- 关节:右轮 -->
  <joint name="base_to_right_wheel" type="continuous">
    <parent link="base_link"/>
    <child link="right_wheel"/>
    <origin xyz="-0.15 -0.2 0" rpy="0 0 0"/>
    <axis xyz="0 1 0"/>
  </joint>
</robot>
💡 我的小习惯: 车轮的 origin 的 y 值正负代表左右。左轮 y 为正,右轮 y 为负。轴选 0 1 0 表示绕 y 轴旋转,这样车轮才能向前滚动。

3.3 用 robot_state_publisher 可视化

URDF 写好了,怎么看到它?robot_state_publisher 这个节点会读取你的 URDF,发布 TF 和关节状态。然后你用 rviz2 就能看到机器人了。

我记得第一次跑的时候,忘了设置 frame_id,结果 rviz 里啥都没有。后来发现只要把 Fixed Frame 改成 base_link 就好了。

3.4 启动命令一条龙

假设你把上面的 URDF 保存为 diff_drive.urdf,然后打开终端:

# 1. 启动 robot_state_publisher,加载 urdf
ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(cat diff_drive.urdf)"

# 2. 新终端,启动 rviz2
rviz2

在 rviz2 里,把 Fixed Frame 设为 base_link,然后添加 RobotModel 显示。你应该能看到一个蓝色的小车底盘,两边各有一个灰色轮子。

✅ 验证成功标志: rviz2 中显示完整的机器人模型,并且 TF 树里能看到 base_link → left_wheel 和 base_link → right_wheel 的变换。

3.5 避坑指南(我踩过的)

  • 车轮不显示? 检查 joint 的 origin 坐标。我曾经把左轮的 y 写成负值,结果两个轮子重叠在一起。
  • robot_state_publisher 报错说找不到 urdf 文件? 用路径或者先 cat 确认文件存在。我习惯写个 launch 文件,省得每次敲路径。
  • rviz 里模型是灰色的? 因为你没加 material。哪怕只给个颜色,看起来也舒服很多。
⚠️ 重要提醒: 差速底盘的轮子关节类型一定要用 continuous(连续旋转),不要用 revolute,否则轮子转不到一圈就被限位卡住了。我之前在项目里吃过这个亏,轮子只能转半圈,机器人原地打转……

3.6 本章核心速览

组件作用常用属性
base_link车身主体,承载所有关节box 几何,尺寸根据底盘定
left_wheel / right_wheel差速驱动轮cylinder,半径 0.06m,长度 0.04m
joint (continuous)连接车身与车轮,允许无限旋转axis="0 1 0",origin 定义位置
robot_state_publisher发布 TF 和 robot_description从参数或文件加载 URDF

嗯,到这里你已经拥有了第一个能“看见”的机器人模型。虽然它还不能动,但骨架已经搭好了。下一章我们会给它装上传感器和执行器,让它真正活起来。