外观
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.bashcolcon 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 listenerB 应该持续打印 收到: hello robots N。再用命令行旁听一次,确认话题确实在总线上:
bash
ros2 topic list
ros2 topic echo /chatter
ros2 topic hz /chatterhz 稳定在 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)都是在这套机制上加东西。 下一步建议直接看 运动学笔记,把"机器人怎么动"这件事补上。