welcom ! Handel home

2025年4月14日 星期一

什麼是 eProsima Micro XRCE-DDS?

 

🔍 一、什麼是 eProsima Micro XRCE-DDS?

名稱說明
XRCE-DDSeXtremely Resource Constrained Environment DDS,是 OMG DDS 的子協定
用途讓微控制器(如 STM32)這種資源有限的裝置,也能參與 DDS 資料流(如 ROS 2 中使用的 DDS)
架構採用 Client / Agent 模式,Client 跑在 MCU,Agent 跑在主機/樹莓派等具備 ROS 2 的系統上

🧱 二、Micro XRCE-DDS 的組成

📦 Micro XRCE-DDS Client(你在 STM32 上運行的程式)

  • 小巧輕便、可裁剪(可用 CMake 調整功能)

  • 透過序列埠(Serial)或網路(UDP)向 Agent 發送請求

  • 可執行的操作:

    • 建立 DDS Participant

    • 建立 Publisher / Subscriber

    • 傳送 topic 訊息 / 接收 topic 資料

📦 Micro XRCE-DDS Agent(跑在 PC / Linux 的「轉譯伺服器」)

  • 接收 Client 送來的請求

  • 幫 Client 在 DDS 中建立實體,如:

    • Participant

    • PublisherSubscriber

    • Topic

  • 是 ROS 2 和 micro-ROS 中的「中介者」

💬 支援的傳輸方式:

傳輸協定是否支援
Serial(UART) ✅
UDPv4 / UDPv6
TCPv4 / TCPv6
自訂 Transport ✅

🔄 三、資料流程概念圖

text
┌─────────────┐ UART / UDP ┌─────────────┐ DDS Middleware ┌──────────────┐ │ STM32 Client│ ─────────────────────▶ │ micro-ROS │ ────────────────────────▶ │ ROS 2 Nodes │ │ (micro-ROS) │ │ Agent │ │ │ └─────────────┘ XRCE-DDS 協定 └─────────────┘ └──────────────┘

⚙️ 四、如何應用在 RRC 控制板

✅ 對應情境:

動作XRCE-DDS 對應機制
接收 /cmd_vel 指令控制馬達create_subscriber("cmd_vel")
回傳 IMU 資料、馬達速度create_publisher("imu/data")
傳輸通道UART (/dev/ttyACM0)
傳送格式DDS-XRCE 編碼封包

🚀 五、實作指引關鍵工具

1. 使用 micro-ROS build system

快速產生 firmware:

bash
ros2 run micro_ros_setup create_firmware_ws.sh freertos stm32f4

2. 編譯與部署

bash
ros2 run micro_ros_setup configure_firmware.sh int32_publisher ros2 run micro_ros_setup build_firmware.sh st-flash write build/micro_ros_firmware.elf 0x8000000

3. 啟動 Agent

bash
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0

🧰 六、學習資源與官方手冊

資源名稱連結
🔗 Start Pagehttps://micro-xrce-dds.readthedocs.io
🔗 GitHub Repohttps://github.com/eProsima/Micro-XRCE-DDS
🔗 ROS 2 Integration Docshttps://micro.ros.org/docs
📘 DDS 標準定義(XRCE)OMG XRCE-DDS

📣 小結

  • 🧠 Micro XRCE-DDS 是 micro-ROS 與 ROS 2 的資料橋梁,幫助資源受限的 STM32 類裝置參與 ROS 通訊

  • ⚙️ Client 在 MCU 上運行,Agent 在 ROS 主機上作為代理

  • 🔌 你在 RRC 上跑的 micro-ROS,實際上就是透過 XRCE-DDS 與 ROS 網路互動


/* === app.c === */
#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <geometry_msgs/msg/twist.h>
#include "differential_chassis.h"

rcl_subscription_t cmd_vel_sub;
geometry_msgs__msg__Twist cmd_vel_msg;

void cmd_vel_callback(const void * msgin) {
    const geometry_msgs__msg__Twist * msg = (const geometry_msgs__msg__Twist *)msgin;
    float linear = msg->linear.x;
    float angular = msg->angular.z;
    diff_chassis_move(linear * 1000, 0, angular * 1000); // RRC 控制函式
}

void appMain(void * arg) {
    rcl_allocator_t allocator = rcl_get_default_allocator();
    rclc_support_t support;
    rcl_node_t node;
    rclc_executor_t executor;

    rclc_support_init(&support, 0, NULL, &allocator);
    rcl_node_init_default(&node, "rrc_chassis_node", "", &support);

    rcl_subscription_init_default(
        &cmd_vel_sub,
        &node,
        ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist),
        "cmd_vel");

    rclc_executor_init(&executor, &support.context, 1, &allocator);
    rclc_executor_add_subscription(&executor, &cmd_vel_sub, &cmd_vel_msg, &cmd_vel_callback, ON_NEW_DATA);

    while (1) {
        rclc_executor_spin_some(&executor, RCL_MS_TO_NS(10));
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

沒有留言: