4. 搭建你的第一个仿真世界:创建地面、添加墙壁、放置障碍物、保存世界文件
好,咱们现在开始动手了。
前面几章我们把 Gazebo 的界面、模型库、插件这些概念捋了一遍。说实话,光看不练容易忘。我自己的习惯是,学一个新工具,第一件事就是搭一个能跑起来的场景。哪怕只是一个地面加几堵墙,也比看十遍文档强。
这一章,我们就来亲手搭建第一个仿真世界。目标很明确:创建地面、添加墙壁、放置障碍物,最后把这个世界保存成文件。你想想看,以后每次启动 Gazebo 都能直接加载你设计的场景,是不是挺有成就感的?
4.1 创建地面:仿真世界的基石
地面是仿真世界的基础。没有地面,机器人一启动就会「掉入虚空」。嗯,这里要注意,Gazebo 默认启动时其实自带一个地面,但我们自己搭建世界时,通常要显式地添加它,方便后续调整纹理、尺寸等属性。
操作步骤:
- 启动 Gazebo(空世界模式):
gazebo --verbose worlds/empty.world - 点击左侧面板的「Insert」选项卡。
- 在模型列表中,找到
Ground Plane,拖拽到仿真视口中。 - 或者,你也可以通过菜单栏:
Edit → Insert Model → Ground Plane。
Building Editor 来创建地面,但初学者直接用拖拽的方式更直观。拖进去之后,地面会自动吸附到 y=0 平面,不用手动调整位置。
如果你想让地面看起来更真实一点,可以右键地面,选择 Edit Model,然后在 Visual 标签页里修改材质(Material)。比如改成草地纹理或者水泥纹理。我在项目中遇到过,仿真环境的地面纹理太滑,导致轮式机器人打滑,后来换成粗糙纹理才解决。
4.2 添加墙壁:给你的世界画个边界
地面有了,接下来要加墙壁。墙壁的作用不只是好看——它能让机器人知道「边界在哪里」。我曾经见过一个新手,没加墙壁,机器人直接跑出视野,然后撞到 Gazebo 的「世界边界」上,物理引擎直接报错。
添加墙壁的方法有两种:
| 方法 | 说明 | 适用场景 |
|---|---|---|
| 拖拽模型 | 从模型库拖拽 Wall 或 Box 模型 |
快速搭建原型 |
| 手动创建 SDF | 编写 .sdf 文件定义墙壁尺寸和位置 |
精确控制、批量生成 |
我们先讲第一种,拖拽方式:
- 在「Insert」面板中,找到
Wall模型(如果没有,可以用Box代替)。 - 拖拽到场景中,调整位置和朝向。
- 右键墙壁 →
Edit Model,可以修改长宽高。
第二种方式,用 SDF 文件。我个人更推荐这种方式,因为可重复性高。比如你要搭一个 10m×10m 的方形围墙,手动拖拽四个墙壁太慢了,而且对齐很麻烦。用代码写,几行就搞定。
<?xml version="1.0" ?>
<sdf version="1.6">
<model name="wall_north">
<static>true</static>
<link name="link">
<collision name="collision">
<geometry>
<box>
<size>10.0 0.2 1.0</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>10.0 0.2 1.0</size>
</box>
</geometry>
<material>
<ambient>0.8 0.8 0.8 1.0</ambient>
</material>
</visual>
</link>
<pose>0.0 5.0 0.5 0 0 0</pose>
</model>
</sdf>
<static>true</static>。否则机器人一撞,墙壁就飞了。我刚开始做仿真时忘了加这个,结果机器人轻轻碰了一下墙壁,墙壁直接弹到天上去了……嗯,那画面挺滑稽的。
4.3 放置障碍物:让世界有点挑战
光有墙壁还不够,我们得放点障碍物。障碍物可以是箱子、圆柱、球体,甚至是一些复杂的形状。说白了,就是给机器人制造一些「麻烦」,测试它的避障能力。
常用障碍物类型:
- 箱子(Box):最常用,适合模拟货架、石块等。
- 圆柱(Cylinder):模拟柱子、树干。
- 球体(Sphere):模拟石头、路障。
- 自定义模型:用
.stl或.dae文件导入复杂形状。
放置障碍物的操作和墙壁类似。我建议你试试拖拽一个 Box 到场景中,然后右键编辑它的尺寸和颜色。比如,把箱子涂成红色,方便视觉识别。
<!-- 一个红色箱子的 SDF 示例 -->
<model name="red_box">
<static>false</static>
<link name="link">
<collision name="collision">
<geometry>
<box>
<size>0.5 0.5 0.5</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>0.5 0.5 0.5</size>
</box>
</geometry>
<material>
<ambient>1.0 0.0 0.0 1.0</ambient>
</material>
</visual>
<pose>2.0 0.0 0.25 0 0 0</pose>
</link>
</model>
<static> 设成 false,结果机器人一碰,箱子就滚走了。如果你希望障碍物固定不动,记得设成 true。但如果你想要可推动的障碍物(比如测试机器人推力),就设成 false。
4.4 保存世界文件:把你的劳动成果存下来
场景搭好了,不保存等于白干。Gazebo 的世界文件是 .world 格式,本质上是一个 SDF 文件,里面包含了所有模型、灯光、物理参数等信息。
保存方法:
- 在 Gazebo 菜单栏中,点击
File → Save World As...。 - 选择保存路径,输入文件名,比如
my_first_world.world。 - 点击保存。
保存后,你可以用文本编辑器打开这个文件看看。里面记录了所有你添加的模型、它们的位置、颜色、物理属性等。以后启动 Gazebo 时,直接加载这个文件:
gazebo --verbose my_first_world.world
worlds/ 目录下,方便管理。比如 ~/catkin_ws/src/my_robot/worlds/。这样在 launch 文件中引用也很方便。
另外,保存时要注意:如果你在场景中修改了模型(比如调整了尺寸),Gazebo 会把这些修改记录到世界文件中。但如果你修改的是模型库里的原始模型,那不会影响世界文件。嗯,这里要区分清楚。
4.5 本章知识体系
为了让你更直观地理解这一章的内容结构,我画了一张流程图。它展示了从零开始搭建一个仿真世界的完整路径。
你看,整个流程其实很线性。从地面开始,到墙壁,到障碍物,最后保存。每一步都有两种实现方式:拖拽(适合快速验证)和 SDF 文件(适合精确控制)。我个人建议你两种都试试,先拖拽感受一下,再用 SDF 文件写一遍,这样理解更深。
好了,这一章的内容就到这里。你搭建的第一个仿真世界已经可以跑起来了。接下来,你可以试着往里面加更多模型,或者调整物理参数,看看效果有什么不同。
可可精品资料库