学习目标
- 了解Micro-ROS与RTOS通信机制和整体架构
- 以micro-ros-arduino为例,熟悉Micro-ROS环境搭建并完成测试
目录
一、ROS2与RTOS通信原理
1、ROS2为什么要与微处理器通信?
-
个人总结:ROS2一般都是安装在上位机上,上位机相当于主机,具有很强的事务处理能力,比如图像处理、复杂算法计算等;微处理器的特点是功耗小、算力小,但方便进行传感器控制,所以微处理器作为机器人的下位机。通过micro-ROS实现安装在上位机的ROS2系统与下位机中烧录的程序进行通信,从而对各种传感器进行控制或获取传感器数据上输给上位机做进一步处理。以下是基本的结构图:
-
以下内容翻译自官网(可能不太准确,对照下面的原文理解吧):
微控制器几乎用于所有机器人产品。典型的原因是:- 传感器访问
- 低延迟的实时性
- 省电
- 另一个重要原因是安全性。
原文如下:
Microcontrollers are used in almost every robotic product. Typical reasons are:
Hardware access
Hard, low-latency real-time
Power saving
Another important reason is safety, but note that micro-ROS is not developed according to any safety standard.
2、整体架构
架构图说明(翻译自官网):
- Micro-ROS遵循ROS 2架构,并利用其中间件可插拔性来使用DDS-XRCE,DDS-XRCE针对微控制器进行了优化。此外,它使用基于POSIX的RTOS(FreeRTOS,Zephyr或NuttX)而不是Linux。
- 深蓝色组件专为微型ROS开发。浅蓝色组件取自标准 ROS 2 堆栈。
- 客户端库为用户代码提供微 ROS API,即用于应用级微 ROS 节点。目标是在微控制器的优化实现中提供所有相关的主要ROS 2概念。同时,我们努力使API尽可能兼容标准ROS 2,以方便代码的移植。
下面来自eProsima的架构图(来自网站:https://docs.vulcanexus.org/en/latest/rst/microros_documentation/index.html)
二、准备工作
1、环境准备
- 软件环境:Ubuntu22.04 Server + ROS2 Humble + Arduino IDE
- 硬件:树莓派 4B、ESP32 Dev板子、USB数据线
树莓派安装Ubuntu22.04、安装ROS2 Humble、安装Arduino IDE(采用教程中第一种方式
,原因见本博客第五章特别说明)、链接配置ESP32开发板请参见本人博客:
- 保姆级教程:树莓派4B 安装Ubuntu 22.04 Server操作系统
- 树莓派4B+Ubuntu22.04 Server安装ROS2 Humble
- 保姆级教程:Ubuntu22.04 上安装 Arduino IDE 配置ESP32开发板 让LED闪起来
2、micro-ros开发环境
micro-ros为嵌入式平台,提供了两种构建micro-ros应用的系统:
- micro_ros_setup:在作为 ROS 2 软件包提供的几个脚本中集成并隐藏特定于 RTOS 的构建工具。
- 与某个平台集成:micro-ROS与多个平台构建工具集成在一起,如Arduino。
以上为官方翻译,说白了就是:一种使用micro_ros_setup,一种使用第三方工具(点击此处查看详情),本博文使用的是第三方Micro-ROS-Arduino,以下是详细说明:
Micro-ROS-Arduino库下载并导入,操作如下:
1、下载Micro-ROS-Arduino库:https://github.com/micro-ROS/micro_ros_arduino/releases,下载对应ROS2的版本,本人下载Humble版,下载.zip
格式。
2、将下载的库文件导入之Arduino IDE,点击菜单:项目→加载库→添加.zip库
,如下图所示:
添加成功后,可以在示例中查看到micro-ros-arduino库示例,如下图:
目标一: 尝试打开一个示例,如micro-ros_publisher烧录到ESP32上。(此时编译应该成功,如果编译或上传报错,说明上述操作存在问题,需要根据错误提示进行处理。)
三、安装 micro-ROS 和 micro-ROS-Agent
按照本文以下说明进行安装,想了解更多内容可以参考以下网站:
1、安装 micro-ROS
特别提示:在执行
rosdep update
命令时,可能报超时,请访问以下网站解决:
https://mp.weixin.qq.com/s/VGs8oWdhHH6XsHcx21lN4Q
打开终端,执行以下脚本:
#Source the ROS 2 installation
source /opt/ros/$ROS_DISTRO/setup.bash
#Create a workspace and download the micro-ROS tools
mkdir microros_ws
cd microros_ws
git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup
#Update dependencies using rosdep
sudo apt update && rosdep update
#特别提示:在执行上面这一行(rosdep update)的命令时,可能报超时,请访问以下网站解决:
# https://mp.weixin.qq.com/s/VGs8oWdhHH6XsHcx21lN4Q
rosdep install --from-paths src --ignore-src -y
#Install pip
sudo apt-get install python3-pip
#Build micro-ROS tools and source them
colcon build
source install/local_setup.bash
目标二: 成功执行:source install/local_setup.bash
2、安装 micro-ROS-Agent
在终端上,仍然在microros_ws
目录下执行以下脚本:
#下载micro-ROS-Agent包
ros2 run micro_ros_setup create_agent_ws.sh
#编译micro-ROS-Agent包
ros2 run micro_ros_setup build_agent.sh
source install/local_setup.bash
目标三: 成功执行: source install/local_setup.bash
micro-ROS-Agent封装了eProsima Micro XRCE-DDS Agent(属于中间件),安装后者也是可以实现通信的,详细参见:https://www.ncnynl.com/archives/202012/3986.html
四、测试
1、首先,保证上文的目标一、目标二、目标三全部成功。
2、运行micro-ROS agent:
ros2 run micro_ros_agent micro_ros_agent serial --dev [device]
我执行的命令为:ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
提示:获取串口设备名称命令:
ls /dev/serial/by-id/*
另外,在执行运行micro-ROS agent命令后,要按ESP32上的EN
按钮,这个要格外注意。
3、执行命令,检查是否能够查看到烧录到ESP32上micro-ros_publisher
中运行的ROS2 topic
ros2 topic list
如果包含以下topic,说明已经打通了ROS2与ESP32的通信:
五、特别说明
Arduino IDE有三种安装方式,经测试,只有通过arduino-1.8.19-linuxaarch64.tar.xz
包下载执行安装命令的方式(详细安装说明本人博客:https://blog.youkuaiyun.com/yunandfei/article/details/128939863),才能把micro-ros的Sample示例烧录到ESP32上,另外两种方式都会报错,以下是记录的错误信息,大家有时间可以研究下原因:
错误信息如下:
Arduino: 1.8.19 (Linux), Board: "ESP32 Dev Module, FTDI Adapter, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 921600, Core 1, Core 1, None, Disabled"
WARNING: Category '' in library ESP Insights is not valid. Setting to 'Uncategorized'
WARNING: Category '' in library ESP RainMaker is not valid. Setting to 'Uncategorized'
WARNING: Category '' in library WiFiProv is not valid. Setting to 'Uncategorized'
WARNING: Spurious .images folder in 'micro_ros_arduino' library
Archiving built core (caching) in: /tmp/arduino_cache_502901/core/core_esp32_esp32_esp32_JTAGAdapter_external,PSRAM_disabled,PartitionScheme_default,CPUFreq_240,FlashMode_qio,FlashFreq_80,FlashSize_4M,UploadSpeed_921600,LoopCore_1,EventsCore_1,DebugLevel_none,EraseFlash_none_707cf5229adfcb1e1e45a3add23f549f.a
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z14timer_callbackP11rcl_timer_sx+0x8): undefined reference to `rcl_publish'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x3c): undefined reference to `rmw_uros_set_custom_transport'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x40): undefined reference to `rcutils_get_default_allocator'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x44): undefined reference to `rclc_support_init'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x48): undefined reference to `rclc_node_init_default'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x4c): undefined reference to `rosidl_typesupport_c__get_message_type_support_handle__std_msgs__msg__Int32'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x50): undefined reference to `rclc_publisher_init_default'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x54): undefined reference to `rclc_timer_init_default'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x58): undefined reference to `rclc_executor_init'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z5setupv+0x5c): undefined reference to `rclc_executor_add_timer'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o:(.literal._Z4loopv+0x4): undefined reference to `rclc_executor_spin_some'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o: in function `timer_callback(rcl_timer_s*, long long)':
/root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:36: undefined reference to `rcl_publish'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o: in function `setup()':
/root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/src/micro_ros_arduino.h:33: undefined reference to `rmw_uros_set_custom_transport'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o: in function `setup()':
/root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:47: undefined reference to `rcutils_get_default_allocator'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:49: undefined reference to `rclc_support_init'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:52: undefined reference to `rclc_node_init_default'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:55: undefined reference to `rosidl_typesupport_c__get_message_type_support_handle__std_msgs__msg__Int32'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:55: undefined reference to `rclc_publisher_init_default'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:58: undefined reference to `rclc_timer_init_default'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:66: undefined reference to `rclc_executor_init'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:73: undefined reference to `rclc_executor_add_timer'
/root/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/micro-ros_publisher.ino.cpp.o: in function `loop()':
/root/Arduino/libraries/micro_ros_arduino-2.0.5-humble/examples/micro-ros_publisher/micro-ros_publisher.ino:81: undefined reference to `rclc_executor_spin_some'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board ESP32 Dev Module.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
六、参考网站
- Micro-ROS for Arduino :https://github.com/micro-ROS/micro_ros_arduino
- Micro-ROS :https://micro.ros.org/docs/tutorials/core/overview/
- Micro XRCE-DDS: https://micro-xrce-dds.docs.eprosima.com/en/latest/index.html
- 创客智造:https://www.ncnynl.com/archives/202012/3986.html
- Mircro-ROS支持的微处理器列表:https://micro.ros.org/docs/overview/hardware/