2、我的第一个仿真世界:创建空白世界、添加静态物体、认识SDF文件格式。
说实话,学Gazebo最怕什么?就是打开软件后面对一片空白,不知道从哪下手。
我当年第一次用Gazebo时,对着空荡荡的界面愣了好几分钟。后来才发现,其实建一个仿真世界,就跟搭积木一样简单。咱们今天就走一遍这个过程。
2.1 创建一个空白世界
先别急着加东西。咱们从零开始,建一个干干净净的世界。
在终端里输入:
gazebo --verbose worlds/empty.world
你会看到一个灰色的地面,上面啥也没有。嗯,这就是我们的“画布”。
我个人习惯用 --verbose 参数,它能打印出启动过程中的详细信息。万一出问题,看日志就能定位。
~/.bashrc 里加一行 alias gz='gazebo --verbose',之后直接敲 gz 就行。
2.2 添加静态物体
空白世界太无聊了。咱们加点东西进去。
点击上方菜单栏的 Insert 标签,你会看到一堆预设模型。选一个 cinder block(煤渣砖块),点一下,然后在地面上点一下放置。
就这么简单?对,就这么简单。
但这里有个坑——我刚开始做项目时,放了一堆物体进去,结果一运行仿真,物体全掉地上了。为什么?因为我没注意物体的 静态属性。
在Gazebo里,你可以右键点击物体,选择 Open Link Inspector,在 Kinematic 选项卡里勾选 Static。这样物体就“焊死”在地上了。
我建议初学者先玩10分钟,把各种预设模型都拖出来试试。感受一下物体的物理行为。
2.3 认识SDF文件格式
刚才拖进去的物体,其实背后都有一个文本描述文件。这个文件就是 SDF(Simulation Description Format)。
SDF是Gazebo的亲儿子格式。它用XML语法描述一个仿真世界里的所有东西:
- 世界属性(重力、光照、物理引擎)
- 模型属性(形状、大小、颜色、质量)
- 关节属性(连接方式、运动范围)
- 传感器属性(摄像头、激光雷达、IMU)
咱们打开刚才那个空白世界的SDF文件看看:
<?xml version="1.0" ?>
<sdf version="1.6">
<world name="default">
<include>
<uri>model://ground_plane</uri>
</include>
<include>
<uri>model://sun</uri>
</include>
</world>
</sdf>
你看,一个空白世界其实包含了两样东西:一个地面(ground_plane)和一个太阳(sun)。没有太阳的话,你的世界就是黑的。
咱们来写一个自己的SDF文件,创建一个红色的立方体:
<?xml version="1.0" ?>
<sdf version="1.6">
<model name="my_red_box">
<static>true</static>
<link name="link">
<collision name="collision">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
<material>
<ambient>1 0 0 1</ambient>
</material>
</visual>
</link>
</model>
</sdf>
保存为 my_box.sdf,然后在Gazebo里加载:
gazebo --verbose my_box.sdf
你会看到一个红色的方块,稳稳地站在地面上。
<link>(刚体),每个link至少包含一个 <collision>(碰撞体)和一个 <visual>(可视化体)。碰撞体决定物理交互,可视化体决定你看到的样子。两者可以不一样——比如碰撞体用简单方块,可视化体用复杂模型,这样仿真跑得快。
2.4 本章知识体系
下面这张图帮你理清今天学的内容:
2.5 避坑指南
我刚开始写SDF文件时,踩过不少坑。分享几个给你:
- 颜色值写错:
<ambient>的四个数字是 RGBA,范围0到1。我当年把红色写成255 0 0 1,结果模型变成白色。因为255被截断成了1。 - 忘了加
<static>:放个桌子结果它掉地上了。嗯,后来我养成了习惯,凡是地面、墙壁、障碍物,一律加<static>true</static>。 - 碰撞体和可视化体不匹配:可视化体是个精细的椅子模型,碰撞体却是个大方块。结果机器人明明撞到椅子腿了,却穿模而过。因为碰撞体只检测那个大方块。
好了,今天的内容就到这。你现在应该能自己建一个空白世界,往里面放静态物体,并且看懂SDF文件的基本结构了。去试试吧,动手才是最好的学习方式。