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
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
bashros2 run micro_ros_setup configure_firmware.sh [APP] [OPTIONS]
The options available for this configuration step are:
--transport
or -t
: udp
, serial
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 transportIn 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:
bashros2 run micro_ros_setup configure_firmware.sh ping_pong --transport serial
bashros2 run micro_ros_setup build_firmware.sh
bashros2 run micro_ros_setup flash_firmware.sh
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/*
bashsource /opt/ros/$ROS_DISTRO/setup.bash
# Subscribe to micro-ROS ping topic
ros2 topic echo /microROS/ping
bashsource /opt/ros/$ROS_DISTRO/setup.bash
# Subscribe to micro-ROS pong topic
ros2 topic echo /microROS/pong
bashsource /opt/ros/$ROS_DISTRO/setup.bash
# Send a fake ping
ros2 topic pub --once /microROS/ping std_msgs/msg/Header '{frame_id: "fake_ping"}'
bashros2 run micro_ros_setup component --help
bashmkdir 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
bashsource install/local_setup.bash
ros2 run micro_ros_setup component stm32cube
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);
}
}
bashros2 run micro_ros_agent micro_ros_agent serial -b 115200 --dev /dev/ttyCH341USB0
bashros2 topic echo /cubemx_publisher
bashros2 topic pub --once /cubemx_subscriber std_msgs/msg/Int32 '{data: 1}'
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.
bashsudo usermod -a -G dialout $(whoami)
sudo chmod a+rw /dev/tty*
bash# 驱动地址:https://www.wch.cn/download/CH341SER_LINUX_ZIP.html
# # CH340系列串口芯片无法识别
sudo apt-get remove --purge brltty
ROS 2 用于通信的默认中间件是 DDS。 在 DDS 中,让不同的逻辑网络共享物理网络的主要机制称为域 ID。 同一域的 ROS 2 节点可以自由地发现消息并相互发送消息,而不同域的 ROS 2 节点则不能。 默认情况下,所有 ROS 2 节点都使用域 ID 0。 为避免同一网络上运行 ROS 2 的不同计算机组之间的干扰,应为每个组设置不同的域 ID。
bashenv | grep ROS_DOMAIN_ID
解决方法 1:取消 域ID 环境变量
bashunset ROS_DOMAIN_ID
解决方法2:在 MCU 代码中设置 域ID
Crcl_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));
bashgit 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
本文作者:菜鸟
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 许可协议。转载请注明出处!