4. 创建第一个模型:使用几何体搭建简单机器人底盘、添加颜色与材质、保存模型

好,咱们正式开始动手了。

前面聊了那么多理论,说实话,我自己刚学Gazebo那会儿,最烦的就是光看不练。今天咱们就直接上手,用最基础的几何体——说白了就是立方体、圆柱体这些——搭一个最简单的机器人底盘。

别小看这一步。我当年带过一个实习生,上来就想搞复杂的URDF,结果连模型文件路径都配不对。嗯,咱们还是从地基开始,稳一点。

4.1 模型文件的结构

在Gazebo里,一个模型其实就是一个文件夹。里面至少要有两样东西:

  • model.config:模型的“身份证”,描述名字、作者、版本
  • model.sdf:模型的“身体”,描述长什么样、什么材质

我个人习惯把模型放在 ~/.gazebo/models/ 目录下。这样Gazebo启动时能自动识别。

小提示: 你也可以放在项目目录里,但需要手动设置 GAZEBO_MODEL_PATH 环境变量。新手建议先放默认路径,省心。

4.2 用几何体搭建底盘

咱们的目标很简单:一个扁平的立方体当底盘,四个圆柱体当轮子。听起来像小学生手工课?没错,但这就是机器人仿真的起点。

先看代码。创建一个文件夹 my_robot,里面放 model.config:

<?xml version="1.0"?>
<model>
  <name>My First Robot</name>
  <version>1.0</version>
  <sdf version="1.6">model.sdf</sdf>
  <author>
    <name>你的名字</name>
    <email>your@email.com</email>
  </author>
  <description>
    一个用几何体搭建的简单机器人底盘
  </description>
</model>

然后创建 model.sdf,这是核心:

<?xml version="1.0" encoding="UTF-8"?>
<sdf version="1.6">
  <model name="my_robot">
    <!-- 底盘:一个扁平的立方体 -->
    <link name="chassis">
      <pose>0 0 0.05 0 0 0</pose>
      <collision name="collision">
        <geometry>
          <box>
            <size>0.4 0.3 0.1</size>
          </box>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <box>
            <size>0.4 0.3 0.1</size>
          </box>
        </geometry>
        <material>
          <ambient>0.2 0.5 0.8 1</ambient>
          <diffuse>0.2 0.5 0.8 1</diffuse>
        </material>
      </visual>
    </link>

    <!-- 左前轮 -->
    <link name="left_front_wheel">
      <pose>-0.15 0.15 -0.05 0 1.5708 0</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.1 0.1 0.1 1</ambient>
          <diffuse>0.1 0.1 0.1 1</diffuse>
        </material>
      </visual>
    </link>

    <!-- 右前轮 -->
    <link name="right_front_wheel">
      <pose>-0.15 -0.15 -0.05 0 1.5708 0</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.1 0.1 0.1 1</ambient>
          <diffuse>0.1 0.1 0.1 1</diffuse>
        </material>
      </visual>
    </link>

    <!-- 左后轮 -->
    <link name="left_back_wheel">
      <pose>0.15 0.15 -0.05 0 1.5708 0</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.1 0.1 0.1 1</ambient>
          <diffuse>0.1 0.1 0.1 1</diffuse>
        </material>
      </visual>
    </link>

    <!-- 右后轮 -->
    <link name="right_back_wheel">
      <pose>0.15 -0.15 -0.05 0 1.5708 0</pose>
      <collision name="collision">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
      </collision>
      <visual name="visual">
        <geometry>
          <cylinder>
            <radius>0.05</radius>
            <length>0.04</length>
          </cylinder>
        </geometry>
        <material>
          <ambient>0.1 0.1 0.1 1</ambient>
          <diffuse>0.1 0.1 0.1 1</diffuse>
        </material>
      </visual>
    </link>
  </model>
</sdf>

代码看着长,其实结构很简单。每个 <link> 就是一个零件,里面分 collision(碰撞体)和 visual(视觉体)。

核心要点: collision 负责物理碰撞,visual 负责显示。两者可以不一样,但新手期建议保持一致,免得出现“看着没撞上,实际被卡住”的诡异情况。

4.3 添加颜色与材质

颜色怎么来的?看 <material> 标签里的 ambient 和 diffuse。这四个数字分别是 RGBA(红绿蓝透明度)。

比如底盘我用的是 0.2 0.5 0.8 1,就是淡蓝色。轮子用 0.1 0.1 0.1 1,深灰色,像橡胶。

为什么会这样设置?其实 ambient 是环境光下的颜色,diffuse 是漫反射颜色。简单点说,你调成一样的值就行,省事。

配色建议: 底盘用亮色(蓝、绿、红),轮子用暗色。这样在仿真里一眼就能看出机器人的朝向。我吃过亏,底盘和轮子都用灰色,结果在仿真里分不清前后,调试时差点把鼠标摔了。

4.4 保存模型并测试

把上面两个文件放到 ~/.gazebo/models/my_robot/ 目录下。然后启动Gazebo:

gazebo --verbose

在左侧模型面板里,找到 My First Robot,拖到场景中。你应该能看到一个蓝色底盘、四个黑色轮子的小车。

注意: 如果模型没出现,检查两点:一是 model.config 里的 <sdf> 文件名是否写对了;二是模型文件夹名字是否和 <model> 里的 name 一致。我曾经因为文件夹叫 my_robot 但模型名叫 my_robot_v2,折腾了半小时。

4.5 本章知识结构

下面这张图帮你理清思路:

创建第一个模型:知识结构 机器人模型 模型文件结构 几何体搭建 颜色与材质 model.config(身份证) model.sdf(身体) link(零件) collision + visual box / cylinder / sphere ambient(环境光) diffuse(漫反射) RGBA颜色值 保存到 ~/.gazebo/models/ 即可使用

嗯,到这里,你的第一个Gazebo模型就诞生了。虽然它还不能动,但你已经掌握了最核心的模型构建逻辑。后面咱们再给它加上关节、传感器,让它真正跑起来。

课后练习: 试着把底盘改成红色,轮子改成白色。看看颜色值怎么调?再试试把轮子半径改成0.08,看看效果。

可可精品资料库