在开始集成Micro-ROS之前,我们需要准备好开发环境。这个过程就像装修房子前要准备工具和材料一样,缺一不可。我建议使用Ubuntu 20.04或22.04作为开发环境,这是目前最稳定的选择。
首先安装必要的工具链:
bash复制sudo apt update
sudo apt install -y build-essential git wget
接下来是Docker的安装。Docker在这里扮演着"搬运工"的角色,它会帮我们获取和构建Micro-ROS所需的库文件。安装步骤稍微复杂一些,但跟着我做就不会出错:
bash复制# 添加Docker官方GPG密钥
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# 添加Docker仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装完成后,记得将当前用户加入docker组,这样就不需要每次都使用sudo了:
bash复制sudo usermod -aG docker $USER
newgrp docker
最后验证Docker是否安装成功:
bash复制docker run hello-world
现在我们来获取Micro-ROS的STM32工具库。这个工具库就像是一个"转换器",能让ROS2和STM32顺畅沟通。我建议新建一个专门的工作目录来存放所有相关文件:
bash复制mkdir -p ~/microros_ws && cd ~/microros_ws
克隆Micro-ROS工具库:
bash复制git clone https://github.com/micro-ROS/micro_ros_stm32cubemx_utils.git
cd micro_ros_stm32cubemx_utils
git checkout humble
这里有几个注意事项:
Makefile就像是项目的"说明书",告诉编译器如何构建我们的程序。我们需要对它进行一些修改,让Micro-ROS能够顺利集成。
首先处理文件格式问题(Windows用户特别注意):
bash复制sudo apt install dos2unix
dos2unix Makefile
然后打开Makefile,找到合适的位置添加以下内容:
makefile复制#######################################
# micro-ROS addons
#######################################
LDFLAGS += micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a
C_INCLUDES += -Imicro_ros_stm32cubemx_utils/microros_static_library/libmicroros/microros_include
# Add micro-ROS utils
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/custom_memory_manager.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_allocators.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_time.c
# Set here the custom transport implementation
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_transports/dma_transport.c
print_cflags:
@echo $(CFLAGS)
这些配置做了以下几件事:
这一步我们要使用Docker来构建Micro-ROS的静态库。这个过程有点像在工厂里定制零件,我们需要提供规格参数,Docker会帮我们生产出需要的库文件。
首先拉取构建镜像:
bash复制docker pull microros/micro_ros_static_library_builder:humble
然后运行构建命令:
bash复制docker run -it --rm -v $(pwd):/project --env MICROROS_LIBRARY_FOLDER=micro_ros_stm32cubemx_utils/microros_static_library microros/micro_ros_static_library_builder:humble
构建过程中会询问一些配置选项,直接按y确认即可。虽然最后可能会报一些包找不到的警告,但实际测试表明这些警告可以忽略。
构建完成后,你会在micro_ros_stm32cubemx_utils/microros_static_library目录下看到生成的静态库文件。这个库文件包含了Micro-ROS的核心功能,相当于把ROS2的精简版打包进了我们的STM32工程。
现在到了最关键的一步——把Micro-ROS真正集成到我们的STM32工程中。这个过程就像把新买的家具搬进房子并安装好。
首先,我们需要从sample_main.c中复制必要的头文件到我们的工程中(通常是freertos.c):
c复制#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <uxr/client/transport.h>
#include <rmw_microxrcedds_c/config.h>
#include <rmw_microros/rmw_microros.h>
#include <std_msgs/msg/int32.h>
然后添加传输接口的声明:
c复制bool cubemx_transport_open(struct uxrCustomTransport * transport);
bool cubemx_transport_close(struct uxrCustomTransport * transport);
size_t cubemx_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
size_t cubemx_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);
void * microros_allocate(size_t size, void * state);
void microros_deallocate(void * pointer, void * state);
void * microros_reallocate(void * pointer, size_t size, void * state);
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state);
接下来是核心的Micro-ROS初始化代码:
c复制rmw_uros_set_custom_transport(
true,
(void *) &huart3, // 根据实际使用的串口修改
cubemx_transport_open,
cubemx_transport_close,
cubemx_transport_write,
cubemx_transport_read);
rcl_allocator_t freeRTOS_allocator = rcutils_get_zero_initialized_allocator();
freeRTOS_allocator.allocate = microros_allocate;
freeRTOS_allocator.deallocate = microros_deallocate;
freeRTOS_allocator.reallocate = microros_reallocate;
freeRTOS_allocator.zero_allocate = microros_zero_allocate;
if (!rcutils_set_default_allocator(&freeRTOS_allocator)) {
printf("Error on default allocators (line %d)\n", __LINE__);
}
最后添加一个简单的发布者示例:
c复制// micro-ROS app
rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
allocator = rcl_get_default_allocator();
// create init_options
rclc_support_init(&support, 0, NULL, &allocator);
// create node
rclc_node_init_default(&node, "cubemx_node", "", &support);
// create publisher
rclc_publisher_init_default(
&publisher,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
"cubemx_publisher");
msg.data = 0;
for(;;) {
rcl_ret_t ret = rcl_publish(&publisher, &msg, NULL);
if (ret != RCL_RET_OK) {
printf("Error publishing (line %d)\n", __LINE__);
}
msg.data++;
osDelay(10);
}
编译过程中可能会遇到各种问题,这里我总结了一些常见问题及解决方法:
Makefile格式错误:
如果遇到"missing separator"错误,可能是因为Makefile中使用了空格而不是Tab。用文本编辑器打开Makefile,确保命令前的缩进是Tab而不是空格。
缺少编译器:
如果提示"arm-none-eabi-gcc not found",需要安装ARM工具链:
bash复制sudo apt install gcc-arm-none-eabi
头文件找不到:
检查C_INCLUDES路径是否正确,特别注意路径是相对于Makefile所在目录的。
串口配置错误:
确保代码中的串口句柄(如&huart3)与实际使用的串口一致。可以在CubeMX中查看配置的串口编号。
内存不足:
Micro-ROS需要一定的内存空间,如果遇到奇怪的崩溃,尝试在CubeMX中增加堆栈大小。
成功编译后,会在build目录下生成.bin和.hex文件。可以使用以下工具烧录:
ST-Link Utility:
适合使用ST-Link调试器的用户,图形化界面操作简单。
OpenOCD:
命令行工具,适合自动化脚本:
bash复制openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program build/your_project.hex verify reset exit"
J-Flash:
适合使用J-Link的用户,功能强大。
烧录完成后,连接串口终端(如Putty或Minicom)查看输出。如果一切正常,你应该能看到Micro-ROS初始化的日志信息。
在ROS2端,可以运行以下命令测试通信:
bash复制source /opt/ros/humble/setup.bash
ros2 topic echo /cubemx_publisher
如果能看到不断递增的数字,恭喜你,Micro-ROS已经在STM32上成功运行了!