3. 机器人建模与URDF:URDF语法详解、link与joint配置、使用xacro优化模型、在Rviz中显示机器人模型
好,咱们进入第三章。这一章可以说是整个底盘驱动开发的「地基」——机器人建模。你想想看,没有模型,你让机器人怎么知道自己长什么样?胳膊多长、轮子多大、传感器装在哪?这些信息,全得靠URDF来描述。
我个人习惯把URDF比作机器人的「身份证」。它用XML格式,把机器人的每一个零件(link)和每一个关节(joint)都交代得清清楚楚。今天咱们就把这张身份证的写法彻底搞明白。
3.1 URDF语法详解
URDF的全称是Unified Robot Description Format,统一机器人描述格式。说白了,就是一个纯文本文件,里面用标签来定义机器人的结构。
它的核心就两个东西:link 和 joint。link是刚体部件,joint是连接两个link的关节。我刚开始学的时候,总把这两个搞混。后来想了个笨办法:link就是骨头,joint就是关节。骨头不会动,关节才能动。
3.1.1 link标签
每个link代表一个刚体部件。比如底盘、轮子、激光雷达支架,这些都是link。一个link标签里,主要包含三部分信息:
- 视觉属性(visual):模型长什么样,用什么几何体,什么颜色
- 碰撞属性(collision):用于物理碰撞检测的简化模型
- 惯性属性(inertial):质量、质心、惯性张量,用于动力学仿真
来看一个最简单的link例子:
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.15" radius="0.10"/>
</geometry>
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.15" radius="0.10"/>
</geometry>
</collision>
<inertial>
<mass value="2.0"/>
<inertia ixx="0.01" ixy="0" ixz="0"
iyy="0.01" iyz="0"
izz="0.02"/>
</inertial>
</link>
3.1.2 joint标签
joint连接两个link,定义了它们之间的相对运动关系。joint有六种类型,但咱们做移动机器人底盘,常用的就两种:
| 类型 | 说明 | 自由度 | 典型应用 |
|---|---|---|---|
| fixed | 固定关节,两个link之间没有相对运动 | 0 | 传感器支架、外壳 |
| continuous | 连续旋转关节,没有角度限制 | 1 | 轮子、转台 |
| revolute | 有限旋转关节,有角度范围限制 | 1 | 机械臂关节 |
| prismatic | 平移关节,沿一个轴滑动 | 1 | 升降机构 |
| planar | 平面关节,在平面内移动和旋转 | 3 | 全向轮底盘(较少用) |
| floating | 浮动关节,6自由度全自由 | 6 | 无人机、水下机器人 |
写joint的时候,最关键的是搞清楚origin和axis。origin定义了子link相对于父link的位置和姿态。axis定义了关节的旋转轴或平移轴。
来看一个轮子joint的例子:
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel_link"/>
<origin xyz="0.15 0.12 -0.05" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
<limit effort="10" velocity="5"/>
</joint>
3.2 使用xacro优化模型
URDF写多了你就会发现,很多重复的内容。比如四个轮子,每个轮子的link和joint结构几乎一样,只是位置不同。这时候,xacro就派上用场了。
xacro是XML Macros的缩写,说白了就是给URDF加了个「宏」的功能。你可以定义变量、写函数、做数学运算。我个人觉得,xacro是URDF建模的「生产力工具」。
3.2.1 定义属性
用xacro,你可以把尺寸、颜色、质量这些参数提取出来,统一管理:
<?xml version="1.0"?>
<robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="wheel_radius" value="0.05"/>
<xacro:property name="wheel_width" value="0.03"/>
<xacro:property name="base_length" value="0.30"/>
<xacro:property name="base_width" value="0.20"/>
<xacro:property name="base_height" value="0.10"/>
<xacro:property name="material_blue" value="0 0 0.8 1"/>
这样改参数的时候,只需要改最上面几行,不用满文件找数字。我在做项目时,经常要调轮距、轴距这些参数,用xacro属性改起来特别方便。
3.2.2 定义宏
宏是xacro最强大的功能。你可以把重复的结构封装起来,像函数一样调用:
<xacro:macro name="wheel" params="prefix x y">
<link name="${prefix}_wheel_link">
<visual>
<geometry>
<cylinder length="${wheel_width}" radius="${wheel_radius}"/>
</geometry>
<material name="gray">
<color rgba="0.5 0.5 0.5 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="${wheel_width}" radius="${wheel_radius}"/>
</geometry>
</collision>
</link>
<joint name="${prefix}_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/>
<origin xyz="${x} ${y} -${base_height/2 - wheel_radius}" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
</xacro:macro>
然后调用的时候,一行就搞定一个轮子:
<xacro:wheel prefix="left_front" x="0.12" y="0.10"/>
<xacro:wheel prefix="right_front" x="0.12" y="-0.10"/>
<xacro:wheel prefix="left_back" x="-0.12" y="0.10"/>
<xacro:wheel prefix="right_back" x="-0.12" y="-0.10"/>
3.3 在Rviz中显示机器人模型
模型写好了,怎么看到它?Rviz是ROS里最常用的可视化工具。要在Rviz里显示你的机器人模型,需要做两件事:
- 启动一个发布机器人状态的节点(robot_state_publisher)
- 在Rviz中添加RobotModel显示插件
3.3.1 创建launch文件
我习惯写一个launch文件,一键启动所有东西:
<launch>
<!-- 加载URDF模型 -->
<param name="robot_description"
command="$(find xacro)/xacro '$(find my_robot_description)/urdf/my_robot.xacro'" />
<!-- 启动robot_state_publisher -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher">
<param name="publish_frequency" value="50.0"/>
</node>
<!-- 启动joint_state_publisher(用于手动调节关节) -->
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui"
type="joint_state_publisher_gui" />
<!-- 启动Rviz -->
<node name="rviz" pkg="rviz" type="rviz"
args="-d $(find my_robot_description)/config/display.rviz"/>
</launch>
3.3.2 在Rviz中配置显示
启动launch文件后,Rviz会打开。你需要手动添加RobotModel显示:
- 点击左下角的「Add」按钮
- 在列表中找到「RobotModel」
- 在「Description Topic」中选择「/robot_description」
如果一切正常,你的机器人模型就会出现在Rviz的3D视图中。你可以用鼠标拖拽旋转视角,从各个角度观察模型。
3.4 实战:搭建一个四轮差速底盘模型
理论说完了,咱们来点实际的。下面是一个完整的四轮差速底盘xacro文件的核心结构:
<?xml version="1.0"?>
<robot name="diff_drive_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="base_length" value="0.40"/>
<xacro:property name="base_width" value="0.30"/>
<xacro:property name="base_height" value="0.12"/>
<xacro:property name="wheel_radius" value="0.06"/>
<xacro:property name="wheel_width" value="0.04"/>
<!-- 底盘link -->
<link name="base_link">
<visual>
<geometry>
<box size="${base_length} ${base_width} ${base_height}"/>
</geometry>
<material name="blue">
<color rgba="0.2 0.2 0.8 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="${base_length} ${base_width} ${base_height}"/>
</geometry>
</collision>
</link>
<!-- 轮子宏定义 -->
<xacro:macro name="wheel" params="prefix side x y">
<link name="${prefix}_wheel">
<visual>
<geometry>
<cylinder length="${wheel_width}" radius="${wheel_radius}"/>
</geometry>
<material name="gray">
<color rgba="0.5 0.5 0.5 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="${wheel_width}" radius="${wheel_radius}"/>
</geometry>
</collision>
</link>
<joint name="${prefix}_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="${prefix}_wheel"/>
<origin xyz="${x} ${y} -${base_height/2}" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
</xacro:macro>
<!-- 四个轮子 -->
<xacro:wheel prefix="left_front" side="left"
x="${base_length/2 - 0.05}" y="${base_width/2 + 0.02}"/>
<xacro:wheel prefix="right_front" side="right"
x="${base_length/2 - 0.05}" y="-${base_width/2 + 0.02}"/>
<xacro:wheel prefix="left_back" side="left"
x="-${base_length/2 + 0.05}" y="${base_width/2 + 0.02}"/>
<xacro:wheel prefix="right_back" side="right"
x="-${base_length/2 + 0.05}" y="-${base_width/2 + 0.02}"/>
</robot>
这个模型虽然简单,但已经包含了差速底盘的核心结构。你可以在Rviz里看到它,并且通过joint_state_publisher_gui手动转动轮子,观察它们是否按预期旋转。
嗯,这一章的内容就到这。URDF建模看起来是体力活,但掌握了xacro之后,你会发现它其实很有规律。下一章咱们要聊的是「机器人运动学模型」,到时候你会用到今天建的底盘模型来做运动学解算。所以,今天的模型一定要跑通,别偷懒。
公众号:蓝海资料掘金营,微信deep3321