教程:VENTUNO Q/ROS 2 入门
概述
本教程将介绍如何在 Arduino® VENTUNO™ Q 上原生安装并运行 ROS 2(Robot Operating System 2)。VENTUNO Q 在主处理器上运行 Ubuntu,因此可以直接在系统上使用标准 ROS 2 安装。
你将按照官方 ROS 环境配置安装 ROS 2 Jazzy Jalisco,通过 turtlesim 仿真示例验证安装,然后从零创建一个包含发布者(publisher)与订阅者(subscriber)节点的 ROS 2 项目。
说明:
本教程稍作调整后也可在 Arduino® UNO™ Q 上复现。
目标
- 通过 SSH、ADB 或 SBC 模式访问 VENTUNO Q shell。
- 在 Ubuntu 上原生安装 ROS 2 Jazzy Jalisco。
- 理解 ROS 2 的基本概念:节点(nodes)、话题(topics)、服务(services)与动作(actions)。
- 通过运行
turtlesim示例验证安装。 - 创建 colcon 工作空间与 ROS 2 Python 包。
- 编写发布者与订阅者节点,并验证二者之间的通信。
硬件与软件要求
硬件要求
- Arduino® VENTUNO™ Q(×1)
- 用于 ADB 连接的 USB-C® 线缆(×1)
- USB 键盘与鼠标(各 ×1)
- HDMI 显示器(×1)
- 可访问互联网的 Wi-Fi® 接入点或以太网(×1)
软件要求
开始之前,请确认 VENTUNO Q 已安装最新系统镜像。此外还需要:
- 通过 ADB、SSH 或 SBC 模式获得 VENTUNO Q 的终端访问权限。若不熟悉这些方法,请参阅 VENTUNO Q 用户手册。
- 开发板上具备可用的互联网连接。
什么是 ROS 2
ROS(Robot Operating System)是一个开源中间件框架,使机器人与嵌入式系统能够通过标准化的节点、话题、服务与动作交换数据。ROS 是 Open Source Robotics Foundation 的商标。
它提供可复用的库与工具、可视化、包管理与消息传递,使开发者能够专注于应用逻辑,而不是底层基础设施。
ROS 2 是 ROS 的现代版本。核心概念保持不变,但 ROS 2 用基于数据分发服务(DDS)标准的工业级基础架构,取代了原先面向研究的架构。主要改进包括:
- 适合安全关键任务与有时限任务的实时与确定性性能。
- 内置身份认证、加密与访问控制,安全性更好。
- 更好的跨平台支持,覆盖 Linux、Windows、macOS 与嵌入式 RTOS。
- 面向多机器人与分布式系统:发现机制、命名空间隔离与 QoS 设置更完善。
- 长期支持(LTS)发行版,便于生产环境中的可预期升级路径。
本教程全程使用 ROS 2 Jazzy Jalisco,这是当前在 Ubuntu 24.04 上受支持的 LTS 发行版,也是 VENTUNO Q 主处理器上运行的操作系统。
访问 VENTUNO Q
安装任何内容之前,需要先在开发板上获得可用的 shell 会话。本教程中的所有步骤都直接在 VENTUNO Q 上执行,而不是在你的电脑上。有三种方式可以在开发板上打开终端。
初次访问的首选是 ADB(Android Debug Bridge)。它通过 USB-C 提供直接 shell 访问,无需任何网络配置,因此在尚未配置 Wi-Fi 时是最佳起点。用 USB-C 将 VENTUNO Q 连接到电脑并运行:
adb devices
该命令列出已连接设备,并确认开发板已被识别。然后打开 shell:
adb shell
进入后,即可通过终端浏览 Ubuntu 系统。若尚未将开发板连接到 Wi-Fi 网络,可在 ADB shell 中使用 nmtui:
sudo nmtui
第二种方式是 SSH:当开发板已连接到本地网络,并且已在 Arduino App Lab 中完成首次设置后即可使用。在电脑终端中运行:
ssh arduino@<boardname>.local
将 <boardname> 替换为开发板已配置的主机名。首次连接时,系统会要求输入 yes 以确认指纹。之后输入开发板密码。
第三种方式是 SBC 模式:若你更喜欢在物理显示器上直接操作开发板,可将键盘和鼠标接到 VENTUNO Q 的 USB-A 口,将 HDMI 显示器接到 HDMI 口,上电并登录。你将获得完整的 Ubuntu 桌面环境,并可从中打开终端。
说明:
有关设置 ADB、SSH 或 SBC 模式的详细说明,请参阅 VENTUNO Q 用户手册。
安装 ROS 2
准备系统
安装 ROS 2 之前,建议先确保系统软件包列表以及已安装的软件包都已更新。这样可以避免 ROS 2 安装程序所依赖的软件包版本新于系统当前缓存的情况:
sudo apt update && sudo apt upgrade
apt update 会刷新已配置仓库中的可用软件包列表,apt upgrade 会安装系统上已有软件包的待处理更新。完成后即可继续安装 ROS 2。
安装 ROS 2 Jazzy
VENTUNO Q 在主处理器上运行 Ubuntu 24.04,这是 ROS 2 Jazzy Jalisco 官方支持的平台之一。因此你可以按标准 ROS 2 安装流程操作,无需针对开发板做特殊修改。
安装过程主要包括三步:确认区域设置正确、将官方 ROS 2 apt 仓库添加到系统,然后安装软件包。请在终端中按下列步骤操作。
首先,检查系统区域设置是否为 UTF-8(ROS 2 要求):
locale
若输出中的区域设置包含 UTF-8,即可继续。否则运行以下命令进行配置:
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
接下来,将 ROS 2 apt 仓库添加到系统。这样包管理器就知道去哪里查找 ROS 2 软件包:
sudo apt install software-properties-common
sudo add-apt-repository universe
然后添加 ROS 2 GPG 签名密钥,以便系统验证所下载软件包的真实性:
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
将 ROS 2 仓库添加到 apt 源列表:
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
更新软件包列表并安装 ROS 2 Jazzy desktop,其中包含核心库、工具以及标准桌面可视化软件包:
sudo apt update
sudo apt upgrade
sudo apt install ros-jazzy-desktop
安装可能需要几分钟,具体取决于网络连接。完成后请继续下方的验证步骤。
说明:
完整官方安装参考见 ROS 2 Jazzy Installation on Ubuntu (ros.org)。
验证安装
安装完成后,先确认 ROS 2 工作正常再继续。ROS 2 自带一组专门用于此目的的演示软件包。
你将运行其中两个:
talker:每秒向某个话题发布一条简单字符串消息listener:订阅该话题并打印收到的每条消息。
若两个节点能互相发现并交换消息,即可确认核心通信层工作正常。
运行任何 ROS 2 命令之前,需要先 source ROS 2 的 setup 文件。该脚本会为 shell 环境配置路径与变量,使 ROS 2 能够定位其软件包与工具。在开发板上打开终端并运行:
source /opt/ros/jazzy/setup.bash
环境就绪后,启动 talker 节点:
ros2 run demo_nodes_cpp talker
ros2 run 命令接受两个参数:
- 软件包名称(
demo_nodes_cpp) - 节点可执行文件(
talker)
你应看到它每秒打印一条新消息:
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
[INFO] [talker]: Publishing: 'Hello World: 3'
现在在开发板上打开第二个终端,再次 source 环境并启动 listener:
source /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_cpp listener
listener 会订阅 talker 正在发布的同一话题,并打印收到的每条消息:
[INFO] [listener]: I heard: [Hello World: 1]
[INFO] [listener]: I heard: [Hello World: 2]
[INFO] [listener]: I heard: [Hello World: 3]
若两个节点都产生类似输出,说明 ROS 2 安装正常。可用 Ctrl+C 停止两个节点。
使环境持久化
你可能注意到,每个终端在使用 ROS 2 之前都要运行 source /opt/ros/jazzy/setup.bash。这是因为 setup 文件配置的是当前 shell 会话的本地环境变量,打开新终端时不会自动继承。
为避免每次都运行该命令,可以把它追加到 .bashrc 文件中;该 shell 脚本会在每次新终端会话启动时自动运行:
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
source ~/.bashrc
第一行将 source 命令追加到 .bashrc 末尾。第二行在当前会话中重新加载 .bashrc,使更改立即生效,无需打开新终端。
此后,你在 VENTUNO Q 上打开的每个新终端都会自动具备 ROS 2 环境。
Turtlesim 示例
turtlesim 是 ROS 2 自带的轻量级 2D 仿真。它是实践学习该框架工作方式的标准起点,因为提供了便于操作的可视化与交互元素。
画布上会出现一只海龟,可通过向话题发布速度命令使其移动,从而在接触真实硬件之前,直观地看到节点、话题与服务的工作方式。
安装 Turtlesim
从 ROS 2 软件包仓库安装 turtlesim 包:
sudo apt install ros-jazzy-turtlesim
运行 Turtlesim
在终端中启动 turtlesim 节点:
ros2 run turtlesim turtlesim_node
终端会打印初始化消息,确认节点已启动并生成了海龟:
[INFO] [turtlesim]: Starting turtlesim with node name /turtlesim
[INFO] [turtlesim]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
屏幕上会出现 turtlesim 窗口,海龟位于画布中央。由于 VENTUNO Q 具有原生 HDMI 输出,在 SBC 模式下无需额外配置即可直接使用。若通过 SSH 连接且未接显示器,节点仍会运行并发布话题,但图形窗口不会渲染。
控制海龟
海龟会监听发布到 /turtle1/cmd_vel 话题的速度命令。在 turtlesim 节点运行时,打开第二个终端并向海龟发送移动命令。
下列命令通过组合前进速度与旋转速率,使海龟画出连续圆:
ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist \
"{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
它以 1 Hz 发布 Twist 消息,指示海龟以每秒 2.0 单位前进,同时以每秒 1.8 弧度旋转。
按 Ctrl+C 停止。也可以运行内置的画正方形演示,海龟会自动按正方形轨迹移动:
ros2 run turtlesim draw_square
重置与清除
也可以通过 ROS 2 服务与 turtlesim 交互。服务与话题不同:它不是连续数据流,而是请求-响应调用。
下列命令使用 /clear 与 /reset 服务清除绘制轨迹并重置海龟位置:
ros2 service call /clear std_srvs/srv/Empty {}
ros2 service call /reset std_srvs/srv/Empty {}
探索 ROS 2 图
在 turtlesim 运行时,打开第三个终端,使用 ROS 2 命令行工具查看系统中发生的情况。
ros2 node list 显示当前正在运行的所有节点。turtlesim 处于活动状态时,应看到列出 /turtlesim:
ros2 node list
ros2 topic list 显示所有活动话题。你会看到用于速度命令的 /turtle1/cmd_vel、用于海龟当前位置的 /turtle1/pose 等:
ros2 topic list
ros2 topic echo 会实时打印某个话题上发布的每条消息。在 /turtle1/cmd_vel 上运行它,可在海龟移动时看到速度命令流:
ros2 topic echo /turtle1/cmd_vel
ros2 node info 显示特定节点的完整详情,包括它发布到哪些话题、订阅哪些话题,以及暴露哪些服务:
ros2 node info /turtlesim
熟悉这些命令很有用,因为无论运行哪些节点,它们的用法都相同,因此你会在本系列的所有教程中用到它们。
创建首个 ROS 2 项目
在 ROS 2 已安装并验证后,下一步是从零构建项目。你将创建工作空间,用 Python 编写发布者节点与订阅者节点,构建软件包,并运行两个节点以观察它们通信。
本节遵循官方 ROS 2 Python 发布者与订阅者指南,并适配到 VENTUNO Q 上运行。完整参考见 Writing a Simple Publisher and Subscriber (Python)。
ROS 2 核心概念
编写代码之前,了解将要使用的关键概念很有帮助:
- Node: 执行某一特定任务的单个进程,例如读取传感器、处理数据或向电机发送命令。节点通过话题、服务与动作相互通信。在真实机器人中,可同时运行数十个节点,各自负责系统的不同部分。
- Topic: 节点异步交换消息的命名通道。可以把它想象成无线电频率:任何节点都可以在其上广播,任何节点都可以调谐收听。任意数量的节点可同时向同一话题发布或订阅。
- Publisher: 节点中向话题发送消息的组件。
- Subscriber: 节点中从话题接收消息并将其交给回调函数的组件。
- Package: ROS 2 中软件组织的基本单元。一个包将相关节点、库、配置文件与构建说明组织在一起。
- Workspace: 使用
colcon构建工具构建并安装一个或多个包的目录。
安装 Colcon
colcon 是 ROS 2 的标准构建工具。它会读取工作空间中每个包的构建配置,并按正确顺序编译它们。使用以下命令安装:
sudo apt update
sudo apt install python3-colcon-common-extensions
创建工作空间
创建用作 colcon 工作空间的目录:
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
所有包都放在 src/ 中。从工作空间根目录运行 colcon build 时会编译它们。
它会在 src/ 旁生成三个目录:
build/:中间文件install/:编译输出log/:构建日志
创建 Python 包
进入 src/,使用 ament_python 构建类型创建新包(这是 ROS 2 中纯 Python 包的标准方式):
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python vntq_pubsub
该命令会创建如下结构:
src/
└── vntq_pubsub/
├── package.xml
├── setup.py
├── setup.cfg
├── resource
├── test
└── vntq_pubsub/
└── __init__.py
package.xml 描述包的元数据与依赖。setup.py 用于将 Python 脚本注册为可执行的 ROS 2 节点。内部的 vntq_pubsub/ 目录是放置节点脚本的 Python 模块。
编写发布者节点
在包的 Python 模块目录中创建发布者脚本:
nano ~/ros2_ws/src/vntq_pubsub/vntq_pubsub/publisher.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class VNTQPublisher(Node):
def __init__(self):
super().__init__('vntq_publisher')
self.publisher_ = self.create_publisher(String, 'vntq_topic', 10)
self.timer = self.create_timer(1.0, self.timer_callback)
self.count = 0
def timer_callback(self):
msg = String()
msg.data = f'Hello from VENTUNO Q: {self.count}'
self.publisher_.publish(msg)
self.get_logger().info(f'Publishing: "{msg.data}"')
self.count += 1
def main(args=None):
rclpy.init(args=args)
node = VNTQPublisher()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
该节点继承自 ROS 2 Node 基类,并以名称 vntq_publisher 注册。在构造函数中,它在话题 vntq_topic 上创建队列大小为 10 的发布者,并设置每秒调用一次 timer_callback 的定时器。
每次回调触发时,它会构建带有当前计数的 String 消息,发布到话题,并将内容记录到控制台。
编写订阅者节点
在同一目录中创建订阅者脚本:
nano ~/ros2_ws/src/vntq_pubsub/vntq_pubsub/subscriber.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class VNTQSubscriber(Node):
def __init__(self):
super().__init__('vntq_subscriber')
self.subscription = self.create_subscription(
String,
'vntq_topic',
self.listener_callback,
10
)
def listener_callback(self, msg):
self.get_logger().info(f'Received: "{msg.data}"')
def main(args=None):
rclpy.init(args=args)
node = VNTQSubscriber()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
该节点在 vntq_topic 上创建队列大小同为 10 的订阅。每当该话题上有消息到达,就会调用 listener_callback,并将消息内容打印到控制台。节点名称为 vntq_subscriber。
注册入口点
节点要用 ros2 run 启动,需要在 setup.py 中注册为 console script 入口点。这会告诉 colcon 在构建时为每个节点创建可执行包装器。打开该文件:
nano ~/ros2_ws/src/vntq_pubsub/setup.py
找到 entry_points 字典并更新为如下内容:
entry_points={
'console_scripts': [
'publisher = vntq_pubsub.publisher:main',
'subscriber = vntq_pubsub.subscriber:main',
],
},
构建工作空间
返回工作空间根目录并构建软件包:
cd ~/ros2_ws
colcon build --packages-select vntq_pubsub
构建完成后,source 工作空间的 install 目录,使该包在当前 shell 会话中可用:
source install/setup.bash
--packages-select 标志告诉 colcon 只构建指定包,而不是工作空间中的全部内容。当你有多个包、只想重建正在处理的那个以节省时间时很有用。若不指定,colcon 会尝试构建 src/ 中找到的所有包。
为避免在每个新终端中手动 source 工作空间,可将其添加到 shell 配置:
echo "source ~/ros2_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc
运行节点
在 VENTUNO Q 上打开两个终端会话。在第一个中启动发布者:
ros2 run vntq_pubsub publisher
你应看到它每秒打印一条新消息:
[INFO] [vntq_publisher]: Publishing: "Hello from VENTUNO Q: 0"
[INFO] [vntq_publisher]: Publishing: "Hello from VENTUNO Q: 1"
[INFO] [vntq_publisher]: Publishing: "Hello from VENTUNO Q: 2"
在第二个终端中启动订阅者:
ros2 run vntq_pubsub subscriber
你应看到它接收并打印发布者发送的每条消息:
[INFO] [vntq_subscriber]: Received: "Hello from VENTUNO Q: 0"
[INFO] [vntq_subscriber]: Received: "Hello from VENTUNO Q: 1"
[INFO] [vntq_subscriber]: Received: "Hello from VENTUNO Q: 2"
若两个节点都显示预期输出,说明你的首个 ROS 2 项目运行正常。
检查系统
在两个节点运行时,打开第三个终端,使用 ROS 2 命令行工具检查图结构。这些工具与 turtlesim 中使用的相同,用法也一样。
ros2 node list 会显示你刚启动的两个节点:
ros2 node list
/vntq_publisher
/vntq_subscriber
ros2 topic list 会显示 /vntq_topic 以及默认的 ROS 2 系统话题:
ros2 topic list
ros2 topic echo 会实时打印到达该话题的每条消息,这是在不运行专用订阅者节点的情况下快速确认数据流动的方法:
ros2 topic echo /vntq_topic
ros2 topic info 显示消息类型、有多少节点在向该话题发布,以及有多少节点在订阅:
ros2 topic info /vntq_topic
故障排除
若找不到 ros2 命令,请确认已用 source /opt/ros/jazzy/setup.bash source 了 ROS 2 setup 文件,或该行已存在于 .bashrc 中。若尚未完成,请参阅 使环境持久化 一节。
若在不同终端中运行的节点无法互相发现,请检查所有终端是否共享相同的 ROS_DOMAIN_ID。默认值为 0;若在某个会话中被更改,节点将无法找到彼此。可以显式设置并使其永久生效:
export ROS_DOMAIN_ID=0
echo "export ROS_DOMAIN_ID=0" >> ~/.bashrc
若 turtlesim 窗口未出现,请检查是否通过 SSH 连接且未接显示器。turtlesim 窗口需要本地显示器才能渲染。
将 HDMI 显示器接到 HDMI 口,将键盘和鼠标接到 USB-A 口,或切换到 SBC 模式即可解决。即使没有显示器,节点本身仍会通过 SSH 运行并发布话题。
若构建后找不到 vntq_pubsub 包,请 source 工作空间的 install 目录:
source ~/ros2_ws/install/setup.bash
若因缺少依赖而导致构建失败,请在构建前从工作空间根目录运行 rosdep:
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -r -y
总结
在本教程中,你已在 VENTUNO Q 上安装 ROS 2 Jazzy,通过 turtlesim 示例验证了安装,并构建了首个通过话题通信的发布者与订阅者 ROS 2 项目。这里介绍的模式——节点、话题、包与工作空间——是本系列每个教程的基础。
后续步骤
现在 ROS 2 已运行,并且你已有可用的项目结构,可以继续将真实传感器连接到 VENTUNO Q。
若需更广泛地了解 ROS 2 概念,建议从 官方 ROS 2 教程 开始。
致谢
ROS 是 Open Source Robotics Foundation 的商标。本教程仅用于教育目的,帮助用户在 Arduino 硬件上学习 ROS 2。本内容并不意味着 Arduino 与 Open Source Robotics Foundation 之间存在背书、合作或隶属关系。
原文:https://docs.arduino.cc/tutorials/ventuno-q/getting-started-ros2/ 本页为 Arduino 官方教程的中文翻译,供内部查阅。命令与代码保持原文。