Skip to content

ROS 2 环境搭建与第一个节点 ​

这篇笔记记录一次从干净系统到"两个节点互相通信"的完整过程。目标很明确:装好 ROS 2, 写一个发布者和一个订阅者,用命令行确认它们真的在通信,而不是只看终端有没有报错。

环境与前提 ​

  • Ubuntu 22.04 LTS(对应 ROS 2 Humble)或 Ubuntu 24.04 LTS(对应 ROS 2 Jazzy)
  • 能访问软件源,有 sudo 权限
  • 不需要预先安装 ROS 1,两者可以共存,但不要在同一终端里混用环境变量

先确认系统版本,避免装错发行版:

bash
lsb_release -a

安装 ROS 2 ​

以 Humble 为例,Jazzy 把下面的 humble 全部替换成 jazzy 即可。

bash
# 1. 准备密钥与软件源
sudo apt update && sudo apt install -y curl gnupg lsb-release
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

# 2. 安装基础桌面版
sudo apt update
sudo apt install -y ros-humble-desktop

# 3. 让当前 shell 认识 ROS 2
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

验证安装:

bash
ros2 --help
ros2 pkg list | head

如果 ros2 命令找不到,九成是 source 没生效或者写错了发行版名字。

创建工作空间 ​

工作空间就是放你自己包的目录,约定放在 ~/ros2_ws:

bash
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
colcon build
source install/setup.bash

colcon build 会在 src 之外生成 build/、install/、log/。 每次新开终端都要 source install/setup.bash,否则找不到自己编译的包。

写一个 Python 包 ​

bash
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python demo_talk --dependencies rclpy std_msgs

目录结构大致如下:

text
demo_talk/
├── demo_talk/
│   ├── __init__.py
│   ├── talker.py
│   └── listener.py
├── package.xml
├── setup.py
└── setup.cfg

发布者 ​

demo_talk/talker.py:

python
import rclpy
from rclpy.node import Node
from std_msgs.msg import String


class Talker(Node):
    def __init__(self):
        super().__init__('talker')
        self.pub = self.create_publisher(String, 'chatter', 10)
        self.count = 0
        self.timer = self.create_timer(1.0, self.tick)

    def tick(self):
        msg = String()
        msg.data = f'hello robots {self.count}'
        self.pub.publish(msg)
        self.get_logger().info(f'发布: {msg.data}')
        self.count += 1


def main():
    rclpy.init()
    node = Talker()
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == '__main__':
    main()

订阅者 ​

demo_talk/listener.py:

python
import rclpy
from rclpy.node import Node
from std_msgs.msg import String


class Listener(Node):
    def __init__(self):
        super().__init__('listener')
        self.sub = self.create_subscription(String, 'chatter', self.on_msg, 10)

    def on_msg(self, msg):
        self.get_logger().info(f'收到: {msg.data}')


def main():
    rclpy.init()
    node = Listener()
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == '__main__':
    main()

注册可执行文件 ​

在 setup.py 里补上入口点:

python
entry_points={
    'console_scripts': [
        'talker = demo_talk.talker:main',
        'listener = demo_talk.listener:main',
    ],
},

然后编译并运行:

bash
cd ~/ros2_ws
colcon build --packages-select demo_talk
source install/setup.bash

验证通信 ​

开两个终端,分别执行:

bash
# 终端 A
ros2 run demo_talk talker

# 终端 B
ros2 run demo_talk listener

B 应该持续打印 收到: hello robots N。再用命令行旁听一次,确认话题确实在总线上:

bash
ros2 topic list
ros2 topic echo /chatter
ros2 topic hz /chatter

hz 稳定在 1 Hz 左右,说明定时器工作正常。

常见问题 ​

现象可能原因处理
Package 'demo_talk' not found没有 source 工作空间source install/setup.bash
两个节点互不可见使用了不同的 ROS_DOMAIN_ID检查环境变量,保持一致
虚拟机里通信不稳定多网卡导致 DDS 选错接口设置 ROS_LOCALHOST_ONLY=1 或指定网卡
colcon: command not found少装构建工具sudo apt install python3-colcon-common-extensions

小结 ​

跑通发布/订阅之后,ROS 2 剩下的概念(服务、动作、参数、TF)都是在这套机制上加东西。 下一步建议直接看 运动学笔记,把"机器人怎么动"这件事补上。

本站内容均为个人学习笔记与实践记录,欢迎交流指正。