游乐游手机版
首页/AI热点日报/热点详情

micro_ros实现ESP32与旭日X3派通信

类型:热点整理2026-07-13
利用micro_ros实现ESP32与旭日X3派串口通讯,下位机作为ROS2节点发布Twist控制turtlesim,线速度恒角速度减。上位机启动micro_ros_agent与turtlesim_node。

本指南将手把手带领你实现 micro_ros 通讯机制,使下位机(如 ESP32)通过串口与上位机(如旭日 x3派)成功连接,并作为 ROS 2 的一个节点发布 Twist 消息,从而控制 turtlesim 中的小乌龟运动。无需编写复杂的通讯协议,即可轻松打通上下位机之间的数据通路。

环境搭建准备

  • 上位机:旭日 x3派(ROS 2 foxy + Ubuntu 20.04)
  • 下位机:M5stack Atom Lite(ESP32 核心)

0. 安装 micro_ros 与 micro_ros_arduino

详细安装步骤请参考我之前撰写的记录:https://zhuanlan.zhihu.com/p/540924221

特别提醒:

  • 2GB 内存的旭日 x3派务必开启 swap 交换空间,否则 micro_ros_agent 在编译过程中极易因内存不足而失败。
  • 网络环境必须能够稳定访问 GitHub,否则很可能安装失败。

1. 下位机配置

1.1 Arduino 支持包安装

本教程使用的下位机为 M5stack Atom Lite(ESP32),采用 Arduino 框架开发。理论上,所有支持 Arduino 开发的嵌入式平台均可适用。

提示:请务必安装与你所使用的嵌入式平台相对应的 Arduino 支持包。

正确安装 M5stack 支持包后,在 Arduino 开发板管理器中应能看到 M5 stack 相关的开发板选项。

1.2 下位机代码

请将以下代码完整复制到 Arduino IDE 中,然后烧录至下位机。

#include 

#include 
#include 
#include 
#include 
#include 

#include  //changed!

rcl_publisher_t publisher;
geometry_msgs__msg__Twist msg; //changed!-->modify msg type

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

#define LED_PIN 27 //changed!-->Modify M5 stack Atom Lite LED pin

#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){
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void timer_callback(rcl_timer_t * timer, int64_t last_call_time){
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    static int cnt = 0;
    msg.linear.x = 0.2; //const linear.x
    msg.angular.z = 1.0 - 0.001*cnt; //variable angular.z
    cnt++;
  }
}

void setup() {
  set_microros_transports();

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // create publisher
  RCCHECK(rclc_publisher_init_default(
    &publisher,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist),
    "turtle1/cmd_vel")); //changed!-->modify topic name

  // create timer,
  const unsigned int timer_timeout = 1000;
  RCCHECK(rclc_timer_init_default(
    &timer,
    &support,
    RCL_MS_TO_NS(timer_timeout),
    timer_callback));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));

  // changed!-->msg initialization
  msg.linear.x=0;
  msg.linear.y=0;
  msg.linear.z=0;
  msg.angular.x=0;
  msg.angular.y=0;
  msg.angular.z=0;
}

void loop() {
  delay(100);
  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

1.3 代码解析

本代码基于 micro_ros_arduino 的示例 micro-ros_publisher 修改而来,主要改动点如下:

  • 引入 Twist 消息类型并定义变量
    #include
    geometry_msgs__msg__Twist msg;
  • 将 Twist 消息的六个分量初始化为 0
    msg.linear.x=0; msg.linear.y=0; msg.linear.z=0;
    msg.angular.x=0; msg.angular.y=0; msg.angular.z=0;
  • 修改发布的 topic 名称"turtle1/cmd_vel",与 ROS 2 中 turtlesim 接收的 topic 保持一致。
    RCCHECK(rclc_publisher_init_default(
        &publisher,
        &node,
        ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist),
        "turtle1/cmd_vel"));
  • 在定时器回调函数中设置线速度恒定、角速度变化
    线速度 linear.x 固定为 0.2,角速度 angular.z 从 1.0 开始递减。
    msg.linear.x = 0.2; //const linear.x
    msg.angular.z = 1.0 - 0.001*cnt; //variable angular.z
    cnt++;
  • 修改 LED 灯管脚号(非必须,可根据实际硬件调整)
    #define LED_PIN 27

2. 上位机配置

将下位机代码烧录完成后,通过 USB 串口线将下位机连接到上位机。本例使用 USB 串口进行通信。

提示:为了显示 turtlesim 图形界面,旭日 x3派需要连接 HDMI 显示器或通过 VNC 远程连接。本教程采用 VNC 方式。

打开上位机终端,依次执行以下命令:

  • 配置 ROS 环境并进入 micro_ros 工作空间
    source /opt/tros/setup.bash   # 或者 source /opt/ros/foxy/setup.bash
    cd /microros_ws/
    source install/setup.bash     # 也可以将这些命令添加到 ~/.bashrc
  • 提升串口读写权限(请确认你的串口设备名,这里以 ttyUSB0 为例)
    sudo chmod -R 777 /dev/ttyUSB0
  • 启动 micro_ros_agent,等待下位机连接
    ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
  • 按下下位机上的复位键这一步非常关键!
  • 另开一个终端,启动 turtlesim_node
    ros2 run turtlesim turtlesim_node

此时,你应该能看到小乌龟开始运动,并且其轨迹呈螺旋状(线速度恒定,角速度逐渐减小)。

3. 其他注意事项

  • 发布频率:示例代码中定时器周期为 1000ms,即 1Hz。你可以将 timer_timeout 改小(例如 100ms)来提高发布频率,实测 10Hz 无问题。但若需达到 100Hz 以上,必须使用 rclc_publisher_init_best_effort 代替 rclc_publisher_init_default
  • QoS 兼容性best_effort 的发布者需要同样为 best_effort 的订阅者才能接收。而 turtlesim 默认使用 reliable 的 QoS,因此即使改用 best_effort 发布 twist,小乌龟也不会运动。关于 QoS 兼容性,可参考 ROS 2 官方文档

常见问题 (FAQ)

  • Q: 为什么按下复位键后 agent 才识别到下位机?
    A: micro_ros_agent 需要在下位机启动时主动发起连接。复位操作会重启下位机,让 micro_ros 的初始化函数重新执行,从而完成握手。如果你在烧录后直接插拔电源,效果是一样的。
  • Q: 如何修改下位机发布的消息类型?
    A: 替换头文件(例如 #include ),将 msg 变量改为对应类型,并在 rclc_publisher_init_default 中传入正确的类型支持宏(如 ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32))。
  • Q: 串口连接后 agent 无反应怎么办?
    A: 检查串口权限(是否执行了 sudo chmod),确认下位机代码已正确烧录且复位有效。也可以尝试更换 USB 口或重启上位机。
  • Q: 下位机 LED 快速闪烁代表什么?
    A: 这说明代码进入了 error_loop(),通常是因为 micro_ros 初始化失败(例如串口未连接、ROS 2 环境未正确加载)。请检查串口连接和 agent 是否已启动。

本文转自地平线开发者社区

原作者:Tianci

原链接:https://developer.horizon.ai/forumDetail/98129540173361336

来源:https://m.elecfans.com/article/2128418.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。