文章目录
- 告别重复代码:Xacro让URDF编写效率翻倍
- 一、Xacro到底解决了什么问题?
- 二、Xacro基础语法:先掌握这5个核心
- 1. 第一步:声明Xacro命名空间(必写!)
- 2. 变量定义与引用:`<xacro:property>`
- (1)定义变量
- (2)引用变量
- 3. 数学计算:直接在`${}`中写公式
- 4. 宏定义:`<xacro:macro>`——复用代码的核心
- (1)定义宏
- (2)调用宏
- 5. 条件判断:`<xacro:if>`/`<xacro:choose>`——按需生成代码
- (1)单条件判断:`<xacro:if>`
- (2)多条件判断:`<xacro:choose>`
- 三、Xacro进阶语法:循环与文件包含(复杂机器人必备)
- 1. 循环生成:`<xacro:for>`——批量创建重复部件
- 2. 文件包含:`<xacro:include>`——模块化拆分代码
- (1)目录结构(推荐)
- (2)包含子文件
- 四、多场景Xacro实战示例(小白可直接复用)
- 场景1:两轮差分机器人(基础款)
- 场景2:传感器挂载模板(可复用)
- 场景3:运行时动态传参(适配不同配置)
- (1)Xacro文件(保留参数变量)
- (2)终端传参转换
- 五、Xacro实操步骤:从编写到转换
- 1. 编写Xacro文件
- 2. 转换为URDF
- 3. 验证转换结果
- 4. 可视化验证
- 六、小白必避的Xacro坑
- 七、Xacro与纯URDF对比
- 总结
告别重复代码:Xacro让URDF编写效率翻倍
在上一篇文章中,我们掌握了URDF的核心语法,但如果要编写复杂机器人(比如6轴机械臂、多轮机器人),纯URDF会充斥大量重复代码——相同的连杆结构写十遍、相似的关节参数改来改去,既费时间又容易出错。这时候就需要URDF的“增强版工具”——Xacro登场了。
Xacro(XML Macros)是ROS(包括ROS2)专为URDF设计的宏扩展工具,核心是通过变量、宏、循环、条件判断等特性,让URDF编写从“复制粘贴”变成“参数化配置”。本文作为小白专属指南,会从基础语法到多场景实战,带你吃透Xacro的所有核心用法,示例覆盖轮式机器人、机械臂、传感器挂载等常见场景,确保你学完就能用。
一、Xacro到底解决了什么问题?
先看一个痛点:如果用纯URDF写两个车轮,需要写两套几乎一样的<link>和<joint>;而用Xacro,只需写一套模板,通过变量替换就能生成左右车轮。
Xacro的核心优势总结为4点:
| 特性 | 解决的问题 | 直观感受 |
|---|---|---|
| 变量定义 | 避免硬编码数值,改参数只需改一处 | 把“底座长0.4米”改成“底座长0.5米”,不用翻遍整个文件 |
| 宏定义 | 复用重复的连杆/关节代码 | 机械臂6个关节,写1个宏就能生成6个 |
| 数学计算 | 自动计算位姿/尺寸,避免手动算错 | 车轮安装位置=底座长度/2 + 车轮半径,直接写公式即可 |
| 条件/循环 | 按需生成代码,适配多场景 | 仿真时加载传感器、实机时不加载,一套代码两用 |
关键认知:Xacro文件后缀是
.xacro,本质是“带语法糖的URDF”,最终必须编译成标准.urdf文件才能被ROS2识别。
二、Xacro基础语法:先掌握这5个核心
Xacro是XML的扩展,所以基础结构和URDF一致,只需额外掌握5个核心语法,我们逐个拆解,每个语法都配小白能看懂的示例。
1. 第一步:声明Xacro命名空间(必写!)
所有Xacro文件的<robot>根节点必须声明Xacro命名空间,否则所有Xacro指令都会失效。
正确写法:
<?xml version="1.0"?><robotname="my_robot"xmlns:xacro="http://www.ros.org/wiki/xacro"><!-- 上面必须加xmlns:xacro="http://www.ros.org/wiki/xacro",且必须在第二行 --><!-- 所有Xacro/URDF代码写在这里 --></robot>2. 变量定义与引用:<xacro:property>
(1)定义变量
用<xacro:property>定义变量,name是变量名,value是变量值(支持数值、字符串、列表)。
<!-- 定义单个数值变量:车轮半径(米) --><xacro:propertyname="wheel_radius"value="0.1"/><!-- 定义列表变量:底座尺寸(长×宽×高) --><xacro:propertyname="base_size"value="0.4 0.2 0.1"/><!-- 定义字符串变量:机器人类型 --><xacro:propertyname="robot_type"value="diff_drive"/>(2)引用变量
用${变量名}引用变量,所有变量必须包裹在${}中,这是Xacro的核心语法!
<!-- 引用单个变量:车轮几何形状 --><geometry><cylinderlength="0.05"radius="${wheel_radius}"/></geometry><!-- 引用列表变量:底座尺寸(按索引取,从0开始) --><geometry><boxsize="${base_size[0]} ${base_size[1]} ${base_size[2]}"/></geometry>3. 数学计算:直接在${}中写公式
Xacro支持加减乘除、三角函数、幂运算等基础计算,无需额外工具,直接在${}中写公式即可。
常用计算示例:
<!-- 基础运算:车轮安装z轴位置 = -车轮半径 --><xacro:propertyname="wheel_z"value="${-wheel_radius}"/><!-- 三角函数:绕x轴旋转90度(π/2弧度) --><xacro:propertyname="wheel_rotate"value="${-pi/2}"/><!-- 幂运算:立方体惯性矩阵计算(简化版) --><xacro:propertyname="ixx"value="${mass*(base_size[1]^2 + base_size[2]^2)/12}"/>4. 宏定义:<xacro:macro>——复用代码的核心
宏是Xacro最实用的功能,把重复的<link>/<joint>封装成“模板”,调用时只需传参数,告别复制粘贴。
(1)定义宏
语法:<xacro:macro params="参数1;参数2;参数3:=默认值">
params:宏的参数,多个参数用分号分隔;参数:=默认值:给参数设置默认值,调用时可省略。
示例:封装连杆宏
<!-- 定义连杆宏:参数包括名称、尺寸、质量、颜色(颜色有默认值) --><xacro:macroname="create_link"params="name;size;mass;color:=gray"><linkname="${name}"><visual><originxyz="0 0 0"rpy="0 0 0"/><geometry><boxsize="${size}"/></geometry><materialname="${color}"/></visual><collision><originxyz="0 0 0"rpy="0 0 0"/><geometry><boxsize="${size}"/></geometry></collision><inertial><massvalue="${mass}"/><inertiaixx="${mass*0.001}"ixy="0.0"ixz="0.0"iyy="${mass*0.001}"iyz="0.0"izz="${mass*0.001}"/></inertial></link></xacro:macro>(2)调用宏
语法:<xacro:宏名 参数1="值1" 参数2="值2"/>
示例:调用连杆宏生成底座
<!-- 调用宏:生成底座连杆(覆盖颜色参数,用蓝色) --><xacro:create_linkname="base_link"size="${base_size}"mass="3.0"color="blue"/><!-- 调用宏:生成支架连杆(用默认颜色gray) --><xacro:create_linkname="support_link"size="0.1 0.1 0.2"mass="1.0"/>5. 条件判断:<xacro:if>/<xacro:choose>——按需生成代码
用于“不同场景生成不同代码”,比如仿真时加载传感器、实机时不加载。
(1)单条件判断:<xacro:if>
<!-- 定义变量:是否启用Gazebo仿真 --><xacro:propertyname="use_gazebo"value="true"/><!-- 条件判断:如果是仿真,就加载传感器 --><xacro:ifvalue="${use_gazebo}">