3. 机器人模型构建

各位同学,欢迎来到第三章。这一章我们要亲手搭建机器人的“骨架”。

说白了,URDF就是机器人的XML简历。它告诉系统:你有几个关节、几根连杆、长什么样、能怎么动。没有它,导航和机械臂抓取就是空中楼阁。

3.1 URDF:机器人的“身份证”

URDF全称是Unified Robot Description Format。它用标签描述机器人的运动学与动力学属性。

我个人习惯把URDF想象成乐高说明书。每个是一块积木,每个是连接积木的卡扣。

核心标签速查表

标签作用必填属性
<link>定义连杆(视觉、碰撞、惯性)name
<joint>定义关节(类型、父子关系、运动轴)name, type, parent, child
<visual>可视化几何体(mesh/box/cylinder/sphere)geometry
<collision>碰撞检测几何体(通常简化)geometry
<inertial>惯性参数(质量、惯性矩阵)mass, inertia

举个例子,一个简单的两轮底盘:

<robot name="my_robot">
  <link name="base_link">
    <visual>
      <geometry><box size="0.4 0.3 0.1"/></geometry>
      <material name="blue"/>
    </visual>
  </link>

  <joint name="left_wheel_joint" 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>
</robot>

嗯,这里要注意:关节的坐标系原点是相对于父连杆的。我曾经在项目里把origin写反了,结果轮子飞到了底盘外面,Rviz里看着像变形金刚。

3.2 XACRO:别让重复代码折磨你

写几个连杆还行,要是写六轴机械臂,URDF能让你写到怀疑人生。这时候XACRO就派上用场了。

XACRO是URDF的宏语言。它支持:

  • 常量定义:<xacro:property name="wheel_radius" value="0.05"/>
  • 数学运算:${wheel_radius * 2}
  • 宏定义:封装重复的连杆-关节对
  • 文件包含:<xacro:include filename="..."/>

你想想看,如果机械臂有6个相同的关节,用宏只需要写一次:

<xacro:macro name="joint_link" params="name length">
  <link name="${name}_link">
    <visual>
      <geometry><box size="0.1 ${length} 0.1"/></geometry>
    </visual>
  </link>
  <joint name="${name}_joint" type="revolute">
    <parent link="previous_link"/>
    <child link="${name}_link"/>
    <axis xyz="0 0 1"/>
  </joint>
</xacro:macro>

调用时只需:<xacro:joint_link name="arm1" length="0.3"/>。是不是清爽多了?

我的习惯:所有尺寸参数都定义成xacro属性,放在一个单独的config.xacro里。改轮径?改一个数字就行,不用满文件找。

3.3 编写一个完整的机器人模型

我们以“差分驱动底盘+5自由度机械臂”为例。结构如下:

base_link
  ├── left_wheel_joint → left_wheel
  ├── right_wheel_joint → right_wheel
  └── arm_base_joint → arm_base_link
        ├── shoulder_joint → shoulder_link
        │     ├── elbow_joint → elbow_link
        │     │     ├── wrist_joint → wrist_link
        │     │     │     └── gripper_joint → gripper_link
        │     │     │           ├── left_finger_joint → left_finger
        │     │     │           └── right_finger_joint → right_finger
        │     │     └── ...

写模型时,我建议遵循三条原则:

  1. 坐标系对齐:base_link的z轴朝上,x轴朝前。这是ROS的约定。
  2. 碰撞体简化:用box或cylinder代替复杂mesh,能大幅提升碰撞检测速度。
  3. 惯性参数别瞎填:质量可以估,惯性矩阵最好用SolidWorks或Fusion 360导出。填错了,仿真时机器人会像纸片一样飘。

避坑指南:我曾经给一个机械臂的连杆惯性矩阵填了单位矩阵,结果仿真时关节一加速,整个臂像面条一样甩动。后来用CAD软件导出了真实惯性参数,才恢复正常。

3.4 在Rviz中可视化

模型写好了,怎么验证?Rviz就是你的“3D预览器”。

步骤很简单:

  • 启动Rviz:rviz2
  • 添加RobotModel显示插件
  • 设置Description Source为“Topic”,话题名为/robot_description
  • 发布模型:ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(xacro model.xacro)"

如果一切正常,你会看到机器人出现在Rviz中。拖动关节滑块,机械臂应该跟着动。

为什么会看到模型不动?最常见的原因是:

  • joint_state_publisher没启动:它负责发布关节角度,让模型动起来。
  • TF树断裂:某个关节的parent或child名字拼错了,导致运动学链断开。
  • 坐标系单位搞混:URDF默认单位是米,如果你用毫米建模,机器人会小得像蚂蚁。

调试小技巧:在终端运行ros2 run tf2_tools view_frames,会生成一个PDF,展示所有TF变换。如果某个关节没连上,一眼就能看出来。

3.5 本章知识体系

下面这张图总结了URDF/XACRO的核心逻辑:

URDF/XACRO 知识体系 URDF 基础标签 XACRO 宏语言 Rviz 可视化 link joint visual/collision inertial 属性/常量 宏定义 数学运算 文件包含 RobotModel TF树 joint_state 可视化调试 核心流程:URDF定义骨架 → XACRO简化重复 → Rviz验证效果 注意:碰撞体简化、惯性参数准确、坐标系对齐

嗯,这一章的内容就到这里。模型是机器人的“身体”,有了它,我们才能谈导航和抓取。下一章我们会给这个身体装上“眼睛”——传感器模型与仿真。

可可精品资料库