在PlatformIO中创建microROS自定义消息的问题求助
我正尝试在NodeMCU Esp32S上创建ROS服务,使用了micro_ros_platformio库,按库文档配置PlatformIO后已成功运行初始程序。但所需服务消息无法通过标准消息满足,需要创建自定义服务消息。
我先创建了名为custom_interfaces_ws的新工作区,以及包含msg和srv文件夹的ROS2包custom_message,按常规ROS2消息构建流程编译后,在platformio.ini中添加了相关引用:
[env:nodemcu-32s] platform = espressif32 board = nodemcu-32s framework = arduino board_microros_distro = humble board_microros_transport = wifi lib_deps = https://github.com/micro-ROS/micro_ros_platformio extra_scripts = pre:read_config.py monitor_speed = 115200 build_flags = -I/home/nash/dev/ros_custom_interfaces_ws/install/custom_messages/include -I/home/nash/dev/ros_custom_interfaces_ws/install/custom_messages/include/custom_messages -L/home/nash/dev/ros_custom_interfaces_ws/install/custom_messages/lib -lcustom_messages__rosidl_typesupport_c -lcustom_messages__rosidl_typesupport_introspection_c
运行时出现.so文件格式不识别的错误:
/home/nash/dev/ros_custom_interfaces_ws/install/custom_messages/lib/libcustom_messages__rosidl_typesupport_c.so: file not recognized: file format not recognized collect2: error: ld returned 1 exit status *** [.pio/build/nodemcu-32s/firmware.elf] Error 1
(该问题在意料之中,因为是在本地机器上编译的消息)
之后我尝试按照microROS官方教程创建自定义消息:通过ros2 run micro_ros_setup create_firmware_ws.sh freertos esp32创建新固件,在firmware/mcu_ws中添加自定义消息包,再用ros2 run micro_ros_setup configure_firmware.sh ping_pong --transport serial配置固件(因必须配置才能编译)。我希望编译出含自定义消息的固件后在PlatformIO中引用,但该方法也失败了。
请问是否仅通过PlatformIO构建工具就能创建microROS自定义消息,或能否借助micro_ros_platformio库实现?
可以直接通过PlatformIO结合micro_ros_platformio库实现自定义消息,核心是要为ESP32架构交叉编译自定义消息,而非使用本地x86架构编译的动态库。具体步骤如下:
1. 规范自定义消息包结构
确保你的custom_messages包符合ROS2标准结构:
custom_messages/ ├── CMakeLists.txt ├── package.xml ├── msg/ │ └── YourCustomMsg.msg └── srv/ └── YourCustomSrv.srv
在package.xml中添加必要依赖:
<buildtool_depend>ament_cmake</buildtool_depend> <build_depend>rosidl_default_generators</build_depend> <exec_depend>rosidl_default_runtime</exec_depend> <member_of_group>rosidl_interface_packages</member_of_group>
在CMakeLists.txt中配置消息生成规则:
cmake_minimum_required(VERSION 3.8) project(custom_messages) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() find_package(ament_cmake REQUIRED) find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "msg/YourCustomMsg.msg" "srv/YourCustomSrv.srv" ) ament_export_dependencies(rosidl_default_runtime) ament_package()
2. 用micro-ROS工具链交叉编译自定义消息
micro_ros_platformio依赖micro-ROS的交叉编译工具链,需用它为ESP32生成兼容的静态库:
- 创建micro-ROS固件工作区(若未创建):
ros2 run micro_ros_setup create_firmware_ws.sh freertos esp32 - 将
custom_messages包复制到firmware/mcu_ws/src目录下 - 配置固件时引入自定义消息依赖(替换为你的项目名或模板名):
ros2 run micro_ros_setup configure_firmware.sh your_project_name --transport wifi - 编译工作区,生成ESP32兼容的头文件和静态库:
编译完成后,产物会存放在ros2 run micro_ros_setup build_firmware.shfirmware/build/include(头文件)和firmware/build/lib(静态库)目录下。
3. 在PlatformIO中引用交叉编译产物
修改platformio.ini的build_flags,指向交叉编译后的文件(替换为你的实际路径):
build_flags = -I/path/to/firmware/build/include -I/path/to/firmware/build/include/custom_messages -L/path/to/firmware/build/lib -lcustom_messages__rosidl_typesupport_c -lcustom_messages__rosidl_typesupport_introspection_c -lcustom_messages__rosidl_generator_c
这里使用的是.a静态库,而非本地编译的.so动态库,可解决格式不兼容问题。
4. 在代码中使用自定义消息
在PlatformIO的Arduino代码中直接引入头文件即可使用:
#include <custom_messages/srv/your_custom_srv.h> // 服务回调示例 void service_callback(const void * req, void * res) { // 处理请求与响应逻辑 } void setup() { // 初始化micro-ROS // ... // 创建服务服务器 RCCHECK(rclc_service_init_default( &service, &node, ROSIDL_GET_SRV_TYPE_SUPPORT(custom_messages, srv, YourCustomSrv), "/your_custom_service" )); }
内容的提问来源于stack exchange,提问作者tucker

