---
# System prepended metadata

title: micro-ROS 理論篇
tags: [MCU, ROS 2, micro-ROS, NCKU]

---

# 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 的語言。

---
