ESP32 与 ROS 2 通信实战教程
使用 micro-ROS + PlatformIO + Snap Agent 实现串口通信

教程目标
- 在 ESP32(如 ESP32-CAM) 上运行 micro-ROS 节点
- 通过 串口(Serial) 与 PC 上的 ROS 2 Humble 通信
- PC 端使用 Snap 安装的 micro-ROS Agent,避免依赖冲突
- 最终实现:ESP32 每秒发布一个递增整数到 ROS 2 Topic
所需环境
| 组件 | 要求 |
|---|---|
| 主机系统 | Ubuntu 20.04 / 22.04 或 WSL2 |
| ROS 2 | 已安装 Humble (/opt/ros/humble) |
| ESP32 开发 | 安装 PlatformIO(推荐 VSCode 插件) |
| micro-ROS Agent | 通过 Snap 安装(非源码编译) |
为什么用 Snap?**
避免 FastDDS / FastCDR 版本冲突,一键安装、沙盒隔离、无需
colcon build!
第一步:在主机安装 micro-ROS Agent(Snap 方式)
bash
# 1. 安装 micro-ros-agent
sudo snap install micro-ros-agent
# 2. 授予串口访问权限(关键!)
sudo snap connect micro_ros_agent:serial-port
# 3. (可选)验证是否安装成功
micro-ros-agent --help
如果你在 WSL2 中使用 USB 设备,请确保已启用 USBIPD-WIN 并将设备透传给 WSL。
第二步:准备 ESP32 代码(PlatformIO 项目)
1. 创建 PlatformIO 项目
在 VSCode 中:
Ctrl+Shift+P→ 输入PlatformIO: New Project- 名称:
esp32_microros_demo - Board:
ESP32 Dev Module(或你的具体型号,如AI Thinker ESP32-CAM) - Framework:
Arduino
2. 替换 platformio.ini
ini
; platformio.ini
[env:esp32dev]
platform = espressif32
board = esp32dev ; 根据你的板子修改,如 esp32cam
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps =
https://gitee.com/ohhuo/micro_ros_platformio.git
; micro-ROS 配置(可选,serial 是默认值)
board_microros_distro = humble
board_microros_transport = serial
[platformio]
description = ESP32 micro-ROS Serial Publisher
注意:如果你用的是 ESP32-CAM ,请将
board = esp32dev改为board = esp32cam。
3. 编写主程序 src/main.cpp
cpp
#include <Arduino.h>
#include <micro_ros_platformio.h>
#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <std_msgs/msg/int32.h>
// 检查是否启用了串口传输
#if !defined(MICRO_ROS_TRANSPORT_ARDUINO_SERIAL)
#error "This example requires serial transport. Check your platformio.ini."
#endif
// 全局变量
rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;
// 宏定义:错误检查
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if(temp_rc != RCL_RET_OK) { error_loop(); } }
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if(temp_rc != RCL_RET_OK) {} }
void error_loop() {
while (1) {
Serial.println("Error! Halting...");
delay(1000);
}
}
// 定时器回调:发布消息
void timer_callback(rcl_timer_t * timer, int64_t last_call_time) {
RCLC_UNUSED(last_call_time);
if (timer != NULL) {
msg.data++;
RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
Serial.printf("Published: %d\n", msg.data);
}
}
void setup() {
// 初始化串口(必须与 Agent 波特率一致)
Serial.begin(115200);
set_microros_serial_transports(Serial);
delay(2000); // 等待串口稳定
// 初始化 micro-ROS
allocator = rcl_get_default_allocator();
RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));
// 创建节点
RCCHECK(rclc_node_init_default(&node, "esp32_microros_node", "", &support));
// 创建 Publisher
RCCHECK(rclc_publisher_init_default(
&publisher,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
"esp32_int32_topic"
));
// 创建定时器(每 1000ms 触发一次)
const unsigned int timer_timeout_ms = 1000;
RCCHECK(rclc_timer_init_default(
&timer,
&support,
RCL_MS_TO_NS(timer_timeout_ms),
timer_callback
));
// 创建执行器并添加定时器
RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
RCCHECK(rclc_executor_add_timer(&executor, &timer));
msg.data = 0;
Serial.println("ESP32 micro-ROS node started!");
}
void loop() {
// 处理 ROS 消息(非阻塞)
RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
delay(10); // 避免 CPU 占用过高
}
第三步:上传固件到 ESP32
-
连接 ESP32 到电脑
-
在 PlatformIO 中点击 Upload (或
pio run --target upload) -
观察串口输出(
pio device monitor),应看到:ESP32 micro-ROS node started!
此时 ESP32 已准备好连接 Agent,但尚未建立通信(需先启动 Agent)。
第四步:启动 micro-ROS Agent
1. 查看串口设备
bash
ls /dev/ttyUSB*
# 通常输出:/dev/ttyUSB0
2. 启动 Agent(波特率必须匹配!)
bash
micro-ros-agent serial --dev /dev/ttyUSB0 -b 115200 -v6
重要操作 :Agent 启动后,立即按下 ESP32 的 RESET 按钮,让其重新发起连接。
你应该看到类似日志:
[INFO] [1717020000.123456]: UDP server listening on port 8888
[INFO] [1717020001.789012]: Client connected successfully
第五步:在 ROS 2 中验证通信
打开新终端:
bash
# 1. 加载 ROS 2 环境
source /opt/ros/humble/setup.bash
# 2. 查看节点
ros2 node list
# 应输出:/esp32_microros_node
# 3. 查看话题
ros2 topic list
# 应包含:/esp32_int32_topic
# 4. 订阅并打印数据
ros2 topic echo /esp32_int32_topic
你将看到不断递增的整数:
yaml
data: 1
---
data: 2
---
data: 3
...
常见问题排查
| 问题 | 解决方案 |
|---|---|
Agent 报 Permission denied |
sudo chmod 666 /dev/ttyUSB0 |
| ESP32 串口无输出 | 检查 monitor_speed 和 Serial.begin() 是否一致 |
| ROS 2 看不到节点 | 确保 Agent 已启动 + ESP32 已复位 + 波特率匹配 |
| Snap 无法识别串口 | 再次运行 sudo snap connect micro_ros_agent:serial-port |
| 编译报错找不到 micro_ros | 确认 lib_deps 使用的是 Gitee 镜像(国内网络更稳) |
扩展建议
- 尝试 WiFi 传输 :修改
platformio.ini中board_microros_transport = wifi,并在代码中配置 SSID/密码/IP。 - 发布 传感器数据(如 DHT11 温湿度)。
- 订阅 ROS 2 指令控制 ESP32 LED。