type
date
slug
category
icon
password
准备条件
- 宿主机 Windows 系统
- esp32开发板
- 订阅-发布测试例子
基于Docker的开发环境搭建完成后,在
example_project
文件夹中有一个 .devcontainer
文件夹,文件夹中有两个文件devcontainer.json
:这是 VS Code 的开发容器配置文件,用于定义开发环境。它允许您在容器中进行开发,确保所有开发者使用相同的环境。主要功能包括:- 指定使用的 Docker 镜像或 Dockerfile
- 配置容器启动选项(如端口映射、挂载卷)
- 定义要安装的 VS Code 扩展
- 设置容器内工作目录和环境变量
Dockerfile
:这是构建开发容器的 Docker 配置文件,定义了容器的基础环境。它包含:- 基础镜像选择
- 安装必要的软件包和依赖
- 配置环境变量
- 设置工作目录
- 其他容器初始化步骤
将提供的例程【订阅-发布测试例子 】解压拷贝到
example_project
文件夹下,文件结构如下。切换到
publisher_subscriber
项目,只需将路径从 "workspaceFolder": "/workspaces/blink"
更改为 "workspaceFolder": "/workspaces/publisher_subscriber"
,然后重新选择 在容器中打开文件夹
。容器打开后,会自动加载Docker镜像,按json文件配置开发环境,将项目映射到
/workspaces/publisher_subscriber
文件夹下。简单看一下
main.c
程序,程序包含了rclc头文件,并且使用了rcl函数接口。这就需要我们安装ESP32-microros 组件。ESP32-microros 组件安装
1. 下载microros组件
下载microros组件到~/esp/Samples/extra_component,这里以下载humble版本为例.
micro_ros组件源码地址:https://github.com/micro-ROS/micro_ros_espidf_component
- WSL安装了Ubuntu2204桌面端,因此这里分支选择-b humble,请根据安装情况切换
- 由于micro_ros组件托管在GitHub上,下载文件可能因网络问题而失败。可能需要科学上网。
2. 激活ESP-IDF开发环境
- 由于我们使用docker开发环境,配置文件进入后会自动激活ESP-IDF开发环境,此步可忽略,若你不是通过docker开发,请手动激活。
- 每次打开新终端都需要先激活ESP-IDF开发环境才可以编译ESP-IDF的工程。
- 启动脚本路径默认为$IDF_PATH/export.sh下,你也可以参考这里确认。
在终端运行以下命令
3. 安装依赖
在终端运行以下命令
注意:一定要先激活ESP-IDF开发环境后才运行以上的命令。
4. 修改microros配置
默认的microros配置只支持1个节点,2个发布者,2个订阅者,1个服务,1个客户端,1个历史记录。
如果觉得不够用的情况,可以修改microros配置。如果现在不修改,后续使用不满足需求需要重新编译时,可输入以下命令清除microros编译生成的文件,再重新执行编译生成microros静态库。
修改micro_ros_espidf_component目录下的colcon.meta文件,找到"rmw_microxrcedds"栏,然后根据实际修改。为了方便使用,将发布者、订阅者、历史记录都修改为3。
- 由于单片机性能有限,刚好满足需求就可以了,避免资源浪费和影响通讯速度。
- 例程实现3个订阅者,3个发布者,这里必须修改,否则在和microros agent 连接时会报错。
- 可以使用 vim 编辑,若容器中没有vim工具,通过apt install vim下载。
5. 编译生成microros静态库
接着在终端运行以下命令。
编译完成后提示"Configuring done"和"Generating done"。
此时系统会自动下载需要的文件,并编译生成libmicroros.a静态库。
此时,已经编译完成。
6. 如何使用
编译生成了libmicroros.a静态库后则表示组装安装完成,接下来使用只需要把extra_components添加到项目的外部组件上即可。
在项目的根CMakeLists.txt文件中添加以下内容,其中“../../extra_components”根据实际路径替换。
如果有需要修改microros的编译参数,可运行以下命令清除microros的缓存,然后重新编译生成libmicroros.a静态库就可以。
7. 编译、下载和监控例程
编译前,需配置SDK中 micro-ROS 配置,参考下图

参考基于Docker搭建ESP32开发环境(Windows) 进行编译,编译完成后,下载到esp32开发板。
拓展阅读:ESP-IDF 项目如何识别micro-ROS的头文件和链接静态库
在ESP32项目中,micro-ROS组件构建完成后,CMakeLists.txt需要正确配置以识别micro-ROS的头文件和链接静态库。根据您提供的文档和当前的CMakeLists.txt,我来解释这个过程:
micro-ROS头文件和库的识别方式
- 组件目录结构
- 头文件:
cmicro_ros_espidf_component/include
- 静态库:
micro_ros_espidf_component/libmicroros.a
micro-ROS在ESP-IDF中作为一个组件被集成。构建过程会在以下位置生成相关文件:
- 在CMakeLists.txt中识别micro-ROS组件
您当前的CMakeLists.txt已经包含了:
- 组件自动识别机制
ESP-IDF的构建系统会自动识别components目录下的组件,因此如果micro-ROS组件位于项目的components目录中,则无需额外配置EXTRA_COMPONENT_DIRS:
链接micro-ROS静态库
micro-ROS组件的CMakeLists.txt已经处理了静态库的链接,您不需要在主项目的CMakeLists.txt中显式链接libmicroros.a。组件的CMakeLists.txt通常包含类似以下内容:
解决可能的链接问题
您当前的CMakeLists.txt中已包含:
这有助于解决micro-ROS与ESP-IDF之间可能出现的符号重复定义问题。
接下来我们安装micro ros 代理,教程中使用docker进行安装。
Docker启动microros代理
开始前,先对网络拓扑结构作说明。
- 宿主机 (Windows)
- 连接到WiFi路由器
- 运行Docker Desktop,在其中启动micro-ROS Agent容器
- Docker容器
- 使用--net=host模式,共享宿主机网络栈
- 包含完整的ROS2环境和工具集
- 命令示例:docker run -it --rm --net=host -p 8090:8090/udp microros/micro-ros-agent:humble udp4 --port 8090 --host 0.0.0.0 -v4 --domain 20
- 在容器内部可以直接运行ROS2命令行工具(ros2 topic list/echo/pub等)
- ESP32开发板
- 通过WiFi连接到同一个路由器
- 配置连接到宿主机IP地址和指定端口(8090)
- 在代码中通过CONFIG_MICRO_ROS_AGENT_IP和CONFIG_MICRO_ROS_AGENT_PORT配置
- 通信流程
- ESP32发布话题:publisher_1, publisher_2, publisher_3
- ESP32订阅话题:subscriber_1, subscriber_2, subscriber_3
- 在Docker容器内部可以通过ROS2命令行工具与Agent交互
- 所有通信使用相同的Domain ID (20)
本次启动microros代理为通过docker启动方式,我们利用开发环境搭建好docker。
Docker启动WIFI代理
docker 命令在宿主机中运行,而非WSL中运行,主要避免WSL和宿主机之间网络隔离。
其中,各参数含义:
- docker run: 创建并启动一个新的容器
- it: 两个参数的组合
- i: 保持STDIN开放,即使未连接
- t: 分配一个伪TTY终端
- -rm: 容器停止运行后自动删除容器
- e ROS_DOMAIN_ID=20: 设置环境变量ROS_DOMAIN_ID为20,指定ROS 2通信的域ID
- p 8090:8090/udp: 将容器内的UDP 8090端口映射到主机的8090端口
- microros/micro-ros-agent:humble: 使用的Docker镜像及标签,这是micro-ROS代理的humble版本
- udp4: 指定使用IPv4的UDP协议
- -port 8090: 设置micro-ROS代理监听的UDP端口为8090
- -host 0.0.0.0: 设置代理监听所有网络接口(而不仅仅是localhost)
- v4: 设置日志详细级别为4(非常详细)
- -domain 20: 设置ROS 2的域ID为20,与环境变量设置相对应
如果需要结束代理,请在终端按Ctrl+C退出代理。注意不可以直接关闭终端,否则docker会在后台继续运行。
如果单片机多次启动重连代理,导致ROS2搜索出来多个相同的节点,实际不影响使用,按Ctrl+C结束代理后再复位单片机重新连接代理即可。
成功启动后,会看到类似以下输出:
Docker启动串口代理
其中,
--dev /dev/ttyUSB0
为串口设备号,-b 921600
为波特率。可以根据实际情况做出修改。代理启动失败的情况

microROS代理只能在一个终端开启,如果已经有终端在后台开启microROS代理,再次开启代理就会报错,请先在原来的代理终端按Ctrl+C退出代理后再运行代理。如果因为直接关闭终端导致下一次启动代理失败的情况,可重启虚拟机/电脑解决,或者手动结束docker解决。
手动结束docker的方法:
请先查询出当前docker进行号,并结束当前代理docker进程。
micro-ROS测试指南
环境准备
- ESP32开发板(已烧录micro-ROS固件)
- ROS2环境(Humble或其他版本,在microros/micro-ros-agent:humble容器中有ros2环境)
ESP32连接到代理
当ESP32成功连接到代理时,会在代理日志中看到以下信息:
然后会创建参与者、话题、发布者和订阅者:
打开ROS2进行通讯
容器内部启动一个交互式 shell,由于已经运行了 micro-ROS Agent 容器,可以在另一个终端窗口执行以下命令来进入该容器(Windows 适用的方式):
- 首先,我们需要找出正在运行的 micro-ros-agent 容器的 ID:
可以按照以下步骤在 Windows 中进入 micro-ros-agent 容器:
- 然后使用该容器 ID 进入容器:
例如,如果容器 ID 是 abc123,则命令为:
- 进入容器后,执行以下命令以启用 ROS2 环境:
- 现在可以使用 ros2 命令了
ROS域ID问题排查
如果在ROS2环境中运行
ros2 topic list
命令只显示系统默认的话题(如/parameter_events
和/rosout
),而没有显示ESP32发布的话题,很可能是ROS域ID不匹配导致的。问题分析
- 检查ESP32的ROS域ID设置:
- 在
main/Kconfig.projbuild
文件中,CONFIG_MICRO_ROS_DOMAIN_ID
默认设置为20 - 在
sdkconfig
文件中确认CONFIG_MICRO_ROS_DOMAIN_ID=20
- 检查micro-ROS代理的域ID:
- 启动命令中使用了
-domain 20
参数
- 检查ROS2环境的域ID:
- 运行
echo $ROS_DOMAIN_ID
发现未设置(默认为0)
解决方法
在ROS2环境中设置相同的域ID:
设置后,应该能看到ESP32发布的话题:
/publisher_1
/publisher_2
/publisher_3
测试通信
- 查看所有可用的话题:
显示micro-ROS创建主题
- 订阅ESP32发布的消息:
输出:
- 向ESP32发送消息:
输出:
当ESP32接收到消息时,会在串口输出中看到类似以下内容:
注意事项
- 确保ESP32和ROS2环境使用相同的域ID
- 如果使用Docker容器运行ROS2,可以在启动容器时设置环境变量:
- 确保ESP32和运行micro-ROS代理的计算机在同一网络中
- 检查ESP32中配置的代理IP地址是否正确(在sdkconfig文件中的
CONFIG_MICRO_ROS_AGENT_IP
)
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/esp_micro_ros_first_example
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!