Background
最近在學習 ROS,但目前手上沒有機器人。於是,想以手邊的 iPad 作為 ROS node,並在 mac 上面獲取對應的,諸如 IMU, Camera, Battery … etc 資訊,理解 ROS node sensor 搜集回來的數據跟對應的命令。
在這篇文章中,我們將
- 將 Macbook 作為 ROS node (使用 docker)
- 將 iPad 變成 ROS node (使用 Conduit)
- 傳送 iPad 上 sensor 的資料回 Macbook
將 Macbook 作為 ROS node (使用 docker)
根據 ROS 的文件中,有提到 在 macOS 上安裝 ROS2 的做法。然而,實際安裝時,遇到相當多套件 deprecated、版本相依等問題,經過與 Claude Code 來回幾趟後,在這個階段先果斷放棄,畢竟當前想看到的是,ROS2 送回的數據形式。
以 Docker Image 的做法 是最簡單上手的。
首先,創一個資料夾 ros2-ipad/,以及底下的 config/ 資料夾。
並且我們要準備三個檔案,如底下所示:Dockerfile, docker-compose.yml, config/zenoh_router.json5。
ros2-ipad
|__ Dockerfile
|__ docker-compose.yml
|__ config/zenoh_router.json5
Dockerfile
FROM --platform=linux/arm64 ros:jazzy
RUN apt-get update && apt-get install -y \
ros-jazzy-rmw-zenoh-cpp \
&& rm -rf /var/lib/apt/lists/*
RUN echo "/opt/ros/jazzy/opt/zenoh_cpp_vendor/lib" > /etc/ld.so.conf.d/zenoh.conf && ldconfig
- 使用 jazzy 發行版的 ros,若在 intel 版本的 macbook,請將 platform 改成
linux/amd64。 - 安裝
ros-jazzy-rmw-zenoh-cpp套件 - 修復函式庫路徑
docker-compose.yml
services:
zenoh_router:
build: .
container_name: zenoh_router
ports:
- "7447:7447/tcp"
- "7447:7447/udp"
stdin_open: true
tty: true
environment:
- ROS_DOMAIN_ID=0
- RMW_IMPLEMENTATION=rmw_zenoh_cpp
- LD_LIBRARY_PATH=/opt/ros/jazzy/opt/zenoh_cpp_vendor/lib
- ZENOH_ROUTER_CONFIG_URI=./config/zenoh_router.json5
volumes:
- ./config:/config:ro
command: >
bash -c "source /opt/ros/jazzy/setup.bash &&
ros2 run rmw_zenoh_cpp rmw_zenohd"
| 欄位 | 說明 |
|---|---|
build: . | 使用當前目錄的 Dockerfile 建立映像檔 |
container_name | 容器名稱固定為 zenoh_router |
ports | 將主機的 7447 port 映射到容器,TCP/UDP 都開放,讓 iPad 等外部裝置能連線 |
stdin_open / tty | 保持終端開啟,可互動操作 |
ROS_DOMAIN_ID=0 | ROS 2 網域 ID,同網域的節點才能互相通訊 |
RMW_IMPLEMENTATION | 指定使用 Zenoh 作為 ROS 2 的通訊中介層 |
LD_LIBRARY_PATH | 讓系統找得到 libzenohc.so 函式庫 |
ZENOH_ROUTER_CONFIG_URI | 指定 Zenoh 路由器的設定檔路徑 |
volumes | 將本機 ./config 資料夾掛載到容器內的 /config(唯讀) |
command | 容器啟動後執行:載入 ROS 2 環境 → 啟動 Zenoh 路由器 |
config/zenoh_router.json5
{
mode: "router",
listen: {
endpoints: [
"tcp/0.0.0.0:7447"
],
},
}
| 欄位 | 值 | 說明 |
|---|---|---|
mode | "router" | 以路由器模式啟動,負責轉發所有節點的訊息 |
listen.endpoints | "tcp/0.0.0.0:7447" | 監聽所有網路介面的 7447 port |
因為 docker 沒有固定 IP,我們在這裡先將監聽的 IP address 設定成 0.0.0.0,來監聽所有的網路介面。
執行
在 ros2-ipad/ 資料夾底下,執行
docker compose build
docker compose up

將 iPad 變成 ROS node (使用 Conduit)
在 iPad 的 App Store 上,搜尋並安裝 Conduit, powered by ROS。

設定 ROS Topic
在 Conduit 進來的首頁,可以設定我們想要 public 的 topic。 可以看到有 IMU, GPS, Camera, Battery 等 Topic 可做選擇。

設定 IP Address
在 Macbook 上,至系統設定「System settings > WiFi」底下,取得當前 WiFi 下,Macbook 的 IP address。

在 iPad 上回到 Conduit,點擊右上角的設定按鈕。 將「Zenoh Router > Router Address」設定為 macbook 的位置。

執行
點擊 Conduit 右下角,執行按鈕開始連線。
傳送 iPad 上 sensor 的資料回 Macbook
請注意,iPad 與 Macbook 需要在同一個 WiFi 網路底下
在 iPad 上按下執行後,回到 Macbook 上。
先透過 docker ps 確認當前執行的 container ID。

以 bash 執行進入該容器。
docker exec -it 2e76462241cb bash
啟用服務。
source /opt/ros/jazzy/setup.bash
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
列出當前 subscribe 的 topic。
root@2e76462241cb:/# ros2 topic list
/conduit/camera/front/camera_info
/conduit/camera/front/image_raw/compressed
/parameter_events
/rosout
/tf_static
透過 ros2 topic echo <topic name> 指令, 查看 topic 資料。
root@2e76462241cb:/# ros2 topic echo <topic name>
%% ros2 topic echo /conduit/camera/front/image_raw/compressed %%

成功獲得相機資訊啦!
Conclusion
在這篇文章中,我們記錄了「如何在 Mac 上,將 iPad 作為 ROS2 的 sensor 並取得數據」。 數據流入底下所示:
iPad
↓
tcp/<macbook ip address>:7447
↓
Docker port mapping 7447 → 7447 容器
↓
Zenoh 監聽 0.0.0.0:7447
學習了 ROS2 的指令,並取得 ROS node 的資訊。