esp32与ros2通信案例

前言

在机器人开发的实际场景中,嵌入式传感器的数据流与 ROS 系统的指令流如何顺畅对接,是决定项目落地效率的关键环节。ESP32 的普及降低了嵌入式开发的门槛,而 ROS 2 的成熟则为机器人系统提供了标准化的开发范式,二者的结合成为小体积、低成本机器人项目的优选方案。本文从环境搭建、代码编写、通信调试到功能验证,逐步拆解整个实现流程。通过本文的案例分析,快速掌握二者通信的核心逻辑与实操技巧,为后续开展机器人导航、环境感知、远程控制等应用提供案例。

基础环境:

  • VMware虚拟机

  • Ubuntu:24.04

搭建PlatformIO开发环境

插件安装

在扩展中搜索PlatformIO,选择后点击安装即可。

安装完成后在侧方栏应该可以看到一个蚂蚁头的图标,这个就是PIO,点击图标,点击上访的Open就可以打开PIO HOME。


新建工程测试

首先点击New Project。


  1. 输入工程名 example01_helloworld

  2. 选择开发板,这里选择Adafruit ESP32 Feather

  3. 选择开发框架,这里我们用Arduino,PIO还支持IDF(IoT Development FrameWork)

  4. 开发位置可以选择默认的位置,也可以自定义位置

最后点击Finish即可。

编译项目

如果是ESP32S3的配置,则PlatformIO的设置为:

[env:esp32s3]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino

下载项目


安装第三方库

方法一:在插件中添加第三方库


方法二:直接在ini文件中添加第三方库


更多方法参考安装第三方开源库

接入MicroROS

ESP32端

1、在main.py文件中输入以下代码:

#include <Arduino.h>
#include <micro_ros_platformio.h>

#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
// 添加头文件
#include <std_msgs/msg/float32.h>
#include <ctime>
#include <chrono>

rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

// 声明话题发布者
rcl_publisher_t publisher;
// 声明消息文件
std_msgs__msg__Float32 pub_msg;

// 定义定时器接收回调函数
void timer_callback(rcl_timer_t *timer, int64_t last_call_time)
{
  RCLC_UNUSED(last_call_time);
if (timer != NULL)
  {
    rcl_publish(&publisher, &pub_msg, NULL);
  }
}

void setup()
{
  Serial.begin(115200);
// 设置通过串口进行MicroROS通信
  set_microros_serial_transports(Serial);
// 延时时一段时间,等待设置完成
  delay(2000);
// 初始化内存分配器
  allocator = rcl_get_default_allocator();
// 创建初始化选项
  rclc_support_init(&support, 0, NULL, &allocator);
// 创建节点 topic_sub_test
  rclc_node_init_default(&node, "topic_pub_test", "", &support);
// 订阅者初始化
  rclc_publisher_init_default(
      &publisher,
      &node,
      ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Float32),
      "random_topic_test");

// 创建定时器,200ms发一次
constunsignedint timer_timeout = 200;
  rclc_timer_init_default(
      &timer,
      &support,
      RCL_MS_TO_NS(timer_timeout),
      timer_callback);

// 创建执行器
  rclc_executor_init(&executor, &support.context, 1, &allocator);
// 给执行器添加定时器
  rclc_executor_add_timer(&executor, &timer);
}

void loop()
{
  delay(100);
// 循环处理数据
  rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
auto now = std::chrono::system_clock::now();
auto ms_ts = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
float float_ms_ts = static_cast<float>(ms_ts.count());
  pub_msg.data = float_ms_ts;
}

2、编译并下载程序

上位机

1、ubuntu安装ros2

wget http://fishros.com/install -O fishros && . fishros

2、Ubuntu安装docker

# 下载并执行Docker官方安装脚本
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

3、启动代理

sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host docker.1ms.run/microros/micro-ros-agent:$ROS_DISTRO serial --dev /dev/ttyACM0 -v

启动代理后,重启单片机即可看到以下输出:


验证测试

  1. 查看节点ros2 node list

  1. 查看话题ros2 topic list

3. 查看话题输出ros2 topic echo "random_topic_test"

4. 查看话题频率ros2 topic hz "random_topic_test"

当改小发送时间间隔后,发现ESP32话题发布的最大频率限制在9.3Hz。

总结

本文围绕鱼香 ROS《动手学 ROS2》中的经典案例展开完整复现,全程覆盖开发环境搭建、ESP32 硬件接入 ROS2 系统、功能验证与测试三大核心环节,通过一步步落地实操,深入体验了 MicroROS 在嵌入式硬件与 ROS2 生态联动中的应用逻辑。 在整个实操过程中,最直观的感受便是框架选择对开发效率的显著影响 ——Arduino 框架接入 MicroROS 的流程远比 ESP-IDF 框架简洁易用。相比之下,Arduino 框架对 MicroROS 的适配更成熟,相关的库文件、配置模板及教程资源也更丰富,只需按照案例指引完成库安装、代码烧录、通信配置等几步基础操作,就能快速实现 ESP32 与 ROS2 的互联互通,几乎没有遇到繁琐的底层配置问题。而 ESP-IDF 框架则截然不同,尽管其在硬件控制精细化、资源占用优化等方面有潜在优势,但我前后多次尝试接入 MicroROS 均以失败告终:要么卡在编译阶段出现依赖库冲突,要么烧录后无法建立通信连接,反复排查配置文件、调整编译参数也未能解决,不得不暂时搁置,实在有些惭愧。后续还需针对性研究 ESP-IDF 与 MicroROS 的适配要点,弥补这一技术缺口。 在功能验证环节,我重点测试了 ESP32 的话题发布性能,却发现一个值得关注的现象:话题发布的最大频率稳定在 9.3Hz 左右,未能达到预期的更高频率。结合实操过程分析,这一限制可能源于两方面原因:一方面是通信链路的瓶颈,此次实操采用串口通信方式,串口的波特率设置、数据传输延迟或许对发布频率形成了约束;另一方面也可能与参数配置有关,比如 MicroROS 的 QoS(服务质量)设置、ESP32 的任务调度优先级、数据缓存大小等参数,是否存在可优化的空间尚未可知。目前已记录下这一问题,后续计划通过更换通信方式(如 WiFi)、调整核心参数、对比不同配置组合的测试结果等方式,进一步定位原因并尝试优化,力求突破当前的频率限制。 整体而言,本次案例复现不仅成功打通了 ESP32 与 ROS2 的连接通路,更在框架选型、问题排查等方面积累了宝贵的实操经验,也为后续的技术优化明确了方向。

参考

  • https://github.com/micro-ROS/micro_ros_espidf_component

  • https://fishros.com/d2lros2/#/

  • https://platformio.org/


往期文章

MCP:让大语言模型(DeepSeek)可以动手干活
🤔g2o、Ceres优化库的使用案例
🤪ORB-SLAM2 真机测试案例:流程与结果记录
ORB-SLAM2 真机测试效果
🫠搞定 Python 与 C++ 协作:Linux 环境下调用类的实操案例
🤪搞定 Python 与 C++ 协作:Windows 环境下调用类的实操案例
【开源】SLAM技术之FAST_LIO和FAST_LIO2算法复现
SLAM技术之仿真环境搭建及虚拟传感器数据获取
🤔C++中的多线程编程及线程同步案例
基于ros2 gazebo harmonic的YOLO机械臂优化
DeepSeek控制Unity中的Panda仿真机械臂
panda机械臂的正逆运动学分析与仿真
【开源】SLAM技术之Unity3D仿真激光雷达、RGBD相机、IMU传感器

发表评论