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
│ │ └── ...
写模型时,我建议遵循三条原则:
- 坐标系对齐:base_link的z轴朝上,x轴朝前。这是ROS的约定。
- 碰撞体简化:用box或cylinder代替复杂mesh,能大幅提升碰撞检测速度。
- 惯性参数别瞎填:质量可以估,惯性矩阵最好用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的核心逻辑:
嗯,这一章的内容就到这里。模型是机器人的“身体”,有了它,我们才能谈导航和抓取。下一章我们会给这个身体装上“眼睛”——传感器模型与仿真。
可可精品资料库