2. 搭建仿真环境(Gazebo)

说实话,很多同学学机器人,第一步就卡在“没真机”上。一台协作臂动辄几万块,总不能为了学个控制就去砸锅卖铁吧?

所以,仿真环境就是你的“免费真机”。这一课,我们就来搞定它。

2.1 环境准备:ROS Noetic + Gazebo 的安装与配置

我个人的习惯是,先装好 Ubuntu 20.04,然后一气呵成把 ROS Noetic 和 Gazebo 都配好。为什么选 Noetic?因为它和 Gazebo 11 是官方推荐的“黄金搭档”,兼容性最好,坑最少。

2.1.1 安装 ROS Noetic

打开终端,一行一行来,别急着复制粘贴一整段。我见过太多人因为网络问题装到一半卡死,结果还得重来。

# 添加 ROS 源
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'

# 添加密钥
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E866D0B7B8B

# 更新并安装完整桌面版
sudo apt update
sudo apt install ros-noetic-desktop-full

安装完成后,别忘了初始化 rosdep。这一步很多人会忘,结果后面跑起来各种找不到依赖。

sudo rosdep init
rosdep update

然后设置环境变量,让它每次打开终端都自动加载:

echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
小技巧: 如果你用的是 zsh,记得把 .bashrc 改成 .zshrc。我曾经在这上面浪费了十分钟,死活找不到 ros 命令。

2.1.2 验证 Gazebo 是否安装成功

ROS Noetic 桌面完整版自带 Gazebo 11。你可以在终端输入:

gazebo --version

如果看到类似 Gazebo multi-robot simulator, version 11.x.x 的输出,那就成了。我第一次看到这个版本号时,心里踏实了不少——至少环境没装歪。

你也可以直接启动 Gazebo 看看界面:

gazebo

嗯,第一次启动可能会有点慢,因为它要加载一堆模型库。耐心等一会儿就好。

2.2 创建你的第一个机器人 URDF 模型

URDF 是啥?说白了,就是用 XML 格式描述机器人长什么样、关节在哪、能怎么动。我刚开始学的时候觉得这东西很繁琐,但用多了你会发现,它其实特别直观。

2.2.1 最简单的两连杆机械臂

我们先做一个只有两个连杆、一个关节的“迷你机械臂”。它虽然简单,但包含了 URDF 的核心要素:link(连杆)和 joint(关节)。

创建一个文件夹,放我们的模型文件:

mkdir -p ~/my_robot_description/urdf
cd ~/my_robot_description/urdf

然后新建一个文件 simple_arm.urdf,内容如下:

<?xml version="1.0"?>
<robot name="simple_arm">

  <!-- 基座 -->
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.2 0.2 0.1"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <material name="blue">
        <color rgba="0 0 1 1"/>
      </material>
    </visual>
  </link>

  <!-- 第一个关节:旋转关节 -->
  <joint name="joint1" type="revolute">
    <parent link="base_link"/>
    <child link="link1"/>
    <origin xyz="0 0 0.05" rpy="0 0 0"/>
    <axis xyz="0 0 1"/>
    <limit lower="-3.14" upper="3.14" effort="10" velocity="1"/>
  </joint>

  <!-- 第一个连杆 -->
  <link name="link1">
    <visual>
      <geometry>
        <cylinder length="0.3" radius="0.02"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0.15"/>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>

</robot>
关键点解析:
  • revolute 表示旋转关节,像人的胳膊肘一样只能转圈
  • axis 定义旋转轴,这里是绕 Z 轴旋转
  • limit 里的 lower/upper 是角度范围,单位是弧度

2.2.2 用 check_urdf 验证模型

写完了别急着用,先检查一下语法对不对:

sudo apt install liburdfdom-tools
check_urdf simple_arm.urdf

如果输出类似 robot name is: simple_arm 且没有 error,恭喜你,模型写对了。我第一次写的时候把 child link 拼成了 child_link,结果检查了半天才发现少了个空格——这种坑,你迟早也会遇到。

2.3 在 Gazebo 中加载模型并实现基本控制

模型有了,怎么让它动起来?我们需要一个 launch 文件来把 URDF 喂给 Gazebo。

2.3.1 创建 launch 文件

在 ~/my_robot_description 下新建 launch 文件夹,然后创建 display.launch:

<launch>
  <!-- 启动 Gazebo 世界 -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="paused" value="false"/>
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="true"/>
    <arg name="headless" value="false"/>
    <arg name="debug" value="false"/>
  </include>

  <!-- 将 URDF 加载到参数服务器 -->
  <param name="robot_description" textfile="$(find my_robot_description)/urdf/simple_arm.urdf"/>

  <!-- 在 Gazebo 中生成机器人 -->
  <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" 
        args="-param robot_description -urdf -model simple_arm" />
</launch>

注意,这里 $(find my_robot_description) 需要你的包路径正确。我建议你把整个文件夹做成一个 ROS 包,这样路径管理会清爽很多。

2.3.2 启动并观察

运行 launch 文件:

roslaunch my_robot_description display.launch

如果一切顺利,你会看到 Gazebo 界面里出现了一个蓝色底座、红色手臂的小家伙。那一刻,说实话,还挺有成就感的。

2.3.3 用命令行控制关节

Gazebo 里的机器人默认是“死”的,需要你给它发指令才能动。我们用 ROS 的 joint_state_publisher 来手动控制:

rosrun joint_state_publisher_gui joint_state_publisher_gui

这会弹出一个滑块窗口。拖动滑块,你会发现机械臂的红色连杆开始旋转了!

注意: 如果滑块窗口没出现,检查一下你的 ROS 环境变量是否设置正确。我曾经在虚拟机上因为显示问题折腾了半天,最后发现是 DISPLAY 变量没设对。

2.4 本章知识体系总览

下面这张图,是我自己总结的“仿真迁移第一步”的核心逻辑。你看完这一课,应该能把这个图印在脑子里:

仿真环境搭建核心流程 ROS Noetic 操作系统层 通信、节点管理 URDF 模型 描述层 连杆、关节、几何 Gazebo 仿真 执行层 物理引擎、可视化 安装配置 rosdep init → 环境变量 编写与验证 check_urdf 语法检查 加载与控制 spawn_model → 滑块控制 最终目标:在仿真中看到机器人并控制它运动 为后续“仿真→真机”迁移打下基础

2.5 避坑指南 & 个人经验

  • 模型加载后 Gazebo 崩溃? 我曾经遇到过 URDF 里缺少 <inertial> 标签导致 Gazebo 直接闪退。解决办法:给每个 link 加上惯性参数,哪怕质量设成 0.1 都行。
  • 滑块控制没反应? 检查一下 joint_state_publisher 是否发布了正确的关节名。URDF 里的 joint name 必须和发布的一致。
  • Gazebo 启动太慢? 第一次启动确实慢,因为要下载模型数据库。你可以把 ~/.gazebo/models 里的内容提前下载好,或者设置离线模式。
我的小习惯: 每次修改 URDF 后,我都会先跑一遍 check_urdf,再启动 Gazebo。这能省下至少一半的调试时间。你想想看,要是等 Gazebo 加载完了才发现语法错误,那得多浪费时间?

好了,到这里,你已经成功搭建了仿真环境,并且让一个简单的机械臂在 Gazebo 里动了起来。这一步虽然基础,但它是整个“仿真迁移”课程的基石。后面的所有内容——从运动规划到真机部署——都建立在这个环境之上。

记住,仿真不是终点,而是通往真机的桥梁。把这一步走扎实了,后面你会感谢自己的。