第二章:开发环境基石——Ubuntu系统安装与配置、ROS2的安装与核心概念

各位同学,欢迎来到第二章。

上一章我们聊了轨迹规划的整体图景,说白了就是画了个大饼。但光画饼不行,咱们得真刀真枪地干。这一章,我们就来搭起真正的开发环境。

我个人习惯把环境搭建比作「打地基」。地基不稳,后面盖的楼再漂亮也得塌。我在项目里见过太多因为环境问题浪费一整天的情况——嗯,咱们今天就把这个坑填上。

2.1 Ubuntu系统安装与配置

为什么选Ubuntu?说白了,ROS2对Ubuntu的支持最好。你非要用Windows或者Mac,也不是不行,但你会发现自己像个异类——社区里的教程、工具链、甚至很多驱动,都是为Ubuntu量身定做的。

2.1.1 版本选择

我个人推荐 Ubuntu 22.04 LTS。为什么?

  • LTS代表长期支持,稳定,不会突然让你升级大版本
  • ROS2的Humble版本完美适配22.04
  • 我踩过20.04的坑,有些新库装不上,折腾半天
注意: 别装最新版的Ubuntu 24.04,虽然新,但很多ROS2包还没适配。你想想看,做项目最怕什么?最怕「我装好了,但跑不起来」。

2.1.2 安装流程

安装过程其实不复杂,我简单说几个关键点:

  1. 下载镜像:去Ubuntu官网下载22.04的ISO文件
  2. 制作启动盘:用Rufus(Windows)或者balenaEtcher(Mac)
  3. 分区建议:至少给Ubuntu留50GB空间,我建议100GB。为什么?后面装ROS2、仿真工具、各种依赖库,空间很快就吃掉了
  4. 双系统还是虚拟机? 如果你有独立显卡,建议双系统。虚拟机在图形渲染上会打折扣。我刚开始做仿真时用的虚拟机,结果Gazebo卡成PPT,后来老老实实装了双系统
小技巧: 安装时选择「最小安装」,省掉那些用不上的办公软件。后面缺什么再装什么,干净利落。

2.1.3 基础配置

装好系统后,第一件事是换源。国内访问Ubuntu官方源慢得让人抓狂。我曾经等一个apt update等了十分钟,后来换了阿里源,十秒搞定。

# 备份原源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

# 替换为阿里源
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

# 更新
sudo apt update && sudo apt upgrade -y

然后装一些基础工具:

sudo apt install -y git curl wget vim net-tools

这些工具后面都会用到。Git管理代码,curl和wget下载东西,vim应急改文件。嗯,别问我为什么不用nano——vim用习惯了,改文件快。

2.2 ROS2的安装

ROS2,全称Robot Operating System 2。名字叫操作系统,其实它是个中间件框架。说白了,它帮我们解决了机器人开发中「多个程序怎么互相说话」的问题。

2.2.1 选择版本

ROS2有很多发行版,对应不同的Ubuntu版本:

ROS2版本 对应Ubuntu 推荐场景
Humble Hawksbill 22.04 稳定,适合学习与生产
Iron Irwini 22.04 较新,但有些包不兼容
Rolling 最新版 尝鲜用,别用在项目里

我们选 Humble。为什么?我在项目里用过Iron,结果发现某个关键包还没发布,折腾了两天。Humble是LTS版本,支持到2027年,够我们用了。

2.2.2 安装步骤

安装ROS2其实就几条命令,但每一步都有坑。我带你走一遍:

# 1. 设置locale
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8

# 2. 添加ROS2源
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

# 3. 安装ROS2 Humble
sudo apt update
sudo apt install ros-humble-desktop -y

# 4. 安装开发工具
sudo apt install ros-dev-tools -y
避坑指南: 我曾经在第二步卡了半小时,因为网络问题下载不了ros.key。解决办法:手动下载key文件放到指定目录,或者换个时间段再试。另外,别用sudo pip安装ros2相关的包,会破坏系统依赖。

2.2.3 环境配置

装好之后,每次打开终端都要source一下才能用ROS2命令。我建议直接写到.bashrc里:

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

验证是否安装成功:

ros2 run demo_nodes_cpp talker

如果看到「Publishing: 'Hello World'」之类的输出,恭喜你,环境搭好了。

2.3 ROS2核心概念

好了,环境搭好了,我们来聊聊ROS2到底是个什么东西。我画了一张图,帮你理解它的核心逻辑:

节点A (传感器驱动) 节点B (轨迹规划器) 节点C (执行器控制) 节点D (可视化界面) 话题总线(Topic Bus) 发布 /scan 订阅 /scan 订阅 /cmd_vel 订阅 /scan 服务请求 服务响应 节点 话题 服务

这张图展示了ROS2的核心通信模式。你看,每个节点(Node)都是一个独立的程序,它们通过话题(Topic)和服务(Service)来交流。说白了,就是「发布-订阅」和「请求-响应」两种模式。

2.3.1 节点(Node)

节点是ROS2中最基本的执行单元。每个节点负责一个具体的功能。比如:

  • 一个节点读取激光雷达数据
  • 一个节点做轨迹规划
  • 一个节点控制电机

节点之间互相独立,一个节点挂了,不影响其他节点。我在项目里就遇到过,传感器节点崩溃了,但规划器还在跑,系统没有完全瘫痪——这就是分布式设计的好处。

创建一个节点很简单:

# Python示例
import rclpy
from rclpy.node import Node

class MyNode(Node):
    def __init__(self):
        super().__init__('my_node')
        self.get_logger().info('节点已启动!')

def main(args=None):
    rclpy.init(args=args)
    node = MyNode()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

2.3.2 话题(Topic)

话题是节点之间传递数据的「通道」。一个节点发布数据到话题,其他节点订阅这个话题来接收数据。这是一种异步通信方式——发布者不管有没有人订阅,它只管发;订阅者也不管谁在发,它只管收。

举个例子:

# 发布者
self.publisher_ = self.create_publisher(String, 'topic_name', 10)

# 订阅者
self.subscription = self.create_subscription(
    String, 'topic_name', self.callback, 10)

这里的10是队列大小。什么意思?如果订阅者处理不过来,消息会在队列里排队。我曾经把队列设成1,结果丢了好多数据,定位直接飘了。后来改成10,问题解决。

经验之谈: 话题的名字最好有层级结构,比如/robot/sensor/lidar,而不是/lidar_data。为什么?项目大了节点多了,命名空间能帮你避免冲突。我见过一个项目里三个节点都叫/data,调试的时候简直灾难。

2.3.3 服务(Service)

服务是另一种通信方式,它是同步的、一对一的。客户端发送请求,服务端处理并返回响应。适合那些需要「一问一答」的场景,比如:

  • 「帮我计算一下这个路径的代价」
  • 「当前机器人的位姿是多少?」

服务定义:

# 服务端
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_callback)

# 客户端
self.cli = self.create_client(AddTwoInts, 'add_two_ints')
req = AddTwoInts.Request()
req.a = 3
req.b = 5
future = self.cli.call_async(req)

注意,ROS2的服务是异步的。什么意思?你发请求的时候不会卡住,程序可以继续干别的事。等结果回来了,回调函数会处理。嗯,这个设计比ROS1好太多了。

2.4 工作空间与包管理

最后,我们聊聊怎么组织代码。ROS2用工作空间(Workspace)来管理多个功能包(Package)。

2.4.1 创建工作空间

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
colcon build

每次编译后,记得source一下:

source install/setup.bash

2.4.2 创建功能包

cd ~/ros2_ws/src
ros2 pkg create my_package --build-type ament_python --dependencies rclpy

这个命令会生成一个标准的包结构,包括setup.py、package.xml等文件。你只需要在my_package目录下写你的节点代码就行了。

核心要点:
  • 节点是独立的功能单元
  • 话题用于异步、多对多通信
  • 服务用于同步、一对一通信
  • 工作空间组织多个功能包

好了,这一章的内容就到这里。环境搭好了,概念也理清了,下一章我们就可以真正开始写轨迹规划的代码了。记住,基础打得牢,后面才跑得快。我在项目里见过太多人急着写代码,结果环境没配好,折腾半天——咱们不犯这个错。


可可精品资料库