【保姆级】ESP32 与 ROS 2 通信实战教程

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

  1. 连接 ESP32 到电脑

  2. 在 PlatformIO 中点击 Upload (或 pio run --target upload

  3. 观察串口输出(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_speedSerial.begin() 是否一致
ROS 2 看不到节点 确保 Agent 已启动 + ESP32 已复位 + 波特率匹配
Snap 无法识别串口 再次运行 sudo snap connect micro_ros_agent:serial-port
编译报错找不到 micro_ros 确认 lib_deps 使用的是 Gitee 镜像(国内网络更稳)

扩展建议

  • 尝试 WiFi 传输 :修改 platformio.iniboard_microros_transport = wifi,并在代码中配置 SSID/密码/IP。
  • 发布 传感器数据(如 DHT11 温湿度)。
  • 订阅 ROS 2 指令控制 ESP32 LED。

参考资料

相关推荐
一颗青果3 小时前
HTTP协议详解
linux·网络·网络协议·http
专业开发者5 小时前
物联网传感器:破解设备维护难题
物联网
广州灵眸科技有限公司6 小时前
瑞芯微(EASY EAI)RV1126B CAN使用
linux·网络·单片机·嵌入式硬件
SmartRadio6 小时前
CH584M vs nRF52840 vs 主流BLE SoC全面对比
单片机·嵌入式硬件·mcu·物联网·开源·硬件工程
专业开发者8 小时前
经 Nordic 实测:蓝牙长距离传输
网络·物联网
魂万劫8 小时前
如何在虚拟机VM上|Linux环境内安装windows
linux·运维·服务器·windows
叁散8 小时前
实验三:基于物联网通信协议的船舶AIS数据传输
物联网
序属秋秋秋8 小时前
《Linux系统编程之进程控制》【进程等待】
linux·c语言·c++·进程·系统编程·进程控制·进程等待
zfj3218 小时前
top 命令中的 wa (IO wait) 指标,理论上几乎完全是由磁盘IO(包括swap)引起的,而不是网络IO
linux·网络·top·iowait
Xの哲學8 小时前
Linux网卡注册流程深度解析: 从硬件探测到网络栈
linux·服务器·网络·算法·边缘计算