ROS 2 从零开始完全指南学习笔记一

适用版本:Ubuntu 24.04 + ROS 2 Jazzy Jalisco
GitHub:github.com/PacktPublishing/ROS-2-from-Scratch


目录

  1. ROS 2 简介
  2. 安装与配置
  3. 核心概念探索
  4. 编写与构建节点

一、ROS 2 简介

1.1 什么是 ROS?

ROS(Robot Operating System) 不是传统意义上的操作系统,而是四大支柱的组合:

支柱 说明
框架 提供构建应用程序的规则,节点间通信由框架自动管理(plumbing)
工具集 命令行工具、日志系统、可视化工具(RViz)、模拟器(Gazebo)
即插即用插件 导航、运动规划等现成算法库,避免重复造轮子
在线社区 开源生态、Stack Exchange、ROS Discourse

1.2 为什么需要 ROS?

核心问题:机器人开发中反复"重新发明轮子"

传统开发流程:
设计机器人 → 开发底层驱动(数月)→ 开发应用核心(时间不足)
     ↑___________________________________________↓
                        下一个项目重复同样过程

ROS 的价值

  • 模块化开发:将应用拆分为独立节点(Node)
  • 通信抽象:节点间通信无需关心底层实现
  • 代码复用:即插即用的算法包(Navigation、MoveIt 等)
  • 仿真测试:Gazebo 物理仿真,脱离硬件开发

1.3 何时使用 ROS?

❌ 不需要 ROS ✅ 需要 ROS
简单的按钮触发拍照 激光雷达建图 + 自主导航
红外传感器控制门开关 多机械臂协同 + 传送带系统
循迹小车(Arduino 即可) 大量传感器/执行器的模块化系统
单一功能的硬件控制 需要 3D 仿真和路径规划

1.4 ROS 1 vs ROS 2

对比项 ROS 1 ROS 2
发布时间 2007 年 2014 年立项,2017 年首发
中间件 自定义 DDS(Data Distribution Service)
实时性 不支持 支持
安全性 较弱 工业级安全支持
生命周期 2025 年 5 月停止维护 持续活跃开发
推荐度 遗留系统维护 新项目首选

结论:ROS 2 是唯一推荐用于新项目的版本。


二、安装与配置

2.1 选择发行版

ROS 2 每年 5 月 23 日(世界乌龟日)发布新版本,采用字母顺序命名:

发行版 Ubuntu 版本 支持周期 类型
Humble Hawksbill 22.04 2022-2027 LTS(推荐)
Jazzy Jalisco 24.04 2024-2029 LTS(本书选用)
Rolling Ridley - 滚动更新 开发版(不稳定)

建议:选择最新的 LTS 版本,发布半年后使用(等待社区包迁移完善)。

2.2 安装 Ubuntu 24.04

方案 A:双启动(推荐)
  • 磁盘预留 ≥ 70GB
  • 下载 Ubuntu 24.04 ISO
  • 使用 Balena Etcher 制作启动盘
  • 安装时选择"与 Windows 共存"
方案 B:虚拟机(VirtualBox)

资源配置建议:

主机配置 建议分配
RAM ≥ 16GB 分配 6GB+
RAM = 8GB 分配 4GB
CPU 分配物理核心的一半(至少 2 核)
磁盘 动态分配,最大 40GB+

关键设置(避免图形问题):

系统 → 加速:取消勾选"启用嵌套分页"
显示 → 取消勾选"启用 3D 加速"
显示 → 视频内存调至 128MB

安装 Guest Additions(支持分辨率自适应和复制粘贴):

sudo apt install build-essential gcc make perl dkms
# 然后:设备 → 插入客户端增强功能 CD 镜像
sudo ./VBoxLinuxAdditions.run

2.3 安装 ROS 2 Jazzy

步骤 1:设置区域设置
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
export LANG=en_US.UTF-8
步骤 2:添加软件源
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:安装 ROS 2
sudo apt update
sudo apt upgrade

# 桌面版(推荐,包含工具和仿真)
sudo apt install ros-jazzy-desktop

# 开发工具
sudo apt install ros-dev-tools
步骤 4:环境配置
# 单次生效
source /opt/ros/jazzy/setup.bash

# 永久生效(添加到 ~/.bashrc)
echo 'source /opt/ros/jazzy/setup.bash' >> ~/.bashrc

验证安装

ros2 run turtlesim turtlesim_node

2.4 推荐开发工具

工具 安装命令 用途
VS Code sudo snap install code --classic IDE + ROS 扩展
Terminator sudo apt install terminator 多终端分屏
CMake 扩展 VS Code 插件市场搜索 twxs.cmake CMakeLists.txt 语法高亮

Terminator 常用快捷键:

  • Ctrl + Shift + O:水平分屏
  • Ctrl + Shift + E:垂直分屏
  • Ctrl + Shift + X:当前终端全屏/恢复
  • Ctrl + Shift + W:关闭当前终端

三、核心概念探索

目标:通过运行现有示例建立直觉,不编写代码。

3.1 节点(Node)

定义:ROS 2 中的基本执行单元,一个节点就是一个 ROS 程序。

# 启动 talker 节点
ros2 run demo_nodes_cpp talker

# 启动 listener 节点
ros2 run demo_nodes_cpp listener

可视化通信

rqt_graph

3.2 主题(Topic)

定义:节点间单向、连续的数据流通信机制。

# 列出所有主题
ros2 topic list

# 查看主题信息
ros2 topic info /chatter

# 查看消息类型定义
ros2 interface show std_msgs/msg/String

# 实时监听主题数据
ros2 topic echo /chatter

# 从终端发布消息
ros2 topic pub /chatter std_msgs/msg/String '{data: "hello"}'

核心特性

  • 发布者(Publisher)→ 主题(Topic)→ 订阅者(Subscriber)
  • 发布者与订阅者完全匿名,通过名称 + 接口类型匹配
  • 支持 N 对 N 通信

3.3 服务(Service)

定义:请求/响应模式的客户端/服务器通信,适合即时操作。

# 列出服务
ros2 service list

# 查看服务类型
ros2 service type /add_two_ints

# 查看服务接口定义
ros2 interface show example_interfaces/srv/AddTwoInts

# 从终端调用服务
ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts '{a: 4, b: 7}'

服务接口格式

int64 a      # 请求部分
int64 b
---
int64 sum    # 响应部分

3.4 动作(Action)

定义:用于长时间任务的客户端/服务器通信,支持反馈和取消。

# 列出动作
ros2 action list

# 查看动作信息
ros2 action info /turtle1/rotate_absolute -t

# 查看动作接口
ros2 interface show turtlesim/action/RotateAbsolute

# 发送动作目标
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute '{theta: 1.0}'

动作接口格式(三部分):

float32 theta      # Goal(目标)
---
float32 delta      # Result(结果)
---
float32 remaining  # Feedback(反馈)

3.5 参数(Parameter)

定义:节点运行时的配置设置。

# 列出节点参数
ros2 param list /turtlesim

# 获取参数值
ros2 param get /turtlesim background_b

# 启动时设置参数
ros2 run turtlesim turtlesim_node --ros-args -p background_b:=0 -p background_r:=0

3.6 启动文件(Launch File)

定义:从一个文件启动多个节点和配置。

# 启动 talker + listener
ros2 launch demo_nodes_cpp talker_listener_launch.py

# 启动多个 turtlesim
ros2 launch turtlesim multisim.launch.py

四、编写与构建节点

4.1 工作空间(Workspace)

# 创建工作空间
cd ~
mkdir -p ros2_ws/src
cd ros2_ws

# 构建(首次即可构建空工作空间)
colcon build

# 目录结构
ros2_ws/
├── build/    # 编译中间文件
├── install/  # 安装目录(含 setup.bash)
├── log/      # 编译日志
└── src/      # 源码目录

环境配置

# 将工作空间添加到 ~/.bashrc(注意顺序:先 ROS 2,后工作空间)
echo 'source /opt/ros/jazzy/setup.bash' >> ~/.bashrc
echo 'source ~/ros2_ws/install/setup.bash' >> ~/.bashrc

4.2 创建功能包

Python 包
cd ~/ros2_ws/src
ros2 pkg create my_py_pkg --build-type ament_python --dependencies rclpy

目录结构

my_py_pkg/
├── my_py_pkg/          # Python 包目录(节点放这里)
│   └── __init__.py
├── package.xml         # 包元数据和依赖
├── setup.py            # 构建和入口点配置
├── setup.cfg
├── resource/
└── test/
C++ 包
cd ~/ros2_ws/src
ros2 pkg create my_cpp_pkg --build-type ament_cmake --dependencies rclcpp

目录结构

my_cpp_pkg/
├── CMakeLists.txt      # 编译配置
├── include/my_cpp_pkg/ # 头文件
├── package.xml
└── src/                # C++ 源文件

4.3 Python 节点开发

完整模板
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node

class MyCustomNode(Node):
    def __init__(self):
        super().__init__("node_name")
        self.counter_ = 0
        self.timer_ = self.create_timer(1.0, self.timer_callback)
        self.get_logger().info("Node started")
    
    def timer_callback(self):
        self.get_logger().info(f"Hello {self.counter_}")
        self.counter_ += 1

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

if __name__ == "__main__":
    main()
配置 setup.py
entry_points={
    'console_scripts': [
        "test_node = my_py_pkg.my_first_node:main"
    ],
}

语法可执行名 = 包名.模块名:函数名

构建与运行
cd ~/ros2_ws
colcon build --packages-select my_py_pkg
source ~/.bashrc
ros2 run my_py_pkg test_node

Python 开发技巧:使用 --symlink-install 选项,修改代码后无需重新编译:

colcon build --packages-select my_py_pkg --symlink-install

4.4 C++ 节点开发

完整模板
#include "rclcpp/rclcpp.hpp"

class MyCustomNode : public rclcpp::Node
{
public:
    MyCustomNode() : Node("node_name"), counter_(0)
    {
        timer_ = this->create_wall_timer(
            std::chrono::seconds(1),
            std::bind(&MyCustomNode::timer_callback, this));
    }

private:
    void timer_callback()
    {
        RCLCPP_INFO(this->get_logger(), "Hello %d", counter_);
        counter_++;
    }
    
    int counter_;
    rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<MyCustomNode>();
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}
配置 CMakeLists.txt
find_package(rclcpp REQUIRED)

add_executable(test_node src/my_first_node.cpp)
ament_target_dependencies(test_node rclcpp)

install(TARGETS
  test_node
  DESTINATION lib/${PROJECT_NAME}/
)

ament_package()
构建与运行
cd ~/ros2_ws
colcon build --packages-select my_cpp_pkg
source ~/.bashrc
ros2 run my_cpp_pkg test_node

4.5 节点检查工具

# 列出所有运行中的节点
ros2 node list

# 查看节点详细信息(发布/订阅的主题、服务、动作)
ros2 node info /node_name

# 运行时重命名节点
ros2 run my_py_pkg test_node --ros-args -r __node:=new_name

4.6 关键概念对比表

概念 通信模式 适用场景 命令前缀
Topic 发布/订阅,单向流 传感器数据、连续状态 ros2 topic
Service 请求/响应,同步 即时计算、简单命令 ros2 service
Action 目标/反馈/结果,异步 长时间任务、可取消 ros2 action
Parameter 节点内部配置 运行时设置 ros2 param

4.7 开发流程速查

创建节点流程:
1. 进入工作空间 src 目录
2. 创建/修改包
3. 编写节点代码(Python/C++)
4. 配置构建文件(setup.py / CMakeLists.txt)
5. cd ~/ros2_ws && colcon build --packages-select <pkg>
6. source ~/.bashrc(或 source install/setup.bash)
7. ros2 run <pkg> <executable>

附录:常见问题速查

问题 解决方案
ros2: command not found 执行 source /opt/ros/jazzy/setup.bash
修改代码后未生效 重新执行 colcon buildsource 环境
No executable found 检查 setup.pyCMakeLists.txt 的入口点配置
节点名冲突 使用 --ros-args -r __node:=unique_name
Python 包找不到 确认 package.xml 中已声明依赖

一键安装
从零开始的 ROS2 指南(一)

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐