Lazy loaded image
🤖 ROS 理论与实践
基于Docker运行micro-ROS第一个例子
Words 3538Read Time 9 min
2025-6-25
2025-6-27
type
date
slug
category
icon
password

准备条件

  1. 宿主机 Windows 系统
  1. 基于Docker搭建ESP32开发环境(Windows)
  1. esp32开发板
  1. 订阅-发布测试例子
 
基于Docker的开发环境搭建完成后,在 example_project 文件夹中有一个 .devcontainer 文件夹,文件夹中有两个文件
  1. devcontainer.json这是 VS Code 的开发容器配置文件,用于定义开发环境。它允许您在容器中进行开发,确保所有开发者使用相同的环境。主要功能包括:
      • 指定使用的 Docker 镜像或 Dockerfile
      • 配置容器启动选项(如端口映射、挂载卷)
      • 定义要安装的 VS Code 扩展
      • 设置容器内工作目录和环境变量
  1. 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版本为例.
⚠️
  1. WSL安装了Ubuntu2204桌面端,因此这里分支选择-b humble,请根据安装情况切换
  1. 由于micro_ros组件托管在GitHub上,下载文件可能因网络问题而失败。可能需要科学上网。

2. 激活ESP-IDF开发环境

⚠️
  1. 由于我们使用docker开发环境,配置文件进入后会自动激活ESP-IDF开发环境,此步可忽略,若你不是通过docker开发,请手动激活。
  1. 每次打开新终端都需要先激活ESP-IDF开发环境才可以编译ESP-IDF的工程。
  1. 启动脚本路径默认为$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。
⚠️
  1. 由于单片机性能有限,刚好满足需求就可以了,避免资源浪费和影响通讯速度。
  1. 例程实现3个订阅者,3个发布者,这里必须修改,否则在和microros agent 连接时会报错。
  1. 可以使用 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 配置,参考下图
notion image
参考
基于Docker搭建ESP32开发环境(Windows)
进行编译,编译完成后,下载到esp32开发板。
拓展阅读:ESP-IDF 项目如何识别micro-ROS的头文件和链接静态库
在ESP32项目中,micro-ROS组件构建完成后,CMakeLists.txt需要正确配置以识别micro-ROS的头文件和链接静态库。根据您提供的文档和当前的CMakeLists.txt,我来解释这个过程:

micro-ROS头文件和库的识别方式

  1. 组件目录结构
    1. micro-ROS在ESP-IDF中作为一个组件被集成。构建过程会在以下位置生成相关文件:
      • 头文件:cmicro_ros_espidf_component/include
      • 静态库:micro_ros_espidf_component/libmicroros.a
  1. 在CMakeLists.txt中识别micro-ROS组件
    1. 您当前的CMakeLists.txt已经包含了:
  1. 组件自动识别机制
    1. 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代理

开始前,先对网络拓扑结构作说明。
  1. 宿主机 (Windows)
      • 连接到WiFi路由器
      • 运行Docker Desktop,在其中启动micro-ROS Agent容器
  1. 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等)
  1. ESP32开发板
      • 通过WiFi连接到同一个路由器
      • 配置连接到宿主机IP地址和指定端口(8090)
      • 在代码中通过CONFIG_MICRO_ROS_AGENT_IP和CONFIG_MICRO_ROS_AGENT_PORT配置
  1. 通信流程
      • 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为波特率。可以根据实际情况做出修改。

代理启动失败的情况

notion image
microROS代理只能在一个终端开启,如果已经有终端在后台开启microROS代理,再次开启代理就会报错,请先在原来的代理终端按Ctrl+C退出代理后再运行代理。如果因为直接关闭终端导致下一次启动代理失败的情况,可重启虚拟机/电脑解决,或者手动结束docker解决。
手动结束docker的方法:
请先查询出当前docker进行号,并结束当前代理docker进程。

micro-ROS测试指南

环境准备

  1. ESP32开发板(已烧录micro-ROS固件)
  1. ROS2环境(Humble或其他版本,在microros/micro-ros-agent:humble容器中有ros2环境)

ESP32连接到代理

当ESP32成功连接到代理时,会在代理日志中看到以下信息:
然后会创建参与者、话题、发布者和订阅者:

打开ROS2进行通讯

容器内部启动一个交互式 shell,由于已经运行了 micro-ROS Agent 容器,可以在另一个终端窗口执行以下命令来进入该容器(Windows 适用的方式):
  1. 首先,我们需要找出正在运行的 micro-ros-agent 容器的 ID:
    1. 可以按照以下步骤在 Windows 中进入 micro-ros-agent 容器:
  1. 然后使用该容器 ID 进入容器:
    1. 例如,如果容器 ID 是 abc123,则命令为:
  1. 进入容器后,执行以下命令以启用 ROS2 环境:
    1. 现在可以使用 ros2 命令了

    ROS域ID问题排查

    如果在ROS2环境中运行ros2 topic list命令只显示系统默认的话题(如/parameter_events/rosout),而没有显示ESP32发布的话题,很可能是ROS域ID不匹配导致的。

    问题分析

    1. 检查ESP32的ROS域ID设置:
        • main/Kconfig.projbuild文件中,CONFIG_MICRO_ROS_DOMAIN_ID默认设置为20
        • sdkconfig文件中确认CONFIG_MICRO_ROS_DOMAIN_ID=20
    1. 检查micro-ROS代理的域ID:
        • 启动命令中使用了-domain 20参数
    1. 检查ROS2环境的域ID:
        • 运行echo $ROS_DOMAIN_ID发现未设置(默认为0)

    解决方法

    在ROS2环境中设置相同的域ID:
    设置后,应该能看到ESP32发布的话题:
    • /publisher_1
    • /publisher_2
    • /publisher_3

    测试通信

    1. 查看所有可用的话题:
      1. 显示micro-ROS创建主题
    1. 订阅ESP32发布的消息:
      1. 输出:
    1. 向ESP32发送消息:
      1. 输出:
        当ESP32接收到消息时,会在串口输出中看到类似以下内容:

    注意事项

    1. 确保ESP32和ROS2环境使用相同的域ID
    1. 如果使用Docker容器运行ROS2,可以在启动容器时设置环境变量:
      1. 确保ESP32和运行micro-ROS代理的计算机在同一网络中
      1. 检查ESP32中配置的代理IP地址是否正确(在sdkconfig文件中的CONFIG_MICRO_ROS_AGENT_IP
       
       
      上一篇
      ESP-IDF VS Code扩展 Cheet Sheet
      下一篇
      micro-ROS架构与接口调用规范

      Comments
      Loading...