教程:VENTUNO Q/ROS 2 入门

来自WindwizPi wiki

概述

本教程将介绍如何在 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


21q_ros2_setup_1.png


接下来,将 ROS 2 apt 仓库添加到系统。这样包管理器就知道去哪里查找 ROS 2 软件包:

sudo apt install software-properties-common
sudo add-apt-repository universe


21q_ros2_setup_2.png


然后添加 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


21q_ros2_setup_3.png


将 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


21q_ros2_setup_4.png


更新软件包列表并安装 ROS 2 Jazzy desktop,其中包含核心库、工具以及标准桌面可视化软件包:

sudo apt update
sudo apt upgrade
sudo apt install ros-jazzy-desktop


21q_ros2_setup_5.png


安装可能需要几分钟,具体取决于网络连接。完成后请继续下方的验证步骤。

说明:

完整官方安装参考见 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'


21q_ros2_setup_6.png


现在在开发板上打开第二个终端,再次 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]


21q_ros2_setup_7.png


若两个节点都产生类似输出,说明 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]


21q_ros2_turtlesim_1.png


屏幕上会出现 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}}"


21q_ros2_turtlesim_2.png


21q_ros2_turtlesim_circle.gif


它以 1 Hz 发布 Twist 消息,指示海龟以每秒 2.0 单位前进,同时以每秒 1.8 弧度旋转。

按 Ctrl+C 停止。也可以运行内置的画正方形演示,海龟会自动按正方形轨迹移动:

ros2 run turtlesim draw_square


21q_ros2_turtlesim_3.png


21q_ros2_turtlesim_square.gif


重置与清除

也可以通过 ROS 2 服务与 turtlesim 交互。服务与话题不同:它不是连续数据流,而是请求-响应调用。

下列命令使用 /clear 与 /reset 服务清除绘制轨迹并重置海龟位置:

ros2 service call /clear std_srvs/srv/Empty {}


21q_ros2_turtlesim_4.png


ros2 service call /reset std_srvs/srv/Empty {}


21q_ros2_turtlesim_5.png


探索 ROS 2 图

在 turtlesim 运行时,打开第三个终端,使用 ROS 2 命令行工具查看系统中发生的情况。

ros2 node list 显示当前正在运行的所有节点。turtlesim 处于活动状态时,应看到列出 /turtlesim:

ros2 node list

ros2 topic list 显示所有活动话题。你会看到用于速度命令的 /turtle1/cmd_vel、用于海龟当前位置的 /turtle1/pose 等:

ros2 topic list


21q_ros2_turtlesim_6.png


ros2 topic echo 会实时打印某个话题上发布的每条消息。在 /turtle1/cmd_vel 上运行它,可在海龟移动时看到速度命令流:

ros2 topic echo /turtle1/cmd_vel


21q_ros2_turtlesim_7.png


ros2 node info 显示特定节点的完整详情,包括它发布到哪些话题、订阅哪些话题,以及暴露哪些服务:

ros2 node info /turtlesim


21q_ros2_turtlesim_8.png


熟悉这些命令很有用,因为无论运行哪些节点,它们的用法都相同,因此你会在本系列的所有教程中用到它们。

创建首个 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


21q_ros2_project_base_1.png


创建工作空间

创建用作 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


21q_ros2_project_base_2.png


该命令会创建如下结构:

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


21q_ros2_project_base_3.png


构建完成后,source 工作空间的 install 目录,使该包在当前 shell 会话中可用:

source install/setup.bash

--packages-select 标志告诉 colcon 只构建指定包,而不是工作空间中的全部内容。当你有多个包、只想重建正在处理的那个以节省时间时很有用。若不指定,colcon 会尝试构建 src/ 中找到的所有包。

为避免在每个新终端中手动 source 工作空间,可将其添加到 shell 配置:

echo "source ~/ros2_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc


21q_ros2_project_base_4.png


运行节点

在 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"


21q_ros2_project_base_5.png


21q_ros2_example_python.gif


若两个节点都显示预期输出,说明你的首个 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


21q_ros2_project_base_6.png


ros2 topic echo 会实时打印到达该话题的每条消息,这是在不运行专用订阅者节点的情况下快速确认数据流动的方法:

ros2 topic echo /vntq_topic


21q_ros2_project_base_7.png


ros2 topic info 显示消息类型、有多少节点在向该话题发布,以及有多少节点在订阅:

ros2 topic info /vntq_topic


21q_ros2_project_base_8.png


故障排除

若找不到 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 官方教程的中文翻译,供内部查阅。命令与代码保持原文。