编辑
2024-04-09
笔记
0

目录

Installing ROS 2 and the micro-ROS build system
Creating a new firmware workspace
Configuring micro-ROS firmware
Building the firmware
Flashing the firmware
Creating the micro-ROS agent
Testing the micro-ROS app
Standalone build system tools
创建自己的 STM32 板子下的 micro-ROS
一些问题解决
注意,需要在工程中添加 microrosstm32cubemxutils 目录下的 extrasources子目录中的一些 .c 代码文件。
Linux 下普通用户使用串口
Linux 下使用 CH340 USB转串口
mcu -serial-> microrosagent 是通的,microrosagent --> ROS2 不通(即ROS2上查看不到 micro-ROS的节点)。
如果在未安装 Docker 环境下编写代码,需要编译 micro-ROS的库。

Installing ROS 2 and the micro-ROS build system

bash
# 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 rosdep update && rosdep install --from-paths src --ignore-src -y # Build micro-ROS tools and source them colcon build source install/local_setup.bash

Creating a new firmware workspace

bash
# Creating a FreeRTOS + micro-ROS firmware workspace ros2 run micro_ros_setup create_firmware_ws.sh freertos olimex-stm32-e407 # Creating a Zephyr + micro-ROS firmware workspace ros2 run micro_ros_setup create_firmware_ws.sh zephyr olimex-stm32-e407

Configuring micro-ROS firmware

bash
ros2 run micro_ros_setup configure_firmware.sh [APP] [OPTIONS]

The options available for this configuration step are:

  • --transport or -tudpserial or any hardware-specific transport label
  • --dev or -d: agent string descriptor in a serial-like transport
  • --ip or -i: agent IP in a network-like transport
  • --port or -p: agent port in a network-like transport

In this tutorial, we will use a Serial transport (labeled as serial) and focus on the out-of-the-box ping_pong application located at firmware/freertos_apps/apps/ping_pong. To execute this application with the chosen transport, run the configuration command above by specifying the [APP] and [OPTIONS] parameters as below:

bash
ros2 run micro_ros_setup configure_firmware.sh ping_pong --transport serial

Building the firmware

bash
ros2 run micro_ros_setup build_firmware.sh

Flashing the firmware

bash
ros2 run micro_ros_setup flash_firmware.sh

Creating the micro-ROS agent

bash
# Download micro-ROS-Agent packages ros2 run micro_ros_setup create_agent_ws.sh # Build step ros2 run micro_ros_setup build_agent.sh source install/local_setup.bash # Run a micro-ROS agent ros2 run micro_ros_agent micro_ros_agent serial --dev [device]

TIP: you can use this command to find your serial device name: ls /dev/serial/by-id/*

Testing the micro-ROS app

bash
source /opt/ros/$ROS_DISTRO/setup.bash # Subscribe to micro-ROS ping topic ros2 topic echo /microROS/ping
bash
source /opt/ros/$ROS_DISTRO/setup.bash # Subscribe to micro-ROS pong topic ros2 topic echo /microROS/pong
bash
source /opt/ros/$ROS_DISTRO/setup.bash # Send a fake ping ros2 topic pub --once /microROS/ping std_msgs/msg/Header '{frame_id: "fake_ping"}'

Standalone build system tools

bash
ros2 run micro_ros_setup component --help

创建自己的 STM32 板子下的 micro-ROS

  1. 执行 "Installing ROS 2 and the micro-ROS build system" 步骤
bash
mkdir f407_ws cd f407_ws git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup rosdep update && rosdep install --from-paths src --ignore-src -y colcon build
  1. 在该 Workspace 目录下执行命令
bash
source install/local_setup.bash ros2 run micro_ros_setup component stm32cube
  1. 使用 STM32CubeMX / STM32CubeIDE 创建 STM32 Project,并根据要求配置好工程。
  2. 修改代码文件 freertos.c 文件。
c
#include "usart.h" #include <cmsis_os.h> #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> 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); void subscription_callback(const void * msgin) { const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin; printf("Received: %d\n", msg->data); } void StartMicroRosTask(void *argument) { // micro-ROS configuration rcl_ret_t ret; ret = rmw_uros_set_custom_transport( true, (void *)&huart1, 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__); } // micro-ROS app rcl_publisher_t publisher; rcl_subscription_t subscriber; 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 ret = rclc_support_init(&support, 0, NULL, &allocator); // create node ret = rclc_node_init_default(&node, "cubemx_node", "", &support); // create publisher ret = rclc_publisher_init_default( &publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "cubemx_publisher"); // create subscriber ret = rclc_subscription_init_default( &subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "/cubemx_subscriber"); // create executor rclc_executor_t executor; ret = rclc_executor_init(&executor, &support.context, 1, &allocator); ret = rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback, ON_NEW_DATA); msg.data = 0; /* Infinite loop */ for(;;) { rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)); ret = rcl_publish(&publisher, &msg, NULL); if (ret != RCL_RET_OK) { printf("Error publishing (line %d)\n", __LINE__); } msg.data++; osDelay(10); } }
  1. 编译烧写固件到 STM32 板子上
  2. 执行 "Creating the micro-ROS agent" 步骤
  3. 执行命令开启 micro-ROS agent
bash
ros2 run micro_ros_agent micro_ros_agent serial -b 115200 --dev /dev/ttyCH341USB0
  1. 查看 STM32 在 ROS2 上发布信息
bash
ros2 topic echo /cubemx_publisher
  1. 发布消息
bash
ros2 topic pub --once /cubemx_subscriber std_msgs/msg/Int32 '{data: 1}'

一些问题解决

注意,需要在工程中添加 micro_ros_stm32cubemx_utils 目录下的 extra_sources子目录中的一些 .c 代码文件。

extra_sources/microros_time.c extra_sources/microros_allocators.c extra_sources/custom_memory_manager.c extra_sources/microros_transports/dma_transport.c or your transport selection.

Linux 下普通用户使用串口

bash
sudo usermod -a -G dialout $(whoami) sudo chmod a+rw /dev/tty*

Linux 下使用 CH340 USB转串口

bash
# 驱动地址:https://www.wch.cn/download/CH341SER_LINUX_ZIP.html # # CH340系列串口芯片无法识别 sudo apt-get remove --purge brltty

mcu -serial-> micro_ros_agent 是通的,micro_ros_agent --> ROS2 不通(即ROS2上查看不到 micro-ROS的节点)。

  1. 查看 ROS_DOMAIN_ID 环境变量。

ROS 2 用于通信的默认中间件是 DDS。 在 DDS 中,让不同的逻辑网络共享物理网络的主要机制称为域 ID。 同一域的 ROS 2 节点可以自由地发现消息并相互发送消息,而不同域的 ROS 2 节点则不能。 默认情况下,所有 ROS 2 节点都使用域 ID 0。 为避免同一网络上运行 ROS 2 的不同计算机组之间的干扰,应为每个组设置不同的域 ID。

bash
env | grep ROS_DOMAIN_ID

解决方法 1:取消 域ID 环境变量

bash
unset ROS_DOMAIN_ID

解决方法2:在 MCU 代码中设置 域ID

C
rcl_node_options_t node_ops = rcl_node_get_default_options(); node_ops.domain_id = 10; RCCHECK(rclc_node_init_with_options(&node, "my_node_name", "", &support, &node_ops));

如果在未安装 Docker 环境下编写代码,需要编译 micro-ROS的库。

  1. 找到一台有 Docker 的电脑/虚拟机。
  2. 在命令行中执行下面的指令。
bash
git clone -b humble https://github.com/micro-ROS/micro_ros_stm32cubemx_utils.git docker pull microros/micro_ros_static_library_builder:humble && docker run --rm -v ./:/project --env MICROROS_LIBRARY_FOLDER=micro_ros_stm32cubemx_utils/microros_static_library_ide microros/micro_ros_static_library_builder:humble
  1. 然后拷贝 micro_ros_stm32cubemx_utils 目录到对应的STM32工程目录下即可。

本文作者:菜鸟

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 许可协议。转载请注明出处!