本文重点讲述如何使用micro-ROS技术让Esp32和Ros2之间进行通讯,并提供了一个双向通讯的示例代码供大家参考,后期可以在此基础上完善esp32的电机控制、ros2的智能控制取代键盘遥控。
ROS 2 主要运行在 Linux 等高性能系统上,而电机控制、传感器读取等实时性要求高的底层任务通常由MCU(如 STM32、ESP32)处理。micro-ROS 使这些 MCU 能够直接作为 ROS 2 网络中的一等节点,与上位机(如 Ubuntu等 )无缝通信,无需通过繁琐的串口协议进行数据转换。
源码下载:百度网盘下载(ros2代码也放在项目中)
测试环境
- Esp32-S3机器人控制板:用来直接驱动电机、舵机和读取IMU等传感器数据;
- 树莓派5:用来处理雷达、视觉信息等需要高性能cpu来计算的数据;
- esp32开发环境:vscode+PlatformIO;
测试目的
- 1.在树莓派上通过键盘发送控制数据给esp32,esp32根据该数据控制小车运动;
- 2.esp32发送心跳包给树莓派,树莓派打印心跳频率;
- 以上两个步骤就实现了ros和esp32的双向通讯,您可根据实际情进一步完善代码,这里仅抛砖引玉。
测试过程
测试环境是使用树莓派5,装ubuntu22.04系统
ros2建议安装最新版本,推荐使用第三方源安装最快捷,您也可以使用官方源码安装
- 测试环境的ros2版本是jazzy,第三方源的安装命令如下
wget http://fishros.com/install -O fishros && bash fishros
2. 配置micro-ros代理
mkdir -p ~/microros_ws/src
cd ~/microros_ws
#下载代理源码
git clone https://github.com/micro-ROS/micro-ROS-Agent.git -b jazzy
git clone https://github.com/micro-ROS/micro_ros_msgs.git -b jazzy
#构建代理
colcon build
3. 安装测试用的键盘控制包
# 安装键盘控制包
sudo apt update
sudo apt install ros-jazzy-teleop-twist-keyboard
# 确认安装成功
ros2 pkg list | grep teleop
4.创建心跳监听节点来订阅esp32发送的心跳信息
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
touch heartbeat_listener.py
chmod +x heartbeat_listener.py
# 代码详见esp32的项目文件下的heartbeat_listener.py文件
5.开始测试
#1.启动代理
cd ~/microros_ws
source install/setup.bash
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888
#2.另开一个终端 启动心跳监听节点
cd ~/ros2_ws/src
python3 heartbeat_listener.py
#3.再开一个终端 启动键盘控制节点
ros2 run teleop_twist_keyboard teleop_twist_keyboard
#4.修改esp32代码中的wifi参数信息后烧录代码,打开串口监听窗口
esp32会定时发送心跳包,在ubuntu的终端能看到心跳信息;
在ubuntu的键盘终端,按下ikjl等键,在esp32的串口日志中可以看到打印出twist数据。
6.测试结果
ros2监听心跳节点订阅的esp32心跳数据

esp32打印的日志如下,其中xyz分别代表ros2发送给esp32的小车行走命令,例如x表示前后行走、y表示左右横移、z代表转向,您也可以根据具体情况自己设计数据结构。

常见问题
如果测试结果未达预期,可以排查具体故障点,例如检查心跳话题是否发布,如没有发布则可能是esp32未能正常发布话题,或者心跳包没问题而收不到twist信息,则可以尝试手动发布消息来验证esp32是否收到
# 检查话题是否存在
ros2 topic list | grep heartbeat
# 直接 echo 话题内容
ros2 topic echo /esp32/heartbeat
# 检查 /cmd_vel 话题是否被正确发布
ros2 topic echo /cmd_vel --once
# 手动发布测试消息
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.5, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}"
优化建议
ubuntu上启动的命令如果过多,可以尝试写一个脚本一起启动,可以参考如下示例
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}=================================${NC}"
echo -e "${GREEN} ESP32 小车控制系统启动 ${NC}"
echo -e "${GREEN}=================================${NC}"
# 检查代理是否已经在运行
if pgrep -f "micro_ros_agent" > /dev/null; then
echo -e "${YELLOW}⚠️ micro-ROS代理已经在运行${NC}"
else
echo -e "${GREEN}启动 micro-ROS 代理...${NC}"
# 在新终端中启动代理
gnome-terminal -- bash -c "source ~/ros2_ws/install/setup.bash; ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888; exec bash" 2>/dev/null || \
xterm -e "source ~/microros_ws/install/setup.bash; ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888" &
sleep 2
fi
echo -e "${GREEN}启动心跳监听节点...${NC}"
# 在新终端中启动心跳监听
gnome-terminal -- bash -c "cd ~/ros2_ws/src; python3 heartbeat_listener.py; exec bash" 2>/dev/null || \
xterm -e "cd ~/ros2_ws/src; python3 heartbeat_listener.py" &
sleep 1
echo -e "${GREEN}启动键盘控制节点...${NC}"
# 在当前终端启动键盘控制(或者新终端)
gnome-terminal -- bash -c "ros2 run teleop_twist_keyboard teleop_twist_keyboard; exec bash" 2>/dev/null || \
xterm -e "ros2 run teleop_twist_keyboard teleop_twist_keyboard" &
echo -e "${GREEN}所有节点已启动!${NC}"
echo -e "${YELLOW}控制说明:${NC}"
echo -e " i - 前进"
echo -e " k - 停止"
echo -e " j - 左转"
echo -e " l - 右转"
echo -e " , - 后退"
echo -e " q/z - 加速/减速"
原创文章,作者:奇果派,如若转载,请注明出处:https://www.7gp.cn/archives/1747
