ROS 2 机器人物理属性配置与 Gazebo 仿真导入
在 Rviz 中,机器人模型往往只是视觉展示,可以穿墙或悬空,因为它不受物理定律约束。而 Gazebo 提供了重力、摩擦力和碰撞检测。如果模型缺乏质量(Mass)或碰撞体积(Collision),它要么会掉进地心,要么会被物理引擎直接剔除。
为了让机器人在仿真环境中真正'活'过来,我们需要完成两个核心步骤:升级 Xacro 文件以添加惯性及碰撞属性,以及编写 Python 启动脚本将机器人实例化到 Gazebo 中。
封装惯性计算宏
手动计算转动惯量涉及复杂的微积分公式,容易出错。利用 Xacro 的宏定义功能,我们可以预先封装球体、圆柱和方块的惯性计算公式,方便复用。
在 .xacro 文件头部添加以下宏定义:
<xacro:macro name="inertial_sphere" params="mass radius">
<inertial>
<mass value="${mass}"/>
<inertia ixx="${(2/5) * mass * (radius*radius)}" ixy="0.0" ixz="0.0" iyy="${(2/5) * mass * (radius*radius)}" iyz="0.0" izz="${(2/5) * mass * (radius*radius)}"/>
</inertial>
</xacro:macro>
<xacro:macro name="inertial_cylinder" params="mass length radius">
<inertial>
<mass value="${mass}"/>
<inertia ixx="${(1/12) * mass * (3*radius*radius + length*length)}" ixy="0.0" ixz="0.0" iyy="${(1/12) * mass * (3*radius*radius + length*length)}" iyz="0.0" izz="${(1/2) * mass * (radius*radius)}"/>
</inertial>
</xacro:macro>
<xacro:macro name="inertial_box" params="mass x y z">
<inertial>
<mass value="${mass}"/>
<inertia ixx="${(1/12) * mass * (y*y+z*z)}" ixy="0.0" ixz="0.0" iyy="${(1/12) * mass * (x*x+z*z)}" iyz="0.0" izz="${(1/12) * mass * (x*x+y*y)}"/>
</inertial>
</xacro:macro>
定义碰撞几何体
修改 base_link、wheel_link 等部件,在 <visual> 标签同级目录下添加 <collision> 标签,并调用上述宏定义设置惯性。
以车身为例:
<link name="base_link">
<visual>
<geometry>
<box size="${base_length} ${base_width} ${base_height}"/>
</geometry>
<material name="blue"/>
</visual>
<collision>
<geometry>
<box size="${base_length} ${base_width} ${base_height}"/>
</geometry>
</collision>
<xacro:inertial_box mass="1.0" x="${base_length}" y="${base_width}" z="${base_height}"/>
</link>
编写 Gazebo 启动脚本
创建 launch/gazebo.launch.py,该脚本负责启动 Gazebo 服务、解析 Xacro 文件,并调用 spawn_entity 节点将机器人放入仿真环境。
(注:核心逻辑主要依赖 gazebo_ros 包中的 spawn_entity.py)
常见调试问题与解决方案
在开发过程中,几个经典的新手 Bug 值得注意。
根节点惯性报错
现象:运行 Launch 文件时,终端提示 KDL 不支持根节点带有惯性。
原因:ROS 规范建议机器人的底座应是一个没有重量的虚拟点,而我的 base_link 包含了重量信息。
解决:引入 base_footprint 作为虚拟底座。
在 xacro 文件最开头添加:
<link name="base_footprint"/>
<joint name="base_joint" type="fixed">
<parent link="base_footprint"/>
<child link="base_link"/>
<origin xyz="0 0 ${base_height/2.0}" rpy="0 0 0"/>
</joint>
模型颜色丢失
现象:Rviz 中车是蓝色的,但在 Gazebo 里显示为灰白色石膏模型。
原因:Gazebo 不识别 URDF 里的 <material name="blue">,它只认自己的 <gazebo> 标签。
解决:在 xacro 文件末尾,专门为 Gazebo 添加颜色标签:
<gazebo reference="base_link">
<material>Gazebo/Blue</material>
</gazebo>
<gazebo reference="left_wheel_link">
<material>Gazebo/Black</material>
</gazebo>
生成位置异常
现象:机器人生成后一半陷在地上,或者编译报错 mismatched tag。
解决:
- 卡地里:在 Launch 文件的
spawn_entity节点参数中添加-z 0.15,让机器人出生在半空中自然掉落。 - XML 报错:检查是否漏掉了闭合标签如
</link>,使用编辑器行号功能定位补全即可。
首次启动时若窗口显示为黑屏,通常是资源加载过程,请耐心等待。
最终效果验证
修复完成后,运行命令启动仿真。Gazebo 窗口弹出后,机器人从空中出现,稳稳落在地上,四个轮子着地,没有散架也没有乱飞。

总结
- Rviz vs Gazebo:Rviz 侧重可视化展示,Gazebo 负责物理仿真。
- 细节决定成败:路径错误、标签未闭合或物理属性缺失都会导致仿真失败。
- 后续计划:当前车辆仅能被动移动,下一步需集成 Differential Drive 插件以实现自主运动控制。
通过正确配置物理属性,我们成功消除了'幽灵车'现象,为后续的算法开发奠定了坚实的物理基础。
