Kaiyasi
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # micro-ROS 理論篇 ## 一、ROS 2 架構 ### 1. ROS 2 的設計理念與定位 ROS(Robot Operating System)最早是為了讓機器人開發更模組化而誕生的。 它不是傳統意義上的「作業系統」,而是一套**通訊框架與軟體生態**, 讓不同模組之間可以以標準化方式交換資料、共享資源、協同運作。 ROS 2 是 ROS 的第二代,最大的改革是將整個通訊底層改寫為 **DDS(Data Distribution Service)**。 這讓 ROS 2 能在不同平台上運行,也能支援更嚴格的即時性與可靠性需求。 ROS 2 的核心思想有三個: 1. **模組化(Modularity)** 系統由許多節點(Node)組成,每個節點只負責一件事。 節點之間不需要知道對方的細節,只需知道 Topic 名稱與訊息格式。 2. **分散式(Distributed)** 節點可以分散在不同裝置上,例如一個在電腦上、另一個在樹莓派上。 只要在同一個 DDS 網路中,節點就能互相發現並通訊。 3. **可重用性(Reusability)** 任何人寫的節點,只要遵守 ROS 訊息規範,就能被別的專案直接使用。 --- ### 2. Node、Topic、Publisher、Subscriber 架構 #### (1) Node Node 是 ROS 世界裡的「程式單元」。 你可以把它想成一個在 ROS 網路中執行的進程(process)。 每個 Node 都有自己的名稱與功能,例如: | Node 名稱 | 功能 | | ------------------ | ------ | | `/camera_node` | 負責影像擷取 | | `/motor_node` | 控制馬達轉速 | | `/navigation_node` | 負責路徑規劃 | 所有 Node 都由 `rclpy`(Python)或 `rclcpp`(C++) 建立與管理。 --- #### (2) Topic Topic 是 ROS 的「資料通道」。 它定義了一個訊息的主題名稱與格式。 節點之間透過發佈與訂閱 Topic 進行資料交換。 例如: ``` Topic: /sensor/temperature Type: std_msgs/Float32 ``` 任何節點都可以發布這個 Topic,也可以同時有多個節點訂閱它。 --- #### (3) Publisher Publisher 是負責「發送資料」的角色。 在 Python 中用 `create_publisher()` 建立。 基本語法: ```python self.publisher = self.create_publisher(Float32, '/sensor/temperature', 10) ``` 這段程式會: * 宣告一個名為 `/sensor/temperature` 的 Topic * 使用 `Float32` 訊息型別 * Queue 大小為 10(即緩衝最多 10 筆資料) Publisher 會使用 `publish(msg)` 將資料送出。 --- #### (4) Subscriber Subscriber 則是「接收資料」的一方。 它訂閱一個 Topic,並在每次收到新訊息時執行 callback 函式。 ```python self.subscription = self.create_subscription(Float32, '/sensor/temperature', self.listener_callback, 10) ``` 其中: * 第 1 個參數是訊息型別 * 第 2 個是 Topic 名稱 * 第 3 個是 callback 函式(當收到資料時執行) * 第 4 個是 Queue 大小 Callback 函式格式通常如下: ```python def listener_callback(self, msg): self.get_logger().info(f'Received: {msg.data}') ``` 這樣 ROS 2 節點就能被動接收並處理資料。 --- ### 3. 通訊協定 DDS 的運作原理 DDS(Data Distribution Service)是 ROS 2 通訊的核心。 它是一種 **Publish–Subscribe 中介層協定**,專為分散式即時系統設計。 它的幾個特性: 1. **自動節點發現** 節點不需手動指定 IP 或 Port。 DDS 會自動偵測同一網路中的 Publisher 與 Subscriber,建立通訊連線。 2. **即時性與可靠性控制** DDS 提供 QoS(Quality of Service)設定,讓使用者可以決定: * 要不要保證資料送達 * 要保留幾筆歷史資料 * 延遲或頻寬的取捨 3. **去中心化(Decentralized)** DDS 沒有中央伺服器。 所有節點都是平等的「Peer」,這讓系統更穩定,也容易擴展。 --- ### 4. QoS(Quality of Service)設定 QoS 是 DDS 的關鍵機制之一,直接影響通訊的可靠度與效率。 常見參數如下: | 參數名稱 | 意義 | 常用值 | | ----------- | -------- | ------------------------------------------- | | Reliability | 資料可靠度 | `Reliable`(保證送達) / `Best Effort`(允許丟包) | | Durability | 是否保留舊資料 | `Volatile`(不保留) / `Transient Local`(保留最近一次) | | History | 保留幾筆訊息 | `Keep Last`、`Keep All` | | Depth | Queue 大小 | 數值,例如 10 | 範例: ```python from rclpy.qos import QoSProfile, QoSReliabilityPolicy qos = QoSProfile(depth=10) qos.reliability = QoSReliabilityPolicy.RELIABLE self.create_subscription(String, '/topic', self.cb, qos) ``` --- ### 5. ROS 2 的優勢與限制 | 面向 | 優勢 | 限制 | | --------- | -------------------------- | ---------------- | | **可擴充性** | 支援多語言(Python / C++ / Java) | 效能取決於 DDS 實作 | | **開發便利性** | 有完整 CLI 工具與 rqt 可視化 | 建構與依賴管理複雜 | | **穩定性** | DDS 架構可靠、去中心化 | 高資源消耗(CPU / RAM) | | **適用對象** | 桌上型機器人、工業自動化、AI 模組 | 無法直接用於 MCU 或裸機系統 | 這個「無法直接用於微控制器」的限制,就是 micro-ROS 出現的理由。 --- ### 6. 為什麼 ROS 2 無法直接用於微控制器 原因主要有三點: 1. **記憶體限制** DDS 的封包協定複雜,包含可靠性、封包重傳、緩衝佇列等機制。 一般微控制器(像 ESP32、STM32)只有幾百 KB 的 RAM,根本撐不住。 2. **作業系統依賴** ROS 2 依賴 POSIX 系統呼叫(執行緒、定時器、socket)。 微控制器多數只有簡單的 RTOS 或無 OS,缺乏這些 API。 3. **效能與即時性問題** ROS 2 是設計給多進程、非即時環境。 在 MCU 上,任務需要硬即時反應(例如 PWM 控制、感測中斷), ROS 2 太「重」而且延遲過高。 因此需要一個「**具 ROS 2 通訊相容性,但能跑在微控制器**」的框架——這就是 micro-ROS。 --- ### 7. 小結 ROS 2 解決了機器人開發的軟體協作問題,但它面向的是運算力夠的主機或 SBC(Single Board Computer)。 它提供完整的通訊功能,但在邊緣設備上代價太高。 接下來,micro-ROS 的角色就是: > 把 ROS 2 的溝通能力延伸到記憶體幾百 KB 的小板子上, > 讓「前線感測」與「後端運算」能講同一種語言。 --- ## 二、micro-ROS 架構與設計理念 ### 1. micro-ROS 的誕生背景 ROS 2 是個強大的框架,但它的前提是「主機」: 有作業系統、有網路堆疊、有記憶體,能跑 DDS。 可是現實裡,大量的機器人與 IoT 應用都依賴 **微控制器(MCU)**: ESP32、STM32、LinkIt 7697、Arduino… 它們的記憶體只有幾百 KB、運算力不到主機的千分之一。 問題在於: > 這些小板子負責了機器人最關鍵的「感測」與「控制」, > 卻無法直接參與 ROS 2 生態系。 於是,**micro-ROS(micro Robot Operating System)** 應運而生。 它由多個歐洲研究單位(如 eProsima、Bosch、Acutronic Robotics)與 ROS 2 官方共同開發, 目標是將 ROS 2 的通訊架構「縮小」到能在 MCU 上執行, 同時保持 **介面相容、資料結構一致、通訊可互通**。 換句話說: > micro-ROS 是 ROS 2 的「嵌入式延伸層」。 --- ### 2. micro-ROS 與 ROS 2 的整合概念 micro-ROS 並不是獨立的新系統,而是 ROS 2 的子集。 它的運作理念非常明確: 「讓微控制器成為 ROS 2 網路中的節點(Node)」。 整體結構可用這張關係圖表示: ``` [ Microcontroller (ESP32 / STM32) ] ↑ Micro XRCE-DDS │ [ micro-ROS Agent (Ubuntu / Jetson) ] ↓ DDS [ ROS 2 Network (Host PC) ] ``` * **Client(micro-ROS Node)**:跑在 MCU 上,使用簡化版 ROS 2 API。 * **Agent**:跑在主機端,負責協定轉換(Micro XRCE-DDS ↔ DDS)。 * **Host Node(ROS 2 節點)**:跑在 ROS 2 網路中,與 Agent 通訊。 這樣設計的好處是: * 保留 ROS 2 的生態(msg 格式、topic、service) * 減輕 MCU 的負擔,通訊邏輯交給 Agent 處理 * 讓小裝置可以無縫加入 ROS 2 網路 --- ### 3. micro-ROS 的架構分層 micro-ROS 不是「一個程式」,而是一整個堆疊(stack), 設計時考慮到即時系統、跨平台與資源受限等限制。 以下是 micro-ROS 軟體堆疊的典型結構(由下而上): ``` +-----------------------------------+ | micro-ROS Application Layer | ← 開發者撰寫的應用程式(C / Python) +-----------------------------------+ | RCL / RCLC Layer | ← ROS Client Library(簡化的 API) +-----------------------------------+ | RMW (ROS Middleware) Interface | ← 連接到 XRCE-DDS 通訊層 +-----------------------------------+ | Micro XRCE-DDS Client Stack | ← 負責封包編碼與傳輸協定 +-----------------------------------+ | Transport Layer (UART / UDP) | ← 實體通訊界面 +-----------------------------------+ | RTOS / Hardware Abstraction | ← FreeRTOS / Zephyr / Arduino Core +-----------------------------------+ | MCU Hardware | +-----------------------------------+ ``` #### 說明: * **Application Layer**:你寫的程式碼。 就像 ROS 2 節點,但用的是 micro-ROS API。 * **RCL / RCLC**:ROS Client Library(C 版本為 `rclc`)。 提供建立 Node、Publisher、Subscriber 的函式。 * **RMW Interface**:中介層,連接 micro-ROS 與 XRCE-DDS。 * **Micro XRCE-DDS Client**:真正處理封包傳輸與序列化。 * **Transport Layer**:決定通訊方式(UDP、Serial、Wi-Fi)。 * **RTOS**:確保即時任務能正常執行。 這樣設計讓 micro-ROS 在任何支援 FreeRTOS 的晶片上都能執行。 --- ### 4. Micro XRCE-DDS 通訊協定 micro-ROS 採用 **Micro XRCE-DDS(Micro Extremely Resource Constrained Environment DDS)** 作為通訊核心。 它是 DDS 的精簡版,由 eProsima 公司開發,專門給微控制器使用。 #### (1) 名稱解釋 * **XRCE**:代表「資源極度受限環境」。 * **DDS**:延續 ROS 2 的資料分配協定理念。 #### (2) 運作方式 在 ROS 2 中,節點之間透過 DDS 直接通訊。 但在 micro-ROS,MCU 不具備 DDS 功能,因此它的通訊是「代理式」的: ``` Client (MCU) --XRCE-DDS--> Agent --DDS--> ROS 2 節點 ``` Client 不直接與 ROS 2 節點連線,而是向 Agent 發送 XRCE 封包。 Agent 解析封包後,再用標準 DDS 向 ROS 2 節點轉送。 這樣做的好處: * MCU 不必理解 DDS 的完整協定。 * 封包輕量化,節省記憶體與頻寬。 * Agent 可以服務多個 micro-ROS Client。 #### (3) 傳輸協定支援 Micro XRCE-DDS 可搭配多種傳輸介面: | 介面 | 使用情境 | | ------------- | ------------------------------ | | UDP | 主機與 MCU 連線穩定(Wi-Fi / Ethernet) | | Serial (UART) | 有線連接,速率穩定、低延遲 | | CAN / SPI | 工業應用或多控制板串接 | | USB | 高速傳輸或除錯使用 | --- ### 5. micro-ROS Client、Agent、Host 的角色分工 #### (1) micro-ROS Client(跑在 MCU) * 執行使用者程式 * 包含 Node、Publisher、Subscriber * 使用 micro-ROS API(`rclc`、`rclpy`) * 將所有封包送給 Agent 處理 #### (2) micro-ROS Agent(跑在主機) * 負責連接 MCU 與 ROS 2 * 解析 XRCE-DDS 封包 * 使用 DDS 協定與 ROS 2 節點通訊 * 可同時服務多個 Client * 常駐執行指令範例: ```bash micro-ros-agent udp4 --port 8888 -v6 ``` #### (3) ROS 2 Host Node(主機端節點) * 普通的 ROS 2 節點,無須修改。 * 透過 DDS 與 Agent 通訊,就能收到 MCU 發來的資料。 #### (4) 範例流程: 以「溫度感測」為例: ``` [ ESP32 + DHT11 Sensor ] → micro-ROS Client 發布 Topic /sensor/temperature ↓ [ micro-ROS Agent ] → 轉為 DDS 封包 → 傳入 ROS 2 Topic ↓ [ Ubuntu ROS 2 Node ] → 訂閱 /sensor/temperature → 顯示數值 ``` --- ### 6. 為什麼 micro-ROS 能跑在微控制器上 micro-ROS 能夠在 MCU 上生存,是因為它的核心架構針對三件事徹底優化: #### (1) 記憶體使用極低 * 移除 ROS 2 的動態記憶體配置與 XML 解析。 * 採固定緩衝區(Static buffer allocation)。 * 封包結構簡化,不支援所有 DDS 功能,但保留主要的 Publish-Subscribe 功能。 #### (2) 執行緒與 RTOS 整合 * ROS 2 原生使用多執行緒架構;micro-ROS 改為單任務 + callback 事件。 * 與 FreeRTOS 整合,可在 Task 裡運行 rclc executor(相當於 ROS 2 的 spin loop)。 * 支援任務排程、定時器與中斷。 #### (3) 封包序列化與壓縮 * 使用 XRCE-DDS 的二進位封包格式(比 DDS 小約 80%)。 * 內建 eProsima Fast CDR 序列化函式庫(極低延遲)。 #### (4) 運行環境靈活 * micro-ROS 可在 FreeRTOS、Zephyr、Nuttx、Arduino Core 執行。 * 同時支援 Wi-Fi、Ethernet、UART、USB 等傳輸介面。 --- ### 7. micro-ROS 的設計理念小結 micro-ROS 的核心哲學,可以用一句話總結: > “Bring ROS 2 to microcontrollers.” > —— 讓最前線的感測與控制節點,直接融入 ROS 生態。 它不是取代 ROS 2,而是延伸它的邊界。 它的存在意義在於: * 讓每個感測器、馬達控制器都能變成 ROS 節點 * 讓主機不必處理底層硬體 * 讓分散式機器人系統的所有裝置都說「同一種語言」 --- ### 8. micro-ROS 與 ROS 2 的對應關係表 | 概念 | 在 ROS 2 中 | 在 micro-ROS 中 | 備註 | | --------- | ----------------------- | --------------------------- | ----------- | | 節點(Node) | `rclpy` / `rclcpp` 節點 | `rclc` 節點 | 功能相同但實作簡化 | | 通訊協定 | DDS | Micro XRCE-DDS | 透過 Agent 轉換 | | 執行環境 | Linux / Windows / macOS | FreeRTOS / Zephyr / Arduino | 無 OS 亦可 | | 資料型別 | std_msgs / sensor_msgs | 相容 ROS 2 格式 | IDL 編譯支援 | | Executor | 多執行緒 spin | 單執行緒事件排程 | 簡化版本 | | Launch 機制 | `.launch.py` | 不支援(需手動啟動) | MCU 不具備作業系統 | --- ### 9. micro-ROS 架構視覺化概覽 ``` +----------------------------+ | ROS 2 Network | | (DDS, Python, C++, etc.) | +-------------+--------------+ ↑ │ DDS │ +-------------+--------------+ | micro-ROS Agent | | (Translate XRCE-DDS→DDS) | +-------------+--------------+ ↑ │ XRCE-DDS │ +-------------+--------------+ | micro-ROS Client (MCU) | | Node + Publisher + RTOS API| +----------------------------+ ``` 這張圖是理解 micro-ROS 最關鍵的思維: **Agent 是橋梁,Client 是節點,Host 是大腦。** --- ### 10. 小結:從架構理解 micro-ROS 的價值 * **角色定位明確:** micro-ROS 是「邊緣節點框架」,專注感測與控制。 * **與 ROS 2 完全兼容:** 使用相同的訊息格式與通訊模型。 * **技術本質:** 不是全新作業系統,而是 ROS 2 的輕量延伸層。 * **開發意義:** 讓開發者能在 MCU 上使用熟悉的 ROS API, 不需再重寫感測器通訊協定或手動管理 UART 資料流。 --- ## 三、資料流與封包傳輸 ### 1. 概述:micro-ROS 資料流的全貌 在 micro-ROS 系統裡,資料不是「直接」從一個節點傳到另一個節點。 它要經過一整套橋接與轉換流程,才能讓主機端 ROS 2 節點理解。 最簡化的流程是這樣的: ``` [ micro-ROS Client (MCU) ] ↓ (Micro XRCE-DDS) [ micro-ROS Agent ] ↓ (DDS) [ ROS 2 Node (Host) ] ``` 這三層分別扮演: * **Client**:產生或接收資料(Publisher / Subscriber) * **Agent**:轉換協定,管理通訊狀態 * **Host Node**:執行 ROS 2 處理邏輯(分析、視覺化、控制) micro-ROS 的傳輸機制是「半雙工」的: MCU → Agent 是 XRCE-DDS 封包; Agent → Host 是 DDS 封包。 這樣的設計可以讓每個環節都專注於自己擅長的事: MCU 管理感測與即時控制、Agent 處理封包翻譯、Host 專注高階運算。 --- ### 2. XRCE-DDS 封包的角色與結構 在 ROS 2 中,DDS 封包本身包含非常多控制資訊:可靠性、時間戳、優先權、歷史緩衝等。 這在 MCU 上太重。micro-ROS 因此改用 **Micro XRCE-DDS** 協定。 XRCE-DDS 的核心概念是「Client–Agent 模型」。 #### (1) Client–Agent 模式 * **Client**(在 MCU 上)只需要知道: * 我要發送哪個 Topic * 我要接收哪個 Topic * 封包資料(payload) * **Agent**(在主機上)負責: * 解析 XRCE 封包 * 轉成 DDS 封包 * 發布到 ROS 2 Topic * 把 ROS 2 的回應再轉回 XRCE 封包給 MCU 這樣 MCU 端可以只保存「極少量狀態資訊」,通常不超過幾 KB。 #### (2) XRCE 封包結構簡介 XRCE 封包非常精簡,一個封包大致長這樣(概念化後的欄位): | 欄位 | 功能 | | --------------- | ----------------------------- | | `header` | 封包標頭,含 Client ID、Session ID | | `submessage_id` | 表示封包類型(CREATE, WRITE, READ 等) | | `object_id` | 對應的 Publisher / Subscriber 物件 | | `payload` | 實際傳輸的資料內容 | | `crc` | 檢查碼(確保資料完整性) | 範例概念: ``` Header [Client=0x01, Session=0x02] Submessage: WRITE_DATA Object_ID: Publisher_1 Payload: "temperature=26.4" CRC: 0xA3 ``` Agent 收到後,會把這個 payload 解析出訊息內容,再封裝成 DDS 格式發布。 --- ### 3. 資料流實例:Ping-Pong 傳輸路徑 這是一個最經典的 micro-ROS 測試範例: Client 傳送「ping」,Host 回傳「pong」。 透過這個例子,我們可以完整看一次資料流。 #### (1) Client 端(MCU) 1. 使用 micro-ROS API 建立 Publisher: `create_publisher(String, "/microROS/ping", 10)` 2. 將字串 "ping #1" 打包成 XRCE-DDS 封包。 3. 封包經由 UART / UDP 傳給 Agent。 #### (2) Agent 1. 收到封包 → 確認 Client ID。 2. 解析出 Topic `/microROS/ping`。 3. 將 payload 轉成 DDS 格式,發布到 ROS 2 Network。 #### (3) Host(ROS 2 節點) 1. 收到 `/microROS/ping` 的訊息。 2. 執行 callback:回傳 `/microROS/pong`。 3. ROS 2 節點使用 DDS 封包發布回應。 #### (4) Agent(回傳階段) 1. 接收 `/microROS/pong` 的 DDS 封包。 2. 將其轉回 XRCE-DDS 格式。 3. 發送回 MCU Client。 #### (5) Client(接收) 1. micro-ROS 解析 XRCE-DDS 封包。 2. 呼叫 callback 顯示結果: ``` [Client] Received: pong for ping #1 ``` --- ### 4. 資料流的四個階段 整個 micro-ROS 的資料傳輸,可以明確分成以下四個階段: | 階段 | 發送者 | 接收者 | 協定 | 備註 | | ------- | ---------------- | ---------------- | -------------- | --------------- | | Stage 1 | micro-ROS Client | micro-ROS Agent | Micro XRCE-DDS | MCU 發送感測資料 | | Stage 2 | micro-ROS Agent | ROS 2 Network | DDS | Agent 轉換封包 | | Stage 3 | ROS 2 Node | micro-ROS Agent | DDS | 主機節點回傳控制命令 | | Stage 4 | micro-ROS Agent | micro-ROS Client | Micro XRCE-DDS | Agent 回傳封包至 MCU | 四個階段是雙向對應的,確保 MCU 與主機之間能同步狀態。 --- ### 5. 節點命名與 Topic 對應規範 micro-ROS 完全遵守 ROS 2 的命名規則。 這保證了 micro-ROS 與 ROS 2 節點可以共用相同的命名空間與 Topic。 | 元素 | 規則 | 範例 | | --------- | ---------------------- | ---------------------- | | Node 名稱 | 只能用小寫字母、數字與底線 | `micro_sensor_node` | | Topic 名稱 | 必須以 `/` 開頭 | `/sensor/temperature` | | Namespace | 可用於分組 | `/robot/front_sensor` | | QoS | 與 ROS 2 相同,可調整可靠性與緩衝大小 | Reliable / Best Effort | 若你在 MCU 上宣告: ```c rclc_publisher_init_default(&publisher, &node, ... "/microROS/temp"); ``` 那在 ROS 2 主機上執行: ```bash ros2 topic echo /microROS/temp ``` 就能直接接收到來自 MCU 的資料。 --- ### 6. Agent 如何管理多個 Client micro-ROS Agent 並不是一對一的,它可以同時服務多個微控制器。 每個 Client 連線時都會被分配一個唯一 ID。 Agent 的工作模式如下: 1. 接收封包 → 讀取 Client ID 2. 驗證 Session 是否存在(若不存在則建立) 3. 維護 Client 狀態表: * 活動中節點(Active Nodes) * 已建立的 Publisher / Subscriber * QoS 配置 4. 每當 Agent 收到 Client 封包,會查表找到對應 DDS 物件。 範例(Agent 狀態表概念): | Client ID | Node 名稱 | Topics 發布 | Topics 訂閱 | | --------- | ------------- | ----------------- | ------------ | | 0x01 | `temp_sensor` | `/sensor/temp` | - | | 0x02 | `motor_ctrl` | `/motor/feedback` | `/motor/cmd` | --- ### 7. micro-ROS 傳輸層(Transport Layer) micro-ROS 的靈活性來自它可替換的傳輸層。 根據應用情境,你可以選擇不同介面。 | 介面 | 特點 | 適用場合 | | ----------------- | ---------- | ---------------- | | **UDP** | 無線網路傳輸,速度快 | Wi-Fi / Ethernet | | **Serial (UART)** | 有線、穩定、延遲低 | MCU ↔ 主機近距離連線 | | **CAN** | 抗干擾能力強 | 車用、工業現場 | | **USB** | 高速、除錯方便 | 開發階段 | | **SPI/I2C** | 低速但簡單 | 板對板通訊 | Transport 層與 XRCE-DDS 是獨立的, 只要提供收送封包的函式指標(`send()`, `recv()`), micro-ROS 就能運作在任何介面上。 --- ### 8. 資料封包轉換範例(深入流程) 以下是「MCU 發送資料 → 主機節點接收」的實際邏輯: ``` Step 1: MCU 端呼叫 publish() ↓ Step 2: rclc → RMW Interface → XRCE Client ↓ Step 3: XRCE Client 將資料序列化為 XRCE 封包 ↓ Step 4: 傳送封包(UART/UDP) ↓ Step 5: Agent 接收 → 反序列化封包 ↓ Step 6: Agent 轉換成 DDS 封包 ↓ Step 7: DDS 通知 ROS 2 Node 有新資料 ↓ Step 8: Node callback 執行,顯示或回應資料 ``` 整條路徑大約只需幾毫秒,取決於傳輸介面與封包大小。 --- ### 9. micro-ROS 封包大小與效能 XRCE-DDS 封包大小通常在 50–150 bytes。 即使加上 header,也遠小於 ROS 2 DDS 的 1–2 KB 封包。 這意味著: * micro-ROS 適合即時回報感測資料(高頻低量) * 不適合大量影像或語音傳輸(封包過多會堵塞) 實際效能測試(ESP32 over UART): | 測試項目 | 效能 | | ---- | ---------------- | | 傳輸速率 | 約 10–20 msgs/sec | | 平均延遲 | 約 40–80 ms | | 最大封包 | 約 256 bytes | --- ### 10. micro-ROS 的資料同步與錯誤修復 micro-ROS Agent 會在通訊過程中自動維護 session 狀態。 如果封包丟失或 Client 掛掉,Agent 會在下一次封包時觸發重建程序。 具體行為包括: * **心跳(Heartbeat)機制**:Agent 定期確認 Client 是否仍存活。 * **重傳(Retransmit)機制**:若 CRC 檢查失敗或 timeout,會重新請求封包。 * **Session 重建**:若 Client 重新上線,Agent 可根據先前設定快速恢復。 這些機制確保即使在不穩定連線下(例如 Wi-Fi), micro-ROS 仍能保持通訊穩定。 --- ### 11. 多 Topic 與多節點資料流整合 micro-ROS Client 可同時管理多個 Topic: ```c rclc_publisher_init_default(&pub_temp, &node, ..., "/sensor/temp"); rclc_publisher_init_default(&pub_humid, &node, ..., "/sensor/humid"); ``` Agent 會在 DDS 網路中註冊多個 Publisher,並同步更新。 在主機上,你可以同時監看多個資料流: ```bash ros2 topic echo /sensor/temp ros2 topic echo /sensor/humid ``` 這讓 micro-ROS 不只是單一感測器節點,而是「多感測模組」。 例如一個 MCU 同時管理溫度、濕度、光照感測器, 每個感測值對應不同 Topic。 --- ### 12. micro-ROS 資料流總結 完整的 micro-ROS 傳輸循環: ``` MCU publish → XRCE-DDS serialize → Agent translate → DDS publish → Host Node receive → DDS reply → Agent translate back → MCU receive ``` | 層級 | 協定 | 主要任務 | | ---------- | ----------------- | ------- | | MCU | Micro XRCE-DDS | 封包產生與接收 | | Agent | XRCE-DDS ↔ DDS 轉換 | 封包解析與轉發 | | ROS 2 Node | DDS | 資料處理與回應 | 核心理念: > MCU 不需要懂 DDS,但仍能參與 DDS 網路。 > micro-ROS 讓它透過 Agent「說出 ROS 的語言」。 --- ### 13. 小結:資料流背後的意義 micro-ROS 的傳輸機制展現出一種「角色分離」的設計哲學: * **MCU:** 專注於「產生資料」。 * **Agent:** 專注於「轉譯資料」。 * **Host:** 專注於「理解資料」。 這個模型讓微控制器能以最小負擔參與複雜的分散式系統。 資料從感測端一路穿過 Agent 到主機,再回到控制端, 形成一個完整的閉環(closed loop)。 這也是 ROS 2 與 micro-ROS 能在現代機器人、IoT 與邊緣計算中共存的關鍵。 --- ## 四、ROS 2 與 micro-ROS 的比較分析 ### 1. 比較前的觀念整理 ROS 2 和 micro-ROS 不是競爭關係,而是「同一棵樹的不同枝幹」。 兩者共享相同的設計哲學──**分散式節點架構 + Publish/Subscribe 通訊模型**, 差別在於它們服務的硬體層級與資源環境。 | 層級 | 典型裝置 | 任務類型 | | ------------- | -------------- | --------------- | | **ROS 2** | 主機、Jetson、樹莓派 | 高階計算、AI 推論、任務協調 | | **micro-ROS** | MCU、感測器板、驅動控制器 | 邊緣控制、即時感測、訊號處理 | 兩者透過 **micro-ROS Agent** 共享同一個通訊空間,使整體成為一個統一的 ROS 2 生態系。 --- ### 2. 架構層級比較 #### (1) 總覽圖 ``` +-------------------------------+ | ROS 2 Network | | (DDS, rclpy/rclcpp Nodes) | +---------------+---------------+ ↑ DDS 封包 ↑ +---------------+---------------+ | micro-ROS Agent | | (DDS ↔ Micro XRCE-DDS) | +---------------+---------------+ ↑ XRCE-DDS 封包 ↑ +---------------+---------------+ | micro-ROS Client (MCU) | | (rclc API, RTOS, Sensors) | +-------------------------------+ ``` #### (2) 分層比較表 | 分層 | ROS 2 | micro-ROS | | -------------- | ---------------------------- | --------------------------- | | 應用層 | Node (Python/C++) | Node (C/C++) | | Client Library | `rclpy` / `rclcpp` | `rclc` / `rcl` | | Middleware | DDS (Fast RTPS, Cyclone DDS) | Micro XRCE-DDS | | 傳輸層 | TCP/UDP | UART/UDP/SPI/CAN | | 作業系統 | Linux / Windows | FreeRTOS / Zephyr / Arduino | | 資源需求 | 高(>512 MB RAM) | 極低(<512 KB RAM) | --- ### 3. 通訊協定差異 #### ROS 2:DDS(Data Distribution Service) * **全功能分散式協定**。 * 節點自動發現 (Discovery)。 * 支援多種 QoS 與安全機制。 * 適合大型系統、高頻資料流。 #### micro-ROS:Micro XRCE-DDS * **輕量化代理式通訊**。 * 以 **Client–Agent** 結構取代節點間直接互聯。 * 省去 Discovery、Security 等複雜程序。 * MCU 只需負責封包生成與解析,計算負擔極低。 | 面向 | DDS | Micro XRCE-DDS | | ----- | ------------ | -------------- | | 模式 | Peer-to-Peer | Client–Agent | | 資料可靠性 | 完整 QoS 支援 | 精簡 QoS | | 節點發現 | 自動 | 由 Agent 管理 | | 封包大小 | 1 KB–2 KB | 約 50–150 bytes | | 通訊負擔 | 高 | 極低 | --- ### 4. 開發環境與工具鏈比較 | 項目 | ROS 2 | micro-ROS | | ---- | --------------------------------------- | ---------------------------- | | 建構工具 | `colcon`, `ament_cmake`, `ament_python` | `colcon` + `micro_ros_setup` | | 套件管理 | `rosdep`, `rosinstall` | 同 ROS 2 架構 | | 編譯平台 | 原生編譯 (x86/ARM64) | 交叉編譯 (arm-none-eabi gcc) | | 開發語言 | Python / C++ | C (支援 C++) | | 啟動方式 | `ros2 run`, launch file | 在 MCU 初始化函式中呼叫 | | 除錯方式 | rqt、CLI、rviz | UART log、Agent verbose 模式 | | 模擬測試 | Gazebo / RViz | 可在 Ubuntu 模擬 Client 節點 | micro-ROS 保持與 ROS 2 幾乎相同的建構邏輯, 讓開發者能用熟悉的 colcon 環境同時管理兩邊專案。 --- ### 5. 效能與資源比較 | 指標 | ROS 2 (Node on Linux) | micro-ROS (Node on MCU) | | ------ | --------------------- | ----------------------- | | 記憶體需求 | 約 300–800 MB | 約 100–400 KB | | CPU 負載 | 中高 | 低 | | 平均延遲 | < 10 ms (UDP) | 40–100 ms (UART) | | 最大封包 | 幾 MB | 256 bytes | | 可連線節點數 | 幾百個 | 受 Agent 管理限制(數十個) | | 即時性 | 軟即時 | 硬即時(依 RTOS) | ROS 2 側重「吞吐量」;micro-ROS 側重「可預測性與低資源消耗」。 --- ### 6. 應用定位與系統角色 | 系統層級 | ROS 2 的角色 | micro-ROS 的角色 | | ------------ | ----------------- | ------------- | | **上層:任務決策** | AI 模型推論、路徑規劃、資料分析 | 不適用 | | **中層:通訊協調** | 節點間整合、狀態監控 | 透過 Agent 介入 | | **下層:感測與控制** | 需外部控制板協助 | 直接運行在 MCU | 在真實系統裡,常見的結構是: ``` AI/Decision (ROS 2) → Control Command Topic ↓ micro-ROS Client (MCU) ↓ Sensor Feedback Topic → ROS 2 Monitor ``` --- ### 7. 功能取捨與相容性分析 | 功能 | ROS 2 | micro-ROS | 備註 | | ---------------------- | --------- | ---------- | --------------------- | | Publisher / Subscriber | ✔ | ✔ | 完全相容 | | Service | ✔ | ✔ | 支援但功能有限 | | Action | ✔ | ✖ | 尚未支援 | | Parameter Server | ✔ | ✖ | 不實作 | | Launch System | ✔ | ✖ | MCU 無 OS | | QoS | 全面支援 | 精簡版 | 僅 Reliability / Depth | | Discovery | 自動 | 由 Agent 管理 | 無廣播負擔 | | Security | 可擴充 | ✖ | 無安全層 | | Diagnostics | rqt / CLI | 需自訂 | 由 Host 負責 | 這些差異說明了:micro-ROS 著重在「能運作」,而非「功能齊全」。 --- ### 8. 實際整合案例 #### 案例 1:智慧小車 * 主機 (Jetson Nano):ROS 2 節點負責影像辨識與路徑規劃。 * 子板 (STM32 + FreeRTOS):micro-ROS Client 控制馬達、回報里程。 * 通訊介面:UART。 * 資料流: ``` /camera/image_raw → AI 處理節點 /cmd_vel → micro-ROS 控制節點 /odom ← micro-ROS 回傳節點 ``` #### 案例 2:工業感測網 * MCU 節點各自感測溫度、壓力。 * 主機 ROS 2 節點彙整資料並視覺化。 * micro-ROS Agent 常駐主機,管理數十個 Client。 #### 案例 3:教育用途 * 用 ESP32 開發板搭建 micro-ROS Client。 * 學生在 Ubuntu 端用 Python 撰寫 ROS 2 Node。 * 即時看到感測值與回應命令。 --- ### 9. 開發思維的轉換 在 ROS 2 裡,開發者思考「多模組協作」。 在 micro-ROS 裡,開發者思考「資源最佳化」。 | 思維 | ROS 2 | micro-ROS | | ---- | ------------------ | -------------- | | 任務重點 | 整體架構設計 | 單節點效率 | | 程式習慣 | 多執行緒 / 大量 Callback | 單執行緒 / 簡化事件循環 | | 錯誤處理 | 豐富例外處理機制 | 偏重穩定、靜態配置 | | 測試方式 | 模擬與視覺化 | UART Log 與即時觀察 | 在嵌入式開發中,**每一筆記憶體配置、每一次封包傳輸都要被量化**。 這是 micro-ROS 開發與桌面級 ROS 2 最大的文化差異。 --- ### 10. 綜合比較表 | 面向 | ROS 2 | micro-ROS | 差異核心 | | ----- | ------------ | ----------------- | -------- | | 通訊核心 | DDS | Micro XRCE-DDS | Agent 橋接 | | 執行環境 | 高階作業系統 | RTOS / Bare Metal | 不同層級 | | 程式語言 | Python / C++ | C / C++ | 語法層級 | | 通訊模型 | Peer-to-Peer | Client–Agent | 架構差異 | | 封包大小 | 大 | 小 | 資源配置 | | 記憶體需求 | 高 | 低 | 適用平台 | | 功能完整度 | 高 | 精簡 | 可用性 | | 即時性 | 軟即時 | 硬即時 | 回應速度 | | 擴充性 | 優 | 受限 | 平台差異 | | 應用面 | AI、導航、雲端 | 感測、控制、IoT | 系統分工 | --- ### 11. 小結:兩者的共生關係 ROS 2 與 micro-ROS 的關係可以這樣總結: > **ROS 2 是整體智慧的「中樞」,micro-ROS 是即時反應的「神經末梢」。** 它們在系統中各司其職: * **ROS 2**:做決策、整合資料、提供全域控制。 * **micro-ROS**:負責接收感測、執行控制命令、即時回報。 兩者透過 Agent 橋接成一個閉環系統: ``` Decision (ROS 2) ↓ command micro-ROS Client → Actuator ↑ feedback ``` 這樣的架構讓大型機器人或 IoT 系統可以同時擁有: * ROS 2 的彈性與資料處理能力, * micro-ROS 的即時性與低耗能特性。 --- ## 五、訊息型別與客製化通訊 ### 1. 為什麼訊息型別很重要 在 ROS 2 / micro-ROS 世界裡,**訊息型別(Message Type)是節點之間通訊的共同語言**。 每個 Topic 都有固定的資料結構, Publisher 和 Subscriber 只有在使用相同的訊息定義時才能理解彼此的封包內容。 範例: ```text Topic: /sensor/temperature Type: std_msgs/msg/Float32 ``` Publisher 傳送一個 `Float32`,Subscriber 也必須用 `Float32` 接收,否則會報錯。 micro-ROS 與 ROS 2 在這點完全一致: 它們都使用 **IDL(Interface Definition Language)** 來定義訊息結構, 再透過編譯器自動生成 C / C++ / Python 對應的程式碼。 --- ### 2. ROS 2 訊息定義的基本語法 在 ROS 2 中,訊息檔(`.msg`)是一種簡單結構定義格式。 範例:建立一個名為 `Temperature.msg` 的自訂型別: ```msg float32 value string unit ``` 這代表每則訊息都有兩個欄位: * 一個浮點數 `value` * 一個字串 `unit` ROS 在建置時會自動將 `.msg` 檔轉換為中介描述檔 `.idl`, 再進一步產生對應語言的類別(C、C++、Python)。 --- ### 3. 訊息型別的轉譯流程 整個轉譯鏈如下: ``` Temperature.msg ↓ IDL (Interface Definition Language) ↓ C / C++ 結構定義 ↓ micro-ROS 編譯結果 (micro_ros_msgs) ``` micro-ROS 會在編譯過程中讀取相同的 IDL 檔案, 因此 ROS 2 和 micro-ROS 兩端能共享相同結構。 --- ### 4. ROS 2 標準訊息庫(std_msgs, sensor_msgs 等) 在一般應用裡,你不一定需要自訂訊息, ROS 已經內建了數百種常用結構, micro-ROS 也完全相容這些型別。 | 套件 | 說明 | 常見訊息 | | ----------------- | ------ | ---------------------------- | | `std_msgs` | 基礎資料型別 | Bool, Int32, Float32, String | | `geometry_msgs` | 幾何資訊 | Vector3, Pose, Twist | | `sensor_msgs` | 感測資料 | Imu, Image, LaserScan | | `nav_msgs` | 導航資訊 | Odometry, Path | | `diagnostic_msgs` | 狀態監控 | KeyValue, DiagnosticArray | 在 micro-ROS 中,這些型別都會在建置時自動轉換為 C 結構。 --- ### 5. micro-ROS 對訊息的支援範圍 micro-ROS 可以使用任何「純資料結構(POD, Plain Old Data)」的型別。 但它**不支援動態記憶體分配或複雜容器**(例如 `std::vector`、`map`)。 支援範圍如下: | 類型 | 支援狀態 | 備註 | | ------------------------------ | ------- | ---------------------------- | | 整數型(int8, int16, int32, int64) | ✔ | 全支援 | | 浮點型(float32, float64) | ✔ | 全支援 | | 布林值(bool) | ✔ | | | 字串(string) | ⚠️ 有限支援 | 長度需固定或限制上限 | | 陣列(定長) | ✔ | 編譯期固定大小 | | 陣列(動長) | ⚠️ 有限支援 | 須使用 `rosidl_runtime_c__*` 型別 | | 物件巢狀 | ✔ | 需先定義子訊息 | 範例: 可以在 micro-ROS 用這種定義: ```msg float32[3] accel ``` 但不能使用: ```msg float32[] accel # 動態長度不保證支援 ``` --- ### 6. 自訂訊息型別的建立步驟 以「溫度 + 濕度」為例,建立一個新的 `EnvData.msg`。 #### (1) 建立目錄結構 ``` my_msgs/ ├── msg/ │ ├── EnvData.msg ├── package.xml └── CMakeLists.txt ``` #### (2) 編寫 `EnvData.msg` ```msg float32 temperature float32 humidity ``` #### (3) 編輯 `CMakeLists.txt` ```cmake find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "msg/EnvData.msg" ) ``` #### (4) 在 micro-ROS Client 專案中引用 在 C 程式碼裡: ```c #include "my_msgs/msg/env_data.h" my_msgs__msg__EnvData data; data.temperature = 25.3; data.humidity = 40.2; rcl_publish(&publisher, &data, NULL); ``` --- ### 7. 資料同步與版本一致性 micro-ROS Client 與 ROS 2 節點使用相同的 `.msg` 定義, 所以**兩邊必須用同一份編譯出的介面檔案**。 建議在同一個工作空間內管理: ``` src/ ├── my_msgs/ # 自訂訊息 ├── micro_ros_client/ # MCU 專案 └── ros2_host_node/ # 主機節點 ``` Host 端與 Client 端在建構時都 include 來自 `my_msgs` 的頭檔, 確保結構完全一致。 --- ### 8. IDL 與跨語言對應 ROS 2 的 `.msg` 實際上在底層轉換為 IDL(Interface Definition Language)。 這使得 ROS 能同時生成多語言綁定: | ROS 2 型別 | C 對應 | Python 對應 | | ------------ | -------------------------- | ------------- | | `float32` | `float` | `float` | | `int32` | `int32_t` | `int` | | `string` | `rosidl_runtime_c__String` | `str` | | `float32[3]` | `float data[3]` | `list[float]` | 在 micro-ROS 裡,使用的是 C 版本的封裝。 它會把每個欄位展開成純 C 結構,方便 MCU 操作。 範例(自動產生的 C 定義): ```c typedef struct my_msgs__msg__EnvData { float temperature; float humidity; } my_msgs__msg__EnvData; ``` --- ### 9. 記憶體配置與訊息初始化 由於 MCU 沒有動態記憶體, micro-ROS 的訊息必須在使用前明確初始化。 ```c my_msgs__msg__EnvData msg; my_msgs__msg__EnvData__init(&msg); msg.temperature = 26.5; msg.humidity = 42.1; rcl_publish(&pub, &msg, NULL); my_msgs__msg__EnvData__fini(&msg); ``` 若使用標準型別(如 `std_msgs/msg/String`), 則需使用 `rosidl_runtime_c__String__assign()` 來設定字串內容: ```c std_msgs__msg__String str; std_msgs__msg__String__init(&str); rosidl_runtime_c__String__assign(&str.data, "Hello micro-ROS"); ``` --- ### 10. 訊息壓縮與效能考量 micro-ROS 為了減少封包負擔, 在序列化時會使用 eProsima Fast-CDR 的緊湊模式。 **最佳化原則:** 1. 儘量使用定長型別(float、int)。 2. 避免字串與可變長陣列。 3. 將結構控制在 256 bytes 以內。 這樣可確保傳輸速率與延遲穩定, 特別是在 UART 或低速網路上運作時。 --- ### 11. micro-ROS 不支援的特殊結構 * **Dynamic Nested Types**:巢狀結構中若包含動態長度字串會導致錯誤。 * **Union / Variant**:IDL 支援但 micro-ROS 不實作。 * **Time / Duration**:需用 `builtin_interfaces/msg/Time` 替代。 若需要傳時間戳,正確寫法: ```msg builtin_interfaces/Time stamp float32 data ``` --- ### 12. 例:整合自訂訊息的 Ping-Pong 系統 你可以把 Ping-Pong 範例改成使用自訂訊息: ```msg string msg int32 counter ``` Host Node: ```python from my_msgs.msg import PingData ... data = PingData() data.msg = "ping" data.counter = self.counter self.publisher.publish(data) ``` micro-ROS Client: ```c #include "my_msgs/msg/ping_data.h" ... my_msgs__msg__PingData rx_msg; my_msgs__msg__PingData__init(&rx_msg); printf("Received: %s #%d\n", rx_msg.msg.data, rx_msg.counter); ``` 兩邊都能自動解析結構,無需手動序列化。 --- ### 13. 小結 1. ROS 2 與 micro-ROS 共享相同的訊息定義機制(IDL → 語言封裝)。 2. micro-ROS 僅支援靜態、定長、POD 型態。 3. 所有自訂 `.msg` 檔必須同時存在於主機與 MCU 專案中。 4. 編譯時會自動生成對應的 C 結構與序列化程式。 5. 透過這一機制,micro-ROS 能以極低負擔實現複雜資料交換。 --- ## 六、系統整合與開發環境 ### 1. 為什麼要「整合開發環境」 micro-ROS 的本質是 ROS 2 的延伸模組, 但它同時要跑在兩個完全不同的世界上: * **主機端(Host)**:ROS 2 + Ubuntu + DDS * **微控制器端(Client)**:FreeRTOS / Zephyr / Arduino 要讓兩邊合作順利,你需要建立一個能同時管理、編譯、測試的環境, 這就是「整合開發環境(Integrated Development Workspace)」的目的。 它能讓: 1. micro-ROS Client 與 ROS 2 Host 共用同一份 `.msg` 定義。 2. Host 端與 Client 端都能用 `colcon build` 一次建構。 3. Agent 可以自動在 Host 啟動,進行測試與模擬。 --- ### 2. 系統整體結構 整個開發環境通常由三個主要部分構成: ``` +---------------------------------------------+ | ROS 2 主機端 (Host) | |---------------------------------------------| | OS: Ubuntu 22.04 | | ROS 2: Humble Hawksbill | | Tool: colcon,micro_ros_setup,micro-ros-agent| |---------------------------------------------| | 節點角色:Subscriber / Controller / Agent | +---------------------------------------------+ ⇅ UDP / UART / Serial +---------------------------------------------+ | micro-ROS 客戶端 (MCU) | |---------------------------------------------| | OS: FreeRTOS / Zephyr / Arduino Core | | Lib: micro-ROS rclc / rcl / XRCE-DDS | |---------------------------------------------| | 節點角色:Publisher / Sensor / MotorCtrl | +---------------------------------------------+ ``` 兩邊透過 Agent 通訊,維持同步的 ROS 2 Topic 資料流。 --- ### 3. ROS 2 版本與 micro-ROS 對應 ROS 2 每個發行版對應一個 micro-ROS 版本。 官方明確要求 **版本必須匹配**,否則訊息結構或 API 可能不相容。 | ROS 2 版本 | micro-ROS 對應版本 | Ubuntu 推薦版本 | 支援狀態 | | ------------------- | -------------- | ------------- | ------- | | Foxy Fitzroy | Foxy | 20.04 LTS | LTS(舊) | | Galactic Geochelone | Galactic | 20.04 / 22.04 | 穩定 | | Humble Hawksbill | Humble | 22.04 LTS | LTS(推薦) | | Iron Irwini | Iron | 22.04 / 24.04 | 最新 | | Jazzy Jalisco | Jazzy | 24.04 LTS | 開發中 | 實務上目前最穩定的是 **Humble + micro-ROS Humble**, 幾乎所有範例與教學都以這對版本為主。 --- ### 4. 建立工作空間(Workspace) 在主機端(Ubuntu)建立 ROS 2 Workspace: ```bash mkdir -p ~/micro_ros_ws/src cd ~/micro_ros_ws ``` 載入 ROS 2 環境: ```bash source /opt/ros/humble/setup.bash ``` --- ### 5. 安裝 micro-ROS 開發工具 micro-ROS 提供官方的 `micro_ros_setup` 套件, 可自動建立、交叉編譯、模擬 micro-ROS Client。 ```bash sudo apt install ros-humble-micro-ros-setup ``` --- ### 6. 初始化 micro-ROS 專案 切換到工作目錄: ```bash cd ~/micro_ros_ws ros2 run micro_ros_setup create_firmware_ws.sh freertos esp32 ``` 這個指令會: 1. 建立 micro-ROS firmware 專案。 2. 自動下載對應的 FreeRTOS / ESP-IDF / micro-ROS libraries。 3. 建立 MCU 編譯環境。 --- ### 7. 建構 micro-ROS Firmware ```bash cd firmware ros2 run micro_ros_setup build_firmware.sh ``` 這一步會: * 編譯 MCU 專案。 * 產生 micro-ROS 客戶端二進位檔(例如 `micro_ros_esp32.bin`)。 --- ### 8. 主機端啟動 micro-ROS Agent 在 Host 端開新終端機,啟動 Agent: ```bash source /opt/ros/humble/setup.bash micro-ros-agent udp4 --port 8888 -v6 ``` 說明: | 參數 | 功能 | | ------------- | -------------- | | `udp4` | 使用 IPv4 UDP 傳輸 | | `--port 8888` | 指定通訊埠 | | `-v6` | 顯示封包細節 | 若使用 UART: ```bash micro-ros-agent serial --dev /dev/ttyUSB0 -b 115200 ``` --- ### 9. 檢查通訊狀態 啟動 Agent 後,你應該會看到: ``` [INFO] Micro XRCE-DDS Agent running... [INFO] Client connected, ID: 0x01 ``` 這代表 MCU 已成功連線。 接著在另一個終端機: ```bash ros2 topic list ``` 若有 `/microROS/ping` 或 `/microROS/temp` 等 Topic 出現,就代表資料流已建立。 --- ### 10. 整合自訂訊息與 Workspace 同步 若有自訂 `.msg` 型別(例如 `EnvData.msg`), 建議統一放在 Workspace 裡的 `my_msgs` 專案中: ``` micro_ros_ws/ ├── src/ │ ├── my_msgs/ │ │ ├── msg/EnvData.msg │ │ ├── CMakeLists.txt │ │ └── package.xml │ ├── micro_ros_firmware/ │ ├── host_controller/ ``` 然後在 MCU 端與 Host 端的 `CMakeLists.txt` 都加上: ```cmake find_package(my_msgs REQUIRED) ament_target_dependencies(target_name my_msgs) ``` 這樣一旦重建 Workspace, Host 與 Client 就會同時擁有相同的訊息結構。 --- ### 11. FreeRTOS 與 micro-ROS 整合 micro-ROS Client 通常執行在 FreeRTOS 的任務中。 範例架構: ```c void appMain(void *argument) { rclc_support_t support; rclc_support_init(&support, 0, NULL, &allocator); ... for(;;) { rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)); vTaskDelay(pdMS_TO_TICKS(100)); } } ``` 這樣設計讓 micro-ROS 能與其他任務(例如感測器採樣、LED 控制) 在 RTOS 的 Task 排程中共存,保證即時性。 --- ### 12. 在 Ubuntu 上模擬 micro-ROS Client 如果沒有 MCU,也可以直接在電腦上模擬: ```bash ros2 run micro_ros_setup configure_firmware.sh host ros2 run micro_ros_setup build_firmware.sh ros2 run micro_ros_setup run_firmware.sh ``` 此模式會用 C 節點模擬 micro-ROS Client, 可搭配 Agent 測試封包流動與功能正確性。 --- ### 13. 常見環境錯誤與排除 | 問題 | 原因 | 解決方案 | | ------------------------- | ---------------- | ------------------------ | | `Agent connection failed` | MCU 未連線或 port 錯誤 | 檢查 `--port` 或 USB 裝置名稱 | | `build_firmware.sh` 失敗 | 缺少 toolchain | 安裝 ESP-IDF 或 ARM GCC | | Topic 收不到資料 | QoS 設定不符 | 在 Host 與 Client 使用相同 QoS | | 訊息解析錯誤 | `.msg` 不一致 | 確保兩端使用同一套 `my_msgs` 套件 | --- ### 14. 多節點整合(Launch 範例) 在 ROS 2 端可以建立 `micro_ros_system.launch.py`, 同時啟動 Agent、控制節點與視覺化節點: ```python from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node(package='micro_ros_agent', executable='micro_ros_agent', arguments=['udp4', '--port', '8888']), Node(package='host_controller', executable='controller_node'), Node(package='rqt_gui', executable='rqt_gui') ]) ``` 執行: ```bash ros2 launch my_system micro_ros_system.launch.py ``` 即可自動啟動整個 micro-ROS 網路。 --- ### 15. 各版本函式庫對應與相容性 | 套件名稱 | ROS 2 對應 | 功能 | | --------------------- | ---------------- | ----------- | | `rclpy` | ROS 2 Host 端 | Python 節點開發 | | `rclcpp` | ROS 2 Host 端 | C++ 節點開發 | | `rclc` | micro-ROS Client | C 節點開發 | | `micro_ros_agent` | ROS 2 Host 端 | Agent 程式 | | `micro_ros_setup` | ROS 2 Host 端 | 自動建構與模擬工具 | | `microxrcedds_client` | MCU 端 | 封包協定層 | 只要版本相符,這些套件會自動整合。 --- ### 16. 環境維護與升級 建議每次建構前重新載入環境: ```bash source /opt/ros/humble/setup.bash colcon build --symlink-install source install/setup.bash ``` micro-ROS 升級時也需重建 firmware: ```bash ros2 run micro_ros_setup update_firmware.sh ``` 這樣能避免 `rosidl` 與 `rclc` 不相容的問題。 --- ### 17. 小結 * micro-ROS 的開發需要同時考慮主機與 MCU 端。 * 透過 Workspace 整合可共用訊息與編譯環境。 * `micro_ros_setup` 是最重要的建構工具。 * Host 與 Client 必須保持版本一致。 * 可使用 Ubuntu 模擬環境快速測試封包流。 整體開發流程如下: ``` 撰寫程式(Host / MCU) ↓ 共用訊息(.msg) ↓ colcon build(同步建構) ↓ 啟動 micro-ROS Agent ↓ 驗證資料流(ros2 topic echo) ``` --- ## 七、實務應用場域(Practical Applications of micro-ROS) ### 1. 為什麼 micro-ROS 適合實務應用 micro-ROS 的定位,就是讓「感測與控制」的最底層設備能說 ROS 的語言。 在現代系統裡,大型主機處理決策(AI、導航、資料融合), 小型控制器負責即時任務(驅動馬達、讀感測器、傳遞資料)。 這兩層如果沒有共通通訊架構,就要手動設計 UART、I2C、MQTT 等協定。 micro-ROS 解決了這個痛點,它讓這些小裝置直接變成 ROS 節點。 --- ### 一、IoT 與感測網(Internet of Things) #### 1. 應用場景 智慧農業、智慧建築、環境監測、能源管理系統等, 通常有上百個感測節點(溫度、濕度、氣體、光照), 資料需要集中到主機再上傳雲端。 micro-ROS 可以讓每個感測器板都成為一個「ROS 2 節點」, 自動以 Topic 發布資料到主機,不必再做自訂通訊協定。 #### 2. 系統架構圖 ``` +---------------------------+ | ROS 2 Host Node | |---------------------------| | Aggregator / Cloud Bridge | | micro-ROS Agent (UDP) | +-------------+-------------+ ↑ Wi-Fi / Ethernet ↑ +-------------+-------------+ | micro-ROS Clients (MCUs) | |---------------------------| | Temp Node | /sensor/temp| | Humid Node | /sensor/hum | | Light Node | /sensor/lux | +---------------------------+ ``` #### 3. 資料流解釋 1. 每個 MCU 節點(如 ESP32)使用 micro-ROS 以 UDP 傳送感測資料: `/sensor/temp`, `/sensor/hum`, `/sensor/lux`。 2. 主機上的 micro-ROS Agent 收到封包並轉成 DDS。 3. ROS 2 Host Node 聚合資料,並可直接以 Python 發布到雲端 API。 範例(主機端 Python 節點): ```python def callback(data): publish_to_cloud(data.temperature, data.humidity) ``` #### 4. 優點 | 面向 | micro-ROS 帶來的優勢 | | --- | ------------------------------- | | 通訊 | 不需自訂協定,直接用 Topic 傳輸 | | 整合 | 可直接接入 ROS 2 雲端橋接(如 MQTT Bridge) | | 可擴展 | 新增感測器只需新增節點 | | 成本 | MCU 價格低、功耗低、可長期運作 | #### 5. 延伸應用 * 智慧電表(Energy metering) * 冷鏈監控(Cold-chain monitoring) * 城市噪音監測 * IoT 資料即時儀表板(整合 RViz / rqt) --- ### 二、機器人與自動化系統(Robotics) #### 1. 應用場景 在機器人系統中,主機(Jetson、NUC)通常負責導航與 AI, 而下層控制板(STM32、ESP32)負責馬達與感測。 這種「主控+子控制器」架構是 micro-ROS 的完美舞台。 #### 2. 系統架構圖 ``` +----------------------------------+ | ROS 2 Host (AI) | |----------------------------------| | Navigation / Vision / Planning | | micro-ROS Agent (serial) | +---------------+------------------+ | UART | +---------------+------------------+ | micro-ROS Client (MCU) | |----------------------------------| | Motor Controller / Encoder Node | | Ultrasonic Sensor Node | +----------------------------------+ ``` #### 3. 資料流 1. Host Node 發布 `/cmd_vel`(速度命令)。 2. MCU 端的 micro-ROS Subscriber 收到命令 → 控制馬達 PWM。 3. MCU 端的 micro-ROS Publisher 發布 `/odom`(里程資訊)。 4. Host 端的 Navigation Node 根據 `/odom` 計算位置。 #### 4. 範例主機端 Python 節點 ```python from geometry_msgs.msg import Twist def move_forward(pub): msg = Twist() msg.linear.x = 0.3 msg.angular.z = 0.0 pub.publish(msg) ``` micro-ROS 端(C 程式): ```c rcl_subscription_t sub; rclc_subscription_init_default(&sub, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist), "/cmd_vel"); ``` 這樣 MCU 就能直接理解 ROS 2 的控制訊息。 #### 5. 延伸應用 * ROS 2 自走車:主機負責 SLAM、MCU 控制驅動。 * 智慧機械臂:ROS 2 做運動規劃,micro-ROS 控制馬達伺服。 * 自動搬運車(AGV):ROS 2 統籌路徑、micro-ROS 執行底層驅動。 --- ### 三、工業控制與邊緣運算(Industrial / Edge Applications) #### 1. 應用場景 在工業自動化中,感測器與控制器分散各地。 傳統做法是使用 Modbus、CAN、PROFINET。 但現在 ROS 2 被引入工控領域, micro-ROS 讓現有的微控制器可以在不改硬體的情況下, 直接成為 ROS 節點參與資料交換。 #### 2. 系統結構 ``` +---------------------------------+ | ROS 2 Host (Edge PC) | |---------------------------------| | Process Monitor Node | | micro-ROS Agent (CAN/UDP) | +---------------------------------+ ↑ CAN Bus / Ethernet ↑ +---------------+---------------+ | micro-ROS Client (STM32) | |-------------------------------| | Pressure Sensor Node | | Valve Controller Node | +-------------------------------+ ``` #### 3. 資料流 * 每個 micro-ROS 節點發佈感測資料: `/sensor/pressure`, `/sensor/flowrate`。 * Host Node 訂閱後整合並作邏輯判斷, 若超出範圍,發送 `/cmd/valve` 回控制器節點。 #### 4. micro-ROS 在工控的優勢 | 面向 | 優勢 | | ---- | --------------------- | | 可靠性 | DDS 架構 + QoS 保證資料到達 | | 可擴充性 | 新設備僅需掛上 Agent | | 整合性 | 支援多介面(CAN, UART, UDP) | | 即時性 | FreeRTOS 排程,毫秒級反應 | #### 5. 實務應用案例 * 智慧工廠設備監控(機械壓力、溫度回饋) * 電力變壓站數據收集與診斷 * 自動化流水線控制(以 micro-ROS 取代 PLC 分層) --- ### 四、教育與研究應用(Education & Research) #### 1. micro-ROS 作為教學工具 因為 micro-ROS 可以在低成本硬體上執行(ESP32、Arduino Nano), 學校與研究單位廣泛使用它來教學「嵌入式 ROS」。 學生不需要昂貴的開發板,只要一台筆電與一片 ESP32, 就能在課堂上體驗從感測、封包、到 ROS 通訊的整個過程。 #### 2. 典型課程架構 | 單元 | 教學內容 | 實作成果 | | ----- | ------------ | ---------------- | | 第 1 週 | ROS 2 架構 | Hello World Node | | 第 2 週 | micro-ROS 簡介 | Client 連線 Agent | | 第 3 週 | Topic 通訊 | MCU 傳感測資料到 PC | | 第 4 週 | Service 實作 | MCU 接收指令控制 LED | | 第 5 週 | IoT 延伸 | 資料上傳雲端平台 | | 第 6 週 | 整合專題 | 完成感測 + 控制專案 | #### 3. 實驗室常見專題 * **導盲車(GuideBot)**:micro-ROS 控制距離感測與避障;ROS 2 主機進行語音辨識與路徑規劃。 * **智慧農場模擬系統**:多個 micro-ROS Client 模擬溫濕度感測;ROS 2 聚合資料後顯示即時趨勢圖。 * **IoT Security 專題**:研究 micro-ROS Agent 資料驗證與加密。 #### 4. 教育應用的價值 * 讓學生同時學習 **嵌入式程式設計 + ROS 架構思維**。 * 實際理解分散式系統、封包通訊與即時控制。 * micro-ROS 是 ROS 2 教學鏈的「前哨站」, 幫助學習者從基礎的 Node 邏輯跨入系統整合思維。 --- ### 五、micro-ROS 的跨領域價值 micro-ROS 不只屬於機器人領域。 它的輕量特性讓它成為 **IoT、AIoT、邊緣運算** 的核心通訊層。 | 領域 | 應用 | 角色 | | -------- | ----------- | ---- | | IoT | 感測器網路、智慧城市 | 邊緣節點 | | Robotics | 自走車、機械手臂 | 驅動控制 | | 工控 | 智慧工廠、遠端監控 | 即時感測 | | 教育 | 嵌入式與 ROS 教學 | 實驗平台 | 在這些場合,micro-ROS 讓「感測端」、「控制端」、「決策端」 可以統一在一個 ROS 2 通訊生態裡運作。 --- ### 6. 小結 1. micro-ROS 已從單純的嵌入式通訊框架,成為 **ROS 2 的邊緣延伸層**。 2. 在 IoT、機器人與工控場域中,它負責「即時、低功耗、標準化」的資料傳輸。 3. 它使開發者能用一套 ROS 工具鏈貫穿從 AI 到硬體的整個開發流程。 4. 它在教育與研究上的普及,正讓 ROS 走入嵌入式與物聯網時代。 --- ## 八、理論篇總結(Summary of the micro-ROS Theoretical Series) ### 1. micro-ROS 為何誕生 micro-ROS 並不是 ROS 2 的替代品,而是 ROS 2 的「邊緣延伸層」。 ROS 2 專注於高階作業系統與強大運算平台(例如 Jetson、x86、雲端伺服器), 但現實世界的大多數設備是微控制器(MCU), 記憶體僅數百 KB,卻是系統的感測與控制基礎。 micro-ROS 讓這些 MCU 也能以 **ROS 的語言** 參與系統, 透過輕量化協定 Micro XRCE-DDS 與 Agent 橋接, 實現「從感測器到雲端」的完整通訊閉環。 --- ### 2. 架構重點回顧 micro-ROS 的三層結構: ``` ROS 2 Node ←DDS→ micro-ROS Agent ←XRCE-DDS→ micro-ROS Client ``` | 組件 | 執行環境 | 功能 | | -------------------- | --------------------- | --------- | | **ROS 2 Node** | Ubuntu / Jetson / x86 | 資料處理與決策 | | **micro-ROS Agent** | Host (Ubuntu) | 封包轉譯、連線管理 | | **micro-ROS Client** | MCU / FreeRTOS | 感測與控制節點 | 這個設計確保了高效能(Host)與即時性(MCU)可以共存, 兩邊透過 Agent 交換封包而不需改協定。 --- ### 3. 通訊與封包哲學 micro-ROS 採用的 **Micro XRCE-DDS** 是 DDS 的極簡版本: * 用 Client–Agent 模式取代節點間直連。 * 用固定大小封包(50–150 bytes)降低傳輸負擔。 * 用靜態記憶體配置確保即時性。 Agent 的角色相當於「翻譯官」, 讓不同層級的裝置都能參與相同 DDS 網路。 --- ### 4. 與 ROS 2 的關係 | 面向 | ROS 2 | micro-ROS | | ---- | --------------- | --------------------------- | | 功能範圍 | 完整生態(AI、導航、服務) | 嵌入式通訊與控制 | | 通訊協定 | DDS | Micro XRCE-DDS | | 語言支援 | Python / C++ | C / C++ | | 作業系統 | Linux / Windows | FreeRTOS / Zephyr / Arduino | | 封包方向 | 節點對節點 | Client–Agent | | 資源需求 | 高 | 低 | micro-ROS 專注於「即時與節能」, 讓 ROS 架構能延伸到每一顆感測器與執行器。 --- ### 5. 訊息型別與資料一致性 * ROS 2 與 micro-ROS 共用 `.msg` / `.idl` 機制。 * 所有訊息在編譯階段轉成固定的 C 結構。 * micro-ROS 僅支援定長與靜態資料型別(避免動態記憶體)。 * 主機與 MCU 必須使用相同版本的訊息定義。 這種靜態資料交換方式,是 micro-ROS 能在 100KB RAM 環境下穩定運作的關鍵。 --- ### 6. 系統整合流程 建立一個完整 micro-ROS 系統的步驟: 1. 在 Ubuntu 建立 ROS 2 + micro-ROS Workspace。 2. 使用 `micro_ros_setup` 產生 MCU 專案與工具鏈。 3. 建構 Firmware 並燒錄至 MCU。 4. 啟動 micro-ROS Agent(UDP / Serial)。 5. 用 `ros2 topic echo` 驗證通訊。 6. 整合自訂訊息、QoS 與多節點架構。 這套流程可同時支援開發、模擬與實體硬體部署。 --- ### 7. 實務應用總覽 | 領域 | micro-ROS 的角色 | | ----------- | -------------------- | | **IoT 感測網** | 邊緣節點,負責資料收集與傳輸 | | **智慧機器人** | 馬達控制、里程回報、避障偵測 | | **工業控制** | 即時監測、閥門控制、機械狀態分析 | | **教育研究** | 嵌入式 ROS 教學、封包模擬、網路實驗 | 在這些系統裡,micro-ROS 讓「硬體端」與「軟體端」以同樣的 ROS 語言協作。 --- ### 8. 技術演進與未來方向 * **QoS 擴充**:逐步支援更多 DDS 參數(例如可靠性重傳)。 * **安全通訊**:整合 DDS Security Plugin,提供資料加密與認證。 * **跨語言支援**:未來可能透過 MicroPython 或 Cython Bridge 實驗性加入 Python 綁定。 * **AI at the Edge**:結合微型 AI 模型(如 TinyML)於 micro-ROS 節點上運行。 這些發展代表 micro-ROS 將成為「低功耗 AI 裝置」與「分散式 ROS 系統」的橋樑。 --- ### 9. 全篇總結 micro-ROS 的價值在於「連結」。 > 它把嵌入式裝置與雲端計算之間的鴻溝, > 用 ROS 架構的共同語言縫合起來。 學會 micro-ROS,代表你能掌握: * ROS 架構的內部機制(Node、Topic、DDS)。 * 嵌入式系統的限制與優化思維。 * 分散式系統的通訊模式與整合技術。 最終目標不只是讓 MCU 發送資料, 而是建立一個 **統一、可擴展、即時反應的智慧系統**。 --- ### 10. 延伸閱讀與參考 * [Official micro-ROS Documentation](https://micro.ros.org/docs/) * [ROS 2 Humble API Reference](https://docs.ros.org/en/humble/) * [eProsima Micro XRCE-DDS Specification](https://github.com/eProsima/Micro-XRCE-DDS) * [rclc API Reference (C)](https://github.com/ros2/rclc) * [micro-ROS Tutorials (Official GitHub)](https://github.com/micro-ROS/micro-ROS-demos) --- ### 11. 結語 micro-ROS 不是一項「小技術」, 而是一座讓嵌入式世界進入 ROS 宇宙的橋梁。 它讓感測器不再只是資料來源,而是分散式網路中的「智慧節點」。 這也是現代嵌入式工程與機器人學融合的象徵。 > 從微控制器到雲端,每一層都說 ROS 的語言。 ---

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully